Compare commits

..

104 Commits

Author SHA1 Message Date
Jonas Herzig
ea2427a73c Create screenshot folder it it does not yet exist 2018-01-16 21:52:05 +01:00
Jonas Herzig
22e4ce4584 Make sure the replay is stopped if the main menu is opened (fixes #95) 2018-01-16 16:14:03 +01:00
Jonas Herzig
d7368d8c87 Remove 5 character restriction from user names (fixes #97) 2018-01-16 16:05:08 +01:00
Jonas Herzig
eb916c395b Add forge server mod for ReplayRestrictions (fixes #102) 2018-01-16 16:03:19 +01:00
Jonas Herzig
23c5df5aaa Allow the mod to be loaded in a dedicated server environment 2018-01-16 16:01:59 +01:00
Jonas Herzig
5a1e893a45 Deselect marker when selecting keyframe (and vice versa) (fixes #104) 2018-01-16 15:08:42 +01:00
Jonas Herzig
e854635a34 Allow hiding of server IPs in replay viewer by pressing F1 (fixes #105) 2018-01-16 14:52:48 +01:00
Jonas Herzig
5bc5ef5fb8 Add buttons in SP/MP menu for quick en-/disabling of recording 2018-01-16 14:21:38 +01:00
Jonas Herzig
08e0d65685 Remove preshadowJar steps from README.md (no longer required as of a8f2c74) 2018-01-16 14:02:17 +01:00
Jonas Herzig
c654d7bd2f Merge branch '360-screenshots' into 1.8-dev 2018-01-16 13:51:25 +01:00
Jonas Herzig
f8aa97405a Merge branch '1.8-viaversion' into 1.8-dev 2018-01-16 13:46:57 +01:00
Jonas Herzig
38f69c52d9 Merge branch '1.8-reprod' into 1.8-dev 2018-01-16 12:40:20 +01:00
Jonas Herzig
2e62cdf838 Fix dead lock when rendering without immediate jump in time
setupTerrain will loop until (among other conditions) the chunksToUpdate set is
empty. However its size is never decreased during setupTerrain.
Having a (backwards) jump in time right before rendering the first frame would
reset the RenderGlobal due to the world change, leaving the chunksToUpdate set
empty to begin with and due to other changes, chunks are never inserted into it
during rendering (because they're always updated immediately).
The new screenshot feature and rendering a path that's in the future will not
trigger any world change, leaving the render process stuck in a life lock.
2018-01-16 11:42:28 +01:00
CrushedPixel
650cc1036d Fix GuiUploadScreenshot showOnDiskButton crashing the game on Windows 2017-12-22 15:14:20 +01:00
CrushedPixel
666a3611bb Actually hide the GUI when exporting a screenshot 2017-11-01 15:43:49 +01:00
CrushedPixel
a4a9473111 Hide GUI when exporting screenshot
Workaround not all chunks being loaded in screenshot
Fix wrong RenderSettings being exposed in ScreenshotRenderer
Update Language submodule
2017-11-01 15:36:15 +01:00
CrushedPixel
2ebec358e0 Added Screenshot export settings GUI 2017-11-01 13:24:52 +01:00
CrushedPixel
7d380e770a Properly handle OOMExceptions when creating a 360° screenshot 2017-10-31 17:28:21 +01:00
Jonas Herzig
434efd16d1 Fix BetterSprinting compat class not actually functioning (fixes #103) 2017-10-31 11:11:33 +01:00
Jonas Herzig
bfbaec44ba Add logging to BetterSprinting compat class 2017-10-31 11:11:03 +01:00
Jonas Herzig
6c0f63c4d2 Enable reproducible builds on drone 2017-10-28 15:16:02 +02:00
Jonas Herzig
faf5c681de Add script for online-cache building 2017-10-28 15:13:40 +02:00
Jonas Herzig
4ad7d61280 Update reprod mixin dep 2017-10-27 18:54:56 +02:00
Jonas Herzig
f4f42f7257 Merge branch '1.8-dev' into 1.8-reprod 2017-10-27 16:32:19 +02:00
Jonas Herzig
1c888aadc2 Add minVersion to mixin configs and bump bundled mixin version 2017-10-27 16:27:28 +02:00
Jonas Herzig
f82d0e9f9f Skip pom generation for root project 2017-10-27 15:53:19 +02:00
Jonas Herzig
cfee84acbc Manually re-pack FG jar 2017-10-27 15:52:41 +02:00
Jonas Herzig
10ce71efe3 Fix mapwriter crash when opening replay for <MC1.12 (fixes #96) 2017-10-27 14:21:12 +02:00
Jonas Herzig
5fb1cf34e2 Fix half-despawned player entities (see #93) when the entity is moved greater distances 2017-10-16 11:29:15 +02:00
Jonas Herzig
ba4aaa3654 Produce pom.xml instead of shading deps of deps 2017-10-03 18:00:24 +02:00
Jonas Herzig
c07e08386d Fetch pre-built artifact if available 2017-10-03 14:36:51 +02:00
Jonas Herzig
cceed1258d Apply externally generated signature to replaymod.jar if requested 2017-10-03 14:04:03 +02:00
Jonas Herzig
c34b059ed9 Replace manual shade patch for FG with reproducible builds plugin 2017-10-03 11:18:42 +02:00
Jonas Herzig
a45dda3169 Update reproducible builds plugin 2017-10-03 11:18:15 +02:00
CrushedPixel
98098ea2ed Update language submodule 2017-09-27 13:13:49 +02:00
CrushedPixel
d2d7a36139 Added post-screenshot GUI 2017-09-27 13:13:20 +02:00
CrushedPixel
9671ee605d Add 360° screenshot feature when pressing Ctrl + Screenshot Keybind 2017-09-27 00:16:39 +02:00
Jonas Herzig
c18644a208 Use gradle-ecj-plugin to make reproducible builds JDK-independent 2017-09-03 21:32:55 +02:00
Jonas Herzig
5be2f36a78 Use gradle-reproducible-builds-plugin instead of configuring Gradle manually 2017-09-03 17:22:12 +02:00
Jonas Herzig
c21408a9d0 Rebase reprod changes on 1.8 2017-09-03 17:22:12 +02:00
Jonas Herzig
a976d8c58f Whitelist forge json in proxy-witness 2017-09-02 19:25:29 +02:00
Jonas Herzig
a8f2c742e5 Remove ReplayStudio submodule and depend on it via maven instead 2017-09-02 19:25:28 +02:00
Jonas Herzig
25df4f181d Whitelist mcp versions.json in proxy-witness 2017-09-02 19:25:28 +02:00
Jonas Herzig
8b86253103 Replace manually built shadow and gitpatcher plugins with upstream 2017-09-02 19:25:28 +02:00
Jonas Herzig
93b8e52e8b Update checksums 2017-09-02 19:25:28 +02:00
Jonas Herzig
6ef61f0878 Manually build ReplayStudio dep 2017-09-02 19:25:28 +02:00
Jonas Herzig
c44de2b22a Add http proxy for artifact verification, remove gradle-witness 2017-09-02 19:25:26 +02:00
Jonas Herzig
25823e1081 Patch FG to work with proxy-witness 2017-09-02 14:19:36 +02:00
Jonas Herzig
ad3ff3e8ef Move gradle config for reproducible builds into init.gradle file 2017-09-02 14:19:36 +02:00
Jonas Herzig
95fc9a5248 Build FG SNAPSHOT deps manually 2017-09-02 14:19:36 +02:00
Jonas Herzig
acd03c0ee3 OSX has neither "xargs -r" nor "sha256sum" 2017-09-02 14:19:36 +02:00
Jonas Herzig
c561a3fa5a Remove further sources of nondeterminism and update SNAPSHOT hashes 2017-09-02 14:15:51 +02:00
Jonas Herzig
ebbe363954 Allow for reproducible builds
REPRODUCIBLE_BUILD=1 ./gradlew clean :build
2017-09-02 14:15:42 +02:00
Jonas Herzig
adfe6a2bfc Fix NPE when spectated non-player entity despawns (fixes #94) 2017-08-28 10:58:04 +02:00
Jonas Herzig
b27af2781b Fix player entities being half-despawned after jumping in time (fixes #93) 2017-08-28 10:56:37 +02:00
Jonas Herzig
41d2547f3c Update translations 2017-08-26 13:33:30 +02:00
Jonas Herzig
00e999ffd2 Fix replay not being closed when opened via URI scheme handler (fixes #92) 2017-08-25 15:13:27 +02:00
Jonas Herzig
767ea292a7 Fix book gui not being suppressed during replay (fixes #90) 2017-08-25 15:01:06 +02:00
Jonas Herzig
5b04edbbd3 Hide ReplayMod app entry from menus on Linux 2017-08-24 20:56:03 +02:00
Jonas Herzig
6aff99d3ac Fix livelock during netty write to embedded channel (fixes #85) 2017-08-23 22:14:08 +02:00
Jonas Herzig
703805f269 Fix infinite loop in mc.scheduledTasks (fixes #86) 2017-08-23 22:12:38 +02:00
Jonas Herzig
6a7147b401 Use ReplayInputStream to support loading older replays on newer MC 2017-08-23 20:31:08 +02:00
Jonas Herzig
7a4440c4a8 Update ReplayStudio
44109f1 Recover from corrupted entity positions cache (fixes #73)
2017-08-21 10:33:26 +02:00
Jonas Herzig
0b9c56cdfd Fix resource packs not working after first time jumping back in time 2017-08-19 15:20:40 +02:00
Jonas Herzig
933ee5f866 [Compat] Fix camera entity with BetterSprinting prior to 2.0.0 (fixes #78) 2017-08-16 15:57:32 +02:00
Jonas Herzig
83b1090e42 Fix hotbar being visible while spectating player (fixes #83) 2017-08-16 13:00:49 +02:00
Jonas Herzig
5c73117e9f [Compat] Fix invisible entities with Orange's 1.7 Animations (fixes #78) 2017-08-16 12:19:48 +02:00
Jonas Herzig
4704b2984e Replace the RenderPlayer hook (used subclassing) with a mixin (fixes #79) 2017-08-14 10:55:09 +02:00
Jonas Herzig
0c226b0236 Fix path at end of replay resulting in constant reloading (fixes #56) 2017-08-13 12:53:44 +02:00
Jonas Herzig
1b9b13ee7f Rename render success sound to all lowercase (required for 1.11) (fixes #66) 2017-08-13 12:14:12 +02:00
Jonas Herzig
c2000b3edc Fix only front-facing chunks visible for ODS rendering (fixes #67) 2017-08-13 12:03:06 +02:00
Jonas Herzig
aafeecc670 Fix initial login gui not closing on success (fixes #68) 2017-08-12 14:27:54 +02:00
Jonas Herzig
9292add867 Use percent-encoding for replay file names (fixes #71) 2017-08-12 14:20:29 +02:00
Jonas Herzig
8499c0f154 Fix name of invis armor stand with CustomNameVisible not rendering (fixes #72) 2017-08-12 13:19:18 +02:00
Jonas Herzig
b9ea572e19 Try to handle invalid ffmpeg arguments more gracefully (fixes #77)
Instead of outright crashing, if the user has modified the ffmpeg arguments,
they are given the chance to re-try with the defaults.
2017-08-12 11:38:11 +02:00
Jonas Herzig
a2f8c88a3d Fix compression packets being recorded (fixes #80) 2017-08-11 15:19:14 +02:00
Jonas Herzig
19629c32f0 Replace usages of System.out with logger 2017-08-11 15:10:30 +02:00
Jonas Herzig
fe1d9b828d Stop Forge from allowing the mod to load on other MC versions (fixes #82) 2017-08-11 14:54:10 +02:00
Jonas Herzig
1a1e96c375 Fix server with RM installed refusing clients without RM (fixes #76) 2017-07-14 13:08:16 +02:00
Jonas Herzig
35eb9cad33 Replace usage of FMLLog with the mod logger 2017-07-14 13:08:12 +02:00
Jonas Herzig
91573d9487 Update jGui, ReplayStudio and Translations
jGui:
9e84e72 Fix inversion of empty selection

ReplayStudio:
ff12b1d Remove invalid filter from services files
c6a9325 Proper value wrapping in CatmullRomSplineInterpolator (fixes #8 GH)
2017-05-31 09:16:19 +02:00
Jonas Herzig
d71358bcba Add confirmation dialog before overwriting path presets (fixes #65) 2017-05-21 19:34:46 +02:00
Jonas Herzig
1a55983986 Move addCallback method from integration test Utils to main Utils 2017-05-21 19:34:46 +02:00
Jonas Herzig
18c5bcd469 Be more cooperative with other mods on the ingame menu (fixes #42) 2017-05-21 18:59:29 +02:00
Jonas Herzig
c054fe83f6 Register keys for simplepathing only once (fixes #63) 2017-05-21 17:11:15 +02:00
Jonas Herzig
f13297c5a5 Fix default interpolator handling in keyframe gui and after loading (fixes #64) 2017-05-21 16:29:59 +02:00
Jonas Herzig
391f304c5f Show error popup if entity tracker fails to load 2017-05-21 12:42:13 +02:00
Jonas Herzig
0e0eaaa9a7 Fix entity tracker being set even if it failed loading (fixes #50) 2017-05-21 12:27:20 +02:00
Jonas Herzig
a34bbbcd68 Fix NPE when spectating a player without a camera entity 2017-05-21 11:57:30 +02:00
Jonas Herzig
60879fbbed Change local class to be an inner class because Srg2Source breaks with it 2017-04-21 17:24:43 +02:00
Jonas Herzig
dfafbecf35 Load translations from github repo, only reload language not all resource packs 2017-04-21 16:36:47 +02:00
Jonas Herzig
8a6ec5191b Add missing tooltips to player overview and various missing chat messages 2017-04-21 16:36:47 +02:00
Jonas Herzig
5677fc54cb Re-add warning to replay editor 2017-04-21 16:36:47 +02:00
Jonas Herzig
748a91e7b2 Fix missing tooltips on fav/like/dislike buttons in replay center 2017-04-21 16:36:47 +02:00
Jonas Herzig
ee24866f29 Fix upload replay button not being updated when name/tags change 2017-04-21 16:36:47 +02:00
Jonas Herzig
dba085c700 Move translations into separate repo 2017-04-21 16:36:47 +02:00
Jonas Herzig
3f0e3e725e Fix NPE when receiving Replay|Restrict messages (fixes #16 GH) 2017-04-21 13:38:08 +02:00
johni0702
40e1d850da Fix crash when saving the last keyframe in the edit gui (fixes #61) 2017-04-14 17:31:16 +02:00
johni0702
03aada1f5f Update Mixin to 0.6.8 (fixes #9 GH) 2017-04-14 17:31:16 +02:00
johni0702
0c1dc658ad Fix interpolator being lost when moving keyframe to the end (fixes #62) 2017-04-14 17:31:16 +02:00
johni0702
fcbbbc9ea1 Add integration test. Run with ./gradlew runIntegrationTest 2017-04-14 17:31:15 +02:00
johni0702
fe6ded0143 Fix movement of keyframe via GuiEditKeyframe not updating selected keyframe
Selecting a keyframe, double clicking it to open the gui, changing the
timestamp, saving and then clicking the Add/Remove Keyframe button used to
crash the client. This is fixed by updating the selection whenever the time is
changed.
2017-04-13 18:18:17 +02:00
johni0702
f58fa8f9c2 Fix Login GUI not respecting other GUIs opened on startup
Previously the Login GUI would simply replace the currently active GUI.
Now the currently active GUI is stored and then re-opened after login.
2017-04-13 18:12:07 +02:00
johni0702
4fc3a3166c Fix OpenEye being installed into working dir instead of mcDataDir 2017-04-13 18:06:21 +02:00
172 changed files with 5251 additions and 1693 deletions

View File

@@ -6,9 +6,8 @@ pipeline:
image: maven:3.3.9-jdk-8
commands:
- curl --fail --create-dirs -o $HOME/.gradle/init.d/mirror.gradle https://maven.johni0702.de/config/gradle
- curl --fail --create-dirs -o $HOME/.m2/settings.xml https://maven.johni0702.de/config/maven
- JAVA_OPTS=-Xmx1516M ./gradlew setupDecompWorkspace
- ./gradlew :build
- git config --global user.email "replaymod@drone" && git config --global user.name "Drone"
- SIGNED_JAR=$(! git describe --exact 2>&1 > /dev/null; echo $?) REPRODUCIBLE_BUILD=1 ./gradlew :build
archive:
image: plugins/s3
acl: public-read

View File

@@ -1 +1 @@
eyJhbGciOiJIUzI1NiJ9.cGlwZWxpbmU6CiAgY2xvbmU6CiAgICBpbWFnZTogcGx1Z2lucy9naXQKICAgIHRhZ3M6IHRydWUKICBidWlsZDoKICAgIGltYWdlOiBtYXZlbjozLjMuOS1qZGstOAogICAgY29tbWFuZHM6CiAgICAgIC0gY3VybCAtLWZhaWwgLS1jcmVhdGUtZGlycyAtbyAkSE9NRS8uZ3JhZGxlL2luaXQuZC9taXJyb3IuZ3JhZGxlIGh0dHBzOi8vbWF2ZW4uam9obmkwNzAyLmRlL2NvbmZpZy9ncmFkbGUKICAgICAgLSBjdXJsIC0tZmFpbCAtLWNyZWF0ZS1kaXJzIC1vICRIT01FLy5tMi9zZXR0aW5ncy54bWwgaHR0cHM6Ly9tYXZlbi5qb2huaTA3MDIuZGUvY29uZmlnL21hdmVuCiAgICAgIC0gSkFWQV9PUFRTPS1YbXgxNTE2TSAuL2dyYWRsZXcgc2V0dXBEZWNvbXBXb3Jrc3BhY2UKICAgICAgLSAuL2dyYWRsZXcgOmJ1aWxkCiAgYXJjaGl2ZToKICAgIGltYWdlOiBwbHVnaW5zL3MzCiAgICBhY2w6IHB1YmxpYy1yZWFkCiAgICByZWdpb246ICJ1cy1lYXN0LTEiCiAgICBidWNrZXQ6ICJyZXBsYXltb2QiCiAgICBwYXRoX3N0eWxlOiB0cnVlCiAgICBzb3VyY2U6IGJ1aWxkL2xpYnMvKgogICAgc3RyaXBfcHJlZml4OiBidWlsZC9saWJzLwogICAgdGFyZ2V0OiAvCg.nzPW0_TpMIjnFZZ5Ci439QDKlaDo1a3DCH-VCYUgpx8
eyJhbGciOiJIUzI1NiJ9.cGlwZWxpbmU6CiAgY2xvbmU6CiAgICBpbWFnZTogcGx1Z2lucy9naXQKICAgIHRhZ3M6IHRydWUKICBidWlsZDoKICAgIGltYWdlOiBtYXZlbjozLjMuOS1qZGstOAogICAgY29tbWFuZHM6CiAgICAgIC0gY3VybCAtLWZhaWwgLS1jcmVhdGUtZGlycyAtbyAkSE9NRS8uZ3JhZGxlL2luaXQuZC9taXJyb3IuZ3JhZGxlIGh0dHBzOi8vbWF2ZW4uam9obmkwNzAyLmRlL2NvbmZpZy9ncmFkbGUKICAgICAgLSBnaXQgY29uZmlnIC0tZ2xvYmFsIHVzZXIuZW1haWwgInJlcGxheW1vZEBkcm9uZSIgJiYgZ2l0IGNvbmZpZyAtLWdsb2JhbCB1c2VyLm5hbWUgIkRyb25lIgogICAgICAtIFNJR05FRF9KQVI9JCghIGdpdCBkZXNjcmliZSAtLWV4YWN0IDI-JjEgPiAvZGV2L251bGw7IGVjaG8gJD8pIFJFUFJPRFVDSUJMRV9CVUlMRD0xIC4vZ3JhZGxldyA6YnVpbGQKICBhcmNoaXZlOgogICAgaW1hZ2U6IHBsdWdpbnMvczMKICAgIGFjbDogcHVibGljLXJlYWQKICAgIHJlZ2lvbjogInVzLWVhc3QtMSIKICAgIGJ1Y2tldDogInJlcGxheW1vZCIKICAgIHBhdGhfc3R5bGU6IHRydWUKICAgIHNvdXJjZTogYnVpbGQvbGlicy8qCiAgICBzdHJpcF9wcmVmaXg6IGJ1aWxkL2xpYnMvCiAgICB0YXJnZXQ6IC8K.cFk9CFCSYjJSwQhcJJp0BqSMwigKYCBd6r-KkvxlQZ0

BIN
.gitignore vendored

Binary file not shown.

6
.gitmodules vendored
View File

@@ -2,6 +2,6 @@
path = jGui
url = https://github.com/ReplayMod/jGui
[submodule "ReplayStudio"]
path = ReplayStudio
url = https://github.com/ReplayMod/ReplayStudio
[submodule "src/main/resources/assets/replaymod/lang"]
path = src/main/resources/assets/replaymod/lang
url = https://github.com/ReplayMod/Translations

View File

@@ -12,7 +12,7 @@ to access private fields is a good indication that this has happened).
You can build the mod by running `./gradlew :build`. You can then find the final jar files in `build/libs/`.
### IntelliJ
For the initial setup run `./gradlew preshadowJar idea genIntellijRuns`.
For the initial setup run `./gradlew idea genIntellijRuns`.
You also need to enable the Mixin annotation processor:
1. Go to File -> Settings -> Build, Execution, Deployment -> Compiler -> Annotation Processors
2. Tick "Enable annotation processing"
@@ -20,8 +20,8 @@ You also need to enable the Mixin annotation processor:
4. Set the name to "reobfSrgFile" and the value to "$path/build/mcp-srg.srg" where you replace $path with the full
path to the folder containing the gradlew file
Whenever you switch to another branch, you can either just run `./gradlew preshadowJar idea` or instead run
`./gradlew preshadowJar copySrg` and then refresh the gradle project from within IntelliJ.
Whenever you switch to another branch, you can either just run `./gradlew idea` or instead run
`./gradlew copySrg` and then refresh the gradle project from within IntelliJ.
### Eclipse

Submodule ReplayStudio deleted from 44f7345b6b

View File

@@ -1,7 +1,5 @@
import groovy.json.JsonOutput
import java.util.zip.ZipInputStream
buildscript {
repositories {
mavenCentral()
@@ -19,8 +17,8 @@ buildscript {
}
}
dependencies {
classpath 'net.minecraftforge.gradle:ForgeGradle:2.2-SNAPSHOT'
classpath 'org.spongepowered:mixingradle:0.4-SNAPSHOT'
classpath 'net.minecraftforge.gradle:ForgeGradle:2.0-SNAPSHOT'
classpath 'org.spongepowered:mixingradle:0.3-SNAPSHOT'
}
}
@@ -36,11 +34,13 @@ archivesBaseName = "replaymod"
minecraft {
coreMod = 'com.replaymod.core.LoadingPlugin'
version = '1.9.4-12.17.0.1976'
version = '1.8-11.14.4.1563'
runDir = "eclipse"
mappings = "snapshot_20160518"
mappings = "snapshot_nodoc_20141130"
replace '@MOD_VERSION@', project.version
replace '@MC_VERSION@', project.minecraft.version
// Includes intentional whitespace to stop Forge from declaring the mod to be compatible with
// a newer srg-compatible MC version (that may be using a different protocol version)
replace '@MC_VERSION@', "[ ${project.minecraft.version} ]"
}
repositories {
@@ -48,9 +48,7 @@ repositories {
name = "SpongePowered Repo"
url = "http://repo.spongepowered.org/maven/"
}
maven {
url 'https://repo.spacehq.org/content/repositories/snapshots/'
}
maven { url 'https://jitpack.io' }
}
configurations {
@@ -61,7 +59,7 @@ configurations {
dependencies {
compile 'org.projectlombok:lombok:1.16.4'
compile 'org.spongepowered:mixin:0.6.4-SNAPSHOT'
compile 'org.spongepowered:mixin:0.7.5-SNAPSHOT'
shade 'com.googlecode.mp4parser:isoparser:1.1.7'
shade 'org.apache.commons:commons-exec:1.3'
shade 'com.google.apis:google-api-services-youtube:v3-rev178-1.22.0'
@@ -71,24 +69,20 @@ dependencies {
shade 'org.aspectj:aspectjrt:1.8.2'
compile project(':ReplayStudio')
shade 'com.github.replaymod:ReplayStudio:a2168ca'
testCompile 'junit:junit:4.11'
}
tasks['idea'].dependsOn ':ReplayStudio:preshadowJar'
jar {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
dependsOn configurations.compile
dependsOn configurations.shade
dependsOn ':ReplayStudio:shadowJar'
def shade = {files(
configurations.compile.findAll {it.name.startsWith 'mixin-'}
+ configurations.shade
+ getTasks().getByPath(':ReplayStudio:shadowJar').outputs.files
)}
def noticeDir = file("$buildDir/NOTICE")
@@ -103,34 +97,13 @@ jar {
}
from noticeDir
def langDir = file("$buildDir/languages")
doFirst {
try {
langDir.deleteDir()
langDir.mkdirs()
def dir = new File(langDir, 'assets/replaymod/lang/')
dir.mkdirs()
def zip = new ZipInputStream(new URL('http://replaymod.com/api/grab_languages').openStream())
def e;
while ((e = zip.nextEntry) != null) {
new File(dir, e.getName()) << zip
zip.closeEntry()
}
} catch(Exception e) {
e.printStackTrace();
}
}
from (langDir) {
exclude '**/en_US.lang'
}
from ({shade().collect { it.isDirectory() ? it : zipTree(it) }}) {
exclude '**/NOTICE*'
// exclude everything taken in from jGui for running the mod in a dev environment
exclude { new File(file('jGui/src/main/resources'), it.relativePath.pathString).exists() }
eachFile {
if (getName() == 'LICENSE.txt') {
setName(getFile().getParentFile().getName().split('-')[0] + '-LICENSE.txt')
setName(getFile().getParentFile().getName().split('.jar_')[0] + '-LICENSE.txt')
}
}
}
@@ -138,7 +111,6 @@ jar {
manifest {
attributes 'TweakClass': 'org.spongepowered.asm.launch.MixinTweaker',
'TweakOrder': '0',
'FMLCorePluginContainsFMLMod': 'true',
'FMLAT': 'replaymod_at.cfg'
}
}
@@ -187,7 +159,14 @@ sourceSets {
resources {
srcDir 'jGui/src/main/resources'
}
refMap = "mixins.replaymod.refmap.json"
ext.refMap = "mixins.replaymod.refmap.json"
}
integrationTest {
compileClasspath += main.runtimeClasspath + main.output
java {
srcDir file('src/integration-test/java')
}
resources.srcDir file('src/integration-test/resources')
}
}
@@ -200,6 +179,30 @@ setupDecompWorkspace.dependsOn copySrg
setupDevWorkspace.dependsOn copySrg
project.tasks.idea.dependsOn copySrg
task runIntegrationTest(type: JavaExec, dependsOn: ["makeStart", "jar"]) {
main = 'GradleStart'
standardOutput = System.out
errorOutput = System.err
workingDir file(minecraft.runDir)
def testDir = new File(minecraft.runDir, "integration-test")
doFirst {
testDir.deleteDir()
testDir.mkdirs()
}
doLast {
testDir.deleteDir()
}
afterEvaluate {
def runClient = tasks.getByName("runClient")
runIntegrationTest.jvmArgs = runClient.jvmArgs + "-Dfml.noGrab=true"
runIntegrationTest.args = runClient.args + "--gameDir" + testDir.canonicalPath
runIntegrationTest.classpath runClient.classpath + sourceSets.integrationTest.output
}
}
def generateVersionsJson() {
// List all tags
def stdout = new ByteArrayOutputStream()

478
gradle/reprod/checksums.txt Normal file
View File

@@ -0,0 +1,478 @@
0ab7e4217b2702316adceabd4c1dfca0250dbe33c22e08c98b433939207edfc0 /com/cloudbees/cloudbees-oss-parent/1/cloudbees-oss-parent-1.pom
e6509db2167c983d254d3530c66a060443e91a6ca38df9fdc4ef2a88ad813fa5 /com/cloudbees/diff4j/1.1/diff4j-1.1.jar
a09a4ac520f9ec5ccd16195272fd8ed4c667285f9e129da5acf633bb21a7d174 /com/cloudbees/diff4j/1.1/diff4j-1.1.pom
754184022345800c2d066eceeaf2f7a88a7c2aaeae23eb1c76ef598854aa9157 /com/fasterxml/jackson/core/jackson-core/2.1.3/jackson-core-2.1.3.jar
cc3bfcc34a29c041e7cafc05ed6f0c3ebf8a7dcf812489a64f4c37f4f5279adf /com/fasterxml/jackson/core/jackson-core/2.1.3/jackson-core-2.1.3.pom
a30a3f89fbbea23deb5290e832eb0d12a8171ae8ba4461af2b936ed0245ee697 /com/fasterxml/oss-parent/4/oss-parent-4.pom
4cad4ee2f1c379fa1f6496912fe026d8a4f2febf0a140ff867206b00a22f988f /com/github/abrarsyed/jastyle/jAstyle/1.3/jAstyle-1.3.jar
cd62bdfd946618c26b49451084361edf79cd6ddb3eae1a485ecb05319295896d /com/github/abrarsyed/jastyle/jAstyle/1.3/jAstyle-1.3.pom
33b3d79f3e27d33c46411ab7b7d81f43f12756e18c8936063f18b1a950a5f84b /com/github/jengelman/gradle/plugins/shadow/1.2.3/shadow-1.2.3.jar
f00facfc855e7d5517fc57553614b4690e61df9ab44f6e93ff583ae201b5a3aa /com/github/jengelman/gradle/plugins/shadow/1.2.3/shadow-1.2.3.pom
27fc3b7f0436f532c9d798dbc006d7e0b9b7c9b436f8d977f122665c633e9892 /com/github/johni0702/gradle-ecj-plugin/795736c/gradle-ecj-plugin-795736c.jar
f98b3e07c6b6a32dd6f9f70f5cef4ac9be42a9a6c850ceb8f33767da94706635 /com/github/johni0702/gradle-ecj-plugin/795736c/gradle-ecj-plugin-795736c.pom
11f4032947acc6ef1be538031cb0ea4d2fdfd50d97a0391af27bff3274a239f2 /com/github/johni0702/gradle-reproducible-builds-plugin/a524ada/gradle-reproducible-builds-plugin-a524ada.jar
03e3dff7f9b3ac6cd3b87684fd36a2f6996a4b164a2f8fab9c22c01cb7bfb84b /com/github/johni0702/gradle-reproducible-builds-plugin/a524ada/gradle-reproducible-builds-plugin-a524ada.pom
75ccc0e24d37ed5b8916e1bcffad1e067c2b1cfa21b635287f968db5c3c1963a /com/github/jponge/lzma-java/1.3/lzma-java-1.3.jar
fbcba81b21a8bc3c0761e4798fa05285444b43d681c03c9af49f9b2e1ecb0184 /com/github/jponge/lzma-java/1.3/lzma-java-1.3.pom
04d7ceaf1e83006d2d93518884353a7856399669332d1174f2572e3d6ec03cd3 /com/github/replaymod/ReplayStudio/a2168ca/ReplayStudio-a2168ca.jar
0703ef825f3e3cd0943f6955fd12da923eb255ed94fe421cbb207b2dcfd61ba4 /com/github/replaymod/ReplayStudio/a2168ca/ReplayStudio-a2168ca.pom
c6ebd74cd6108b8c372c95b842725ee5bd6d3303ba26cb00f18bc92f80b47956 /com/github/tony19/named-regexp/0.2.3/named-regexp-0.2.3.jar
7cdd89a892927998beab59398ef073232588f6e83e411cf4f0905833bf300487 /com/github/tony19/named-regexp/0.2.3/named-regexp-0.2.3.pom
47c625c83a8cf97b8bbdff2acde923ff8fd3174e62aabcfc5d1b86692594ffba /com/google/api-client/google-api-client/1.22.0/google-api-client-1.22.0.jar
83175461277124a08d23d9df647912771276fed44ce60ff03847b51c98bf7459 /com/google/api-client/google-api-client/1.22.0/google-api-client-1.22.0.pom
d68647ba10cfa33e0b6e538c704723229932795d5ee495288cec46a6156c5891 /com/google/api-client/google-api-client-gson/1.20.0/google-api-client-gson-1.20.0.jar
383d5b31bfa2b5599de972dfc3d77750b8015c9496f66c591d92ca778a23dd4e /com/google/api-client/google-api-client-gson/1.20.0/google-api-client-gson-1.20.0.pom
df4f423f33f467d248e51deb555404771f7bc41430b2d4d1e49966c79c0b207b /com/google/api-client/google-api-client-java6/1.20.0/google-api-client-java6-1.20.0.jar
766995ae6c9240e1c77a68b3347706506ecde95aa8196ddd4ed567ce8df8cceb /com/google/api-client/google-api-client-java6/1.20.0/google-api-client-java6-1.20.0.pom
d8e9ec26a01cc19c530ab781cc71185acb9f9d576716e3d585a1d4f12f2089c8 /com/google/api-client/google-api-client-parent/1.20.0/google-api-client-parent-1.20.0.pom
2bc283b1247550e6e8401d97dc7f1ac2d5b17382b9984df011d9a3564fe632ae /com/google/api-client/google-api-client-parent/1.22.0/google-api-client-parent-1.22.0.pom
88debb16c533600c3b0290a088f2de3b3a8318ff86ebe0bdbcefeab0a0eafb9e /com/google/apis/google-api-services-youtube/v3-rev178-1.22.0/google-api-services-youtube-v3-rev178-1.22.0.jar
4dad29307c34e923ebb6d29e2c265850a0f0b691c7a63384279aa8353eae28b9 /com/google/apis/google-api-services-youtube/v3-rev178-1.22.0/google-api-services-youtube-v3-rev178-1.22.0.pom
905721a0eea90a81534abb7ee6ef4ea2e5e645fa1def0a5cd88402df1b46c9ed /com/google/code/findbugs/jsr305/1.3.9/jsr305-1.3.9.jar
feab9191311c3d7aeef2b66d6064afc80d3d1d52d980fb07ae43c78c987ba93a /com/google/code/findbugs/jsr305/1.3.9/jsr305-1.3.9.pom
1e7f53fa5b8b5c807e986ba335665da03f18d660802d8bf061823089d1bee468 /com/google/code/findbugs/jsr305/2.0.1/jsr305-2.0.1.jar
02c12c3c2ae12dd475219ff691c82a4d9ea21f44bc594a181295bf6d43dcfbb0 /com/google/code/findbugs/jsr305/2.0.1/jsr305-2.0.1.pom
8cc1f0813a186079f82d300a43156bdf852a88008f4f1a1fa71e788fb3b9a86d /com/google/code/google-collections/google-collect/snapshot-20080530/google-collect-snapshot-20080530.jar
7d131d6a082a33363bdfbf55d2fee2219d9bc8d1c455cc3f7c6403cf2a4496a5 /com/google/code/google-collections/google-collect/snapshot-20080530/google-collect-snapshot-20080530.pom
35c94198255e95f6f11501eb4b3d43a5276bfdd142ab7c904722e69bff51f69e /com/google/code/gson/gson/2.1/gson-2.1.jar
894da89d477e805389c9df1d6fa8bd552285aed56a399d5749213520a7c74054 /com/google/code/gson/gson/2.1/gson-2.1.pom
c0328cd07ca9e363a5acd00c1cf4afe8cf554bd6d373834981ba05cebec687fb /com/google/code/gson/gson/2.2.4/gson-2.2.4.jar
ae984d5d19894ce6dc4689866eaa12f8fc31409113e60ee3b44853b8ac4fd380 /com/google/code/gson/gson/2.2.4/gson-2.2.4.pom
4838f4f29a027522363cef1bcda1b48808880b0de4953fab6db4121ee27b649b /com/googlecode/jarjar/jarjar/1.1/jarjar-1.1.jar
be4f53c0bc04da4e3d6c65c8f3243d1ea4135e35c7d7dda88af1c582687263d7 /com/googlecode/jarjar/jarjar/1.1/jarjar-1.1.pom
d1296fa8926f71743be61cb4bfdac2ac3deb9ffe1a4948b1f293cb7a1bdb1800 /com/googlecode/javaewah/JavaEWAH/0.5.6/JavaEWAH-0.5.6.jar
fa5c2d7edcd57c6e1b402773dc32a180f82c111af44bfc2d483a2c7be1862e8f /com/googlecode/javaewah/JavaEWAH/0.5.6/JavaEWAH-0.5.6.pom
ddbbf392f8e61f770a509a49aed5f32ead19768283b4b512c626e09e1ba5cc46 /com/googlecode/mp4parser/isoparser/1.1.7/isoparser-1.1.7.jar
6890ebacb23d3ab51a5751a830f5269b7e8fdd19d08b7e055bc739f62b4bd174 /com/googlecode/mp4parser/isoparser/1.1.7/isoparser-1.1.7.pom
8c36a80ea613d0b6b8040a17cf837c5bbe3677bc1b06a058a6c174fdb787ebbc /com/google/guava/guava/17.0/guava-17.0.jar
2a0d16010d3825c732aeab1d25f181074945063d8f76c28004e7d423d66cb75b /com/google/guava/guava/17.0/guava-17.0.pom
d664fbfc03d2e5ce9cab2a44fb01f1d0bf9dfebeccc1a473b1f9ea31f79f6f99 /com/google/guava/guava/18.0/guava-18.0.jar
e743d61d76f76b5dc060d6f7914fdd41c4418b3529062556920116a716719836 /com/google/guava/guava/18.0/guava-18.0.pom
58d4cc2e05ebb012bbac568b032f75623be1cb6fb096f3c60c72a86f7f057de4 /com/google/guava/guava/19.0/guava-19.0.jar
addc064da7f1077fdf4dc90e5aaa887cd790850d1b74fe2e6e25d5f78551ac63 /com/google/guava/guava/19.0/guava-19.0.pom
59bf456547b6dda3ced968cb56f7f2d3e14474e2de2960a32c47e31c1e456c61 /com/google/guava/guava-jdk5/17.0/guava-jdk5-17.0.jar
f8c152627813d45bc4e7cc17ad6ed6a649a0231ae819ffb8e05d19b205a3db66 /com/google/guava/guava-jdk5/17.0/guava-jdk5-17.0.pom
9fba53585551d3c775179de859760a73c4beab407dfde16b551a09a87b50532a /com/google/guava/guava-parent/17.0/guava-parent-17.0.pom
a4accc8895e757f6a33f087e4fd0b661c5638ffe5e0728f298efe7d80551b166 /com/google/guava/guava-parent/18.0/guava-parent-18.0.pom
3b76ff43ecdf10f74da36e4aae2b470c9d063e053c5ca026f5512ae94f1c3e10 /com/google/guava/guava-parent/19.0/guava-parent-19.0.pom
5a9606bc27632956b3c11df887e9b3e785854068aaa4e0808ed5660f60b1fb6f /com/google/guava/guava-parent-jdk5/17.0/guava-parent-jdk5-17.0.pom
f744c79f198e53deea4cd311f9135a568ab67052804d80fd3d60b0385644cf65 /com/google/http-client/google-http-client/1.20.0/google-http-client-1.20.0.pom
f88ffa329ac52fb4f2ff0eb877ef7318423ac9b791a107f886ed5c7a00e77e11 /com/google/http-client/google-http-client/1.22.0/google-http-client-1.22.0.jar
30e7611df40360bdc24325caaa2f7888e847680f2e64e579c28c87a53e5bb422 /com/google/http-client/google-http-client/1.22.0/google-http-client-1.22.0.pom
cc144c70d40acf7c6e6f773ac19a2ac6e3ed9830d8e33e32421ff21a91450994 /com/google/http-client/google-http-client-gson/1.20.0/google-http-client-gson-1.20.0.jar
9b292239a52300b687940164987f0fccc1132049e774d8d90274998e58949f7c /com/google/http-client/google-http-client-gson/1.20.0/google-http-client-gson-1.20.0.pom
45b1e34b2dcef5cb496ef25a1223d19cf102b8c2ea4abf96491631b2faf4611c /com/google/http-client/google-http-client-jackson2/1.22.0/google-http-client-jackson2-1.22.0.jar
184c3aaa66f32be7bf592caab362becd10a80b15b077c3ebe9ae9fa9d387f41a /com/google/http-client/google-http-client-jackson2/1.22.0/google-http-client-jackson2-1.22.0.pom
5c592d663ac30387eb30551a20cbd401bde859095f94ec2bef8ed2a4acf7a8f1 /com/google/http-client/google-http-client-parent/1.20.0/google-http-client-parent-1.20.0.pom
3927309767100e548d1f5c20e150d75716e03a3d8a1a1b970c8a75fbddae072e /com/google/http-client/google-http-client-parent/1.22.0/google-http-client-parent-1.22.0.pom
f279a8172e7671c9dcd896850aaa6ce85e1d93e5bc0a10fd7c7a6efbf76f60db /com/google/oauth-client/google-oauth-client/1.20.0/google-oauth-client-1.20.0.pom
a4c56168b3e042105d68cf136e40e74f6e27f63ed0a948df966b332678e19022 /com/google/oauth-client/google-oauth-client/1.22.0/google-oauth-client-1.22.0.jar
52a2b2c1a4365668545134157ee7bb141c6b537caa29a4e51f3228ce0bbbeaf9 /com/google/oauth-client/google-oauth-client/1.22.0/google-oauth-client-1.22.0.pom
3149ae4fa222c7e804c5b7bc0d044702bc6bb8309b5ed94f6d350a5d4d657fc9 /com/google/oauth-client/google-oauth-client-java6/1.20.0/google-oauth-client-java6-1.20.0.jar
61233bbb437dc91504076a644ce77b1066f679d1252362d08de67d296c404cf0 /com/google/oauth-client/google-oauth-client-java6/1.20.0/google-oauth-client-java6-1.20.0.pom
daabf9d4e35d4015c2c917982463572856a5c8d7fa718e94edb2b6b114a2a8a2 /com/google/oauth-client/google-oauth-client-jetty/1.20.0/google-oauth-client-jetty-1.20.0.jar
2c594b64206b24c2ec9506769cac5c637346152c7822f0337721776c6eb092db /com/google/oauth-client/google-oauth-client-jetty/1.20.0/google-oauth-client-jetty-1.20.0.pom
374fb28a2c74f92999de4d843f788838f38fd89b570c95813513546a0e7ae3ca /com/google/oauth-client/google-oauth-client-parent/1.20.0/google-oauth-client-parent-1.20.0.pom
2e7acb933f8c1b801b78925e4d22c32040a414dc7246bfdb777d8ad78404fa66 /com/google/oauth-client/google-oauth-client-parent/1.22.0/google-oauth-client-parent-1.22.0.pom
bbc21cab2e0b0c76c9977fdf8b80c311788094d81e6910a2a6e63d80910102c7 /com/gradle/publish/plugin-publish-plugin/0.9.1/plugin-publish-plugin-0.9.1.jar
89aa507536b0a93d8c9d3087d738255eefffc002cefa255ebdbd6891b8165447 /com/gradle/publish/plugin-publish-plugin/0.9.1/plugin-publish-plugin-0.9.1.pom
147592c5eb8e11fc8394125954f877acf25918bae13aa210c2825aefc3030ed8 /com/ibm/icu/icu4j-core-mojang/51.2/icu4j-core-mojang-51.2.jar
06b382efe9d60474aa3df7f4851397b3ae0c4f142567f0fc66a8fa2706a665e4 /com/ibm/icu/icu4j-core-mojang/51.2/icu4j-core-mojang-51.2.pom
48cd629c3081dff4d8c35e7da4efb3bcc4ed4b35c8a7e8198d5c30e0312bd912 /com/jcraft/jsch/0.1.46/jsch-0.1.46.jar
eb60cec1e570efad3d750afd9a86b763dba49e47c3c106a599c05e708260efc4 /com/jcraft/jsch/0.1.46/jsch-0.1.46.pom
2c149735a093b6c65a27db760896ad5c5b06e29100bb8969937667784fef4ba0 /com/mojang/authlib/1.5.16/authlib-1.5.16.jar
d05175230d79f518b5c4664d24e3d115f5f3888e3806f3b6076cd0b4943e6ca6 /com/mojang/authlib/1.5.16/authlib-1.5.16.pom
ce7a9c86ebebf30b89929026f4a0a3c58ce0f4d47937d6dc086ae4fd0c77544a /com/mojang/authlib/1.5.21/authlib-1.5.21.jar
d59283c7303b42e416518d8f5c265895295c11690fd8d36079f1a04c6a56b17c /com/mojang/authlib/1.5.21/authlib-1.5.21.pom
3120fd24c09ab9bc088cb9c1eb2065be86718608450fdbc27b5d371729a619cb /com/mojang/netty/1.6/netty-1.6.jar
568cc3fad81e5e389bad0012a07eca5db073e287200c6c9cb02caf3dc489e9f6 /com/mojang/netty/1.6/netty-1.6.pom
0ad91190cd480af14954d361d7b9ffc53ab3c5344797e3c9fd90c29bf5d28499 /com/mojang/realms/1.6.1/realms-1.6.1.jar
6c724ad415af96416e035a5ae96b113b1df9247d5833fbf73135c66b23263904 /com/mojang/realms/1.6.1/realms-1.6.1.pom
e7cd8951956d349b568b7ccfd4f5b2529a8c113e67c32b028f52ffda371259d9 /commons-cli/commons-cli/1.2/commons-cli-1.2.jar
18f3e92076e08c2fde48317025098e9f6baaa85f6912eb43f2d7e68d570e4561 /commons-cli/commons-cli/1.2/commons-cli-1.2.pom
1bafd2ece2e88db4cdf835a7f8f0de65fab5b1147977a5dcc59b7c1b8c6f5080 /commons-codec/commons-codec/1.3/commons-codec-1.3.jar
d157e34244e884dd91fa01921ca84372e11f7bb08fedb5d456c0670c28054636 /commons-codec/commons-codec/1.3/commons-codec-1.3.pom
54b34e941b8e1414bd3e40d736efd3481772dc26db3296f6aa45cec9f6203d86 /commons-codec/commons-codec/1.6/commons-codec-1.6.jar
a06e35d3fff3a6b813d94894ebf3e498f9540c864c5b39ae783907e3a6c72889 /commons-codec/commons-codec/1.6/commons-codec-1.6.pom
ad19d2601c3abf0b946b5c3a4113e226a8c1e3305e395b90013b78dd94a723ce /commons-codec/commons-codec/1.9/commons-codec-1.9.jar
e5efcf039cd909688c201dc5479b144fd6f01f0e40252b7fc5e7d2e1b5c07990 /commons-codec/commons-codec/1.9/commons-codec-1.9.pom
a7f713593007813bf07d19bd1df9f81c86c0719e9a0bb2ef1b98b78313fc940d /commons-io/commons-io/1.4/commons-io-1.4.jar
2dae496a19c82b8e9985a1246aa80cf98082b1ae2217cf4b2d4d5ff13a365af2 /commons-io/commons-io/1.4/commons-io-1.4.pom
cc6a41dc3eaacc9e440a6bd0d2890b20d36b4ee408fe2d67122f328bb6e01581 /commons-io/commons-io/2.4/commons-io-2.4.jar
b2b5dd46cf998fa626eb6f8a1c114f6167c8d392694164e62533e5898e9b31f2 /commons-io/commons-io/2.4/commons-io-2.4.pom
ce6f913cad1f0db3aad70186d65c5bc7ffcc9a99e3fe8e0b137312819f7c362f /commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar
d0f2e16d054e8bb97add9ca26525eb2346f692809fcd2a28787da8ceb3c35ee8 /commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.pom
70903f6fc82e9908c8da9f20443f61d90f0870a312642991fe8462a0b9391784 /commons-logging/commons-logging/1.1.3/commons-logging-1.1.3.jar
3250ac3ac6bd60ed0631f5cd0335032b2993d63e405a6ae0555d27a7e4865849 /commons-logging/commons-logging/1.1.3/commons-logging-1.1.3.pom
33a4dd47bb4764e4eb3692d86386d17a0d9827f4f4bb0f70121efab6bc03ba35 /commons-logging/commons-logging-api/1.1/commons-logging-api-1.1.jar
69b8be61aa746c7d02acb1b11eb3b57cb22b246780ed71d79764195cbbe3d99d /commons-logging/commons-logging-api/1.1/commons-logging-api-1.1.pom
f868fc9e23d7203834abb5e0d11782e1e8920d4e95a06735a13dd51ab8049de8 /com/mycila/maven-license-plugin/maven-license-plugin/1.10.b1/maven-license-plugin-1.10.b1.jar
9576f1134ebf1f0dae51d1e5cce46a6a6e5b5c5998cc12318ebfd16162702d8b /com/mycila/maven-license-plugin/maven-license-plugin/1.10.b1/maven-license-plugin-1.10.b1.pom
d190c18ef3caf788c84a49d6bc200be29a76c00d3ad6030bf11f7afaa4b24f88 /com/mycila/parent-pom/5/parent-pom-5.pom
870f9396789e2f48a7b8fb28dfc070c2f8e74b2007274ce23e69b658110fd294 /com/mycila/xmltool/xmltool/3.3/xmltool-3.3.jar
eb83f616945c8c7dfb4d80e6f909e7286f523bb11077802bcd216bd70e9c717a /com/mycila/xmltool/xmltool/3.3/xmltool-3.3.pom
a661dfcb749053fc26eada2a0a8e619a8ead1ca9eda29e1698687aa2cdd80152 /com/nothome/javaxdelta/2.0.1/javaxdelta-2.0.1.jar
93bbe8babc70e175d406ac689b90e689f4915c6e39e738eb6406fa5b529ce36c /com/nothome/javaxdelta/2.0.1/javaxdelta-2.0.1.pom
6c4b4e50e608763564afa1bde2d25ece9dd715e7c9129540faa1faded4896506 /com/paulscode/codecjorbis/20101023/codecjorbis-20101023.jar
d246a119ba41e3c866bf728fb6e98277bd3f8695130056039dbbfd000cc3ff6b /com/paulscode/codecjorbis/20101023/codecjorbis-20101023.pom
bb7d17b340afe6abdfbfdaa03683bce4aef39a64887dbab0636eaff3cf2d59ba /com/paulscode/codecwav/20101023/codecwav-20101023.jar
5f95932d9b4b254b890d9105f2d3917bc60ceaf77ae1bc75a79c6b20662e596d /com/paulscode/codecwav/20101023/codecwav-20101023.pom
333bbefeff5eb1722dc9b8d2e26c38bc69c1efa07d0ca870480f29d8858aa336 /com/paulscode/libraryjavasound/20101123/libraryjavasound-20101123.jar
ce4a18bc8e94f155421f6b3d0b9bb6939c9ca206df85e5c10587e66e34310c44 /com/paulscode/libraryjavasound/20101123/libraryjavasound-20101123.pom
107d11509f6af59b8c2ba23df828bc5d3c4e067b58f3d858c7deb90ca5308f84 /com/paulscode/librarylwjglopenal/20100824/librarylwjglopenal-20100824.jar
ff88b9584f5ba98863f24fc3f6014854c7a176fe7017813a6d023e722ce05aee /com/paulscode/librarylwjglopenal/20100824/librarylwjglopenal-20100824.pom
2882d64550240dd0c026724da664d9f97ef205c91d6a85273d10790d88608f34 /com/paulscode/soundsystem/20120107/soundsystem-20120107.jar
c1a2438a4d35f8586c71d96c44a7e2f133ec924597147a246f8c501acca6acb5 /com/paulscode/soundsystem/20120107/soundsystem-20120107.pom
4ccbc821a417f0174c9734fc721f078177cacef94ded09c3775ebf40c6a7bdfd /com/typesafe/akka/akka-actor_2.11/2.3.3/akka-actor_2.11-2.3.3.jar
9f9920b48ae5f1045fe966f08164d6b4e0a727cf17f8e4813ae5c0f2daecffbc /com/typesafe/akka/akka-actor_2.11/2.3.3/akka-actor_2.11-2.3.3.pom
c160fbd78f51a0c2375a794e435ce2112524a6871f64d0331895e9e26ee8b9ee /com/typesafe/config/1.2.1/config-1.2.1.jar
62361ef10448869fff8c05150bd0449b423e3ff4498f2a4bab825b3c7685aa3c /com/typesafe/config/1.2.1/config-1.2.1.pom
68f43fed6611873d19f6dcf2d6739e1f2ddbed3cdd39e6a9f72ec1caee459f59 /de/oceanlabs/mcp/mcp/1.8/mcp-1.8-srg.zip
cf2630841a5ef712b4be22a814f1b83964850b0de4dc78f6131b66280beb3249 /de/oceanlabs/mcp/mcp_snapshot_nodoc/20141130-1.8/mcp_snapshot_nodoc-20141130-1.8.zip
22c45060f350fcaa94e503f4a420cf8237c26c0fcdb4ada4aa98389b75c7b231 /de/oceanlabs/mcp/RetroGuard/3.6.6/RetroGuard-3.6.6.jar
d6f165bb39aaa20ee14fdcbbdb0b8fffae38067087f333ec6e0acd3f6666b2ad /de/oceanlabs/mcp/RetroGuard/3.6.6/RetroGuard-3.6.6.pom
8bc2b71a17ed1b5c6329bcc61fa9a2f7fe071074548fa137ebafec2a23d49d89 /io/netty/netty-all/4.0.15.Final/netty-all-4.0.15.Final.jar
9dfcfbce5531faa07e6afb1a2fc9579f096ffe88707bf95869d83ad81228a157 /io/netty/netty-all/4.0.15.Final/netty-all-4.0.15.Final.pom
8064a2f9d222704882928e6ff104decc071ab6b7b07dce8efb90100d1e624e30 /io/netty/netty-parent/4.0.15.Final/netty-parent-4.0.15.Final.pom
09adf7955baa6bddf57a4bdbf9a91cf690261314969b59a18085ece1e05eccf9 /java3d/vecmath/1.5.2/vecmath-1.5.2.jar
a4aee4668f1b127c95c9afe1b922f4c5a0b1ad879ba811077cb7d0e048dce231 /java3d/vecmath/1.5.2/vecmath-1.5.2.pom
90a8e1603eeca48e7e879f3afbc9560715322985f39a274f6f6070b43f9d06fe /junit/junit/4.11/junit-4.11.jar
18ad8b0ae9e65a9195d04e25427dfe8b58175abcdae875a5a406aee38bddfb26 /junit/junit/4.11/junit-4.11.pom
dc67378cf428c06408e7959e83bdc1518dd22ccd313e7c28a986612d65c276c7 /log4j/log4j/1.2.12/log4j-1.2.12.jar
cb54dedc5d8c4510148dfa792701cbac1a84c383a84f48f5a32e6d7e460bbb72 /log4j/log4j/1.2.12/log4j-1.2.12.pom
0c3085cb93c3ef95d731c274b6f2dd195aa0405fe9328d69cab7f5e899d5e124 /lzma/lzma/0.0.1/lzma-0.0.1.jar
a096bc9f7579cec07483874151578720eeb3189c546c19cff56a6203df17b50e /lzma/lzma/0.0.1/lzma-0.0.1.pom
ccccd0a92f76fbb24279691daad9b67f85d80471a37e59e0da76d7754982dfe8 /mc/game/1.8/client/d722504db9de2b47f46cc592b8528446272ae648/client.jar
40e23f3823d6f0e3cbadc491cedb55b8ba53f8ab516b68182ddd1536babeb291 /mc/game/1.8/server/a028f00e678ee5c6aef0e29656dca091b5df11c7/server.jar
745fdfbba409679b8347f3172109ff186ff743edfed1a9c5bf37443c05fdd480 /mc/game/d74a4b45e8877084e1bcc8121012845f28def238/1.8.json
* /mc/game/version_manifest.json
79b5a4f5829e1a49a415711f7fb8eb5b9ad22defa72929fda2da96ec30d3f018 /net/java/jinput/jinput/2.0.5/jinput-2.0.5.jar
3199d547c1275e806e0c7be19e90dcb00d9561ec3b31fb2e780e12d7d8785810 /net/java/jinput/jinput/2.0.5/jinput-2.0.5.pom
1ab4d194277816b6105253d224c8c69f1b6d720690efe7c85f3ce884f0ea273d /net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-linux.jar
171024b00f9a743b92388b48733dc30fd3f6d3a7da4f66f9821531fbcf1aa074 /net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-osx.jar
24afbd5e1fab17da57d16a4d3f19d53f36155ef46a9976484201a4bb9722287f /net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-windows.jar
ba27597365ae85a836c1f51819903668b4a1a7490e39e530633cc8a7b40b5500 /net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5.pom
c3334ff39cf0ab3b54925619101054c90098b7c733b1e7834c7b75e4c41e84a5 /net/java/jutils/jutils/1.0.0/jutils-1.0.0.jar
af09ead4eb241473e7ec4d152a91a722ea09a717a202e20e4b385eac3217b7d6 /net/java/jutils/jutils/1.0.0/jutils-1.0.0.pom
b47c5d5810643426a3147ddb2195ef2ab67c80b167e7c2ac64a5d0dee8c030dd /net/md-5/SpecialSource/1.7.4/SpecialSource-1.7.4.jar
5f374f8ae7afff8dbc23aff14e59c5bd585c230afe9a8dcaa7b928e8cb16a27e /net/md-5/SpecialSource/1.7.4/SpecialSource-1.7.4.pom
5d166a260388526b502b07c167beb8ae5cd18d46f60a10a029c1d6e1206e093a /net/minecraftforge/forge/1.8-11.14.4.1563/forge-1.8-11.14.4.1563.pom
3e33989b813090abe749334b5a9a663bd37cb20e987b91f78fc616cc7fb91ee1 /net/minecraftforge/forge/1.8-11.14.4.1563/forge-1.8-11.14.4.1563-userdev.jar
* /net/minecraftforge/forge/json
e74b65b8948446982a506a96176dd8baf4688237ba4903f56ca6f667b6c7ee42 /net/minecraft/launchwrapper/1.11/launchwrapper-1.11.jar
616c4971035d1e6ab4809e16daabb02aa308c1dc001c06dd547c7d3b2e916999 /net/minecraft/launchwrapper/1.11/launchwrapper-1.11.pom
57f402b626d16cc2705bf2a37add7adbb074f0ca3b3102fa6e23aa303dae682f /net/minecraft/launchwrapper/1.12/launchwrapper-1.12.jar
5f1fced192c1dc9b68ef7dec12ba7a033129a71b290c283046a59aa2902e1fbc /net/minecraft/launchwrapper/1.12/launchwrapper-1.12.pom
64335a48be6b142a7d0c13ec5c82a707857aa58c0234e6eda3eaca0e96eea51b /net/sf/jopt-simple/jopt-simple/4.5/jopt-simple-4.5.jar
60f08a3d6fc0e7948fd00fc95fad014fae5a5dc7eb991a631e0efee8bfad0b27 /net/sf/jopt-simple/jopt-simple/4.5/jopt-simple-4.5.pom
3fcfbe3203c2ea521bf7640484fd35d6303186ea2e08e72f032d640ca067ffda /net/sf/jopt-simple/jopt-simple/4.6/jopt-simple-4.6.jar
692744a19473011539ebc1370a264b8af1c056e0ae21f5372aa9dd7d4b4e5a2b /net/sf/jopt-simple/jopt-simple/4.6/jopt-simple-4.6.pom
9f0c8d50fa4b79b6ff1502dbec8502179d6b9497cacbe17a13074001aed537ec /net/sf/jopt-simple/jopt-simple/5.0.1/jopt-simple-5.0.1.jar
606e9b1d8e448a8f454b7eb585320b392e80f68880e92bef98cdf9dab8714340 /net/sf/jopt-simple/jopt-simple/5.0.1/jopt-simple-5.0.1.pom
dc0ba5bff6140dc92339973026a0ecbddc2a3b01bdd46ed9d16becc2f6d78de6 /net/sf/opencsv/opencsv/2.3/opencsv-2.3.jar
57f5607565d6a90dee6722801d4524813d9d2785046f2954a18861dfbf4a2149 /net/sf/opencsv/opencsv/2.3/opencsv-2.3.pom
294fb88c272598b9a5dcae15f13d228e64134256de941fbc28917a994beeb075 /net/sf/trove4j/trove4j/2.1.0/trove4j-2.1.0.jar
6d486c048a84c90ad9239b7b06a7d686d43eda28f827fac08d4f4ea942d21d0a /net/sf/trove4j/trove4j/2.1.0/trove4j-2.1.0.pom
3c8616203d61a12a7e3487e8b34f3c198c2b5ba9e90da0c7ea32d99cd4958012 /net/sf/trove4j/trove4j/3.0.3/trove4j-3.0.3.jar
11327b94615d0bf16d4e17334902de783c2022f5e909d51fbce993a7a9d7e1d8 /net/sf/trove4j/trove4j/3.0.3/trove4j-3.0.3.pom
3b93b62c0ea3ab9b5c1c1cdb1a3f25a7eb758f9974e8998f4e1815ba33cb7a1e /nl/javadude/gradle/plugins/license-gradle-plugin/0.11.0/license-gradle-plugin-0.11.0.jar
afded103d53d00171f486ab23c35151d8b82b32e51390c30ae734e83de863c52 /nl/javadude/gradle/plugins/license-gradle-plugin/0.11.0/license-gradle-plugin-0.11.0.pom
4ead9d3e3f305a4ed26fd732e6f0df0be2524e2daf2681df1b001fbb8efc9735 /oauth/signpost/oauth-signpost/1.2.1.2/oauth-signpost-1.2.1.2.pom
e26198c1bb8e3cde5f6e85305d0c4ef7730c53406c0d2a1f36ce30661df9fc22 /oauth/signpost/signpost-commonshttp4/1.2.1.2/signpost-commonshttp4-1.2.1.2.jar
5d3ef59d3820f64a6dd09b9ad7a083bbe24a9f97ce01ad412238877594e34e56 /oauth/signpost/signpost-commonshttp4/1.2.1.2/signpost-commonshttp4-1.2.1.2.pom
a1d69c5346ebf086b0f63c382b4500ceb29304d8fe95157b060aa4cd3861f230 /oauth/signpost/signpost-core/1.2.1.2/signpost-core-1.2.1.2.jar
f3c6788ccec4e1818b3f02d32fe8b5ab9caac52b0962e98466d980710c47298c /oauth/signpost/signpost-core/1.2.1.2/signpost-core-1.2.1.2.pom
649ae0730251de07b8913f49286d46bba7b92d47c5f332610aa426c4f02161d8 /org/apache/ant/ant/1.9.4/ant-1.9.4.jar
5ce23a18f28d04be351f863020da0136214218aface05560516b97555a5077fd /org/apache/ant/ant/1.9.4/ant-1.9.4.pom
7bccea20b41801ca17bcbc909a78c835d0f443f12d639c77bd6ae3d05861608d /org/apache/ant/ant-launcher/1.9.4/ant-launcher-1.9.4.jar
c9193ed600adc6c7943a6c6dc6bd952edcb5f10fb2cda594b7199766fdeef698 /org/apache/ant/ant-launcher/1.9.4/ant-launcher-1.9.4.pom
a93aa9c66665872b0e51360c15ae282971e36a8aa987b40ef4d82d9a5aa151c4 /org/apache/ant/ant-parent/1.9.4/ant-parent-1.9.4.pom
802feece72852dafcbd0a425a60367c72c5cb9b6ea5aae59481128569189daf9 /org/apache/apache/10/apache-10.pom
ff513db0361fd41237bef4784968bc15aae478d4ec0a9496f811072ccaf3841d /org/apache/apache/13/apache-13.pom
36c2f2f979ac67b450c0cb480e4e9baf6b40f3a681f22ba9692287d1139ad494 /org/apache/apache/15/apache-15.pom
9e9323a26ba8eb2394efef0c96d31b70df570808630dc147cab1e73541cc5194 /org/apache/apache/4/apache-4.pom
4946e60a547c8eda69f3bc23c5b6f0dadcf8469ea49b1d1da7de34aecfcf18dd /org/apache/apache/9/apache-9.pom
93f8dfcd20831a28d092427723f696bceb70b28e7fb89d7914f14d5ea492ce5a /org/apache/commons/commons-collections4/4.0/commons-collections4-4.0.jar
f23d3625d35b016f3e8b77fb3ebf5e543807081fce2492f45a79d00160789a78 /org/apache/commons/commons-collections4/4.0/commons-collections4-4.0.pom
5fca136503f86ecc6cb61fbd17b137d59e56b45c7a5494e6b8fd3cabd4697fbd /org/apache/commons/commons-compress/1.8.1/commons-compress-1.8.1.jar
10137adb14e8520b2abcddc308003e432eb836c4d1f9a00f68601d63583b9fb8 /org/apache/commons/commons-compress/1.8.1/commons-compress-1.8.1.pom
cb49812dc1bfb0ea4f20f398bcae1a88c6406e213e67f7524fb10d4f8ad9347b /org/apache/commons/commons-exec/1.3/commons-exec-1.3.jar
82827f6019c0f71bd74fba886ab337ff6da291f63df9723379a209d6ad3b44f8 /org/apache/commons/commons-exec/1.3/commons-exec-1.3.pom
6b81d10754dadf184d386011486e6509c2cc0c3d33565ced4fb4402b9413d47d /org/apache/commons/commons-lang3/3.3.2/commons-lang3-3.3.2.jar
e1875bf575999ebc62dec34304a0d108c30a4ff8101e8ea5c9a9332715277940 /org/apache/commons/commons-lang3/3.3.2/commons-lang3-3.3.2.pom
b9e0306f393460105b8a3fa5105250c5291b1efaa99954ace0ec1c783109a02a /org/apache/commons/commons-parent/11/commons-parent-11.pom
fb8c5e55e30a7addb4ff210858a0e8d2494ed6757bbe19012da99d51586c3cbb /org/apache/commons/commons-parent/22/commons-parent-22.pom
467ae650442e876867379094e7518dfdd67d22c5352ebd39808c84259e9790ba /org/apache/commons/commons-parent/25/commons-parent-25.pom
14733a68e8b120b69de60cd96d222146dcf32f03c1c6cc6a750b1269bafe86c7 /org/apache/commons/commons-parent/28/commons-parent-28.pom
e4d258af8b2ff4032148d415379def7870789a6003e80576f1504b10f26b4be8 /org/apache/commons/commons-parent/32/commons-parent-32.pom
53d0011352e2e5106f379dafccdac7754ec6f0f78243c0305e4969f5acddf8fb /org/apache/commons/commons-parent/33/commons-parent-33.pom
7098a1ab8336ecd4c9dc21cbbcac869f82c66f64b8ac4f7988d41b4fcb44e49a /org/apache/commons/commons-parent/35/commons-parent-35.pom
8bd632c00bdf80a7de36c22b60f12452c147d8eca2f00d79d66699ebe7daa02a /org/apache/commons/commons-parent/5/commons-parent-5.pom
01e97067a1f9bd0e0a34f2f32bbf43fe6e9b11910f3b0dfe77fd7fb418619105 /org/apache/commons/commons-parent/7/commons-parent-7.pom
752596ebdc7c9ae5d9a655de3bb06d078734679a9de23321dbf284ee44563c03 /org/apache/httpcomponents/httpclient/4.0.1/httpclient-4.0.1.jar
51b8c025a4a1700d861d17bc2332f2b5045a81bad5d55291d9b652bb782151b2 /org/apache/httpcomponents/httpclient/4.0.1/httpclient-4.0.1.pom
9d0e815461efc8fc9aa5de4dda9ae29d076430b2e93e268a31d7a47cc00a31cf /org/apache/httpcomponents/httpclient/4.2.2/httpclient-4.2.2.jar
2ee7f81822a156a897b10a934b2158fa44d574dc20488f2fb9eb4d058673cbe7 /org/apache/httpcomponents/httpclient/4.2.2/httpclient-4.2.2.pom
9844cc9b5440d65a88d28bcba9d771374d2dfdab898848cda164611091633013 /org/apache/httpcomponents/httpclient/4.3.3/httpclient-4.3.3.jar
03f7d67d6547083a38413c0da921d194a6010236f8980c7585c0c8f3019c0aa8 /org/apache/httpcomponents/httpclient/4.3.3/httpclient-4.3.3.pom
1a5cfc674477ce7fd1150e8ea841f18301da1a4bfc729a029e072e81f3f36515 /org/apache/httpcomponents/httpcomponents-client/4.0.1/httpcomponents-client-4.0.1.pom
aecd5527c274ea6ed63da7f71b69c6a61a64784ff6c7266e0d94fcbf391027e2 /org/apache/httpcomponents/httpcomponents-client/4.2.2/httpcomponents-client-4.2.2.pom
15c27734dbcedc6af2cf18fa72a8c6e248477144a3d936a0fc228aaa74a02b00 /org/apache/httpcomponents/httpcomponents-client/4.3.3/httpcomponents-client-4.3.3.pom
70d3b2bb5d199da825681559ff68aa5bdee201206c50af177bf7ca4d94226752 /org/apache/httpcomponents/httpcomponents-core/4.0.1/httpcomponents-core-4.0.1.pom
ad4346d6375faa11a4d8cb45130acc86fb7ede86451194066da0559e41d5789e /org/apache/httpcomponents/httpcomponents-core/4.2.2/httpcomponents-core-4.2.2.pom
aa3ec31c7dd2161cfe3a3975645ea8703db0a6d6adb7d5b1766b32764c5c1806 /org/apache/httpcomponents/httpcomponents-core/4.3.2/httpcomponents-core-4.3.2.pom
3b6bf92affa85d4169a91547ce3c7093ed993b41ad2df80469fc768ad01e6b6b /org/apache/httpcomponents/httpcore/4.0.1/httpcore-4.0.1.jar
d1f666e38907c9471c64a3cdf87e0b1b0469d503e51cc14661860f7f6bd70c6e /org/apache/httpcomponents/httpcore/4.0.1/httpcore-4.0.1.pom
c32bbf016f1eec0581febb177c761c2f657d9635d110affdd8c63382425e50f0 /org/apache/httpcomponents/httpcore/4.2.2/httpcore-4.2.2.jar
c1695c0b0c3d7be7f02f558b56763b0024ecaae6b9f981e2e145c05e9fea0972 /org/apache/httpcomponents/httpcore/4.2.2/httpcore-4.2.2.pom
abd02320e2356f89d054dae4cf02306bef20a9cf7865b3ac94ec7552b4f1528b /org/apache/httpcomponents/httpcore/4.3.2/httpcore-4.3.2.jar
dfe5335f45b9466af820368b95c543d7542fcfcbe5f5d379e91cf0432e2df489 /org/apache/httpcomponents/httpcore/4.3.2/httpcore-4.3.2.pom
61434dbb2314cbb8d28025feb6ae53bbc45d1042daa34371d8911e1e7f570b36 /org/apache/httpcomponents/httpmime/4.3.3/httpmime-4.3.3.jar
30e52abf8461a7ab254f20ec2c28e01865721ad9fbdb3baf14f32251623a1f87 /org/apache/httpcomponents/httpmime/4.3.3/httpmime-4.3.3.pom
a35e70c72865add3f9416194e02d6f9967dbf0c77d253933f80fbf46ad4d2169 /org/apache/httpcomponents/project/4.0/project-4.0.pom
b5d9225adb8683c1d7c5514544382add004547c93694abb5bd52b87346886f42 /org/apache/httpcomponents/project/6/project-6.pom
3d6eba428555a558de046b5d76eacc1f5a54b4f5f20b84d636ed7aff18aa48c3 /org/apache/httpcomponents/project/7/project-7.pom
9ab50a08565c7c01082266d2464b7656e2448e40788375ff5c034da17042cc24 /org/apache/logging/log4j/log4j/2.0-beta9/log4j-2.0-beta9.pom
eb0ca9bdd938f80711152a758d6bc331a8b0d769199d457294dc67ed03f73498 /org/apache/logging/log4j/log4j-api/2.0-beta9/log4j-api-2.0-beta9.jar
4e10aac66cfabc8a16f0045bca650e082a190caca85d1c28376a71b9b918b40d /org/apache/logging/log4j/log4j-api/2.0-beta9/log4j-api-2.0-beta9.pom
dcde6033b205433d6e9855c93740f798951fa3a3f252035a768d9f356fde806d /org/apache/logging/log4j/log4j-core/2.0-beta9/log4j-core-2.0-beta9.jar
f360def8ad0c62f5420a9b2ef8d6a51f87703e05c1df08494578a1d4024b05ad /org/apache/logging/log4j/log4j-core/2.0-beta9/log4j-core-2.0-beta9.pom
4d223e01a6569d6655c1f4fce84969d45142cdbabdb118ea08c5c8c33ec632f6 /org/apache/maven/maven/3.0.4/maven-3.0.4.pom
4c2f8341518aeb9d488844e334c02fa66dd4bb091bfdeb965c8a848ac6ea5aa2 /org/apache/maven/maven/3.0-alpha-2/maven-3.0-alpha-2.pom
33ff4aabbd0d02e4dd8279cda8f366c69915302bc4bb97bc01814a985f5c0643 /org/apache/maven/maven-aether-provider/3.0.4/maven-aether-provider-3.0.4.jar
a5082fe0a870bd361b3ecd6ab3e4641cfe775a8da19d80d8b2e277e7861f831b /org/apache/maven/maven-aether-provider/3.0.4/maven-aether-provider-3.0.4.pom
3c199a96af9550872724f41c053d7839dfcc6512e7704fa16c675363c4146796 /org/apache/maven/maven-artifact/3.0.4/maven-artifact-3.0.4.jar
e39722dcdf98a6a245db3e0f54d0d4a5555c8c9361e3efbfed3a7be1158b9c6c /org/apache/maven/maven-artifact/3.0.4/maven-artifact-3.0.4.pom
85500348730f338599e5f454be4a9909a6d01e86effc1ed0650a71e544bc67d5 /org/apache/maven/maven-compat/3.0-alpha-2/maven-compat-3.0-alpha-2.jar
4196effcccdbe4ef8dc625e5dd8e13284971dd884dc80109cb1f44d76dd0d7e7 /org/apache/maven/maven-compat/3.0-alpha-2/maven-compat-3.0-alpha-2.pom
3dd795c0ad9742a0be65a2a5ec22428d59dd2a891a7565ae94f64661e3740528 /org/apache/maven/maven-core/3.0.4/maven-core-3.0.4.jar
61d1fc83ce71c4af6a5061d0c4884b0cad5a9bd4ef12bce0a628ece6db13a9a7 /org/apache/maven/maven-core/3.0.4/maven-core-3.0.4.pom
26b6825ea73ac4d7b1a6f5e62ac1c11b0fc272504da6dde9ba8f894cd847e1c1 /org/apache/maven/maven-model/3.0.4/maven-model-3.0.4.jar
264be3f212d59f9103d3b997c9d0197ff89489d06b7d195d80ee56356b6c662e /org/apache/maven/maven-model/3.0.4/maven-model-3.0.4.pom
b4f1d3ae53c290e1ae45694c5ce2d17bf8d577ff5ece0f9aa0cffe151a6ef4e7 /org/apache/maven/maven-model-builder/3.0.4/maven-model-builder-3.0.4.jar
ac605e66a84dd9ee63610d650b007e3c8fbb7feef73e94bdd899e60dd475a20f /org/apache/maven/maven-model-builder/3.0.4/maven-model-builder-3.0.4.pom
81fe14cb9779d36e0c610e1049e5b32a6b9974957f257921acf628b31c5486c8 /org/apache/maven/maven-parent/10/maven-parent-10.pom
fc45af8911ea307d1b57564eef1f78b69801e9c11a5619e7eb58d5d00ae9db8e /org/apache/maven/maven-parent/21/maven-parent-21.pom
3cb6712f827c80dc6b0b0b967776dba451c023a92b7741bba45d23ab7a83281a /org/apache/maven/maven-parent/8/maven-parent-8.pom
4e5ee7f7ab7e43f691788489e59f2da4a322e3e35f2a2d8b714ad929f624eead /org/apache/maven/maven-plugin-api/3.0.4/maven-plugin-api-3.0.4.jar
bd928e987661ac90495ca7cdcd5d2fd20cbed97fb9565e30d8425aadae26ee90 /org/apache/maven/maven-plugin-api/3.0.4/maven-plugin-api-3.0.4.pom
0b76d82011452170dddd21fb33da6bfc414ff6629fce6219fbf1d78ce1518e90 /org/apache/maven/maven-project/3.0-alpha-2/maven-project-3.0-alpha-2.jar
24477230086e456dff22c24dec30aab0a8ae321a2ce5645a85a8516f7dd829e3 /org/apache/maven/maven-project/3.0-alpha-2/maven-project-3.0-alpha-2.pom
f3905cb8c223c33f6121bc937b66a2f58653be766042fb6e924b9882c555d891 /org/apache/maven/maven-project-builder/3.0-alpha-2/maven-project-builder-3.0-alpha-2.jar
392f9bcc7eb6d9ab85b693cda0c3ba698fc770d32843491c8815b87f40fe02a8 /org/apache/maven/maven-project-builder/3.0-alpha-2/maven-project-builder-3.0-alpha-2.pom
a25c4db27cffda9e9229db168b1190d6a3e5439f3f67d6afec3df9470e0752d5 /org/apache/maven/maven-repository-metadata/3.0.4/maven-repository-metadata-3.0.4.jar
5fe2b1d87fd326c1a22aac3869da7935ad31760d978fdff9a073c3fbfd54e18d /org/apache/maven/maven-repository-metadata/3.0.4/maven-repository-metadata-3.0.4.pom
3e3df17f5df5e4ce1e7b7f2011c57d61d328e65678542ade2048f0d0fa295f09 /org/apache/maven/maven-settings/3.0.4/maven-settings-3.0.4.jar
beedffd7c7e49ad35ef945c3413f1819f04e43ea294a31804714c8cbb0f372b3 /org/apache/maven/maven-settings/3.0.4/maven-settings-3.0.4.pom
a38a54ec1e69a30ddfc14434e0aec2764fc268668abcc0e132d86692a5dce3e4 /org/apache/maven/maven-settings-builder/3.0.4/maven-settings-builder-3.0.4.jar
3e0b3f60267b6070a741b15db5b40fbd824c61db12a1f4f166ed658b9f62ece0 /org/apache/maven/maven-settings-builder/3.0.4/maven-settings-builder-3.0.4.pom
6c35daab503ff462f4f63317ae723bd37cae37460ea3576374a347583e7c4327 /org/apache/maven/wagon/wagon/1.0-beta-4/wagon-1.0-beta-4.pom
6a82569576cda4cae793800ed2985202de8a59e414d2140e217cf077709e7bbb /org/apache/maven/wagon/wagon-provider-api/1.0-beta-4/wagon-provider-api-1.0-beta-4.jar
1739331652c6e93dd3305a9c5b33f493c85782171e9e8a3e0c750b030dabadd1 /org/apache/maven/wagon/wagon-provider-api/1.0-beta-4/wagon-provider-api-1.0-beta-4.pom
56ab9c6c2d022a9b7079006ba500a996cd2c21411d53cac524933af20c5a4b99 /org/apache/xbean/xbean/3.4/xbean-3.4.pom
17e0efa187127034623197fb88c50c30d3baa62baa0f07d6ec693047ac92ec3b /org/apache/xbean/xbean-reflect/3.4/xbean-reflect-3.4.jar
01c97d4286dd3b5e5441faac3abb589f1fe123cea138bb4ae0995ffae14938df /org/apache/xbean/xbean-reflect/3.4/xbean-reflect-3.4.pom
c7964f00c3d3889c5223e8fcb7476610c59453c86bccc68ef493a56d171bf655 /org/aspectj/aspectjrt/1.8.2/aspectjrt-1.8.2.jar
ba5261a1f07260c3d8016623fdd27d662b9934266a75d4f57f165bfbaf9af1a8 /org/aspectj/aspectjrt/1.8.2/aspectjrt-1.8.2.pom
f07694998acb204782c72cc8067b237a04097a2170f07d440614883f14a67630 /org/codehaus/groovy/groovy-backports-compat23/2.4.4/groovy-backports-compat23-2.4.4.jar
2f93f476d35dd52828e13f32a4be68ab80a3b999713079feb98c67ae9e8d858f /org/codehaus/groovy/groovy-backports-compat23/2.4.4/groovy-backports-compat23-2.4.4.pom
e246e2a062b5d989fdefc521c9c56431ba5554ff8d2344edee9218a34a546a33 /org/codehaus/plexus/plexus/2.0.2/plexus-2.0.2.pom
2b59062030ab0a15c5d0977ba22421706368926488739a65f25793e715cc8a74 /org/codehaus/plexus/plexus/2.0.7/plexus-2.0.7.pom
259d528a29722cab6349d7e7d432e3fd4877c087ffcb04985a6612e97023bba8 /org/codehaus/plexus/plexus-classworlds/2.4/plexus-classworlds-2.4.jar
c0439c2b2d850488686143e2529f521b38f2abded6ac212add8f0c637eb912e9 /org/codehaus/plexus/plexus-classworlds/2.4/plexus-classworlds-2.4.pom
4df7a6a7be64b35bbccf60b5c115697f9ea3421d22674ae67135dde375fcca1f /org/codehaus/plexus/plexus-component-annotations/1.5.5/plexus-component-annotations-1.5.5.jar
815f3ec316b8c5fa701385fdf4009bfb51e07d780e8f6a6e2afe720c52d7e292 /org/codehaus/plexus/plexus-component-annotations/1.5.5/plexus-component-annotations-1.5.5.pom
ef5dbc7fa918b6dbba71d27e5b3d7a00df624bcfa2549a7297f36fe275f634d7 /org/codehaus/plexus/plexus-components/1.1.18/plexus-components-1.1.18.pom
00aa0be06a029e4b45032f682089d5052b014c028f9187f83c70adc073672c46 /org/codehaus/plexus/plexus-container-default/1.0-beta-3.0.5/plexus-container-default-1.0-beta-3.0.5.jar
3d90bbd9f534020621c77453dcffdad4e761e42911c2be9adaeec724f9972a9c /org/codehaus/plexus/plexus-container-default/1.0-beta-3.0.5/plexus-container-default-1.0-beta-3.0.5.pom
f53a82db260a2910a9823d6e72a927891daae33d8eb6884ab838a2a2768c6b86 /org/codehaus/plexus/plexus-containers/1.0-beta-3.0.5/plexus-containers-1.0-beta-3.0.5.pom
1bc264824ec876b0ca6f4f5838175c541c638cbc43326a268b9aee7d4778b5ef /org/codehaus/plexus/plexus-containers/1.5.5/plexus-containers-1.5.5.pom
7fc63378d3e84663619b9bedace9f9fe78b276c2be3c62ca2245449294c84176 /org/codehaus/plexus/plexus-interpolation/1.14/plexus-interpolation-1.14.jar
d08155c497df37b2c3d9b5b0dfdb02ec0525b2070b5be3739fffde942fcac9af /org/codehaus/plexus/plexus-interpolation/1.14/plexus-interpolation-1.14.pom
8b909f4ca9788647942f883d4e559bcc642123f7c6bcd3846983a2e465469c33 /org/codehaus/plexus/plexus-utils/2.0.6/plexus-utils-2.0.6.jar
fddad4fa62c82310aec43525e519cd59f27d04c7569fe21b1b03ca210887810c /org/codehaus/plexus/plexus-utils/2.0.6/plexus-utils-2.0.6.pom
35608df55aa672a195d6b01573a5630a315998b3bbd06310b20eb169113923aa /org/codehaus/plexus/plexus-utils/2.1/plexus-utils-2.1.jar
9f4ac6987113d09099bf43b846d2ec1d5e7a8091a6185f1f16d68e845f681243 /org/codehaus/plexus/plexus-utils/2.1/plexus-utils-2.1.pom
03cbe8dcaa909a6f72219abec105675c6df08898971c326cf7e64373bff5e769 /org/codehaus/woodstox/wstx-asl/3.2.6/wstx-asl-3.2.6.jar
784db534cc3c5051f88198e8251da9c8b13625e0eb365a347e1085387d8203b1 /org/codehaus/woodstox/wstx-asl/3.2.6/wstx-asl-3.2.6.pom
e4144cbc26da195c6b22a53691fd079f70b74aa5f55bd6089cd77ec99a0ee8fe /org/eclipse/core/contenttype/3.4.200-v20130326-1255/contenttype-3.4.200-v20130326-1255.pom
4dd6ec1376693bd8ac4e2ceacc7be70880920978f3fef31db4968e6ade001c87 /org/eclipse/core/contenttype/3.4.200-v20140207-1251/contenttype-3.4.200-v20140207-1251.jar
f82370a400c38f78f479df4e79c6e1563e4ec050049279601ca01d85186456a7 /org/eclipse/core/contenttype/3.4.200-v20140207-1251/contenttype-3.4.200-v20140207-1251.pom
52d8987073cf765e620afc7f44e3934a8e854d56c8feca25f6ffb9163871c53f /org/eclipse/core/contenttype/maven-metadata.xml
4a73a4a0ebf5ca5f7e9d5e8978b24cd72ebacd5b561de961517f4c976aa7e30f /org/eclipse/core/expressions/3.3.0-v20070606-0010/expressions-3.3.0-v20070606-0010.jar
fa0d8eb0460cf3d5a7201e9af86431f66473726b9883e461b579056d0f3725e8 /org/eclipse/core/expressions/3.3.0-v20070606-0010/expressions-3.3.0-v20070606-0010.pom
582a5012b8525775059ee59d931179f79bff4bebf41bdab4060341b25742c77a /org/eclipse/core/expressions/maven-metadata.xml
b418d15acf94545248f4bd55b4a9b62fc49246488758729d6b3ff52ae149df24 /org/eclipse/core/filesystem/1.1.0-v20070606/filesystem-1.1.0-v20070606.jar
08f7bd3493e934a6cfe6b30941661bfb7c61ac72181b9d72f6745c03f20cae0a /org/eclipse/core/filesystem/1.1.0-v20070606/filesystem-1.1.0-v20070606.pom
0fb7079593f1e2544828c9a56db2710ea223655eee911ae5fb69e2f6d49b36eb /org/eclipse/core/filesystem/maven-metadata.xml
b52babdb3c1e073175ac0be84cbc41764b0cd5e89ca0dd2ebe29cc3f8d40aa86 /org/eclipse/core/jobs/3.5.300-v20130429-1813/jobs-3.5.300-v20130429-1813.pom
ef971ecb154fba0cc06d913448640fb2e5ab3f9079c1c7854385d1c30d81a94f /org/eclipse/core/jobs/3.6.0-v20140424-0053/jobs-3.6.0-v20140424-0053.jar
851e8123acc70a823fe38f1ad5f95f953c815f8da2cceaa483dfa5604d3ecc38 /org/eclipse/core/jobs/3.6.0-v20140424-0053/jobs-3.6.0-v20140424-0053.pom
753ba9e22869180b1e959860d76a5a2bf9e1a2aa398375a138daa518313efce3 /org/eclipse/core/jobs/maven-metadata.xml
e46a6444a6d7c0fe70f196ce42d9700c4514b68bf55bae296b2e3c287883ffdc /org/eclipse/core/org.eclipse.core.commands/3.6.0/org.eclipse.core.commands-3.6.0.jar
49eccab170e7e1c6aa598f49019fc8310a3da4c87a3e2b9e463825f6e2ba086f /org/eclipse/core/org.eclipse.core.commands/3.6.0/org.eclipse.core.commands-3.6.0.pom
73f9a1a2403f7f9c44d11431c40be4641295f3620570bfef2168a66c5de68fee /org/eclipse/core/resources/3.2.1-R32x_v20060914/resources-3.2.1-R32x_v20060914.jar
592accd91b5c786a4fe082176cabe07034f7603981e4d723ebe39b6d7f620672 /org/eclipse/core/resources/3.2.1-R32x_v20060914/resources-3.2.1-R32x_v20060914.pom
363ad8af4d8fc7f208b6fa640e490c7ba84b2aa78c26809e569bb1b0737ce9cb /org/eclipse/core/runtime/3.10.0-v20140318-2214/runtime-3.10.0-v20140318-2214.jar
ef7f45930ccd7b088b0cab1c932a145c494a2672f48e4244e20a1be06d2d30f3 /org/eclipse/core/runtime/3.10.0-v20140318-2214/runtime-3.10.0-v20140318-2214.pom
9fa94682175edfa5ec863f636087d2875aab106b09507199d914988b60edd522 /org/eclipse/core/runtime/3.9.0-v20130326-1255/runtime-3.9.0-v20130326-1255.pom
ddf19054374a2617ba9c10d7a5ec8eeaeb8f62c2c6e430144e81da15718bb585 /org/eclipse/core/runtime/compatibility/3.1.200-v20070502/compatibility-3.1.200-v20070502.jar
6b3a348064b85a050a1b8f7bd96edd081e8152f7269141308c5f5f4fcc444362 /org/eclipse/core/runtime/compatibility/3.1.200-v20070502/compatibility-3.1.200-v20070502.pom
7d95f541e873e42a0c068dc0f38e819a32f0f386c5ea1ae745ef649a40acb628 /org/eclipse/core/runtime/compatibility/maven-metadata.xml
6bddb60e50592d8f7c9b616624b9b4413accfaf8480d320f7cab8638a46a0515 /org/eclipse/core/runtime/maven-metadata.xml
7b2ad6c43d922f3ba0d18d99879d1d56d6a994ba7b639d5d6276f1a167b6a7ac /org/eclipse/equinox/app/1.3.200-v20130910-1609/app-1.3.200-v20130910-1609.jar
17dbfaba6a138e6fc0eb361069470f00aaf70a94e2d3384f398dee4843eb8fe7 /org/eclipse/equinox/app/1.3.200-v20130910-1609/app-1.3.200-v20130910-1609.pom
83a2cde9ed188efcabebbd2db14128c531c5ba73f8abc599dcae83459a779109 /org/eclipse/equinox/app/maven-metadata.xml
6bc086aab7686a5a528d8c4ab2253d6cec7ead04b052576951e90cc561782257 /org/eclipse/equinox/common/3.6.200-v20130402-1505/common-3.6.200-v20130402-1505.jar
9234dbfd064411a849444abfeb8a10978672690d125beb4194f9e5b0f0a7ee5e /org/eclipse/equinox/common/3.6.200-v20130402-1505/common-3.6.200-v20130402-1505.pom
9274fc22b74d6dc42608049ea51aa046b8fc8fc60b2a7d6ff6d884d76e6ef3f6 /org/eclipse/equinox/common/maven-metadata.xml
32b046de57df2f4887fc5a2c343740d9d12c7fe17541e2cede73cfa4ccbc2436 /org/eclipse/equinox/org.eclipse.equinox.common/3.6.0/org.eclipse.equinox.common-3.6.0.jar
84f171f4c3ded1b29880003b3c42e8e5be780a11f19d6b7d1b6d0125b4a198d8 /org/eclipse/equinox/org.eclipse.equinox.common/3.6.0/org.eclipse.equinox.common-3.6.0.pom
dbaa0e5c2a44c3b314086fba9b6d91fd4a374032ccffc82373d3614bd9d385ea /org/eclipse/equinox/preferences/3.5.100-v20130422-1538/preferences-3.5.100-v20130422-1538.pom
6498d32ab6503b49a44e0a0bfe1c2ac28ffb7e8f88acbdb4dda89d73092d8ca7 /org/eclipse/equinox/preferences/3.5.200-v20140224-1527/preferences-3.5.200-v20140224-1527.jar
d68a303f399eeef919b681c43885481c46bf3cfe39f4ede369f7433087bbe14c /org/eclipse/equinox/preferences/3.5.200-v20140224-1527/preferences-3.5.200-v20140224-1527.pom
70a4c81e2def4d69b44dbc680dc0dce29f274f1dff22b98d1f1f34a0fb28514d /org/eclipse/equinox/preferences/maven-metadata.xml
a6833a81795978d4ad8d2e54597171e2a3447fd6983b8e902710aa1dc946fa24 /org/eclipse/equinox/registry/3.5.400-v20140428-1507/registry-3.5.400-v20140428-1507.jar
cb7c954965e6b2946c2f7be78c1e089b530e0444b1fefc2d8079a5681362bfa1 /org/eclipse/equinox/registry/3.5.400-v20140428-1507/registry-3.5.400-v20140428-1507.pom
d7cd093fdad45c7cc979f44f7166f259607b41cf44a8afe77561594cef4c39d3 /org/eclipse/equinox/registry/maven-metadata.xml
9cddda75f4a1b4469e73f44e7b61a3e897d0f657df4797f9106ffe88c4eeade0 /org/eclipse/jdt/core/compiler/ecj/4.6.1/ecj-4.6.1.jar
536c45e8804de01321c478cfb994377f81f1e32897636616fa21b877fd137c6f /org/eclipse/jdt/core/compiler/ecj/4.6.1/ecj-4.6.1.pom
5a91ef99dc827e77c8dae1481bd5a92a0ce877304f2b25151ba4e0834e8a917d /org/eclipse/jdt/org.eclipse.jdt.core/3.10.0.v20131029-1755/org.eclipse.jdt.core-3.10.0.v20131029-1755.jar
5591ec1f9826a0506b33cb2a7bceceaf4058f667c0d5e8fd1a348c36540d9dcb /org/eclipse/jdt/org.eclipse.jdt.core/3.10.0.v20131029-1755/org.eclipse.jdt.core-3.10.0.v20131029-1755.pom
d6aba7a1569952e082630de6907f460f476c20d97032cb9f7e4f3e14ddb928e7 /org/eclipse/jetty/jetty-parent/14/jetty-parent-14.pom
cf65a484e0626d6b79cc40daa820459d893ba6945cbed119859be4db0a07c1fa /org/eclipse/jgit/org.eclipse.jgit/3.2.0.201312181205-r/org.eclipse.jgit-3.2.0.201312181205-r.jar
bfe5eb76e637e740e7769f6e081c1c2815f0272f76b93b9bad0b6e686f5a9030 /org/eclipse/jgit/org.eclipse.jgit/3.2.0.201312181205-r/org.eclipse.jgit-3.2.0.201312181205-r.pom
0a6f74d2b3a411b785e305ae9678cac377aa2352815a085e4b980d5ba4323f29 /org/eclipse/jgit/org.eclipse.jgit-parent/3.2.0.201312181205-r/org.eclipse.jgit-parent-3.2.0.201312181205-r.pom
fa1d59411d4d2667d8f15638af7c0ac44539234c0982c27a2b65ba06c32a0b3e /org/eclipse/osgi/3.10.0-v20140606-1445/osgi-3.10.0-v20140606-1445.jar
1e10819cdb1fe55d44ac94d37f3b1030275199979a73d04b7b53e2d6000d5d2e /org/eclipse/osgi/3.10.0-v20140606-1445/osgi-3.10.0-v20140606-1445.pom
bddf4d130cb65fdfc1df7df1febde313fc2ff1ac83c8574ff97befd6c515cc30 /org/eclipse/osgi/3.9.1-v20130814-1242/osgi-3.9.1-v20130814-1242.pom
9fbddba8d8cd6322229030a26356ba447421562edebba078267490104ff61d83 /org/eclipse/osgi/maven-metadata.xml
1bacf311ac3d39cc53b03f8de7a4ccffc89c208938f0004a90c652383e927f18 /org/eclipse/text/org.eclipse.text/3.5.101/org.eclipse.text-3.5.101.jar
86545f7161948937a1e632b6bd493008c67c855966acfb7ddd4e710cd7a121ab /org/eclipse/text/org.eclipse.text/3.5.101/org.eclipse.text-3.5.101.pom
88b506fa09a810b19517a2d45cb8f5eaa76c22b18abfbdcf36cd07aebfd56cb0 /org/eclipse/update/configurator/3.2.100-v20070615/configurator-3.2.100-v20070615.jar
4645380254baefd0056e15cc9af6a273fb7d014b8be4ff395a5a61bfe8f4a89c /org/eclipse/update/configurator/3.2.100-v20070615/configurator-3.2.100-v20070615.pom
3c731988480eae3024b27d648aa0408a1cdc065fc523cf41a049fb97148fd30a /org/eclipse/update/configurator/maven-metadata.xml
66fdef91e9739348df7a096aa384a5685f4e875584cce89386a7a47251c4d8e9 /org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar
fde386a7905173a1b103de6ab820727584b50d0e32282e2797787c20a64ffa93 /org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.pom
6d535f94efb663bdb682c9f27a50335394688009642ba7a9677504bc1be4129b /org/hamcrest/hamcrest-parent/1.3/hamcrest-parent-1.3.pom
32ed093f39c46a8d99f801240069478eac93b35f07351c001f2cef4330e97b4a /org/jdom/jdom2/2.0.5/jdom2-2.0.5.jar
ebac276b5ad62e9d312fb6ce663d55fdebaba9badc918166e7d60b1ffd1bd475 /org/jdom/jdom2/2.0.5/jdom2-2.0.5.pom
212f6eaa0491dd7359dc33c3a72e82a23b096e1890d984b4d92395abc9a6bf7f /org/jvnet/localizer/localizer/1.12/localizer-1.12.jar
313b5700337e773a68eeab64ec6952c61b5e7a51839d46bcf77376887fe92f02 /org/jvnet/localizer/localizer/1.12/localizer-1.12.pom
e21488c2fe8db4b23a00c3cfdeab3b600e84c1647e08fb7bee442f5fc1f83990 /org/jvnet/localizer/localizer-parent/1.12/localizer-parent-1.12.pom
c118f8d84313980f79e1e7f7ae4b14b10c2f20c77ea4a1c29f6f0b02bc139077 /org/lwjgl/lwjgl/lwjgl/2.9.1/lwjgl-2.9.1.jar
1adb09c3cf35e0f55d5ecd91e4364100364d8a8031cdfa64ae61eaa64f0d79d4 /org/lwjgl/lwjgl/lwjgl/2.9.1/lwjgl-2.9.1.pom
a50aaa5a89304c23a9257295cbe803e6130526a4dfaea1784076adbacacfd68e /org/lwjgl/lwjgl/lwjgl-platform/2.9.1/lwjgl-platform-2.9.1-natives-linux.jar
e14afffd87719ba12034dd989d40a75540902a6286629fab1330b51c255ab792 /org/lwjgl/lwjgl/lwjgl-platform/2.9.1/lwjgl-platform-2.9.1-natives-osx.jar
ade8deedceb0b60c630f3e78a7b052b7f8f02ff53d91849d1985d3146bf95590 /org/lwjgl/lwjgl/lwjgl-platform/2.9.1/lwjgl-platform-2.9.1-natives-windows.jar
82eb11d59b06700b9ff3db4e0476de1cf86501ba7cd00bb279f40a7c23ad662b /org/lwjgl/lwjgl/lwjgl-platform/2.9.1/lwjgl-platform-2.9.1.pom
32d7e73005a2dc0ccc3c62470c435b351f6501de8e8718e26960534754570a77 /org/lwjgl/lwjgl/lwjgl_util/2.9.1/lwjgl_util-2.9.1.jar
10eab9f1aa97eef450d6c8eca8f459dcdcb9b1d3efbf54eb3dcde33b7aaea1dc /org/lwjgl/lwjgl/lwjgl_util/2.9.1/lwjgl_util-2.9.1.pom
9cf1643b0d805db942498cebf941d1c43df0a1322137291c258aec6109200858 /org/lwjgl/lwjgl/parent/2.9.1/parent-2.9.1.pom
21091d3a9c1349f640fdc421504a604c040ed89087ecc12afbe32353326ed4e5 /org/mortbay/jetty/jetty/6.1.26/jetty-6.1.26.jar
8169c421acc4931f9eb80b818b13a4553a8582e02d08dfc12a51e4f23b2726c6 /org/mortbay/jetty/jetty/6.1.26/jetty-6.1.26.pom
b24e31635c0e6c401ff84e28905b96d1a760144c15f1deae1a22d5b3356e1667 /org/mortbay/jetty/jetty-parent/10/jetty-parent-10.pom
0173d8dbfed2b8ab2a5b36b608a9c509ea0a3fbb4faca67ce7067680c895066a /org/mortbay/jetty/jetty-parent/7/jetty-parent-7.pom
9b974ce2b99f48254b76126337dc45b21226f383aaed616f59780adaf167c047 /org/mortbay/jetty/jetty-util/6.1.26/jetty-util-6.1.26.jar
1e3c13f07407a4b331e229da6bb782ae734f88b6a26a3fbeb165acabc5f6ef24 /org/mortbay/jetty/jetty-util/6.1.26/jetty-util-6.1.26.pom
a3d6e7608155600a73c763ccac74e6b321f8c23dc4747f90635fc2f7cfc1548a /org/mortbay/jetty/project/6.1.26/project-6.1.26.pom
068756096996fe00f604ac3b6672d6f663dc777ea4a83056e240d0456e77e472 /org/mortbay/jetty/servlet-api/2.5-20081211/servlet-api-2.5-20081211.jar
2d705bf03b0b653b0ba3a260b8fe94833e1266bb1e7eb9efc67821555141c9ee /org/mortbay/jetty/servlet-api/2.5-20081211/servlet-api-2.5-20081211.pom
71c4f78e437b8fdcd9cc0dfd2abea8c089eb677005a6a5cff320206cc52b46cc /org/ow2/asm/asm/5.0.3/asm-5.0.3.jar
7d34653ffe62be7714d2f1969660a17df9ec1b19d8250c4f03db1123c82ba6a0 /org/ow2/asm/asm/5.0.3/asm-5.0.3.pom
18c1e092230233c9d29e46f21943d769bdb48130cc279e4b0e663f423948c2da /org/ow2/asm/asm-commons/5.0.3/asm-commons-5.0.3.jar
e87ea4823ecf2dd856901da359270be904236be59c27e2781eb8d78c97e45b2a /org/ow2/asm/asm-commons/5.0.3/asm-commons-5.0.3.pom
2969356ac1e40fe4141948c563690238f5d79d76aec7fd873536867a331ede81 /org/ow2/asm/asm-debug-all/5.0.3/asm-debug-all-5.0.3.jar
9c99d7a555725bc2f8379977935cdba16d687d9c93b6e0725e196180d490c995 /org/ow2/asm/asm-debug-all/5.0.3/asm-debug-all-5.0.3.pom
2341a72bba5e38c1028a332c11607e1706c13fa600fee6fb546b9a1708418097 /org/ow2/asm/asm-debug-all/5.0.4/asm-debug-all-5.0.4.jar
62efbf37e5068a8708541ae0a4da3d1140f4d711d30e4366445cb96ce13cc79e /org/ow2/asm/asm-debug-all/5.0.4/asm-debug-all-5.0.4.pom
f7ac3f642c36c406543bb56ae3db3a53f263f71bd857b04709986e2d5798c8c4 /org/ow2/asm/asm-debug-all/5.1/asm-debug-all-5.1.jar
0a46e33f6b80bd21ac41eec33fca2e43d79253fb46a32d64ba3867ee22451fff /org/ow2/asm/asm-debug-all/5.1/asm-debug-all-5.1.pom
254b82bec9da4f8efbc8b1f93ab2b87f7465227a82b36cf3d05d9e77a0e8dd2e /org/ow2/asm/asm-debug-all/5.2/asm-debug-all-5.2.jar
491f13bd60757a7cfe76e767766b061d557010394f52cec2fb067707de702caa /org/ow2/asm/asm-debug-all/5.2/asm-debug-all-5.2.pom
b4845405fee9fe4f5f665dfe19badcf32581e3eea51b99a45e9f76a0a830c09d /org/ow2/asm/asm-debug-all/5.2/asm-debug-all-5.2-sources.jar
c2edabf4128a534df4b8b4b0b9b562e94f242ba95ac24dc61485432b8a188e32 /org/ow2/asm/asm-parent/5.0.3/asm-parent-5.0.3.pom
fdf05b9df226573b331a7e5df01135e527dcc07c71626445732bd04379aa4a72 /org/ow2/asm/asm-parent/5.0.4/asm-parent-5.0.4.pom
85ec8258fafc283f61647e6a11b404890821c11db6fcf550779ecf7a14151007 /org/ow2/asm/asm-parent/5.1/asm-parent-5.1.pom
cbfacd5dd812db16dc910994007fe58d9402a25507f81a1c2218e15c2c1bedfa /org/ow2/asm/asm-parent/5.2/asm-parent-5.2.pom
347a7a9400f9964e87c91d3980e48eebdc8d024bc3b36f7f22189c662853a51c /org/ow2/asm/asm-tree/5.0.3/asm-tree-5.0.3.jar
65819ca7c5a218ff49f8ebe72f3b39219c81f137d017acc1aec15b1054cf5236 /org/ow2/asm/asm-tree/5.0.3/asm-tree-5.0.3.pom
51215c67d2c068d8b7d2f6f80f51372a098075deccc448d4bdd7b987ba8328fb /org/ow2/ow2/1.3/ow2-1.3.pom
fcb8d5745f776567f1cce332282750b1653568324621ecef03288c8a25919d0e /org/projectlombok/lombok/1.16.4/lombok-1.16.4.pom
e0a471be03e1e6b02bf019480cec7a3ac9801702bf7bf62f15d077ad4df8dd5d /org/projectlombok/lombok/1.16.6/lombok-1.16.6.jar
32ac0a2363ccc0c5086b62cfc05e28a355b74e155efef6b426f5498a0dfc9e4c /org/projectlombok/lombok/1.16.6/lombok-1.16.6.pom
19495ce701fd9ba3c499c137e3ad5364acee8f87a01ef99e912f995a23fd4cb1 /org/scala-lang/modules/scala-parser-combinators_2.11/1.0.1/scala-parser-combinators_2.11-1.0.1.jar
4da632931d9182b1033ddc01a240a18ce9d5704534f52faa515d43119fa6d49f /org/scala-lang/modules/scala-parser-combinators_2.11/1.0.1/scala-parser-combinators_2.11-1.0.1.pom
4a7c757d4d87dd37382bd777ad611b5875748aef148277cf25bb39eebb496d07 /org/scala-lang/modules/scala-swing_2.11/1.0.1/scala-swing_2.11-1.0.1.jar
5201b071fbf92d388940ec1d12cba89baec25dc7b402b1e26110e1f4261b0f2b /org/scala-lang/modules/scala-swing_2.11/1.0.1/scala-swing_2.11-1.0.1.pom
13c0d8d442bde14b73af3ed60e8d53452f9e1ad62ffbe3d944cb918df652db6f /org/scala-lang/modules/scala-xml_2.11/1.0.2/scala-xml_2.11-1.0.2.jar
44b8a07ac6ae1cbc11bba1c03eb90bcf4a707c562eb51e9d56028914a99ab112 /org/scala-lang/modules/scala-xml_2.11/1.0.2/scala-xml_2.11-1.0.2.pom
8dd0a4941f4564117cc991734ca36aa53dff6bb0be329f39eab46d8819f60d1a /org/scala-lang/plugins/scala-continuations-library_2.11/1.0.2/scala-continuations-library_2.11-1.0.2.jar
e8e084c66182fbb88dae252a0c3dba24f8735609d8264feaed1be69915724e85 /org/scala-lang/plugins/scala-continuations-library_2.11/1.0.2/scala-continuations-library_2.11-1.0.2.pom
79329971a31ede7b6823f21a6ab765506b4093d9276debdc9dbe17b996884f2b /org/scala-lang/plugins/scala-continuations-plugin_2.11.1/1.0.2/scala-continuations-plugin_2.11.1-1.0.2.jar
d6b98448db39957d4a5ab49d1d9355889c1b7ef1e4e371e77889da1f66f59c60 /org/scala-lang/plugins/scala-continuations-plugin_2.11.1/1.0.2/scala-continuations-plugin_2.11.1-1.0.2.pom
fa33c031c291ef618e33398aa193ddf4d4c6859d805c9fb3cd4b7c4fbc9acbc6 /org/scala-lang/scala-actors/2.11.0/scala-actors-2.11.0.jar
42665fa39eeb8960adb74dd51fdb239c34e45eacd4b74dc88074d518b7ecfc26 /org/scala-lang/scala-actors/2.11.0/scala-actors-2.11.0.pom
b89d0beb76df20c7b2c2bee59ba53b802cc48566bc3e89ac96ce6361c5c2ee38 /org/scala-lang/scala-actors-migration_2.11/1.1.0/scala-actors-migration_2.11-1.1.0.jar
cd1a673205be12880e73c9c11234d809a901c024a256f4f4c7ae59b0a7aecc75 /org/scala-lang/scala-actors-migration_2.11/1.1.0/scala-actors-migration_2.11-1.1.0.pom
3aa616f5c56d2052fc5e3231f3e8cf1736f876caff0142a66096fc5b4dc87ae5 /org/scala-lang/scala-compiler/2.11.1/scala-compiler-2.11.1.jar
abe89207b0bfcbcf164c820cbba2c962ab5e9f3a0d0f37d81bde4f6c293a874b /org/scala-lang/scala-compiler/2.11.1/scala-compiler-2.11.1.pom
088bcb80f71b6e6a2a31d2fe7288c1fd64f19663ce281b924cdfab3fb105f4f3 /org/scala-lang/scala-library/2.11.1/scala-library-2.11.1.jar
3268a48dc36c664e7f4bd5d88b366bf098a13f7b6e8b87611e3a4413b72860d4 /org/scala-lang/scala-library/2.11.1/scala-library-2.11.1.pom
41938d1e89670979dd783102777a8b879999f4fb00a5b811b51c105b02a9d4f8 /org/scala-lang/scala-reflect/2.11.1/scala-reflect-2.11.1.jar
8b58df7e9e5f2f4f7d2f0dc24353f356abe965337e48504cec36a344e6294757 /org/scala-lang/scala-reflect/2.11.1/scala-reflect-2.11.1.pom
719fe091fd3fe4c6a7b8f69c8714935138b85a2b6145068a1ccfdb57d2e500d1 /org/sonatype/aether/aether/1.13.1/aether-1.13.1.pom
ae8dc80232771f8913febfa410c5719e9ba8ded81fb99788e214fd676dbbe13f /org/sonatype/aether/aether-api/1.13.1/aether-api-1.13.1.jar
9a58a1ddbbbe5b635674a958ac9d95d4ffaba7a40b9f800cde2cdf4986c3ef2a /org/sonatype/aether/aether-api/1.13.1/aether-api-1.13.1.pom
865511994805827e88f327944a089142bb7f3d88cde271ba3dceb732cb137a93 /org/sonatype/aether/aether-impl/1.13.1/aether-impl-1.13.1.jar
5d85a54716b6c6fc043895b129c3c76a2b9ca922c3bd79158ef08b7960aaf330 /org/sonatype/aether/aether-impl/1.13.1/aether-impl-1.13.1.pom
d5de4e299be5a79feb1dbe8ff3814034c6e44314b4c00b92ffa8d97576ded5b3 /org/sonatype/aether/aether-spi/1.13.1/aether-spi-1.13.1.jar
3d0c466fe8af3983356991ca7ff01a802920e04f946675d920420e154c5edec2 /org/sonatype/aether/aether-spi/1.13.1/aether-spi-1.13.1.pom
687799a0ce988bee9e8eb9ae0ba870300adc0114248ad4a4327bdb625d27e010 /org/sonatype/aether/aether-util/1.13.1/aether-util-1.13.1.jar
abd5e7869aa58f720d8c7301004334449351ad297aeb6ba2ebabf9b38503267b /org/sonatype/aether/aether-util/1.13.1/aether-util-1.13.1.pom
c14fb9c32b59cc03251f609416db7c0cff01f811edcccb4f6a865d6e7046bd0b /org/sonatype/forge/forge-parent/10/forge-parent-10.pom
03263b68791fb11e7464ffcc2c3de7eaeae235de8c94827ce6407e0454d2aae9 /org/sonatype/forge/forge-parent/3/forge-parent-3.pom
1838d132479005b4b7459b798e9d9915515090c288082fdcd86db0b10983a24c /org/sonatype/forge/forge-parent/4/forge-parent-4.pom
e56188aa8ce51278006aa90bc7e0f304a81e2f1219f462e7d21f262535cd2795 /org/sonatype/forge/forge-parent/5/forge-parent-5.pom
1678d4120a585d8a630131aeec4c524d928398583b7eab616ee7d5a87f520d3d /org/sonatype/oss/oss-parent/5/oss-parent-5.pom
b4306d13e8f5392458a1b30866f1cff161b3d2e6999a88d059eea3932c8a8499 /org/sonatype/oss/oss-parent/6/oss-parent-6.pom
b51f8867c92b6a722499557fc3a1fdea77bdf9ef574722fe90ce436a29559454 /org/sonatype/oss/oss-parent/7/oss-parent-7.pom
fb40265f982548212ff82e362e59732b2187ec6f0d80182885c14ef1f982827a /org/sonatype/oss/oss-parent/9/oss-parent-9.pom
5a15fdba22669e0fdd06e10dcce6320879e1f7398fbc910cd0677b50672a78c4 /org/sonatype/plexus/plexus-cipher/1.4/plexus-cipher-1.4.jar
a63a2e23988cca7fac6c93886d6f0506fd26d88d7e8cc0cb89b9c6e0d6c994ad /org/sonatype/plexus/plexus-cipher/1.4/plexus-cipher-1.4.pom
3b0559bb8432f28937efe6ca193ef54a8506d0075d73fd7406b9b116c6a11063 /org/sonatype/plexus/plexus-sec-dispatcher/1.3/plexus-sec-dispatcher-1.3.jar
d5e650c50ef6958c028ed024b59af04cf3d38e1453a77d542b6b484bc0f4ca0b /org/sonatype/plexus/plexus-sec-dispatcher/1.3/plexus-sec-dispatcher-1.3.pom
a966df5e36d54a9d9690db81c459806252b924da949a42b538eba5683d6267db /org/sonatype/sisu/inject/containers/2.3.0/containers-2.3.0.pom
cfc3507491767609fb2da36dcf32ebb0055b8bd32a2af182c021df9ecce26a76 /org/sonatype/sisu/inject/guava-parent/0.9.9/guava-parent-0.9.9.pom
852f10c4ba2210c29f75d330dc81f406ab8db5cb46430c5ba4082f9c13df180d /org/sonatype/sisu/inject/guice-bean/2.3.0/guice-bean-2.3.0.pom
6c1be769d69337f1a8cc2d7e756f94b8bdc02a76c3087545aad1e374ac4bd0ce /org/sonatype/sisu/inject/guice-parent/3.1.0/guice-parent-3.1.0.pom
9188fe7eb026bf4c35309f685ea7cf14cb2ebd7c7d49572486f5a97d4b312a03 /org/sonatype/sisu/inject/guice-plexus/2.3.0/guice-plexus-2.3.0.pom
9897e80ff6c08fc45b5b5ebd81d9e943a1087bdf0ad50cda457d616abbdaacd9 /org/sonatype/sisu/sisu-guava/0.9.9/sisu-guava-0.9.9.jar
2c007ed1e50e0edc62f8e3cdf725e1f61068206bc955aec48f3eb13a3467c6e5 /org/sonatype/sisu/sisu-guava/0.9.9/sisu-guava-0.9.9.pom
4b76079f35407e5682aac1ecbe67afd5f430ae619044a9d6a413666a45750c25 /org/sonatype/sisu/sisu-guice/3.1.0/sisu-guice-3.1.0-no_aop.jar
28a7c38bd751e9e2a9f8d13ddf876266f90f9d6e29c9178b524828afbc5e45f4 /org/sonatype/sisu/sisu-guice/3.1.0/sisu-guice-3.1.0.pom
4b112cc2452aee6930dff95512f05041e4c66a2df0a828e95f8439c23a8759e9 /org/sonatype/sisu/sisu-inject/2.3.0/sisu-inject-2.3.0.pom
75819b29737c2bee1bfbda1011d455c7036738e0ef32ffbf85ba1d8fa157ceb2 /org/sonatype/sisu/sisu-inject-bean/2.3.0/sisu-inject-bean-2.3.0.jar
f41fc69095282c2c332cf3d9f27a2f3b2d87cd22fcb6511df59fffd90a977ec0 /org/sonatype/sisu/sisu-inject-bean/2.3.0/sisu-inject-bean-2.3.0.pom
bf9083fb846993689409b2bdbc735048e53bac6cc32707cde7ef84817b6e9365 /org/sonatype/sisu/sisu-inject-plexus/2.3.0/sisu-inject-plexus-2.3.0.jar
34feae95889f78e7d4260167736e6af444296fbc5f3794b8c1b90eb6332c4714 /org/sonatype/sisu/sisu-inject-plexus/2.3.0/sisu-inject-plexus-2.3.0.pom
aef1fd28efd25bd778aa3d3770c6f9e606ca2354149e985f1d63fc7c6a366bd2 /org/sonatype/sisu/sisu-parent/2.3.0/sisu-parent-2.3.0.pom
02161ae46462da669b1d7be3f9b64687c6347f84d04c890fa467eff6def0ae10 /org/sonatype/spice/model-builder/1.3/model-builder-1.3.jar
0d2cc363cdfc6c102203adb6a5c138c195eaf1198527a09e6a17aa0227a66bcd /org/sonatype/spice/model-builder/1.3/model-builder-1.3.pom
683c012c6bf5e1e31b232b3755c027ccd829692a09c8216652b414b09d4ae623 /org/sonatype/spice/spice-parent/10/spice-parent-10.pom
21a19b26dbe5c38ddb5114cf4eadbf5ccb411bc6b128fdd5949b1ccb12f3683e /org/sonatype/spice/spice-parent/12/spice-parent-12.pom
258f43b5e805687302a5bb400856b972a573ec42a44f949641354a84b9243758 /org/sonatype/spice/spice-parent/16/spice-parent-16.pom
d1968436fc216c901fb9b82c7e878b50fd1d30091676da95b2edd3a9c0ccf92e /stax/stax-api/1.0.1/stax-api-1.0.1.jar
87b13ae136a2bb9299271a0dfe8c351f76661b654ed8fde035c2cabb198cf259 /stax/stax-api/1.0.1/stax-api-1.0.1.pom
ad68a86cfd0255a2bc0525ce11ec49640caea7e34ff91eb89c3193dcccd77f05 /trove/trove/1.0.2/trove-1.0.2.jar
83f2682bd3ded1fe417b7e98e7ac86510cd747378eae7e3a5d1d35c7c7f0d2ea /trove/trove/1.0.2/trove-1.0.2.pom
3b90f9f7ad968b9588482e3a09b6e7d0d81c6cf7c214c5cecd8120e3ee509ae9 /tv/twitch/twitch/6.5/twitch-6.5.jar
56820ae80518871ff0af04dbfa54e311f6fa54de922d201f71bd2d3f210e94ba /tv/twitch/twitch/6.5/twitch-6.5.pom
0825d6081eef7e57434cd15525d6c1e7bc5d590e08eaea5b7516820031978af9 /tv/twitch/twitch-external-platform/4.5/twitch-external-platform-4.5-natives-windows-32.jar
6428eb438f53afc563d58c7f2a563ca9fcaae80db3520af744de5e5db1c9df6a /tv/twitch/twitch-external-platform/4.5/twitch-external-platform-4.5-natives-windows-64.jar
5ac03ac36144e4aeeb57b8ccc968b1ed75ae4b9ed4b094f47cb2b7b64c23a67d /tv/twitch/twitch-external-platform/4.5/twitch-external-platform-4.5.pom
4005b7d20bc7e8c37cb0fd94bb7c44b5a6373846f3cb59e7a0095f6ebdf3e4f3 /tv/twitch/twitch-platform/6.5/twitch-platform-6.5-natives-osx.jar
8315b4943f4e1356c34b213d4f309784d5e36cbded1fb37c49efcc7d22c909cb /tv/twitch/twitch-platform/6.5/twitch-platform-6.5-natives-windows-32.jar
75337e7362e489a6f8c9712aeced9e131e82a3ce851cafbd4d03fda284cc7116 /tv/twitch/twitch-platform/6.5/twitch-platform-6.5-natives-windows-64.jar
3b5636dae28488379b110bd87a769497af8227518c273e62110cfd638f9fdcb6 /tv/twitch/twitch-platform/6.5/twitch-platform-6.5.pom
* /versions.json

69
gradle/reprod/init.gradle Normal file
View File

@@ -0,0 +1,69 @@
import java.util.jar.JarEntry
import java.util.jar.JarFile
import java.util.jar.JarOutputStream
initscript {
repositories {
maven { url 'http://jitpack.io' }
}
dependencies {
classpath 'com.github.johni0702:gradle-reproducible-builds-plugin:a524ada'
classpath 'com.github.johni0702:gradle-ecj-plugin:795736c'
}
}
def convertRepoToHttp = { repo ->
if (repo instanceof MavenArtifactRepository && repo.url.toString().startsWith('https://')) {
URL url = repo.url.toURL()
repo.url = new URL("http", url.getHost(), url.getPort(), url.getFile()).toURI()
}
}
allprojects {
buildscript {
repositories.all convertRepoToHttp
}
repositories { mavenCentral() } // for ecj
repositories.all convertRepoToHttp
apply plugin: de.johni0702.gradle.ReproducibleBuildsPlugin, to: project
apply plugin: xink.gradle.ecj.EcjPlugin, to: project
apply plugin: 'maven', to: project
ecj {
warn = ['none']
}
repositories {
maven {
url(project.file('gradle/reprod').exists() ? 'gradle/reprod/deps/repo' : '../repo')
}
}
task createPom {
doLast {
pom {
project {
groupId 'reprod'
artifactId project.file('.').name
version '0'
}
whenConfigured {
dependencies.removeAll { it.artifactId == 'mixin-asm-debug-all' }
}
}.writeTo("pom.xml")
}
}
if (!project.file('gradle/reprod').exists()) {
build.dependsOn createPom
}
reproducibleBuilds {
if (project.file('.').name == 'forgegradle') {
project.tasks.all {
if (it.name == 'jar') {
println 'Manually repacking archive after jar task'
repackAfter it
}
}
}
}
}

View File

@@ -0,0 +1,37 @@
From a1b7d25752424f267f5e9d299babc0403dbf7752 Mon Sep 17 00:00:00 2001
From: Jonas Herzig <me@johni0702.de>
Date: Tue, 8 Aug 2017 19:44:44 +0200
Subject: [PATCH] Add build.gradle
---
build.gradle | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
create mode 100644 build.gradle
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..22fa679
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,18 @@
+apply plugin: 'java'
+
+sourceCompatibility = 1.8
+
+sourceSets {
+ main {
+ java {
+ srcDirs = ['src']
+ }
+ }
+}
+
+jar {
+ manifest {
+ attributes 'Main-Class': 'org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler'
+ }
+}
+
--
2.5.5

View File

@@ -0,0 +1,84 @@
From 5d778fec168a72d41df672ad38ee5f01973916ce Mon Sep 17 00:00:00 2001
From: Jonas Herzig <me@johni0702.de>
Date: Sat, 2 Sep 2017 15:40:15 +0200
Subject: [PATCH] Fix compilation with newer gradle versions
---
src/main/java/net/minecraftforge/gradle/tasks/CreateStartTask.java | 1 -
src/main/java/net/minecraftforge/gradle/user/TaskRecompileMc.java | 1 -
src/main/java/net/minecraftforge/gradle/user/UserBasePlugin.java | 1 -
.../java/net/minecraftforge/gradle/util/SourceDirSetSupplier.java | 4 ++--
src/main/java/net/minecraftforge/gradle/util/json/JsonFactory.java | 1 -
5 files changed, 2 insertions(+), 6 deletions(-)
diff --git a/src/main/java/net/minecraftforge/gradle/tasks/CreateStartTask.java b/src/main/java/net/minecraftforge/gradle/tasks/CreateStartTask.java
index 1de9ac3..8d0a5a5 100644
--- a/src/main/java/net/minecraftforge/gradle/tasks/CreateStartTask.java
+++ b/src/main/java/net/minecraftforge/gradle/tasks/CreateStartTask.java
@@ -128,7 +128,6 @@ public class CreateStartTask extends CachedTask
LoggingManager log = getLogging();
LogLevel startLevel = getProject().getGradle().getStartParameter().getLogLevel();
if (startLevel.compareTo(LogLevel.LIFECYCLE) >= 0) {
- log.setLevel(LogLevel.ERROR);
}
// INVOKE!
this.getAnt().invokeMethod("javac", ImmutableMap.builder()
diff --git a/src/main/java/net/minecraftforge/gradle/user/TaskRecompileMc.java b/src/main/java/net/minecraftforge/gradle/user/TaskRecompileMc.java
index 224292c..f61618c 100644
--- a/src/main/java/net/minecraftforge/gradle/user/TaskRecompileMc.java
+++ b/src/main/java/net/minecraftforge/gradle/user/TaskRecompileMc.java
@@ -86,7 +86,6 @@ public class TaskRecompileMc extends CachedTask
LoggingManager log = getLogging();
LogLevel startLevel = getProject().getGradle().getStartParameter().getLogLevel();
if (startLevel.compareTo(LogLevel.LIFECYCLE) >= 0) {
- log.setLevel(LogLevel.ERROR);
}
// recompile
diff --git a/src/main/java/net/minecraftforge/gradle/user/UserBasePlugin.java b/src/main/java/net/minecraftforge/gradle/user/UserBasePlugin.java
index 98391fc..9408a07 100644
--- a/src/main/java/net/minecraftforge/gradle/user/UserBasePlugin.java
+++ b/src/main/java/net/minecraftforge/gradle/user/UserBasePlugin.java
@@ -37,7 +37,6 @@ import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
-import com.beust.jcommander.internal.Lists;
import org.gradle.api.Action;
import org.gradle.api.DefaultTask;
import org.gradle.api.NamedDomainObjectContainer;
diff --git a/src/main/java/net/minecraftforge/gradle/util/SourceDirSetSupplier.java b/src/main/java/net/minecraftforge/gradle/util/SourceDirSetSupplier.java
index 4e9dbe5..4f3744e 100644
--- a/src/main/java/net/minecraftforge/gradle/util/SourceDirSetSupplier.java
+++ b/src/main/java/net/minecraftforge/gradle/util/SourceDirSetSupplier.java
@@ -19,13 +19,13 @@
*/
package net.minecraftforge.gradle.util;
-import com.beust.jcommander.internal.Lists;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
import net.minecraftforge.srg2source.util.io.InputSupplier;
import net.minecraftforge.srg2source.util.io.OutputSupplier;
import org.gradle.api.file.FileVisitDetails;
import org.gradle.api.file.FileVisitor;
import org.gradle.api.file.SourceDirectorySet;
-import org.testng.collections.Maps;
import java.io.*;
import java.util.List;
diff --git a/src/main/java/net/minecraftforge/gradle/util/json/JsonFactory.java b/src/main/java/net/minecraftforge/gradle/util/json/JsonFactory.java
index b75f653..fa61537 100644
--- a/src/main/java/net/minecraftforge/gradle/util/json/JsonFactory.java
+++ b/src/main/java/net/minecraftforge/gradle/util/json/JsonFactory.java
@@ -26,7 +26,6 @@ import java.io.IOException;
import java.util.*;
import java.util.Map.Entry;
-import com.beust.jcommander.internal.Lists;
import com.google.common.base.Strings;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
--
2.9.5

View File

@@ -0,0 +1,75 @@
From 7127699cb761a518cce8872b0b78694e357f21fe Mon Sep 17 00:00:00 2001
From: Jonas Herzig <me@johni0702.de>
Date: Mon, 28 Aug 2017 17:50:38 +0200
Subject: [PATCH] Replace https urls with http for proxy-witness
---
.../java/net/minecraftforge/gradle/common/BasePlugin.java | 13 ++++++++++---
.../java/net/minecraftforge/gradle/common/Constants.java | 4 ++--
2 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/src/main/java/net/minecraftforge/gradle/common/BasePlugin.java b/src/main/java/net/minecraftforge/gradle/common/BasePlugin.java
index df369f1..e3e50c0 100644
--- a/src/main/java/net/minecraftforge/gradle/common/BasePlugin.java
+++ b/src/main/java/net/minecraftforge/gradle/common/BasePlugin.java
@@ -350,6 +350,13 @@ public abstract class BasePlugin<K extends BaseExtension> implements Plugin<Proj
// not required.. but you probably wanan implement this
}
+ private static String http(String url) {
+ if (url.startsWith("https://")) {
+ url = "http" + url.substring("https".length());
+ }
+ return url;
+ }
+
@SuppressWarnings("serial")
private void makeCommonTasks()
{
@@ -358,7 +365,7 @@ public abstract class BasePlugin<K extends BaseExtension> implements Plugin<Proj
@Override
public String call()
{
- return mcManifest.get(getExtension().getVersion()).url;
+ return http(mcManifest.get(getExtension().getVersion()).url);
}
});
getVersionJson.setFile(delayedFile(JSON_VERSION));
@@ -435,7 +442,7 @@ public abstract class BasePlugin<K extends BaseExtension> implements Plugin<Proj
@Override
public String call()
{
- return mcVersionJson.getClientUrl();
+ return http(mcVersionJson.getClientUrl());
}
});
@@ -449,7 +456,7 @@ public abstract class BasePlugin<K extends BaseExtension> implements Plugin<Proj
@Override
public String call()
{
- return mcVersionJson.getServerUrl();
+ return http(mcVersionJson.getServerUrl());
}
});
diff --git a/src/main/java/net/minecraftforge/gradle/common/Constants.java b/src/main/java/net/minecraftforge/gradle/common/Constants.java
index b42b1c2..a0753e0 100644
--- a/src/main/java/net/minecraftforge/gradle/common/Constants.java
+++ b/src/main/java/net/minecraftforge/gradle/common/Constants.java
@@ -115,10 +115,10 @@ public class Constants
// urls
- public static final String URL_MC_MANIFEST = "https://launchermeta.mojang.com/mc/game/version_manifest.json";
+ public static final String URL_MC_MANIFEST = "http://launchermeta.mojang.com/mc/game/version_manifest.json";
public static final String URL_FF = "http://files.minecraftforge.net/fernflower-fix-1.0.zip";
public static final String URL_ASSETS = "http://resources.download.minecraft.net";
- public static final String URL_LIBRARY = "https://libraries.minecraft.net/";
+ public static final String URL_LIBRARY = "http://libraries.minecraft.net/";
public static final String URL_FORGE_MAVEN = "http://files.minecraftforge.net/maven";
public static final String URL_MCP_JSON = "http://export.mcpbot.bspk.rs/versions.json";
--
2.5.5

View File

@@ -0,0 +1,36 @@
From 2309fc9515d4010c5d9db89008660e3e60ea529b Mon Sep 17 00:00:00 2001
From: Jonas Herzig <me@johni0702.de>
Date: Sat, 26 Aug 2017 17:40:48 +0200
Subject: [PATCH] Replace SNAPSHOT deps with manually built ones
---
build.gradle | 49 +++----------------------------------------------
1 file changed, 3 insertions(+), 46 deletions(-)
diff --git a/build.gradle b/build.gradle
index bfadecd..774a015 100644
--- a/build.gradle
+++ b/build.gradle
@@ -67,7 +67,7 @@ dependencies {
compile 'com.nothome:javaxdelta:2.0.1' // GDIFF implementation for BinPatches
compile 'com.google.code.gson:gson:2.2.4' // Used instead of Argo for buuilding changelog.
compile 'com.github.tony19:named-regexp:0.2.3' // 1.7 Named regexp features
- compile 'net.minecraftforge:fernflower:2.0-SNAPSHOT' // Fernflower Forge edition
+ compile 'reprod:forgeflower:0' // Fernflower Forge edition
shade 'net.md-5:SpecialSource:1.7.4' // deobf and reobs
// compile 'net.md-5:SpecialSource:1.7.4' // when md5 publishes
@@ -78,8 +78,8 @@ dependencies {
// mcp stuff
shade 'de.oceanlabs.mcp:RetroGuard:3.6.6'
- shade 'de.oceanlabs.mcp:mcinjector:3.4-SNAPSHOT'
- shade 'net.minecraftforge.srg2source:Srg2Source:3.3-SNAPSHOT'
+ shade 'reprod:mcinjector:0'
+ shade 'reprod:srg2source:0'
//Stuff used in the GradleStart classes
compileOnly 'com.mojang:authlib:1.5.16'
--
2.5.5

View File

@@ -0,0 +1,126 @@
From 85e6315018dd8ff9f613b1f0c4d00c5b0c6c37d6 Mon Sep 17 00:00:00 2001
From: Jonas Herzig <me@johni0702.de>
Date: Sat, 26 Aug 2017 17:27:06 +0200
Subject: [PATCH 1/2] Remove non-essential parts and shade manually
---
build.gradle | 92 +-----------------------------------------------------------
1 file changed, 1 insertion(+), 91 deletions(-)
diff --git a/build.gradle b/build.gradle
index 2e5f949..b6c63bb 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,15 +1,5 @@
-buildscript {
- repositories {
- mavenCentral()
- }
- dependencies {
- classpath 'eu.appsatori:gradle-fatjar-plugin:0.2-rc1'
- }
-}
-
apply plugin: 'java'
apply plugin: 'eclipse'
-apply plugin: 'fatjar'
apply plugin: 'maven'
group = 'de.oceanlabs.mcp'
@@ -22,93 +12,12 @@ repositories {
}
jar {
manifest.attributes('Main-Class': 'de.oceanlabs.mcp.mcinjector.MCInjector')
}
-fatJar {
- classifier 'fatjar'
- manifest.attributes('Main-Class': 'de.oceanlabs.mcp.mcinjector.MCInjector')
-}
-
-artifacts {
- archives jar
- archives fatJar
-}
dependencies {
compile 'org.ow2.asm:asm-debug-all:5.0.4'
compile 'net.sf.jopt-simple:jopt-simple:4.5'
compile 'com.google.code.gson:gson:2.2.4'
}
-configurations { deployJars }
-uploadArchives {
- repositories {
- add project.repositories.mavenLocal()
- }
- repositories.mavenDeployer {
- configuration = configurations.deployJars
- if (project.hasProperty("filesmaven")) {
- logger.info('Publishing to files server')
- repository(url: project.filesmaven.url) {
- authentication(userName: project.filesmaven.username, privateKey: project.filesmaven.key)
- }
- } else {
- logger.info('Publishing to repo folder')
- repository(url: 'file://localhost/' + project.file('repo').getAbsolutePath())
- }
-
- pom {
- groupId = project.group
- version = project.version
- artifactId = project.archivesBaseName
- }
- pom.project {
- name project.archivesBaseName
- packaging 'jar'
- description 'Java class metadata injector'
- url 'https://github.com/ModCoderPack/MCInjector'
-
- scm {
- url 'https://github.com/ModCoderPack/MCInjector'
- connection 'scm:git:git://github.com/ModCoderPack/MCInjector.git'
- developerConnection 'scm:git:git@github.com:ModCoderPack/MCInjector.git'
- }
-
- issueManagement {
- system 'github'
- url 'https://github.com/ModCoderPack/MCInjector/issues'
- }
-
- licenses {
- license {
- name ''
- url ''
- distribution 'repo'
- }
- }
-
- developers {
- developer {
- id 'Fesh0r'
- name 'Fesh0r'
- roles { role 'developer' }
- }
- developer {
- id 'Searge'
- name 'Searge'
- roles { role 'developer' }
- }
- developer {
- id 'cpw'
- name 'cpw'
- roles { role 'developer' }
- }
- developer {
- id 'LexManos'
- name 'Lex Manos'
- roles { role 'developer' }
- }
- }
- }
- }
-}
--
2.5.5

View File

@@ -0,0 +1,54 @@
From c245b961e83176a1731a7eaf1f1f3ffbefa1afb7 Mon Sep 17 00:00:00 2001
From: Jonas Herzig <me@johni0702.de>
Date: Tue, 8 Aug 2017 19:08:56 +0200
Subject: [PATCH 2/7] Remove/replace all buildscript dependencies
---
build.gradle | 24 +-----------------------
1 file changed, 1 insertion(+), 23 deletions(-)
diff --git a/build.gradle b/build.gradle
index e0c46ea..165dbe4 100644
--- a/build.gradle
+++ b/build.gradle
@@ -5,13 +5,11 @@
}
dependencies {
- classpath 'nl.javadude.gradle.plugins:license-gradle-plugin:0.11.0'
classpath 'com.github.jengelman.gradle.plugins:shadow:1.2.3'
}
}
// Apply plugin
apply plugin: 'java'
-apply plugin: 'license'
apply plugin: 'checkstyle'
apply plugin: 'maven'
apply plugin: 'eclipse'
@@ -170,23 +165,6 @@ tasks.withType(AbstractArchiveTask) {
from 'LICENSE.txt'
}
-// License header formatting
-license {
- ext {
- name = project.name
- organization = project.organization
- url = project.url
- }
- include '**/*.java'
- header file("HEADER.txt")
- sourceSets = project.sourceSets
- ignoreFailures false
- strictCheck true
- mapping {
- java = 'SLASHSTAR_STYLE'
- }
-}
-
checkstyle {
configProperties = [
"name" : project.name,
--
2.5.5

View File

@@ -0,0 +1,25 @@
From 0f250141ba6515dbeffeb0722bf29976850bb323 Mon Sep 17 00:00:00 2001
From: Jonas Herzig <me@johni0702.de>
Date: Tue, 8 Aug 2017 19:13:17 +0200
Subject: [PATCH 3/7] Fix for Gradle 3
---
build.gradle | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/build.gradle b/build.gradle
index 165dbe4..0f189ec 100644
--- a/build.gradle
+++ b/build.gradle
@@ -92,7 +92,7 @@ dependencies {
// Task to read ASM library and rename packages
task renamedASM {
- outputs.file files(configurations.asm.files.withIndex().collect { file, i -> def dep = configurations.asm.dependencies[i]
+ outputs.files files(configurations.asm.files.withIndex().collect { file, i -> def dep = configurations.asm.dependencies[i]
new File(new File(renamedPackageRoot, "org/spongepowered/mixin-" + dep.name + "/" + dep.version), "mixin-" + file.name).path
})
ant {
--
2.5.5

View File

@@ -0,0 +1,42 @@
From eb4fa04cf82067b20caa7222c154f8b6f7ab95ac Mon Sep 17 00:00:00 2001
From: Jonas Herzig <me@johni0702.de>
Date: Tue, 8 Aug 2017 19:13:45 +0200
Subject: [PATCH 4/7] Disable checkstyle
---
build.gradle | 12 ------------
1 file changed, 12 deletions(-)
diff --git a/build.gradle b/build.gradle
index 0f189ec..f8598a3 100644
--- a/build.gradle
+++ b/build.gradle
@@ -7,7 +7,6 @@ buildscript {
// Apply plugin
apply plugin: 'java'
-apply plugin: 'checkstyle'
apply plugin: 'maven'
apply plugin: 'eclipse'
apply plugin: 'idea'
@@ -165,17 +164,6 @@ tasks.withType(AbstractArchiveTask) {
from 'LICENSE.txt'
}
-checkstyle {
- configProperties = [
- "name" : project.name,
- "organization": project.organization,
- "url" : project.url,
- "year" : project.inceptionYear
- ]
- configFile = file("checkstyle.xml")
- toolVersion = '6.19'
-}
-
// Source compiler configuration
tasks.withType(JavaCompile) {
options.compilerArgs += ['-Xlint:all', '-Xlint:-path']
--
2.5.5

View File

@@ -0,0 +1,25 @@
From c66ba83e4b27f6f094c2dcdaaac095d3ca69b41c Mon Sep 17 00:00:00 2001
From: Jonas Herzig <me@johni0702.de>
Date: Tue, 8 Aug 2017 19:35:08 +0200
Subject: [PATCH 5/7] Replace fernflower SNAPSHOT depencency
---
build.gradle | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/build.gradle b/build.gradle
index f8598a3..e9a965b 100644
--- a/build.gradle
+++ b/build.gradle
@@ -143,7 +143,7 @@ dependencies {
// Fernflower decompiler
fernflowerCompile configurations.compile
- fernflowerCompile 'org.jetbrains.java.decompiler:fernflower:sponge-SNAPSHOT'
+ fernflowerCompile 'reprod:fernflower:0'
// LegacyLauncher service
launchwrapperCompile configurations.compile
--
2.5.5

View File

@@ -0,0 +1,56 @@
From 6422d5985faeff394237a499e5529b765dd46b7e Mon Sep 17 00:00:00 2001
From: Jonas Herzig <me@johni0702.de>
Date: Tue, 8 Aug 2017 21:40:59 +0200
Subject: [PATCH 6/7] Use TreeMap in ReferenceMapper for reproducibility
---
.../java/org/spongepowered/asm/mixin/refmap/ReferenceMapper.java | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/src/main/java/org/spongepowered/asm/mixin/refmap/ReferenceMapper.java b/src/main/java/org/spongepowered/asm/mixin/refmap/ReferenceMapper.java
index 2a368e7..082b5dd 100644
--- a/src/main/java/org/spongepowered/asm/mixin/refmap/ReferenceMapper.java
+++ b/src/main/java/org/spongepowered/asm/mixin/refmap/ReferenceMapper.java
@@ -29,7 +29,6 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.Serializable;
-import java.util.HashMap;
import java.util.Map;
import org.apache.commons.io.IOUtils;
@@ -71,13 +70,13 @@ public final class ReferenceMapper implements Serializable {
* by the AP. Each entry is keyed by the owning mixin, with the value map
* containing the actual remappings for each owner
*/
- private final Map<String, Map<String, String>> mappings = Maps.newHashMap();
+ private final Map<String, Map<String, String>> mappings = Maps.newTreeMap();
/**
* All mapping sets, keyed by environment type, eg. "notch", "searge". The
* format of each map within this map is the same as for {@link #mappings}
*/
- private final Map<String, Map<String, Map<String, String>>> data = Maps.newHashMap();
+ private final Map<String, Map<String, Map<String, String>>> data = Maps.newTreeMap();
/**
* True if this refmap cannot be written. Only true for the
@@ -191,13 +190,13 @@ public final class ReferenceMapper implements Serializable {
if (context != null) {
mappings = this.data.get(context);
if (mappings == null) {
- mappings = Maps.newHashMap();
+ mappings = Maps.newTreeMap();
this.data.put(context, mappings);
}
}
Map<String, String> classMappings = mappings.get(className);
if (classMappings == null) {
- classMappings = new HashMap<String, String>();
+ classMappings = Maps.newTreeMap();
mappings.put(className, classMappings);
}
return classMappings.put(reference, newReference);
--
2.5.5

View File

@@ -0,0 +1,26 @@
From c3d6d12f47bae3c12c597e59d9a69989fdaa9550 Mon Sep 17 00:00:00 2001
From: Jonas Herzig <me@johni0702.de>
Date: Fri, 25 Aug 2017 19:27:13 +0200
Subject: [PATCH] Do not include java version and user name in jar
---
build.gradle | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/build.gradle b/build.gradle
index debc97b..ae53e1b 100644
--- a/build.gradle
+++ b/build.gradle
@@ -241,8 +241,7 @@ jar {
// JAR manifest configuration
manifest.mainAttributes(
- "Built-By": System.properties['user.name'],
- "Created-By": System.properties['java.vm.version'] + " (" + System.properties['java.vm.vendor'] + ")",
+ "Built-By": 'ReplayMod reprod',
"Implementation-Title": name,
"Implementation-Version": version + "+" + ciSystem + "-b" + buildNumber + ".git-" + commit,
"Implementation-Vendor": url,
--
2.13.2

View File

@@ -0,0 +1,26 @@
From 6de53f46b4b14c7667e7cff8010bde040ae7967b Mon Sep 17 00:00:00 2001
From: Jonas Herzig <me@johni0702.de>
Date: Fri, 25 Aug 2017 18:34:39 +0200
Subject: [PATCH] Do not include java version and user name in jar
---
build.gradle | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/build.gradle b/build.gradle
index db80dfa..2f5e041 100644
--- a/build.gradle
+++ b/build.gradle
@@ -59,8 +59,7 @@ processResources {
}
jar.manifest.mainAttributes (
- "Built-By": System.properties['user.name'],
- "Created-By": System.properties['java.vm.version'] + " (" + System.properties['java.vm.vendor'] + ")",
+ "Built-By": 'ReplayMod reprod',
"Implementation-Title": name,
"Implementation-Version": version
)
--
2.13.2

View File

@@ -0,0 +1,53 @@
From 6b7ad7fd8c22384e62585a962e1bd74d6d003582 Mon Sep 17 00:00:00 2001
From: Jonas Herzig <me@johni0702.de>
Date: Sat, 2 Sep 2017 15:10:35 +0200
Subject: [PATCH] Disable license plugin
---
build.gradle | 18 ------------------
1 file changed, 18 deletions(-)
diff --git a/build.gradle b/build.gradle
index 60ad57d..57aa5e4 100644
--- a/build.gradle
+++ b/build.gradle
@@ -5,13 +5,11 @@ buildscript {
}
}
dependencies {
- classpath 'nl.javadude.gradle.plugins:license-gradle-plugin:0.11.0'
classpath "com.gradle.publish:plugin-publish-plugin:0.9.1"
}
}
apply plugin: 'groovy'
-apply plugin: 'license'
apply plugin: 'maven'
apply plugin: 'eclipse'
apply plugin: "com.gradle.plugin-publish"
@@ -42,22 +40,6 @@ processResources {
from 'LICENSE.txt'
}
-license {
- ext {
- name = project.name
- organization = project.organization
- url = project.url
- }
- include '**/*.groovy'
- header file("HEADER.txt")
- sourceSets = project.sourceSets
- ignoreFailures false
- strictCheck true
- mapping {
- java = 'SLASHSTAR_STYLE'
- }
-}
-
jar.manifest.mainAttributes (
"Built-By": 'ReplayMod reprod',
"Implementation-Title": name,
--
2.9.5

View File

@@ -0,0 +1,44 @@
From 493dbd8ed387d661eef3e33ee614c79d7487f1bd Mon Sep 17 00:00:00 2001
From: Jonas Herzig <me@johni0702.de>
Date: Mon, 7 Aug 2017 20:41:05 +0200
Subject: [PATCH 1/5] Replace buildscript dependencies with manually built ones
---
build.gradle | 19 ++-----------------
1 file changed, 2 insertions(+), 17 deletions(-)
diff --git a/build.gradle b/build.gradle
index ee24828..42d0607 100755
--- a/build.gradle
+++ b/build.gradle
@@ -1,24 +1,17 @@
import groovy.json.JsonOutput
buildscript {
repositories {
mavenCentral()
- maven {
- name = "forge"
- url = "http://files.minecraftforge.net/maven"
- }
- maven {
- name = "sponge"
- url = "https://repo.spongepowered.org/maven"
- }
maven {
name = "sonatype"
url = "https://oss.sonatype.org/content/repositories/snapshots/"
}
+ maven { url 'gradle/reprod/deps/repo' }
}
dependencies {
- classpath 'net.minecraftforge.gradle:ForgeGradle:2.0-SNAPSHOT'
- classpath 'org.spongepowered:mixingradle:0.3-SNAPSHOT'
+ classpath 'reprod:forgegradle:0'
+ classpath 'reprod:mixingradle:0'
}
}
--
2.5.5

View File

@@ -0,0 +1,25 @@
From 9e4e7ac3f8ee5508939cf71e731189e4c0e1c7b5 Mon Sep 17 00:00:00 2001
From: Jonas Herzig <me@johni0702.de>
Date: Tue, 8 Aug 2017 20:06:39 +0200
Subject: [PATCH 2/5] Replace mixin dep with manually built one
---
build.gradle | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/build.gradle b/build.gradle
index 42d0607..bfa3914 100755
--- a/build.gradle
+++ b/build.gradle
@@ -44,7 +44,7 @@ configurations {
dependencies {
compile 'org.projectlombok:lombok:1.16.4'
- compile 'org.spongepowered:mixin:0.7.5-SNAPSHOT'
+ compile 'reprod:mixin:0'
shade 'com.googlecode.mp4parser:isoparser:1.1.7'
shade 'org.apache.commons:commons-exec:1.3'
shade 'com.google.apis:google-api-services-youtube:v3-rev178-1.22.0'
--
2.5.5

21
gradle/reprod/prepareCache.sh Executable file
View File

@@ -0,0 +1,21 @@
# Collects build artifacts that aren't present in the online cache
# into a subfolder that can be merged with the online cache
# This script isn't expected to function on OSX.
set -e
set -x
# Step one: copy all artifacts into subfolder under new name
rm -rf artifactCache
mkdir artifactCache
cd artifactCache
for f in $(find ../deps/repo -type f); do
cp $f $(sha256sum $f | cut -d' ' -f1)
done
# Step two: remove all files that are already in the cache
for f in *; do
if wget -q --spider "https://www.johni0702.de/replaymod/artifact/$f"; then
rm $f
fi
done

147
gradle/reprod/setup.sh Executable file
View File

@@ -0,0 +1,147 @@
#!/usr/bin/env bash
set -e
set -x
PROXY_PORT="25678"
PROXY_SETTINGS="-Dhttps.proxyHost=127.0.0.1 -Dhttps.proxyPort=$PROXY_PORT -Dhttp.proxyHost=127.0.0.1 -Dhttp.proxyPort=$PROXY_PORT"
pushd gradle/reprod
SHA256SUM="sha256sum"
command -v "$SHA256SUM" > /dev/null 2>&1 || SHA256SUM="shasum -a 256" # OSX
sha256val () {
$SHA256SUM $1 | cut -d' ' -f1
}
setup_dep () {
dep=$1
url=$2
commit=$3
jar=$4
jarhash=$5
pomhash=$6
depjar="deps/repo/reprod/$dep/0/$dep-0.jar"
deppom="deps/repo/reprod/$dep/0/$dep-0.pom"
[ -f "$depjar" ] && [ "$(sha256val "$depjar")" == "$jarhash" ] && [ -f "$deppom" ] && [ "$(sha256val "$deppom")" == "$pomhash" ] && return
[ -f "$depjar" ] && [ "*" == "$jarhash" ] && return
rm -rf "$depjar" "$deppom"
mkdir -p "deps/repo/reprod/$dep/0"
if [ "*" != "$jarhash" ] && [ "$OFFLINE" != "1" ]; then
# Try to fetch the pre-built artifact
if wget -O "deps/dl.jar" "https://www.johni0702.de/replaymod/artifact/$jarhash" && wget -O "deps/dl.pom" "https://www.johni0702.de/replaymod/artifact/$pomhash"; then
# Verify downloaded jar/pom files
if [ "$(sha256val "deps/dl.jar")" == "$jarhash" ] && [ "$(sha256val "deps/dl.pom")" == "$pomhash" ]; then
# Got valid pre-built artifact, use it
mv "deps/dl.jar" "$depjar"
mv "deps/dl.pom" "$deppom"
return
fi
fi
fi
if [ ! -d "deps/$dep" ] || [ "$(git -C "deps/$dep" rev-parse $commit^{commit})" != "$commit" ]; then
rm -rf "deps/$dep"
mkdir -p "deps/$dep"
pushd "deps/$dep"
git clone "$url" .
git fetch origin $commit
git checkout "$commit"
popd
fi
pushd "deps/$dep"
git reset --hard "$commit"
git submodule update --init --recursive
patches=$(find ../../patches/$dep/ -name *.patch | sort)
[ "$patches" != "" ] && echo "$patches" | xargs git am
git reset --soft "$commit" # Because forgegradle includes the commit hash in the jar
rm -rf gradle/wrapper gradlew
[ ! -d gradle ] && mkdir gradle
cp -r ../../../wrapper gradle/
cp ../../../wrapper/gradle-wrapper.properties gradle/wrapper/
cp ../../../../gradlew .
chmod +x gradlew
if [ "$dep" == "proxy-witness" ]; then
./gradlew $PROXY_SETTINGS build -x test -x javadoc
else
./gradlew $PROXY_SETTINGS -I ../../init.gradle build -x test -x javadoc
fi
actual_hash=$(sha256val "$jar")
if [ "*" != "$jarhash" ] && [ "$actual_hash" != "$jarhash" ]; then
echo "Failed to verify checksum of build artifact of dependency: $dep"
echo "Expected: $jarhash"
echo "But was: $actual_hash"
exit 1
fi
actual_hash=$(sha256val "pom.xml")
if [ "*" != "$jarhash" ] && [ "$actual_hash" != "$pomhash" ]; then
echo "Failed to verify checksum of build artifact pom of dependency: $dep"
echo "Expected: $pomhash"
echo "But was: $actual_hash"
exit 1
fi
# Subshell to allow for expansion of *
cp "$(echo $jar)" "../../$depjar"
[ "$dep" == "proxy-witness" ] || cp "pom.xml" "../../$deppom"
popd
}
# Setup http(s) proxy
setup_dep "proxy-witness" "https://github.com/johni0702/proxy-witness" "17ebb2e22f812faed9a28bae6bf1d8b28f798d56" "build/libs/proxy-witness.jar" "*" "*"
java -Dproxywitness.httpUris=http://export.mcpbot.bspk.rs/versions.json -jar deps/repo/reprod/proxy-witness/0/proxy-witness-0.jar "$PROXY_PORT" checksums.txt > proxy.log 2>&1 &
proxy_pid=$!
trap "kill $proxy_pid" EXIT
# Required for mixin
setup_dep "fernflower" "https://github.com/fesh0r/fernflower.git" "adbf29f8ce902cd164fc0c41491030268ecc8265" "build/libs/fernflower.jar" "d2042d3121118a7175fc902d0e49f4ad37d00467e7ea535574974142eff64184" "901b8a76ceb15db97d4dd19c5e8fcb0fc226ae602ef38ea906eb5258be9b929a"
# Required for forgegradle
setup_dep "forgeflower" "https://github.com/MinecraftForge/FernFlowerLegacy.git" "114aebe82cf40075c5c4f916c409b8aebf8096d5" "build/libs/fernflower-2.0-SNAPSHOT.jar" "c8b4a4a13a1158008aed46da2c805184078324718697f14a67f1778168579956" "fbda3f30d54624fe4c59a69e145b644d8642afc0dd4eb0d732ccdaa0ebd5d8a3"
setup_dep "mcinjector" "https://github.com/ModCoderPack/MCInjector.git" "7258466461baf7dc4f313b06b0d589407e4e1fba" "build/libs/mcinjector-3.4-SNAPSHOT.jar" "98b685ea0d3ae9fad8b8a7e7b885512f7fe0b61becf27d9c74b91a626d107efc" "3c08655c11e6509bfc62ff87d0770cefa0ecbd8dccece9e083c9b7b89779a8c5"
setup_dep "srg2source" "https://github.com/MinecraftForge/Srg2Source.git" "5f11e2933f722000dbf742ffdd0d9c5ee8044bbb" "build/libs/Srg2Source-3.3-SNAPSHOT.jar" "9aa601ade2c33ce52fe09894efd4c1bb69c68a238c2dd260605881863083362e" "cbfdd113cd054b80ce3a1e5636d254fea4f59a82af9874ae9f3786cb1901920d"
# Required for RM
setup_dep "mixingradle" "https://github.com/SpongePowered/MixinGradle.git" "52217aa8ca221dcd0b9fb657b037e663db808f38" "build/libs/mixingradle-0.4-SNAPSHOT.jar" "8b3508867128a5d564631635dff898a36f9aca8db54b7bb3af6f4924e3f4bead" "42cbf81136d4e26c06d3234427665b50d18768cc1f210512204ca1d5e3a42b5c"
setup_dep "forgegradle" "https://github.com/MinecraftForge/ForgeGradle.git" "17806f45d20d0b55bff70a616eaeb939bd6a543c" "build/libs/ForgeGradle-2.1-SNAPSHOT.jar" "dc3da35074bbb1c55e68f7863a8fc8660803da3192aa8d0a7e33280424d3c8d0" "4c670a05fbd9aeaa581ae8ba7597df1d1def7b04160e1c6b076ed6778dd45e58"
setup_dep "mixin" "https://github.com/SpongePowered/Mixin.git" "404f5da0b6b18980b4e44c7f1cfeddcd47fe4aa6" "build/libs/mixin-0.7.5-SNAPSHOT.jar" "7d181a5e7c317c00c07da14e7770e4356b0f201414cd2a836e987be9fa133d43" "11000383a5051f25a70c2bff3a3167b6859ae4f9838a0ab45560e9f9c9d9def7"
rm -rf tmp
mkdir tmp
pushd tmp
cp ../../../build.gradle build.gradle
git init
git add build.gradle
git commit -m "Add build.gradle"
git am ../patches/replaymod/*.patch
popd
popd # Back to root
./gradlew -Preprod $PROXY_SETTINGS -I gradle/reprod/init.gradle "$@"
if [ "$SIGNED_JAR" == "1" ]; then
echo "Trying fetch signature for resulting jar file.."
# Note: This requires there to be one and only one jar file (ignoring source artifacts)
jar="build/libs/$(ls build/libs | grep -v sources)"
jar_hash=$(sha256val "$jar")
pushd gradle/reprod/tmp
mkdir sign_tmp
pushd sign_tmp
# Signatures are generated using:
# jarsigner -sigfile johni -signedjar signed.jar unsigned.jar replaymod
# jar xf signed.jar META-INF/MANIFEST.MF META-INF/JOHNI.SF META-INF/JOHNI.RSA
# tar cJf signature.tar.xz META-INF
wget -O - "https://www.johni0702.de/replaymod/signature/$jar_hash" | tar xJ
jar uMf "../../../../$jar" META-INF/
popd
fi

Binary file not shown.

View File

@@ -1,6 +1,6 @@
#Sun May 10 21:57:58 CEST 2015
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=http\://services.gradle.org/distributions/gradle-2.11-all.zip
distributionUrl=http\://services.gradle.org/distributions/gradle-3.5.1-all.zip
distributionSha256Sum=69d99ade952de3727b65a88f3188ee72231ff4e28c2d00aacfc96a42c6d6f303

15
gradlew vendored
View File

@@ -6,6 +6,11 @@
##
##############################################################################
if [ "$REPRODUCIBLE_BUILD" == "1" ] && [ -f ./gradle/reprod/setup.sh ] && [ "$1" != "-Preprod" ]; then
./gradle/reprod/setup.sh "$@"
exit
fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
@@ -42,11 +47,6 @@ case "`uname`" in
;;
esac
# For Cygwin, ensure paths are in UNIX format before anything is touched.
if $cygwin ; then
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
@@ -61,9 +61,9 @@ while [ -h "$PRG" ] ; do
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >&-
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >&-
cd "$SAVED" >/dev/null
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
@@ -114,6 +114,7 @@ fi
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`

2
gradlew.bat vendored
View File

@@ -46,7 +46,7 @@ echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args

2
jGui

Submodule jGui updated: 26af916257...59ef539033

View File

@@ -1 +1,5 @@
include 'ReplayStudio'
if (System.getenv('REPRODUCIBLE_BUILD') == '1') {
rootProject.buildFileName = 'gradle/reprod/tmp/build.gradle'
} else {
include 'ReplayStudio'
}

View File

@@ -0,0 +1,30 @@
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Entry point for running integration tests from within the IDE.
* This is <b>not</b> called when running integration tests directly from gradle.
*/
public class IntegrationTest {
public static void main(String[] args) throws Throwable {
// Prevent MC from grabbing our mouse during the test (it's not needed)
System.setProperty("fml.noGrab", "true");
// Make sure the test folder exists and is fresh
File gameDir = new File(System.getProperty("user.dir"), "integration-test");
if (gameDir.exists()) {
FileUtils.forceDelete(gameDir);
}
FileUtils.forceMkdir(gameDir);
// Set game dir to test folder and call regular entry point
List<String> argsList = new ArrayList<>(Arrays.asList(args));
argsList.add("--gameDir");
argsList.add(gameDir.getCanonicalPath());
GradleStart.main(argsList.toArray(new String[argsList.size()]));
}
}

View File

@@ -0,0 +1,342 @@
package com.replaymod.core;
import com.google.common.collect.Iterables;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.SettableFuture;
import de.johni0702.minecraft.gui.container.AbstractGuiOverlay;
import de.johni0702.minecraft.gui.container.AbstractGuiScreen;
import de.johni0702.minecraft.gui.container.GuiContainer;
import de.johni0702.minecraft.gui.container.GuiOverlay;
import de.johni0702.minecraft.gui.container.GuiScreen;
import de.johni0702.minecraft.gui.element.GuiButton;
import de.johni0702.minecraft.gui.element.GuiElement;
import de.johni0702.minecraft.gui.element.GuiTexturedButton;
import de.johni0702.minecraft.gui.popup.AbstractGuiPopup;
import de.johni0702.minecraft.gui.utils.Consumer;
import net.minecraft.client.Minecraft;
import net.minecraft.client.settings.KeyBinding;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent;
import org.lwjgl.input.Keyboard;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.concurrent.TimeoutException;
import static com.replaymod.core.ReplayModIntegrationTest.LOGGER;
import static com.replaymod.core.utils.Utils.addCallback;
public abstract class AbstractTask implements Task {
public static Task create(Consumer<AbstractTask> init) {
return new AbstractTask() {
@Override
protected void init() {
init.consume(this);
}
};
}
public static final Minecraft mc = Minecraft.getMinecraft();
public final ReplayMod core = ReplayMod.instance;
public SettableFuture<Void> future;
@Override
public ListenableFuture<Void> execute() {
future = SettableFuture.create();
FMLCommonHandler.instance().bus().register(this);
MinecraftForge.EVENT_BUS.register(this);
addCallback(future, success -> {
FMLCommonHandler.instance().bus().unregister(this);
MinecraftForge.EVENT_BUS.unregister(this);
}, error -> {});
init();
return future;
}
protected void init() {}
protected void runLater(Runnable runnable) {
core.runLater(() -> {
try {
runnable.run();
} catch (Throwable t) {
future.setException(t);
}
});
}
public void expectGuiClosed(Runnable onClosed) {
expectGuiClosed0(10, onClosed);
}
public void expectGuiClosed(int timeout, Runnable onClosed) {
expectGuiClosed0(timeout, onClosed);
}
private void expectGuiClosed0(int timeout, Runnable onClosed) {
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
class EventHandler {
final net.minecraft.client.gui.GuiScreen currentScreen = mc.currentScreen;
int framesPassed;
@SubscribeEvent
public void onGuiOpen(TickEvent.RenderTickEvent event) {
if (event.phase != TickEvent.Phase.START) return;
if (currentScreen != mc.currentScreen) {
FMLCommonHandler.instance().bus().unregister(this);
onClosed.run();
} else {
if (framesPassed < timeout) {
framesPassed++;
} else {
Object gui = (gui = GuiScreen.from(currentScreen)) == null ? currentScreen : gui;
Exception e = new TimeoutException("Timeout while waiting for " + gui + " to be closed.");
e.setStackTrace(Arrays.copyOfRange(stackTrace, 3, stackTrace.length));
future.setException(e);
}
}
}
}
FMLCommonHandler.instance().bus().register(new EventHandler());
}
public void expectPopupClosed(Runnable onClosed) {
expectPopupClosed0(10, onClosed);
}
public void expectPopupClosed(int timeout, Runnable onClosed) {
expectPopupClosed0(timeout, onClosed);
}
private void expectPopupClosed0(int timeout, Runnable onClosed) {
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
AbstractGuiPopup popup = getPopup(mc.currentScreen);
if (popup == null) {
throw new IllegalStateException("No popup found.");
}
class EventHandler {
int framesPassed;
@SubscribeEvent
public void onGuiOpen(TickEvent.RenderTickEvent event) {
if (event.phase != TickEvent.Phase.START) return;
if (getPopup(mc.currentScreen) != popup) {
FMLCommonHandler.instance().bus().unregister(this);
onClosed.run();
} else {
if (framesPassed < timeout) {
framesPassed++;
} else {
Exception e = new TimeoutException("Timeout while waiting for " + popup + " to be closed.");
e.setStackTrace(Arrays.copyOfRange(stackTrace, 3, stackTrace.length));
future.setException(e);
}
}
}
}
FMLCommonHandler.instance().bus().register(new EventHandler());
}
private AbstractGuiPopup getPopup(net.minecraft.client.gui.GuiScreen minecraft) {
GuiContainer<?> container = GuiOverlay.from(minecraft);
if (container == null) {
container = GuiScreen.from(minecraft);
}
if (container != null) {
while (container.getContainer() != null) {
container = container.getContainer();
}
GuiElement popup = Iterables.getLast(container.getChildren());
if (popup instanceof AbstractGuiPopup) {
return (AbstractGuiPopup) popup;
}
}
return null;
}
public <T> void expectGui(Class<T> guiClass, Consumer<T> onOpen) {
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
class EventHandler {
net.minecraft.client.gui.GuiScreen currentScreen;
int framesPassed;
@SubscribeEvent
public void onGuiOpen(TickEvent.RenderTickEvent event) {
if (event.phase != TickEvent.Phase.START) return;
if (currentScreen != mc.currentScreen) {
currentScreen = mc.currentScreen;
framesPassed = 0;
}
if (framesPassed < 10) {
framesPassed++;
return;
}
FMLCommonHandler.instance().bus().unregister(this);
Object foundGui = null;
if (AbstractGuiScreen.class.isAssignableFrom(guiClass)) {
AbstractGuiScreen guiScreen = GuiScreen.from(currentScreen);
if (guiClass.isInstance(guiScreen)) {
onOpen.consume(guiClass.cast(guiScreen));
return;
}
foundGui = guiScreen;
} else if (AbstractGuiOverlay.class.isAssignableFrom(guiClass)) {
AbstractGuiOverlay guiScreen = GuiOverlay.from(currentScreen);
if (guiClass.isInstance(guiScreen)) {
onOpen.consume(guiClass.cast(guiScreen));
return;
}
foundGui = guiScreen;
} else if (AbstractGuiPopup.class.isAssignableFrom(guiClass)) {
AbstractGuiPopup popup = getPopup(currentScreen);
if (guiClass.isInstance(popup)) {
onOpen.consume(guiClass.cast(popup));
return;
}
} else {
if (guiClass.isInstance(currentScreen)) {
onOpen.consume(guiClass.cast(currentScreen));
return;
}
}
class UnexpectedGuiException extends Exception {
UnexpectedGuiException(Object foundGui) {
super("Expected instance of " + guiClass + " but found " + foundGui);
setStackTrace(Arrays.copyOfRange(stackTrace, 2, stackTrace.length));
}
}
future.setException(new UnexpectedGuiException(foundGui == null ? currentScreen : foundGui));
}
}
FMLCommonHandler.instance().bus().register(new EventHandler());
}
private void clickNow(int x, int y) {
try {
Method method = net.minecraft.client.gui.GuiScreen.class
.getDeclaredMethod("mouseClicked", int.class, int.class, int.class);
method.setAccessible(true);
method.invoke(mc.currentScreen, x, y, 0);
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
future.setException(e);
}
}
public void click(int x, int y) {
runLater(() -> {
LOGGER.info("Clicking at {}/{}", x, y);
clickNow(x, y);
});
}
private void dragNow(int x, int y) {
try {
Method method = net.minecraft.client.gui.GuiScreen.class
.getDeclaredMethod("mouseClickMove", int.class, int.class, int.class, long.class);
method.setAccessible(true);
method.invoke(mc.currentScreen, x, y, 0, 0);
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
future.setException(e);
}
}
public void drag(int x, int y) {
runLater(() -> {
LOGGER.info("Dragging to {}/{}", x, y);
dragNow(x, y);
});
}
public void click(GuiButton button) {
runLater(() -> {
if (!button.isEnabled()) {
future.setException(new IllegalStateException("Button is disabled: " + button.getLabel()));
return;
}
LOGGER.info("Clicking button {}", button.getLabel());
button.onClick();
});
}
public void click(GuiTexturedButton button) {
runLater(() -> {
if (!button.isEnabled()) {
future.setException(new IllegalStateException("Button is disabled: " + button.getTexture()));
return;
}
LOGGER.info("Clicking textured button {}", button.getTexture());
button.onClick();
});
}
public void click(String buttonText) {
runLater(() -> {
LOGGER.info("Clicking button {}", buttonText);
try {
Field field = net.minecraft.client.gui.GuiScreen.class.getDeclaredField("buttonList");
field.setAccessible(true);
@SuppressWarnings("unchecked")
List<net.minecraft.client.gui.GuiButton> buttonList = (List)
field.get(mc.currentScreen);
net.minecraft.client.gui.GuiButton button = null;
for (net.minecraft.client.gui.GuiButton guiButton : buttonList) {
if (guiButton.displayString.equals(buttonText)) {
button = guiButton;
}
}
if (button == null) {
future.setException(new NoSuchElementException("No button with label: " + buttonText));
return;
}
clickNow(button.xPosition + 5, button.yPosition + 5);
} catch (IllegalAccessException | NoSuchFieldException e) {
future.setException(e);
}
});
}
public void type(String string) {
for (char c : string.toCharArray()) {
press(c, Keyboard.getKeyIndex(String.valueOf(c).toUpperCase()));
}
}
public void press(int keyCode) {
String keyName = Keyboard.getKeyName(keyCode);
char character = keyName.length() == 1 ? keyName.charAt(0) : '\0';
press(character, keyCode);
}
public void press(char character, int keyCode) {
runLater(() -> {
LOGGER.info("Pressing key {}", Keyboard.getKeyName(keyCode));
if (mc.currentScreen == null || mc.currentScreen.allowUserInput) {
KeyBinding.onTick(keyCode);
FMLCommonHandler.instance().fireKeyInput();
}
if (mc.currentScreen != null) {
try {
Method method = net.minecraft.client.gui.GuiScreen.class
.getDeclaredMethod("keyTyped", char.class, int.class);
method.setAccessible(true);
method.invoke(mc.currentScreen, character, keyCode);
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
future.setException(e);
}
}
});
}
}

View File

@@ -0,0 +1,41 @@
package com.replaymod.core;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.SettableFuture;
import static com.replaymod.core.ReplayModIntegrationTest.LOGGER;
import static com.replaymod.core.utils.Utils.addCallback;
public class CompositeTask implements Task {
private SettableFuture<Void> future;
protected final Task[] children;
public CompositeTask(Task[] children) {
this.children = children;
}
@Override
public ListenableFuture<Void> execute() {
future = SettableFuture.create();
executeChild(0);
return future;
}
private void executeChild(int childIndex) {
if (future.isDone()) return;
if (childIndex < children.length) {
ReplayMod.instance.runLater(() -> {
try {
Task task = children[childIndex];
LOGGER.info("Running task {}", task);
ListenableFuture<Void> childFuture = task.execute();
addCallback(childFuture, done -> executeChild(childIndex + 1), err -> future.setException(err));
} catch (Throwable t) {
future.setException(t);
}
});
} else {
future.set(null);
}
}
}

View File

@@ -0,0 +1,73 @@
package com.replaymod.core;
import com.replaymod.core.regression.RegressionTest60;
import com.replaymod.core.regression.RegressionTest61;
import com.replaymod.core.regression.RegressionTest62;
import com.replaymod.extra.DownloadOpenEye;
import com.replaymod.online.SkipLogin;
import com.replaymod.recording.CreateSPWorld;
import com.replaymod.recording.ExitSPWorld;
import com.replaymod.replay.ExitReplay;
import com.replaymod.replay.LoadReplay;
import com.replaymod.replay.OpenReplayViewer;
import net.minecraft.client.Minecraft;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import org.apache.logging.log4j.Logger;
import static com.replaymod.core.AbstractTask.mc;
import static com.replaymod.core.ReplayModIntegrationTest.MOD_ID;
import static com.replaymod.core.utils.Utils.addCallback;
/**
* Helper mod that initiates the integration tests.
*/
@Mod(modid = MOD_ID)
public class ReplayModIntegrationTest {
public static final String MOD_ID = "replaymod-integration-test";
public static Logger LOGGER;
@Mod.EventHandler
public void init(FMLPreInitializationEvent event) {
LOGGER = event.getModLog();
// Make sure the game window doesn't have to remain in focus during the test
mc.gameSettings.pauseOnLostFocus = false;
runTasks(
new SkipLogin(),
new DownloadOpenEye(),
new CreateSPWorld(),
new Wait(5000),
new ExitSPWorld(),
new OpenReplayViewer(),
new LoadReplay(),
new RegressionTest60(),
new RegressionTest61(),
new RegressionTest62(),
// new AbstractTask() {}, // Uncomment to not exit on success (useful for writing more tests)
new ExitReplay()
);
}
private void runTasks(Task... tests) {
addCallback(new CompositeTask(tests).execute(), success -> {
if (!Minecraft.getMinecraft().hasCrashed) {
LOGGER.info("===================================================");
LOGGER.info("= ALL TESTS PASSED =");
LOGGER.info("===================================================");
FMLCommonHandler.instance().exitJava(0, false);
}
}, error -> {
LOGGER.error("Failed task:", error);
LOGGER.error("===================================================");
LOGGER.error("= TEST FAILED =");
LOGGER.error("===================================================");
FMLCommonHandler.instance().exitJava(1, false);
});
}
}

View File

@@ -0,0 +1,35 @@
package com.replaymod.core;
import com.google.common.util.concurrent.ListenableFuture;
public interface Task {
ListenableFuture<Void> execute();
static Task click(int x, int y) {
return AbstractTask.create(task -> {
task.click(x, y);
task.runLater(() -> task.future.set(null));
});
}
static Task drag(int x, int y) {
return AbstractTask.create(task -> {
task.drag(x, y);
task.runLater(() -> task.future.set(null));
});
}
static Task pressKey(int keyCode) {
return AbstractTask.create(task -> {
task.press(keyCode);
task.runLater(() -> task.future.set(null));
});
}
static Task pressKey(char character, int keyCode) {
return AbstractTask.create(task -> {
task.press(character, keyCode);
task.runLater(() -> task.future.set(null));
});
}
}

View File

@@ -0,0 +1,9 @@
package com.replaymod.core;
public class Utils {
public static void times(int x, Runnable runnable) {
for (int i = 0; i < x; i++) {
runnable.run();
}
}
}

View File

@@ -0,0 +1,21 @@
package com.replaymod.core;
public class Wait extends AbstractTask {
private final int duration;
public Wait(int duration) {
this.duration = duration;
}
@Override
protected void init() {
new Thread(() -> {
try {
Thread.sleep(duration);
runLater(() -> future.set(null));
} catch (InterruptedException e) {
runLater(() -> future.setException(e));
}
}).start();
}
}

View File

@@ -0,0 +1,59 @@
package com.replaymod.core.regression;
import com.replaymod.core.AbstractTask;
import com.replaymod.core.CompositeTask;
import com.replaymod.core.Task;
import com.replaymod.replay.SpectatePlayer;
import com.replaymod.replay.overlay.OverlayGui;
import com.replaymod.simplepathing.GuiPathingTasks;
import com.replaymod.simplepathing.gui.GuiEditKeyframe;
import org.lwjgl.input.Keyboard;
import static com.replaymod.core.AbstractTask.mc;
import static com.replaymod.core.Utils.times;
/**
* Regression test: #60 Crash in path preview when two spectator keyframes are closer than 50ms
*/
public class RegressionTest60 extends CompositeTask {
public RegressionTest60() {
super(new Task[]{
new SpectatePlayer(),
OverlayGui.whileOpened(
// Place first spectator keyframe
new GuiPathingTasks.ClickPositionKeyframeButton(),
// Place second spectator keyframe
Task.click(130, 50),
new GuiPathingTasks.ClickPositionKeyframeButton(),
// Move second keyframe to 20ms on the keyframe timeline
AbstractTask.create(task -> {
// Double click keyframe
task.click(130, 50);
task.click(130, 50);
task.expectGui(GuiEditKeyframe.Spectator.class, gui -> {
// Set ms field to 20
task.click(mc.currentScreen.width / 2 + 80, mc.currentScreen.height / 2);
times(4, () -> task.press(Keyboard.KEY_BACK));
task.type("20");
// Set other fields to 0
times(2, () -> {
task.press(Keyboard.KEY_TAB);
times(4, () -> task.press(Keyboard.KEY_BACK));
task.press(Keyboard.KEY_0);
});
task.click(gui.saveButton);
task.expectPopupClosed(() -> task.future.set(null));
});
}),
// Place second spectator keyframe
new GuiPathingTasks.ClickPositionKeyframeButton()
),
// Stop spectating player
new SpectatePlayer.End(),
// Enable path preview
Task.pressKey(Keyboard.KEY_H),
new GuiPathingTasks.ClearKeyframeTimeline(),
Task.pressKey(Keyboard.KEY_H),
});
}
}

View File

@@ -0,0 +1,35 @@
package com.replaymod.core.regression;
import com.replaymod.core.AbstractTask;
import com.replaymod.core.CompositeTask;
import com.replaymod.core.Task;
import com.replaymod.replay.overlay.OverlayGui;
import com.replaymod.simplepathing.GuiPathingTasks;
import com.replaymod.simplepathing.gui.GuiEditKeyframe;
/**
* Regression test: #61 NPE when saving in edit keyframe gui of last keyframe
*/
public class RegressionTest61 extends CompositeTask {
public RegressionTest61() {
super(new Task[]{
OverlayGui.whileOpened(
// Place keyframe
Task.click(130, 50),
new GuiPathingTasks.ClickPositionKeyframeButton(),
AbstractTask.create(task -> {
// Double click keyframe
task.click(130, 50);
task.click(130, 50);
task.expectGui(GuiEditKeyframe.Position.class, gui -> {
task.click(gui.saveButton);
task.expectPopupClosed(() -> task.future.set(null));
});
}),
// Place second spectator keyframe
new GuiPathingTasks.ClickPositionKeyframeButton()
),
new GuiPathingTasks.ClearKeyframeTimeline(),
});
}
}

View File

@@ -0,0 +1,28 @@
package com.replaymod.core.regression;
import com.replaymod.core.CompositeTask;
import com.replaymod.core.Task;
import com.replaymod.replay.overlay.OverlayGui;
import com.replaymod.simplepathing.GuiPathingTasks;
/**
* Regression test: #62 Swapping the only two existing keyframes causes NPE
*/
public class RegressionTest62 extends CompositeTask {
public RegressionTest62() {
super(new Task[]{
OverlayGui.whileOpened(
// Place first keyframe
Task.click(130, 50),
new GuiPathingTasks.ClickPositionKeyframeButton(),
// Place second keyframe
Task.click(150, 50),
new GuiPathingTasks.ClickPositionKeyframeButton(),
// Move first keyframe past second keyframe
Task.click(130,50),
Task.drag(170,50)
),
new GuiPathingTasks.ClearKeyframeTimeline()
});
}
}

View File

@@ -0,0 +1,25 @@
package com.replaymod.extra;
import com.replaymod.core.AbstractTask;
import com.replaymod.extras.OpenEyeExtra;
import net.minecraftforge.fml.common.Loader;
import java.io.File;
import java.nio.file.NoSuchFileException;
public class DownloadOpenEye extends AbstractTask {
@Override
protected void init() {
expectGui(OpenEyeExtra.OfferGui.class, offerGui -> {
click(offerGui.yesButton);
expectGuiClosed(20 * 1000, () -> {
File targetFile = new File(mc.mcDataDir, "mods/" + Loader.MC_VERSION + "/OpenEye.jar");
if (!targetFile.exists()) {
future.setException(new NoSuchFileException(targetFile.getAbsolutePath()));
} else {
future.set(null);
}
});
});
}
}

View File

@@ -0,0 +1,14 @@
package com.replaymod.online;
import com.replaymod.core.AbstractTask;
import com.replaymod.online.gui.GuiLoginPrompt;
public class SkipLogin extends AbstractTask {
@Override
protected void init() {
expectGui(GuiLoginPrompt.class, gui -> {
click(gui.cancelButton);
expectGuiClosed(() -> future.set(null));
});
}
}

View File

@@ -0,0 +1,32 @@
package com.replaymod.recording;
import com.replaymod.core.AbstractTask;
import net.minecraft.client.gui.GuiCreateWorld;
import net.minecraft.client.gui.GuiMainMenu;
import net.minecraft.client.gui.GuiSelectWorld;
import net.minecraftforge.client.event.RenderGameOverlayEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
public class CreateSPWorld extends AbstractTask {
@Override
protected void init() {
expectGui(GuiMainMenu.class, mainMenu -> {
click("Singleplayer");
expectGui(GuiSelectWorld.class, selectWorld -> {
click("Create New World");
expectGui(GuiCreateWorld.class, createWorld -> {
click("Create New World");
class EventHandler {
@SubscribeEvent
public void onRenderIngame(RenderGameOverlayEvent.Pre event) {
MinecraftForge.EVENT_BUS.unregister(this);
runLater(() -> future.set(null));
}
}
MinecraftForge.EVENT_BUS.register(new EventHandler());
});
});
});
}
}

View File

@@ -0,0 +1,36 @@
package com.replaymod.recording;
import com.replaymod.core.AbstractTask;
import net.minecraft.client.gui.GuiIngameMenu;
import net.minecraft.client.gui.GuiMainMenu;
import org.apache.commons.io.filefilter.DirectoryFileFilter;
import java.io.IOException;
public class ExitSPWorld extends AbstractTask {
@Override
protected void init() {
mc.displayInGameMenu();
expectGui(GuiIngameMenu.class, ingameMenu -> {
click("Save and Quit to Title");
expectGui(GuiMainMenu.class, mainMenu -> new Thread(() -> {
try {
while (true) {
String[] dirs = core.getReplayFolder().list(DirectoryFileFilter.DIRECTORY);
if (dirs == null) {
future.setException(new NullPointerException("dirs is null"));
return;
}
if (dirs.length == 0) {
runLater(() -> future.set(null));
return;
}
Thread.sleep(10);
}
} catch (IOException | InterruptedException e) {
future.setException(e);
}
}).start());
});
}
}

View File

@@ -0,0 +1,16 @@
package com.replaymod.replay;
import com.replaymod.core.AbstractTask;
import net.minecraft.client.gui.GuiIngameMenu;
import net.minecraft.client.gui.GuiMainMenu;
public class ExitReplay extends AbstractTask {
@Override
protected void init() {
mc.displayInGameMenu();
expectGui(GuiIngameMenu.class, ingameMenu -> {
click("Exit Replay");
expectGui(GuiMainMenu.class, mainMenu -> future.set(null));
});
}
}

View File

@@ -0,0 +1,32 @@
package com.replaymod.replay;
import com.replaymod.core.AbstractTask;
import com.replaymod.replay.gui.screen.GuiReplayViewer;
import de.johni0702.minecraft.gui.function.Clickable;
import net.minecraftforge.client.event.RenderGameOverlayEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import org.lwjgl.util.Point;
import org.lwjgl.util.ReadableDimension;
public class LoadReplay extends AbstractTask {
@Override
protected void init() {
expectGui(GuiReplayViewer.class, replayViewer -> runLater(() -> {
ReadableDimension size = replayViewer.getMaxSize();
// Select first entry
replayViewer.forEach(Clickable.class).mouseClick(new Point(size.getWidth() / 2, 40), 0);
// Load first replay
click(replayViewer.loadButton);
class EventHandler {
@SubscribeEvent
public void onRenderIngame(RenderGameOverlayEvent.Pre event) {
MinecraftForge.EVENT_BUS.unregister(this);
runLater(() -> future.set(null));
}
}
MinecraftForge.EVENT_BUS.register(new EventHandler());
}));
}
}

View File

@@ -0,0 +1,15 @@
package com.replaymod.replay;
import com.replaymod.core.AbstractTask;
import com.replaymod.replay.gui.screen.GuiReplayViewer;
import net.minecraft.client.gui.GuiMainMenu;
public class OpenReplayViewer extends AbstractTask {
@Override
protected void init() {
expectGui(GuiMainMenu.class, mainMenu -> {
click("Replay Viewer");
expectGui(GuiReplayViewer.class, replayViewer -> future.set(null));
});
}
}

View File

@@ -0,0 +1,42 @@
package com.replaymod.replay;
import com.replaymod.core.AbstractTask;
import com.replaymod.extras.playeroverview.PlayerOverviewGui;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent;
import org.lwjgl.input.Keyboard;
import java.util.concurrent.TimeoutException;
public class SpectatePlayer extends AbstractTask {
@Override
protected void init() {
press(Keyboard.KEY_B);
expectGui(PlayerOverviewGui.class, overview -> {
click(overview.getMaxSize().getWidth() / 2 - 60, 60);
press(Keyboard.KEY_ESCAPE);
expectGuiClosed(() -> future.set(null));
});
}
public static class End extends AbstractTask {
private int timeout;
@Override
protected void init() {
runLater(() -> press(Keyboard.KEY_LSHIFT));
}
@SubscribeEvent
public void onTick(TickEvent.RenderTickEvent event) {
if (event.phase != TickEvent.Phase.START) return;
if (timeout++ > 20) {
future.setException(new TimeoutException("Camera hasn't stopped spectating."));
return;
}
if (mc.getRenderViewEntity() == mc.thePlayer) {
future.set(null);
}
}
}
}

View File

@@ -0,0 +1,33 @@
package com.replaymod.replay.overlay;
import com.replaymod.core.AbstractTask;
import com.replaymod.core.CompositeTask;
import com.replaymod.core.Task;
import com.replaymod.replay.gui.overlay.GuiReplayOverlay;
import org.lwjgl.input.Keyboard;
public class OverlayGui {
public static Task whileOpened(Task...tasks) {
Task[] nTasks = new Task[tasks.length + 2];
System.arraycopy(tasks, 0, nTasks, 1, tasks.length);
nTasks[0] = new Open();
nTasks[tasks.length + 1] = new Close();
return new CompositeTask(nTasks);
}
public static class Open extends AbstractTask {
@Override
protected void init() {
press(Keyboard.KEY_T);
expectGui(GuiReplayOverlay.class, done -> future.set(null));
}
}
public static class Close extends AbstractTask {
@Override
protected void init() {
press(Keyboard.KEY_ESCAPE);
expectGuiClosed(() -> future.set(null));
}
}
}

View File

@@ -0,0 +1,35 @@
package com.replaymod.simplepathing;
import com.replaymod.core.AbstractTask;
import com.replaymod.replay.gui.overlay.GuiReplayOverlay;
import com.replaymod.simplepathing.gui.GuiPathing;
import de.johni0702.minecraft.gui.popup.GuiYesNoPopup;
import org.lwjgl.input.Keyboard;
public abstract class GuiPathingTasks extends AbstractTask {
@Override
protected void init() {
expectGui(GuiReplayOverlay.class, ign -> init0(ReplayModSimplePathing.instance.getGuiPathing()));
}
protected abstract void init0(GuiPathing guiPathing);
public static class ClickPositionKeyframeButton extends GuiPathingTasks {
@Override
protected void init0(GuiPathing guiPathing) {
click(guiPathing.positionKeyframeButton);
runLater(() -> future.set(null));
}
}
public static class ClearKeyframeTimeline extends AbstractTask {
@Override
protected void init() {
press(Keyboard.KEY_C);
expectGui(GuiYesNoPopup.class, popup -> {
click(popup.getYesButton());
expectGuiClosed(() -> future.set(null));
});
}
}
}

View File

@@ -1,24 +1,39 @@
package com.replaymod.compat;
import com.replaymod.compat.bettersprinting.DisableBetterSprinting;
import com.replaymod.compat.optifine.DisableFastRender;
import com.replaymod.compat.oranges17animations.HideInvisibleEntities;
import com.replaymod.compat.shaders.ShaderBeginRender;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import net.minecraftforge.fml.common.eventhandler.EventBus;
import org.apache.logging.log4j.Logger;
@Mod(modid = ReplayModCompat.MOD_ID,
version = "@MOD_VERSION@",
acceptedMinecraftVersions = "@MC_VERSION@",
acceptableRemoteVersions = "*",
clientSideOnly = true,
useMetadata = true)
public class ReplayModCompat {
public static final String MOD_ID = "replaymod-compat";
public static Logger LOGGER;
@Mod.EventHandler
public void preInit(FMLPreInitializationEvent event) {
LOGGER = event.getModLog();
}
@Mod.EventHandler
public void init(FMLInitializationEvent event) {
EventBus bus = MinecraftForge.EVENT_BUS;
EventBus bus = FMLCommonHandler.instance().bus();
bus.register(new ShaderBeginRender());
bus.register(new DisableFastRender());
bus.register(new HideInvisibleEntities());
DisableBetterSprinting.register();
}
}

View File

@@ -0,0 +1,103 @@
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.minecraft.util.BlockPos;
import net.minecraft.world.IWorldAccess;
import net.minecraftforge.client.event.GuiOpenEvent;
import net.minecraftforge.common.MinecraftForge;
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;
import java.util.Collections;
import static com.replaymod.compat.ReplayModCompat.LOGGER;
/**
* 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.theWorld != null) {
// During replay, get ready to revert BetterSprinting's overwritten playerController
originalController = mc.playerController;
mc.theWorld.addWorldAccess(worldAccessHook);
}
}
@SubscribeEvent(priority = EventPriority.LOW)
public void afterGuiOpenEvent(GuiOpenEvent event) {
if (ReplayModReplay.instance.getReplayHandler() != null && mc.theWorld != null) {
mc.theWorld.removeWorldAccess(worldAccessHook);
}
}
@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 implements IWorldAccess {
@Override
public void onEntityRemoved(Entity entityIn) {
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 markBlockForUpdate(BlockPos pos) {}
@Override public void notifyLightSet(BlockPos pos) {}
@Override public void markBlockRangeForRenderUpdate(int x1, int y1, int z1, int x2, int y2, int z2) {}
@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) {}
@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 playRecord(String recordName, BlockPos blockPosIn) {}
@Override public void broadcastSound(int p_180440_1_, BlockPos p_180440_2_, int p_180440_3_) {}
@Override public void playAusSFX(EntityPlayer p_180439_1_, int p_180439_2_, BlockPos blockPosIn, int p_180439_4_) {}
@Override public void sendBlockBreakProgress(int breakerId, BlockPos pos, int progress) {}
}
}

View File

@@ -0,0 +1,35 @@
package com.replaymod.compat.mapwriter.mixin;
import com.replaymod.replay.ReplayModReplay;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ServerData;
import net.minecraftforge.fml.common.Loader;
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;
/**
* 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())) {
ci.setReturnValue(new ServerData(null, "replay"));
return;
}
}
}
}
}

View File

@@ -0,0 +1,28 @@
package com.replaymod.compat.oranges17animations;
import com.replaymod.replay.camera.CameraEntity;
import net.minecraft.client.Minecraft;
import net.minecraftforge.client.event.RenderLivingEvent;
import net.minecraftforge.fml.common.Loader;
import net.minecraftforge.fml.common.eventhandler.EventPriority;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
/**
* 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 {
private final Minecraft mc = Minecraft.getMinecraft();
private final boolean modLoaded = Loader.isModLoaded("animations");
@SubscribeEvent(priority = EventPriority.HIGH)
public void preRenderLiving(RenderLivingEvent.Pre event) {
if (modLoaded) {
if (mc.thePlayer instanceof CameraEntity && event.entity.isInvisible()) {
event.setCanceled(true);
}
}
}
}

View File

@@ -16,6 +16,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;
public class KeyBindingRegistry {
private Map<String, KeyBinding> keyBindings = new HashMap<String, KeyBinding>();
@@ -85,7 +86,7 @@ public class KeyBindingRegistry {
CrashReport crashReport = CrashReport.makeCrashReport(cause, "Handling Key Binding");
CrashReportCategory category = crashReport.makeCategory("Key Binding");
category.addCrashSection("Key Binding", keyBinding);
category.setDetail("Handler", runnable::toString);
category.addCrashSectionCallable("Handler", runnable::toString);
throw new ReportedException(crashReport);
}
}
@@ -100,7 +101,12 @@ public class KeyBindingRegistry {
CrashReport crashReport = CrashReport.makeCrashReport(cause, "Handling Raw Key Binding");
CrashReportCategory category = crashReport.makeCategory("Key Binding");
category.addCrashSection("Key Code", keyCode);
category.setDetail("Handler", runnable::toString);
category.addCrashSectionCallable("Handler", new Callable() {
@Override
public Object call() throws Exception {
return runnable;
}
});
throw new ReportedException(crashReport);
}
}

View File

@@ -19,7 +19,9 @@ public class LoadingPlugin implements IFMLLoadingPlugin {
Mixins.addConfiguration("mixins.recording.replaymod.json");
Mixins.addConfiguration("mixins.render.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) {
@@ -29,7 +31,7 @@ public class LoadingPlugin implements IFMLLoadingPlugin {
if (file.isFile()) {
// This forces forge to reexamine the jar file for FML mods
// Should eventually be handled by Mixin itself, maybe?
CoreModManager.getIgnoredMods().remove(file.getName());
CoreModManager.getLoadedCoremods().remove(file.getName());
}
} catch (URISyntaxException e) {
e.printStackTrace();

View File

@@ -6,6 +6,7 @@ import com.replaymod.core.gui.GuiReplaySettings;
import com.replaymod.core.gui.RestoreReplayGui;
import com.replaymod.core.handler.MainMenuHandler;
import com.replaymod.core.utils.OpenGLUtils;
import com.replaymod.render.utils.SoundHandler;
import com.replaymod.replaystudio.util.I18n;
import de.johni0702.minecraft.gui.container.GuiScreen;
import lombok.Getter;
@@ -13,11 +14,10 @@ import net.minecraft.client.Minecraft;
import net.minecraft.client.settings.GameSettings;
import net.minecraft.crash.CrashReport;
import net.minecraft.crash.CrashReportCategory;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.*;
import net.minecraftforge.common.MinecraftForge;
import net.minecraft.util.*;
import net.minecraftforge.common.config.Configuration;
import net.minecraftforge.fml.client.FMLClientHandler;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.common.Loader;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventHandler;
@@ -26,16 +26,22 @@ import net.minecraftforge.fml.common.ModContainer;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import net.minecraftforge.fml.common.eventhandler.EventBus;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Queue;
@Mod(modid = ReplayMod.MOD_ID,
useMetadata = true,
version = "@MOD_VERSION@",
acceptedMinecraftVersions = "@MC_VERSION@",
acceptableRemoteVersions = "*",
clientSideOnly = true,
updateJSON = "https://raw.githubusercontent.com/ReplayMod/ReplayMod/master/versions.json",
guiFactory = "com.replaymod.core.gui.GuiFactory")
public class ReplayMod {
@@ -67,6 +73,8 @@ public class ReplayMod {
@Deprecated
public static Configuration config;
@Deprecated
public static SoundHandler soundHandler = new SoundHandler();
private final KeyBindingRegistry keyBindingRegistry = new KeyBindingRegistry();
private final SettingsRegistry settingsRegistry = new SettingsRegistry();
@@ -109,7 +117,7 @@ public class ReplayMod {
new MainMenuHandler().register();
MinecraftForge.EVENT_BUS.register(keyBindingRegistry);
FMLCommonHandler.instance().bus().register(keyBindingRegistry);
getKeyBindingRegistry().registerKeyBinding("replaymod.input.settings", 0, () -> {
new GuiReplaySettings(null, settingsRegistry).display();
@@ -123,7 +131,150 @@ public class ReplayMod {
if(!FMLClientHandler.instance().hasOptifine())
GameSettings.Options.RENDER_DISTANCE.setValueMax(64f);
testIfMoeshAndExitMinecraft();
if (System.getProperty("replaymod.render.file") != null) {
final File file = new File(System.getProperty("replaymod.render.file"));
if (!file.exists()) {
throw new IOException("File \"" + file.getPath() + "\" not found.");
}
final String path = System.getProperty("replaymod.render.path");
String type = System.getProperty("replaymod.render.type");
String bitrate = System.getProperty("replaymod.render.bitrate");
String fps = System.getProperty("replaymod.render.fps");
String waitForChunks = System.getProperty("replaymod.render.waitforchunks");
String linearMovement = System.getProperty("replaymod.render.linearmovement");
String skyColor = System.getProperty("replaymod.render.skycolor");
String width = System.getProperty("replaymod.render.width");
String height = System.getProperty("replaymod.render.height");
String exportCommand = System.getProperty("replaymod.render.exportcommand");
String exportCommandArgs = System.getProperty("replaymod.render.exportcommandargs");
/*
final RenderOptions options = new RenderOptions();
if (bitrate != null) {
options.setBitrate(bitrate);
}
if (fps != null) {
options.setFps(Integer.parseInt(fps));
}
if (waitForChunks != null) {
options.setWaitForChunks(Boolean.parseBoolean(waitForChunks));
}
if (linearMovement != null) {
options.setLinearMovement(Boolean.parseBoolean(linearMovement));
}
if (skyColor != null) {
if (skyColor.startsWith("0x")) {
options.setSkyColor(Integer.parseInt(skyColor.substring(2), 16));
} else {
options.setSkyColor(Integer.parseInt(skyColor));
}
}
if (width != null) {
options.setWidth(Integer.parseInt(width));
}
if (height != null) {
options.setHeight(Integer.parseInt(height));
}
if (exportCommand != null) {
options.setExportCommand(exportCommand);
}
if (exportCommandArgs != null) {
options.setExportCommandArgs(exportCommandArgs);
} else {
options.setExportCommandArgs(EncodingPreset.MP4DEFAULT.getCommandLineArgs());
}
options.setOutputFile(new File(String.valueOf(System.currentTimeMillis())));
Pipelines.Preset pipelinePreset = Pipelines.Preset.DEFAULT;
if (type != null) {
String[] parts = type.split(":");
type = parts[0].toUpperCase();
if ("NORMAL".equals(type) || "DEFAULT".equals(type)) {
pipelinePreset = Pipelines.Preset.DEFAULT;
} else if ("STEREO".equals(type) || "STEREOSCOPIC".equals(type)) {
pipelinePreset = Pipelines.Preset.STEREOSCOPIC;
} else if ("CUBIC".equals(type)) {
if (parts.length < 2) {
throw new IllegalArgumentException("Cubic renderer requires boolean for whether it's stable.");
}
pipelinePreset = Pipelines.Preset.CUBIC;
} else if ("EQUIRECTANGULAR".equals(type)) {
if (parts.length < 2) {
throw new IllegalArgumentException("Equirectangular renderer requires boolean for whether it's stable.");
}
pipelinePreset = Pipelines.Preset.EQUIRECTANGULAR;
} else if ("ODS".equals(type)) {
if (parts.length < 2) {
throw new IllegalArgumentException("ODS renderer requires boolean for whether it's stable.");
}
pipelinePreset = Pipelines.Preset.ODS;
} else {
throw new IllegalArgumentException("Unknown type: " + parts[0]);
}
}
options.setMode(pipelinePreset);
*/
@SuppressWarnings("unchecked")
Queue<ListenableFutureTask> tasks = mc.scheduledTasks;
synchronized (mc.scheduledTasks) {
tasks.add(ListenableFutureTask.create(new Runnable() {
@Override
public void run() {
String renderDistance = System.getProperty("replaymod.render.mc.renderdistance");
String clouds = System.getProperty("replaymod.render.mc.clouds");
if (renderDistance != null) {
mc.gameSettings.renderDistanceChunks = Integer.parseInt(renderDistance);
}
if (clouds != null) {
mc.gameSettings.clouds = Boolean.parseBoolean(clouds);
}
System.out.println("Loading replay...");
// TODO
// try {
// ReplayHandler.startReplay(file, false);
// } catch (Throwable t) {
// t.printStackTrace();
// FMLCommonHandler.instance().exitJava(1, false);
// }
//
// int index = 0;
// if (path != null) {
// for (KeyframeSet set : ReplayHandler.getKeyframeRepository()) {
// if (set.getName().equals(path)) {
// break;
// }
// index++;
// }
// if (index >= ReplayHandler.getKeyframeRepository().length) {
// throw new IllegalArgumentException("No path named \"" + path + "\".");
// }
// } else if (ReplayHandler.getKeyframeRepository().length == 0) {
// throw new IllegalArgumentException("Replay file has no paths defined.");
// }
// ReplayHandler.useKeyframePresetFromRepository(index);
//
// System.out.println("Rendering started...");
// try {
// ReplayProcess.startReplayProcess(options, true);
// } catch (Throwable t) {
// t.printStackTrace();
// FMLCommonHandler.instance().exitJava(1, false);
// }
// if (mc.hasCrashed) {
// System.out.println(mc.crashReporter.getCompleteReport());
// }
// System.out.println("Rendering done. Shutting down...");
// mc.shutdown();
}
}, null));
}
testIfMoeshAndExitMinecraft();
}
runLater(() -> {
// Cleanup deleted corrupted replays
@@ -159,9 +310,38 @@ public class ReplayMod {
});
}
/**
* 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;
public void runLater(Runnable runnable) {
if (mc.isCallingFromMinecraftThread() && inRunLater) {
EventBus bus = FMLCommonHandler.instance().bus();
bus.register(new Object() {
@SubscribeEvent
public void onRenderTick(TickEvent.RenderTickEvent event) {
if (event.phase == TickEvent.Phase.START) {
runLater(runnable);
bus.unregister(this);
}
}
});
return;
}
@SuppressWarnings("unchecked")
Queue<ListenableFutureTask> tasks = mc.scheduledTasks;
synchronized (mc.scheduledTasks) {
mc.scheduledTasks.add(ListenableFutureTask.create(runnable, null));
tasks.add(ListenableFutureTask.create(() -> {
inRunLater = true;
try {
runnable.run();
} finally {
inRunLater = false;
}
}, null));
}
}
@@ -190,13 +370,13 @@ public class ReplayMod {
private void printToChat(boolean warning, String message, Object... args) {
if (getSettingsRegistry().get(Setting.NOTIFICATIONS)) {
// Some nostalgia: "§8[§6Replay Mod§8]§r Your message goes here"
Style coloredDarkGray = new Style().setColor(TextFormatting.DARK_GRAY);
Style coloredGold = new Style().setColor(TextFormatting.GOLD);
ITextComponent text = new TextComponentString("[").setStyle(coloredDarkGray)
.appendSibling(new TextComponentTranslation("replaymod.title").setStyle(coloredGold))
.appendSibling(new TextComponentString("] "))
.appendSibling(new TextComponentTranslation(message, args).setStyle(new Style()
.setColor(warning ? TextFormatting.RED : TextFormatting.DARK_GREEN)));
ChatStyle coloredDarkGray = new ChatStyle().setColor(EnumChatFormatting.DARK_GRAY);
ChatStyle coloredGold = new ChatStyle().setColor(EnumChatFormatting.GOLD);
IChatComponent text = new ChatComponentText("[").setChatStyle(coloredDarkGray)
.appendSibling(new ChatComponentTranslation("replaymod.title").setChatStyle(coloredGold))
.appendSibling(new ChatComponentText("] "))
.appendSibling(new ChatComponentTranslation(message, args).setChatStyle(new ChatStyle()
.setColor(warning ? EnumChatFormatting.RED : EnumChatFormatting.DARK_GREEN)));
// Send message to chat GUI
// The ingame GUI is initialized at startup, therefore this is possible before the client is connected
mc.ingameGUI.getChatGUI().printChatMessage(text);

View File

@@ -2,8 +2,8 @@ package com.replaymod.core;
import com.replaymod.core.events.SettingsChangedEvent;
import net.minecraft.client.resources.I18n;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.config.Configuration;
import net.minecraftforge.fml.common.FMLCommonHandler;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
@@ -83,7 +83,7 @@ public class SettingsRegistry {
throw new IllegalArgumentException("Default type " + key.getDefault().getClass() + " not supported.");
}
settings.put(key, value);
MinecraftForge.EVENT_BUS.post(new SettingsChangedEvent(this, key));
FMLCommonHandler.instance().bus().post(new SettingsChangedEvent(this, key));
}
public void save() {

View File

@@ -6,6 +6,8 @@ import net.minecraftforge.client.event.GuiScreenEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import java.util.List;
/**
* Moves certain buttons on the main menu upwards so we can inject our own.
*/
@@ -16,12 +18,14 @@ public class MainMenuHandler {
@SubscribeEvent
public void onInit(GuiScreenEvent.InitGuiEvent.Post event) {
if (event.getGui() instanceof GuiMainMenu) {
for (GuiButton button : event.getButtonList()) {
if (event.gui instanceof GuiMainMenu) {
@SuppressWarnings("unchecked")
List<GuiButton> buttonList = event.buttonList;
for (GuiButton button : buttonList) {
// Buttons that aren't in a rectangle directly above our space don't need moving
if (button.xPosition + button.width < event.getGui().width / 2 - 100
|| button.xPosition > event.getGui().width / 2 + 100
|| button.yPosition > event.getGui().height / 4 + 10 + 4 * 24) continue;
if (button.xPosition + button.width < event.gui.width / 2 - 100
|| button.xPosition > event.gui.width / 2 + 100
|| button.yPosition > event.gui.height / 4 + 10 + 4 * 24) continue;
// Move button up to make space for two rows of buttons
// and then move back down by 10 to compensate for the space to the exit button that was already there
button.yPosition -= 2 * 24 - 10;

View File

@@ -2,8 +2,7 @@ package com.replaymod.core.utils;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.VertexBuffer;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.client.renderer.WorldRenderer;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
@@ -35,14 +34,14 @@ public class OpenGLUtils {
float f5 = 1.0F / textureHeight;
Tessellator tessellator = Tessellator.getInstance();
VertexBuffer vertexBuffer = tessellator.getBuffer();
WorldRenderer worldrenderer = tessellator.getWorldRenderer();
GlStateManager.translate(x+(width/2), y+(width/2), 0);
GlStateManager.rotate(rotation, 0, 0, 1);
vertexBuffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
vertexBuffer.pos(-width / 2, height / 2, 0.0D).tex((double) (u * f4), (double) ((v + (float) height) * f5)).endVertex();
vertexBuffer.pos(width/2, height/2, 0.0D).tex((double)((u + (float)width) * f4), (double)((v + (float)height) * f5)).endVertex();
vertexBuffer.pos(width/2, -height/2, 0.0D).tex((double)((u + (float)width) * f4), (double)(v * f5)).endVertex();
vertexBuffer.pos(-width/2, -height/2, 0.0D).tex((double)(u * f4), (double)(v * f5)).endVertex();
worldrenderer.startDrawingQuads();
worldrenderer.addVertexWithUV(-width / 2, height / 2, 0.0D, (double) (u * f4), (double) ((v + (float) height) * f5));
worldrenderer.addVertexWithUV(width/2, height/2, 0.0D, (double)((u + (float)width) * f4), (double)((v + (float)height) * f5));
worldrenderer.addVertexWithUV(width/2, -height/2, 0.0D, (double)((u + (float)width) * f4), (double)(v * f5));
worldrenderer.addVertexWithUV(-width/2, -height/2, 0.0D, (double)(u * f4), (double)(v * f5));
tessellator.draw();
GlStateManager.popMatrix();

View File

@@ -1,7 +1,7 @@
package com.replaymod.core.utils;
import net.minecraft.network.PacketBuffer;
import net.minecraft.network.play.server.SPacketCustomPayload;
import net.minecraft.network.play.server.S3FPacketCustomPayload;
/**
* Restrictions set by the server,
@@ -14,7 +14,7 @@ public class Restrictions {
private boolean onlyFirstPerson;
private boolean onlyRecordingPlayer;
public String handle(SPacketCustomPayload packet) {
public String handle(S3FPacketCustomPayload packet) {
PacketBuffer buffer = packet.getBufferData();
while (buffer.isReadable()) {
String name = buffer.readStringFromBuffer(64);

View File

@@ -1,7 +1,9 @@
package com.replaymod.core.utils;
import com.google.common.net.PercentEscaper;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import de.johni0702.minecraft.gui.GuiRenderer;
import de.johni0702.minecraft.gui.RenderInfo;
import de.johni0702.minecraft.gui.container.AbstractGuiScrollable;
@@ -15,16 +17,20 @@ import de.johni0702.minecraft.gui.layout.HorizontalLayout;
import de.johni0702.minecraft.gui.layout.VerticalLayout;
import de.johni0702.minecraft.gui.popup.GuiInfoPopup;
import de.johni0702.minecraft.gui.utils.Colors;
import lombok.SneakyThrows;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.network.NetworkPlayerInfo;
import net.minecraft.client.resources.DefaultPlayerSkin;
import net.minecraft.crash.CrashReport;
import net.minecraft.util.ResourceLocation;
import org.apache.commons.io.Charsets;
import org.apache.commons.io.FilenameUtils;
import org.apache.logging.log4j.Logger;
import org.lwjgl.input.Keyboard;
import org.lwjgl.util.Dimension;
import org.lwjgl.util.ReadableDimension;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.imageio.ImageIO;
import javax.net.ssl.SSLContext;
@@ -34,6 +40,8 @@ import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
@@ -45,6 +53,7 @@ import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.UUID;
import java.util.function.Consumer;
import static net.minecraft.client.Minecraft.getMinecraft;
@@ -134,8 +143,24 @@ public class Utils {
return mail.matches("^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$");
}
private static final PercentEscaper REPLAY_NAME_ENCODER = new PercentEscaper(".-_ ", false);
public static String replayNameToFileName(String replayName) {
return REPLAY_NAME_ENCODER.escape(replayName) + ".mcpr";
}
@SneakyThrows(UnsupportedEncodingException.class)
public static String fileNameToReplayName(String fileName) {
String baseName = FilenameUtils.getBaseName(fileName);
try {
return URLDecoder.decode(baseName, Charsets.UTF_8.name());
} catch (IllegalArgumentException e) {
return baseName;
}
}
public static ResourceLocation getResourceLocationForPlayerUUID(UUID uuid) {
NetworkPlayerInfo info = getMinecraft().getConnection().getPlayerInfo(uuid);
NetworkPlayerInfo info = getMinecraft().getNetHandler().getPlayerInfo(uuid);
ResourceLocation skinLocation;
if (info != null && info.hasLocationSkin()) {
skinLocation = info.getLocationSkin();
@@ -149,6 +174,20 @@ public class Utils {
return Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) || Keyboard.isKeyDown(Keyboard.KEY_RCONTROL);
}
public static <T> void addCallback(ListenableFuture<T> future, Consumer<T> onSuccess, Consumer<Throwable> onFailure) {
Futures.addCallback(future, new FutureCallback<T>() {
@Override
public void onSuccess(@Nullable T result) {
onSuccess.accept(result);
}
@Override
public void onFailure(@Nonnull Throwable t) {
onFailure.accept(t);
}
});
}
public static GuiInfoPopup error(Logger logger, GuiContainer container, CrashReport crashReport, Runnable onClose) {
// Convert crash report to string
String crashReportStr = crashReport.getCompleteReport();

View File

@@ -27,7 +27,7 @@ public class WrappedTimer extends Timer {
to.elapsedPartialTicks = from.elapsedPartialTicks;
to.lastSyncSysClock = from.lastSyncSysClock;
to.lastSyncHRClock = from.lastSyncHRClock;
to.counter = from.counter;
to.field_74285_i = from.field_74285_i;
to.timeSyncAdjustment = from.timeSyncAdjustment;
}
}

View File

@@ -11,6 +11,8 @@ import org.apache.logging.log4j.Logger;
@Mod(modid = ReplayModEditor.MOD_ID,
version = "@MOD_VERSION@",
acceptedMinecraftVersions = "@MC_VERSION@",
acceptableRemoteVersions = "*",
clientSideOnly = true,
useMetadata = true)
public class ReplayModEditor {
public static final String MOD_ID = "replaymod-editor";

View File

@@ -36,7 +36,6 @@ import de.johni0702.minecraft.gui.popup.GuiYesNoPopup;
import de.johni0702.minecraft.gui.utils.Colors;
import net.minecraft.crash.CrashReport;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.lwjgl.util.ReadableDimension;
import javax.annotation.Nullable;
@@ -59,6 +58,9 @@ public class GuiReplayEditor extends GuiScreen {
public GuiButton currentTabButton;
public GuiPanel currentTabPanel;
public final GuiLabel warningLabel = new GuiLabel(this).setColor(Colors.RED)
.setI18nText("replaymod.gui.editor.disclaimer");
public final GuiPanel tabButtons = new GuiPanel(this).setLayout(new GridLayout().setSpacingX(5));
public final List<GuiPanel> tabPanels = new ArrayList<>();
@@ -84,15 +86,18 @@ public class GuiReplayEditor extends GuiScreen {
// Move all inactive panels aside
tabPanels.forEach(e -> pos(e, Integer.MIN_VALUE, Integer.MIN_VALUE));
pos(warningLabel, 10, 22);
size(warningLabel, width - 20, 10);
pos(tabButtons, 10, y(warningLabel) + height(warningLabel) + 2);
size(tabButtons, width - 20, 20);
pos(buttonPanel, width - 10 - width(buttonPanel), height - 10 - height(buttonPanel));
if (currentTabPanel != null) {
pos(currentTabPanel, 10, 50);
pos(currentTabPanel, 10, y(tabButtons) + height(tabButtons) + 10);
size(currentTabPanel, width - 20, y(buttonPanel) - 10 - y(currentTabPanel));
}
pos(tabButtons, 10, 20);
size(tabButtons, width - 20, 20);
}
});
}
@@ -119,7 +124,7 @@ public class GuiReplayEditor extends GuiScreen {
}
public void save(File inputFile, PacketStream.FilterInfo...filters) {
save(FilenameUtils.getBaseName(inputFile.getName()), (outputFile) -> {
save(Utils.fileNameToReplayName(inputFile.getName()), (outputFile) -> {
Studio studio = new ReplayStudio();
File tmpDir = null;
try {
@@ -214,7 +219,7 @@ public class GuiReplayEditor extends GuiScreen {
Utils.error(LOGGER, GuiReplayEditor.this, CrashReport.makeCrashReport(e, "Getting replay folder"), null);
return;
}
File targetFile = new File(replayFolder, name + ".mcpr");
File targetFile = new File(replayFolder, Utils.replayNameToFileName(name));
if (targetFile.exists()) {
LOGGER.trace("Selected file already exists, asking for confirmation");
Futures.addCallback(GuiYesNoPopup.open(GuiReplayEditor.this,

View File

@@ -20,7 +20,6 @@ import de.johni0702.minecraft.gui.layout.HorizontalLayout;
import de.johni0702.minecraft.gui.layout.VerticalLayout;
import net.minecraft.client.resources.I18n;
import net.minecraft.crash.CrashReport;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOCase;
import org.apache.commons.io.filefilter.SuffixFileFilter;
import org.lwjgl.util.Dimension;
@@ -52,7 +51,7 @@ public class GuiTrimPanel extends GuiPanel {
public final GuiDropdownMenu<File> inputReplays = new GuiDropdownMenu<File>(this)
.setMinSize(new Dimension(200, 20)).onSelection(i -> updateSelectedReplay())
.setToString(f -> f == NO_REPLAY ? "" : FilenameUtils.getBaseName(f.getName()));
.setToString(f -> f == NO_REPLAY ? "" : Utils.fileNameToReplayName(f.getName()));
public final GuiNumberField startHour = newGuiNumberField();
public final GuiNumberField startMin = newGuiNumberField();

View File

@@ -8,8 +8,11 @@ import net.minecraft.client.gui.GuiMainMenu;
import net.minecraft.client.resources.I18n;
import net.minecraftforge.client.event.GuiScreenEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import java.util.List;
public class GuiHandler {
private static final int BUTTON_REPLAY_EDITOR = 17890237;
@@ -20,28 +23,31 @@ public class GuiHandler {
}
public void register() {
FMLCommonHandler.instance().bus().register(this);
MinecraftForge.EVENT_BUS.register(this);
}
@SubscribeEvent
public void injectIntoMainMenu(GuiScreenEvent.InitGuiEvent event) {
if (!(event.getGui() instanceof GuiMainMenu)) {
if (!(event.gui instanceof GuiMainMenu)) {
return;
}
GuiButton button = new GuiButton(BUTTON_REPLAY_EDITOR, event.getGui().width / 2 + 2,
event.getGui().height / 4 + 10 + 3 * 24, I18n.format("replaymod.gui.replayeditor"));
@SuppressWarnings("unchecked")
List<GuiButton> buttonList = event.buttonList;
GuiButton button = new GuiButton(BUTTON_REPLAY_EDITOR, event.gui.width / 2 + 2,
event.gui.height / 4 + 10 + 3 * 24, I18n.format("replaymod.gui.replayeditor"));
button.width = button.width / 2 - 2;
event.getButtonList().add(button);
buttonList.add(button);
}
@SubscribeEvent
public void onButton(GuiScreenEvent.ActionPerformedEvent.Pre event) {
if(!event.getButton().enabled) return;
if(!event.button.enabled) return;
if (event.getGui() instanceof GuiMainMenu) {
if (event.getButton().id == BUTTON_REPLAY_EDITOR) {
new GuiReplayEditor(GuiScreen.wrap(event.getGui()), mod.getCore()).display();
if (event.gui instanceof GuiMainMenu) {
if (event.button.id == BUTTON_REPLAY_EDITOR) {
new GuiReplayEditor(GuiScreen.wrap(event.gui), mod.getCore()).display();
}
}
}

View File

@@ -9,7 +9,7 @@ import de.johni0702.minecraft.gui.element.GuiImage;
import de.johni0702.minecraft.gui.element.IGuiImage;
import de.johni0702.minecraft.gui.layout.HorizontalLayout;
import net.minecraft.client.settings.GameSettings;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent;
import org.lwjgl.input.Keyboard;
@@ -40,7 +40,7 @@ public class FullBrightness implements Extra {
}
});
MinecraftForge.EVENT_BUS.register(this);
FMLCommonHandler.instance().bus().register(this);
}
@SubscribeEvent

View File

@@ -17,7 +17,7 @@ import de.johni0702.minecraft.gui.layout.GridLayout;
import de.johni0702.minecraft.gui.layout.HorizontalLayout;
import de.johni0702.minecraft.gui.layout.LayoutData;
import net.minecraft.client.resources.I18n;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import org.lwjgl.input.Keyboard;
import org.lwjgl.util.Dimension;
@@ -35,7 +35,7 @@ public class HotkeyButtons implements Extra {
public void register(ReplayMod mod) throws Exception {
this.mod = mod;
MinecraftForge.EVENT_BUS.register(this);
FMLCommonHandler.instance().bus().register(this);
}
@SubscribeEvent

View File

@@ -1,106 +1,110 @@
package com.replaymod.extras;
import com.google.common.base.Charsets;
import com.google.common.collect.ImmutableSet;
import com.replaymod.core.ReplayMod;
import com.replaymod.online.ReplayModOnline;
import com.replaymod.online.api.ApiClient;
import com.replaymod.online.api.ApiException;
import lombok.RequiredArgsConstructor;
import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.IResourcePack;
import net.minecraft.client.resources.data.IMetadataSection;
import net.minecraft.client.resources.data.MetadataSerializer;
import net.minecraft.client.resources.data.IMetadataSerializer;
import net.minecraft.util.ResourceLocation;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.io.IOUtils;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ConnectException;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import static com.replaymod.extras.ReplayModExtras.LOGGER;
public class LocalizationExtra implements Extra {
private ReplayModOnline module;
private static final String ZIP_FILE_URL = "https://github.com/ReplayMod/Translations/archive/master.zip";
private static final String LANG_PREFIX = "Translations-master/";
@Override
public void register(ReplayMod mod) throws Exception {
this.module = ReplayModOnline.instance;
final Minecraft mc = mod.getMinecraft();
Thread localizedResourcePackLoader = new Thread(new Runnable() {
@Override
public void run() {
try {
if (Boolean.parseBoolean(System.getProperty("replaymod.offline", "false"))) {
return;
}
Thread localizedResourcePackLoader = new Thread(() -> {
try {
// Download zip of lang files
LOGGER.debug("Downloading languages from {}", ZIP_FILE_URL);
Map<String, byte[]> languages = new HashMap<>();
try (InputStream urlIn = new URL(ZIP_FILE_URL).openStream();
ZipInputStream in = new ZipInputStream(urlIn)) {
ZipEntry entry;
while ((entry = in.getNextEntry()) != null) {
String name = entry.getName();
if (!name.startsWith(LANG_PREFIX) || !name.endsWith(".lang")) {
continue;
}
name = name.substring(LANG_PREFIX.length());
languages.put(name, IOUtils.toByteArray(in));
LOGGER.debug("Added language file {}", name);
}
}
LOGGER.debug("Downloaded {} languages", languages.size());
// Add lang files as resource pack
mc.addScheduledTask(() -> {
@SuppressWarnings("unchecked")
List<IResourcePack> defaultResourcePacks = mc.defaultResourcePacks;
defaultResourcePacks.add(new LocalizedResourcePack(module.getApiClient()));
mc.addScheduledTask(new Runnable() {
@Override
public void run() {
mc.refreshResources();
}
});
} catch(Exception e) {
e.printStackTrace();
}
defaultResourcePacks.add(new LocalizedResourcePack(languages));
mc.getLanguageManager().onResourceManagerReload(mc.getResourceManager());
LOGGER.debug("Added language files to resource packs and reloaded LanguageManager");
});
} catch (Throwable t) {
LOGGER.error("Loading localized resource pack:", t);
}
}, "localizedResourcePackLoader");
localizedResourcePackLoader.setDaemon(true);
localizedResourcePackLoader.start();
}
@RequiredArgsConstructor
public static class LocalizedResourcePack implements IResourcePack {
private final ApiClient apiClient;
private Map<String, String> availableLanguages = new HashMap<>();
private boolean websiteAvailable = true;
private final Pattern LANG_PATTERN = Pattern.compile("^lang/([.+].lang)$");
private final Map<String, byte[]> languages;
public LocalizedResourcePack(Map<String, byte[]> languages) {
this.languages = languages;
}
@Override
public InputStream getInputStream(ResourceLocation loc) {
if(!loc.getResourcePath().endsWith(".lang")) return null;
String langcode = loc.getResourcePath().split("/")[1].split("\\.")[0];
if(availableLanguages.containsKey(langcode)) return new ByteArrayInputStream(availableLanguages.get(langcode).getBytes(Charsets.UTF_8));
if (!"replaymod".equals(loc.getResourceDomain())) return null;
Matcher matcher = LANG_PATTERN.matcher(loc.getResourcePath());
if (matcher.matches()) {
byte[] bytes = languages.get(matcher.group());
if (bytes != null) {
return new ByteArrayInputStream(bytes);
}
}
return null;
}
@Override
public boolean resourceExists(ResourceLocation loc) {
if(!(loc.getResourcePath().endsWith(".lang"))) return false;
String langcode = loc.getResourcePath().split("/")[1].split("\\.")[0];
if(availableLanguages.containsKey(langcode)) return true;
if(!websiteAvailable) return false;
try {
if (Boolean.parseBoolean(System.getProperty("replaymod.offline", "false"))) {
return false;
}
String lang = apiClient.getTranslation(langcode);
String prop = StringEscapeUtils.unescapeHtml4(lang);
availableLanguages.put(langcode, prop);
return true;
} catch (ApiException e) {
if (e.getError() == null || e.getError().getId() != 16) { // This language has not been translated
e.printStackTrace();
}
} catch(ConnectException ce) {
websiteAvailable = false;
ce.printStackTrace();
} catch(Exception e) {
e.printStackTrace();
}
return false;
// Assumes that getInputStream returns a ByteArrayInputStream that doesn't need to be closed
return getInputStream(loc) != null;
}
@Override
public Set<String> getResourceDomains() {
return ImmutableSet.of("minecraft", "replaymod");
public Set getResourceDomains() {
return ImmutableSet.of("replaymod");
}
@Override
public <T extends IMetadataSection> T getPackMetadata(MetadataSerializer metadataSerializer, String metadataSectionName) throws IOException {
public IMetadataSection getPackMetadata(IMetadataSerializer p_135058_1_, String p_135058_2_) throws IOException {
return null;
}

View File

@@ -43,7 +43,7 @@ public class OpenEyeExtra implements Extra {
}
}
private class OfferGui extends AbstractGuiScreen<OfferGui> {
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),
@@ -69,7 +69,7 @@ public class OpenEyeExtra implements Extra {
GuiPopup popup = new GuiPopup(OfferGui.this);
new Thread(() -> {
try {
File targetFile = new File("mods/" + Loader.MC_VERSION, "OpenEye.jar");
File targetFile = new File(mod.getMinecraft().mcDataDir, "mods/" + Loader.MC_VERSION + "/OpenEye.jar");
FileUtils.forceMkdir(targetFile.getParentFile());
HttpsURLConnection connection = (HttpsURLConnection) new URL(DOWNLOAD_URL).openConnection();
@@ -107,7 +107,7 @@ public class OpenEyeExtra implements Extra {
}
}
private static final class GuiPopup extends AbstractGuiPopup<GuiPopup> {
public static final class GuiPopup extends AbstractGuiPopup<GuiPopup> {
GuiPopup(GuiContainer container) {
super(container);
popup.addElements(null, new GuiIndicator().setColor(Colors.BLACK));

View File

@@ -1,6 +1,7 @@
package com.replaymod.extras;
import com.replaymod.core.ReplayMod;
import com.replaymod.extras.advancedscreenshots.AdvancedScreenshots;
import com.replaymod.extras.playeroverview.PlayerOverview;
import com.replaymod.extras.urischeme.UriSchemeExtra;
import com.replaymod.extras.youtube.YoutubeUpload;
@@ -10,11 +11,16 @@ import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import org.apache.logging.log4j.Logger;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@Mod(modid = ReplayModExtras.MOD_ID,
version = "@MOD_VERSION@",
acceptedMinecraftVersions = "@MC_VERSION@",
acceptableRemoteVersions = "*",
clientSideOnly = true,
useMetadata = true)
public class ReplayModExtras {
public static final String MOD_ID = "replaymod-extras";
@@ -23,6 +29,7 @@ public class ReplayModExtras {
public static ReplayModExtras instance;
private static final List<Class<? extends Extra>> builtin = Arrays.asList(
AdvancedScreenshots.class,
PlayerOverview.class,
UriSchemeExtra.class,
YoutubeUpload.class,
@@ -32,11 +39,14 @@ public class ReplayModExtras {
OpenEyeExtra.class
);
private Logger logger;
private final Map<Class<? extends Extra>, Extra> instances = new HashMap<>();
public static Logger LOGGER;
@Mod.EventHandler
public void preInit(FMLPreInitializationEvent event) {
logger = event.getModLog();
LOGGER = event.getModLog();
ReplayMod.instance.getSettingsRegistry().register(Setting.class);
}
@Mod.EventHandler
@@ -45,9 +55,14 @@ public class ReplayModExtras {
try {
Extra extra = cls.newInstance();
extra.register(ReplayMod.instance);
instances.put(cls, extra);
} catch (Throwable t) {
logger.warn("Failed to load extra " + cls.getName() + ": ", t);
LOGGER.warn("Failed to load extra " + cls.getName() + ": ", t);
}
}
}
public <T extends Extra> Optional<T> get(Class<T> cls) {
return Optional.ofNullable(instances.get(cls)).map(cls::cast);
}
}

View File

@@ -0,0 +1,8 @@
package com.replaymod.extras;
import com.replaymod.core.SettingsRegistry;
public final class Setting<T> {
public static final SettingsRegistry.SettingKey<Boolean> SKIP_POST_SCREENSHOT_GUI =
new SettingsRegistry.SettingKeys<>("advanced", "skipPostScreenshotGui", null, false);
}

View File

@@ -0,0 +1,41 @@
package com.replaymod.extras.advancedscreenshots;
import com.replaymod.core.ReplayMod;
import com.replaymod.extras.Extra;
import com.replaymod.replay.events.ReplayDispatchKeypressesEvent;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiControls;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import org.lwjgl.input.Keyboard;
public class AdvancedScreenshots implements Extra {
private ReplayMod mod;
private final Minecraft mc = Minecraft.getMinecraft();
@Override
public void register(ReplayMod mod) throws Exception {
this.mod = mod;
MinecraftForge.EVENT_BUS.register(this);
}
@SubscribeEvent
public void onDispatchKeypresses(ReplayDispatchKeypressesEvent.Pre event) {
int keyCode = Keyboard.getEventKey() == 0 ? Keyboard.getEventCharacter() : Keyboard.getEventKey();
// all the conditions required to trigger a screenshot condensed in a single if statement
if (keyCode != 0 && !Keyboard.isRepeatEvent()
&& (!(mc.currentScreen instanceof GuiControls) || ((GuiControls) mc.currentScreen).time <= mc.getSystemTime() - 20L)
&& Keyboard.getEventKeyState()
&& keyCode == mc.gameSettings.keyBindScreenshot.getKeyCode()) {
ReplayMod.instance.runLater(() -> {
new GuiCreateScreenshot(mod).display();
});
event.setCanceled(true);
}
}
}

View File

@@ -0,0 +1,94 @@
package com.replaymod.extras.advancedscreenshots;
import com.replaymod.core.ReplayMod;
import com.replaymod.render.RenderSettings;
import com.replaymod.render.gui.GuiRenderSettings;
import com.replaymod.replay.ReplayModReplay;
import de.johni0702.minecraft.gui.container.GuiContainer;
import de.johni0702.minecraft.gui.container.GuiPanel;
import de.johni0702.minecraft.gui.element.GuiLabel;
import de.johni0702.minecraft.gui.function.Loadable;
import de.johni0702.minecraft.gui.layout.GridLayout;
import de.johni0702.minecraft.gui.layout.VerticalLayout;
import net.minecraft.crash.CrashReport;
import net.minecraft.util.ScreenShotHelper;
import net.minecraftforge.common.config.Configuration;
import net.minecraftforge.common.config.Property;
import java.io.File;
import java.util.ArrayList;
import static com.replaymod.core.utils.Utils.error;
import static com.replaymod.render.ReplayModRender.LOGGER;
public class GuiCreateScreenshot extends GuiRenderSettings implements Loadable {
private final ReplayMod mod;
public GuiCreateScreenshot(ReplayMod mod) {
super(null, null);
this.mod = mod;
resetChildren(settingsList.getListPanel()).addElements(new VerticalLayout.Data(0.5),
new GuiLabel().setI18nText("replaymod.gui.advancedscreenshots.title"), mainPanel, new GuiPanel(),
new GuiLabel().setI18nText("replaymod.gui.rendersettings.advanced"), advancedPanel, new GuiPanel());
resetChildren(mainPanel).addElements(new GridLayout.Data(1, 0.5),
new GuiLabel().setI18nText("replaymod.gui.rendersettings.renderer"), renderMethodDropdown,
new GuiLabel().setI18nText("replaymod.gui.advancedscreenshots.resolution"), videoResolutionPanel,
new GuiLabel().setI18nText("replaymod.gui.rendersettings.outputfile"), outputFileButton);
resetChildren(advancedPanel).addElements(null, nametagCheckbox, new GuiPanel().setLayout(
new GridLayout().setCellsEqualSize(false).setColumns(2).setSpacingX(5).setSpacingY(15))
.addElements(new GridLayout.Data(0, 0.5),
new GuiLabel().setI18nText("replaymod.gui.rendersettings.stabilizecamera"), stabilizePanel,
chromaKeyingCheckbox, chromaKeyingColor));
exportArguments.setText(""); // To disable any preset-based checks
buttonPanel.removeElement(queueButton);
renderButton.setI18nLabel("replaymod.gui.advancedscreenshots.create").onClick(() -> {
// Closing this GUI ensures that settings are saved
getMinecraft().displayGuiScreen(null);
mod.runLater(() -> {
try {
RenderSettings settings = save(false);
boolean success = new ScreenshotRenderer(settings).renderScreenshot();
if (success) {
new GuiUploadScreenshot(ReplayModReplay.instance.getReplayHandler().getOverlay(), mod,
settings).open();
}
} catch (Throwable t) {
error(LOGGER, GuiCreateScreenshot.this, CrashReport.makeCrashReport(t, "Rendering video"), () -> {});
display(); // Re-show the render settings gui and the new error popup
}
});
});
}
private <T extends GuiContainer<?>> T resetChildren(T container) {
new ArrayList<>(container.getChildren()).forEach(container::removeElement);
return container;
}
@Override
public void load() {
// pause replay when opening this gui
ReplayModReplay.instance.getReplayHandler().getReplaySender().setReplaySpeed(0);
}
@Override
protected File generateOutputFile(RenderSettings.EncodingPreset encodingPreset) {
File screenshotFolder = new File(getMinecraft().mcDataDir, "screenshots");
return ScreenShotHelper.getTimestampedPNGFileForDirectory(screenshotFolder);
}
@Override
protected Property getConfigProperty(Configuration configuration) {
return configuration.get("screenshotsettings", "settings", "{}",
"Last state of the screenshot settings GUI. Internal use only.");
}
}

View File

@@ -0,0 +1,128 @@
package com.replaymod.extras.advancedscreenshots;
import com.replaymod.core.ReplayMod;
import com.replaymod.core.SettingsRegistry;
import com.replaymod.extras.Setting;
import com.replaymod.render.RenderSettings;
import de.johni0702.minecraft.gui.container.GuiContainer;
import de.johni0702.minecraft.gui.container.GuiPanel;
import de.johni0702.minecraft.gui.element.GuiButton;
import de.johni0702.minecraft.gui.element.GuiCheckbox;
import de.johni0702.minecraft.gui.element.GuiLabel;
import de.johni0702.minecraft.gui.layout.HorizontalLayout;
import de.johni0702.minecraft.gui.layout.VerticalLayout;
import de.johni0702.minecraft.gui.popup.AbstractGuiPopup;
import org.lwjgl.util.ReadableColor;
import java.awt.*;
import java.io.IOException;
import java.net.URI;
public class GuiUploadScreenshot extends AbstractGuiPopup<GuiUploadScreenshot> {
public final ReplayMod mod;
public final RenderSettings renderSettings;
public final GuiLabel successLabel = new GuiLabel()
.setI18nText("replaymod.gui.advancedscreenshots.finished.description")
.setColor(ReadableColor.BLACK);
public final GuiLabel veerLabel = new GuiLabel()
.setI18nText("replaymod.gui.advancedscreenshots.finished.description.veer")
.setColor(ReadableColor.BLACK);
public final GuiButton veerUploadButton = new GuiButton()
.setSize(150, 20)
.setI18nLabel("replaymod.gui.advancedscreenshots.finished.upload.veer");
public final GuiButton showOnDiskButton = new GuiButton()
.setSize(150, 20)
.setI18nLabel("replaymod.gui.advancedscreenshots.finished.showfile");
public final GuiButton closeButton = new GuiButton()
.setSize(150, 20)
.setI18nLabel("replaymod.gui.close");
public final GuiCheckbox neverOpenCheckbox = new GuiCheckbox();
public final GuiLabel neverOpenLabel = new GuiLabel()
.setI18nText("replaymod.gui.notagain")
.setColor(ReadableColor.BLACK);
public final GuiPanel checkboxPanel = GuiPanel.builder()
.layout(new HorizontalLayout(HorizontalLayout.Alignment.RIGHT).setSpacing(5))
.with(neverOpenCheckbox, new HorizontalLayout.Data(0.5))
.with(neverOpenLabel, new HorizontalLayout.Data(0.5))
.build();
public GuiUploadScreenshot(GuiContainer container, ReplayMod mod, RenderSettings renderSettings) {
super(container);
this.mod = mod;
this.renderSettings = renderSettings;
boolean veer = renderSettings.getRenderMethod() == RenderSettings.RenderMethod.EQUIRECTANGULAR;
if (renderSettings.getRenderMethod() == RenderSettings.RenderMethod.EQUIRECTANGULAR) {
successLabel.setI18nText("replaymod.gui.advancedscreenshots.finished.description.360");
}
if (veer) {
veerUploadButton.onClick(() -> {
try {
Desktop.getDesktop().browse(URI.create("https://veer.tv/upload"));
} catch (IOException e) {
e.printStackTrace();
}
});
}
showOnDiskButton.onClick(() -> {
try {
Desktop.getDesktop().browse(renderSettings.getOutputFile().toURI());
} catch (IOException e) {
e.printStackTrace();
}
});
closeButton.onClick(() -> {
if (neverOpenCheckbox.isChecked()) {
SettingsRegistry settingsRegistry = mod.getSettingsRegistry();
settingsRegistry.set(Setting.SKIP_POST_SCREENSHOT_GUI, true);
settingsRegistry.save();
}
close();
});
popup.addElements(new VerticalLayout.Data(0.5), successLabel);
if (veer) {
popup.addElements(new VerticalLayout.Data(0.5),
veerLabel,
veerUploadButton);
}
popup.addElements(new VerticalLayout.Data(0.5),
successLabel,
showOnDiskButton,
closeButton);
popup.addElements(new VerticalLayout.Data(1),
checkboxPanel);
popup.setLayout(new VerticalLayout().setSpacing(5));
}
@Override
protected void open() {
if (mod.getSettingsRegistry().get(Setting.SKIP_POST_SCREENSHOT_GUI)) {
return;
}
super.open();
}
@Override
protected GuiUploadScreenshot getThis() {
return this;
}
}

View File

@@ -0,0 +1,66 @@
package com.replaymod.extras.advancedscreenshots;
import com.replaymod.render.RenderSettings;
import com.replaymod.render.capturer.RenderInfo;
import com.replaymod.render.hooks.ChunkLoadingRenderGlobal;
import com.replaymod.render.rendering.Pipelines;
import lombok.RequiredArgsConstructor;
import net.minecraft.client.Minecraft;
import net.minecraft.crash.CrashReport;
import org.lwjgl.util.Dimension;
import org.lwjgl.util.ReadableDimension;
@RequiredArgsConstructor
public class ScreenshotRenderer implements RenderInfo {
private final Minecraft mc = Minecraft.getMinecraft();
private final RenderSettings settings;
public boolean renderScreenshot() throws Throwable {
try {
int displayWidthBefore = mc.displayWidth;
int displayHeightBefore = mc.displayHeight;
boolean hideGUIBefore = mc.gameSettings.hideGUI;
mc.gameSettings.hideGUI = true;
ChunkLoadingRenderGlobal clrg = new ChunkLoadingRenderGlobal(mc.renderGlobal);
Pipelines.newPipeline(settings.getRenderMethod(),this,
new ScreenshotWriter(settings.getOutputFile())).run();
clrg.uninstall();
mc.gameSettings.hideGUI = hideGUIBefore;
mc.resize(displayWidthBefore, displayHeightBefore);
return true;
} catch (OutOfMemoryError e) {
e.printStackTrace();
CrashReport report = CrashReport.makeCrashReport(e, "Creating Equirectangular Screenshot");
Minecraft.getMinecraft().crashed(report);
}
return false;
}
@Override
public ReadableDimension getFrameSize() {
return new Dimension(settings.getVideoWidth(), settings.getVideoHeight());
}
@Override
public int getTotalFrames() {
// render 2 frames, because only the second contains all frames fully loaded
return 2;
}
@Override
public float updateForNextFrame() {
return mc.timer.renderPartialTicks;
}
@Override
public RenderSettings getRenderSettings() {
return settings;
}
}

View File

@@ -0,0 +1,65 @@
package com.replaymod.extras.advancedscreenshots;
import com.replaymod.core.ReplayMod;
import com.replaymod.core.utils.Utils;
import com.replaymod.extras.ReplayModExtras;
import com.replaymod.render.frame.RGBFrame;
import com.replaymod.render.rendering.FrameConsumer;
import com.replaymod.replay.ReplayModReplay;
import net.minecraft.client.Minecraft;
import net.minecraft.crash.CrashReport;
import org.lwjgl.util.ReadableDimension;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class ScreenshotWriter implements FrameConsumer<RGBFrame> {
private final File outputFile;
public ScreenshotWriter(File outputFile) {
this.outputFile = outputFile;
}
@Override
public void consume(RGBFrame frame) {
// skip the first frame, in which not all chunks are properly loaded
if (frame.getFrameId() == 0) return;
try {
final ReadableDimension frameSize = frame.getSize();
BufferedImage img = new BufferedImage(frameSize.getWidth(), frameSize.getHeight(), BufferedImage.TYPE_INT_RGB);
for (int y = 0; y < frameSize.getHeight(); y++) {
for (int x = 0; x < frameSize.getWidth(); x++) {
byte r = frame.getByteBuffer().get();
byte g = frame.getByteBuffer().get();
byte b = frame.getByteBuffer().get();
int color = ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff);
img.setRGB(x, y, color);
}
}
outputFile.getParentFile().mkdirs();
ImageIO.write(img, "PNG", outputFile);
} catch (OutOfMemoryError e) {
e.printStackTrace();
CrashReport report = CrashReport.makeCrashReport(e, "Exporting frame");
Minecraft.getMinecraft().crashed(report);
} catch (Throwable t) {
CrashReport report = CrashReport.makeCrashReport(t, "Exporting frame");
ReplayMod.instance.runLater(() -> Utils.error(ReplayModExtras.LOGGER,
ReplayModReplay.instance.getReplayHandler().getOverlay(),
report, null));
}
}
@Override
public void close() throws IOException {
}
}

View File

@@ -9,12 +9,11 @@ import com.replaymod.replay.ReplayModReplay;
import com.replaymod.replay.camera.CameraEntity;
import com.replaymod.replay.events.ReplayCloseEvent;
import com.replaymod.replay.events.ReplayOpenEvent;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.entity.RenderPlayer;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraftforge.client.event.RenderHandEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import org.lwjgl.input.Keyboard;
@@ -57,13 +56,8 @@ public class PlayerOverview implements Extra {
}
});
FMLCommonHandler.instance().bus().register(this);
MinecraftForge.EVENT_BUS.register(this);
RenderManager renderManager = mod.getMinecraft().getRenderManager();
@SuppressWarnings("unchecked")
Map<String, RenderPlayer> skinMap = renderManager.skinMap;
skinMap.put("default", new PlayerRenderHook(this, renderManager, false));
skinMap.put("slim", new PlayerRenderHook(this, renderManager, true));
}
public boolean isHidden(UUID uuid) {

View File

@@ -4,10 +4,15 @@ import com.replaymod.core.utils.Utils;
import com.replaymod.replay.ReplayModReplay;
import de.johni0702.minecraft.gui.GuiRenderer;
import de.johni0702.minecraft.gui.RenderInfo;
import de.johni0702.minecraft.gui.container.*;
import de.johni0702.minecraft.gui.container.GuiClickable;
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.container.GuiVerticalList;
import de.johni0702.minecraft.gui.element.GuiCheckbox;
import de.johni0702.minecraft.gui.element.GuiImage;
import de.johni0702.minecraft.gui.element.GuiLabel;
import de.johni0702.minecraft.gui.element.GuiTooltip;
import de.johni0702.minecraft.gui.element.IGuiCheckbox;
import de.johni0702.minecraft.gui.function.Closeable;
import de.johni0702.minecraft.gui.layout.CustomLayout;
@@ -16,8 +21,7 @@ import de.johni0702.minecraft.gui.utils.Colors;
import net.minecraft.client.audio.PositionedSoundRecord;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EnumPlayerModelParts;
import net.minecraft.init.MobEffects;
import net.minecraft.init.SoundEvents;
import net.minecraft.potion.Potion;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.util.Dimension;
import org.lwjgl.util.ReadableDimension;
@@ -37,21 +41,22 @@ public class PlayerOverviewGui extends GuiScreen implements Closeable {
public final GuiVerticalList playersScrollable = new GuiVerticalList(contentPanel)
.setDrawSlider(true).setDrawShadow(true);
public final GuiCheckbox saveCheckbox = new GuiCheckbox(contentPanel)
.setTooltip(new GuiTooltip().setI18nText("replaymod.gui.playeroverview.remembersettings.description"))
.setI18nLabel("replaymod.gui.playeroverview.remembersettings");
public final GuiCheckbox checkAll = new GuiCheckbox(contentPanel){
@Override
public void onClick() {
getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.getMasterRecord(SoundEvents.UI_BUTTON_CLICK, 1.0F));
getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.create(BUTTON_SOUND, 1.0F));
playersScrollable.forEach(IGuiCheckbox.class).setChecked(true);
}
}.setLabel("").setChecked(true);
}.setLabel("").setChecked(true).setTooltip(new GuiTooltip().setI18nText("replaymod.gui.playeroverview.showall"));
public final GuiCheckbox uncheckAll = new GuiCheckbox(contentPanel){
@Override
public void onClick() {
getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.getMasterRecord(SoundEvents.UI_BUTTON_CLICK, 1.0F));
getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.create(BUTTON_SOUND, 1.0F));
playersScrollable.forEach(IGuiCheckbox.class).setChecked(false);
}
}.setLabel("").setChecked(false);
}.setLabel("").setChecked(false).setTooltip(new GuiTooltip().setI18nText("replaymod.gui.playeroverview.hideall"));
{
setBackground(Background.NONE);
@@ -91,7 +96,7 @@ public class PlayerOverviewGui extends GuiScreen implements Closeable {
public void draw(GuiRenderer renderer, ReadableDimension size, RenderInfo renderInfo) {
renderer.bindTexture(texture);
renderer.drawTexturedRect(0, 0, 8, 8, 16, 16, 8, 8, 64, 64);
if (p.isWearing(EnumPlayerModelParts.HAT)) {
if (p.func_175148_a(EnumPlayerModelParts.HAT)) {
renderer.drawTexturedRect(0, 0, 40, 8, size.getWidth(), size.getHeight(), 8, 8, 64, 64);
}
}
@@ -140,7 +145,7 @@ public class PlayerOverviewGui extends GuiScreen implements Closeable {
}
private static boolean isSpectator(EntityPlayer e) {
return e.isInvisible() && e.getActivePotionEffect(MobEffects.INVISIBILITY) == null;
return e.isInvisible() && e.getActivePotionEffect(Potion.invisibility) == null;
}
private static final class PlayerComparator implements Comparator<EntityPlayer> {

View File

@@ -1,20 +0,0 @@
package com.replaymod.extras.playeroverview;
import net.minecraft.client.entity.AbstractClientPlayer;
import net.minecraft.client.renderer.culling.ICamera;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.entity.RenderPlayer;
public class PlayerRenderHook extends RenderPlayer {
private final PlayerOverview extra;
public PlayerRenderHook(PlayerOverview extra, RenderManager renderManager, boolean useSmallArms) {
super(renderManager, useSmallArms);
this.extra = extra;
}
@Override
public boolean shouldRender(AbstractClientPlayer entity, ICamera camera, double camX, double camY, double camZ) {
return !extra.isHidden(entity.getUniqueID()) && super.shouldRender(entity, camera, camX, camY, camZ);
}
}

View File

@@ -0,0 +1,40 @@
package com.replaymod.extras.playeroverview.mixin;
import com.replaymod.extras.ReplayModExtras;
import com.replaymod.extras.playeroverview.PlayerOverview;
import net.minecraft.client.renderer.culling.ICamera;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
/**
* This mixin prevents players that are hidden in the PlayerOverview from being rendered.
*
* Cancelling the RenderPlayerEvent.Pre is insufficient because it affects neither the shadows nor the fire texture.
* See: https://github.com/MinecraftForge/MinecraftForge/issues/2987
*
* The previous solution was to overwrite the RenderPlayer instances which has been dropped in favor of this one
* because it is less compatible with other mods whereas this one should be fine as long as no other mod completely
* overwrites the shouldRender method.
* One example of the previous solution breaking is when used with VanillaEnhancements because it replaces the
* RenderManager with a new custom one which in turn will reset our registered RenderPlayer instances because
* it does so after we have already registered with the old RenderManager.
*/
@Mixin(value = Render.class, priority = 1200)
public abstract class MixinRender {
@Inject(method = "shouldRender", at=@At("HEAD"), cancellable = true)
public void replayModExtras_isPlayerHidden(Entity entity, ICamera camera, double camX, double camY, double camZ, CallbackInfoReturnable<Boolean> ci) {
ReplayModExtras.instance.get(PlayerOverview.class).ifPresent(playerOverview -> {
if (entity instanceof EntityPlayer) {
EntityPlayer player = (EntityPlayer) entity;
if (playerOverview.isHidden(player.getUniqueID())) {
ci.setReturnValue(false);
}
}
});
}
}

View File

@@ -25,6 +25,7 @@ public class LinuxUriScheme extends UriScheme {
"Icon=" + iconFile.getAbsolutePath().replace("\\", "\\\\").replace("\"", "\\\"") + "\n" +
"Type=Application\n" +
"Terminal=false\n" +
"NoDisplay=true\n" +
"MimeType=x-scheme-handler/replaymod;";
FileOutputStream out = new FileOutputStream(file);

View File

@@ -17,8 +17,8 @@ public class YoutubeUpload implements Extra {
@SubscribeEvent
public void onGuiOpen(GuiScreenEvent.InitGuiEvent.Post event) {
if (GuiScreen.from(event.getGui()) instanceof GuiRenderingDone) {
GuiRenderingDone gui = (GuiRenderingDone) GuiScreen.from(event.getGui());
if (GuiScreen.from(event.gui) instanceof GuiRenderingDone) {
GuiRenderingDone gui = (GuiRenderingDone) GuiScreen.from(event.gui);
// Check if there already is a youtube button
if (gui.actionsPanel.getChildren().stream().anyMatch(it -> it instanceof YoutubeButton)) {
return; // Button already added

View File

@@ -36,6 +36,8 @@ import java.security.GeneralSecurityException;
import java.util.Collections;
import java.util.concurrent.atomic.AtomicBoolean;
import static com.replaymod.extras.ReplayModExtras.LOGGER;
public class YoutubeUploader {
private static final String CLIENT_ID = "743126594724-mfe7pj1k7e47uu5pk4503c8st9vj9ibu.apps.googleusercontent.com";
private static final String CLIENT_SECRET = "gMwcy3mRYCRamCIjJIYP7rqc";
@@ -137,7 +139,7 @@ public class YoutubeUploader {
CommandLine commandLine = new CommandLine(settings.getExportCommand());
commandLine.addArguments(args);
System.out.println("Re-encoding for ODS with " + settings.getExportCommand() + args);
LOGGER.info("Re-encoding for ODS with {} {}", settings.getExportCommand(), args);
Process process = new ProcessBuilder(commandLine.toStrings()).directory(videoFile.getParentFile()).start();
final AtomicBoolean active = new AtomicBoolean(true);
@@ -149,7 +151,7 @@ public class YoutubeUploader {
char c = (char) in.read();
if (c == '\r') {
String str = sb.toString();
System.out.println(str);
LOGGER.debug("[FFmpeg] {}", str);
if (str.startsWith("frame=")) {
str = str.substring(6).trim();
str = str.substring(0, str.indexOf(' '));

View File

@@ -12,8 +12,8 @@ import com.replaymod.replaystudio.replay.ReplayFile;
import com.replaymod.replaystudio.replay.ZipReplayFile;
import com.replaymod.replaystudio.studio.ReplayStudio;
import de.johni0702.minecraft.gui.container.GuiScreen;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.config.Configuration;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
@@ -29,6 +29,8 @@ import static net.minecraft.client.Minecraft.getMinecraft;
@Mod(modid = ReplayModOnline.MOD_ID,
version = "@MOD_VERSION@",
acceptedMinecraftVersions = "@MC_VERSION@",
acceptableRemoteVersions = "*",
clientSideOnly = true,
useMetadata = true)
public class ReplayModOnline {
public static final String MOD_ID = "replaymod-online";
@@ -40,7 +42,7 @@ public class ReplayModOnline {
private ReplayModReplay replayModule;
private Logger logger;
public static Logger LOGGER;
private ApiClient apiClient;
@@ -53,7 +55,7 @@ public class ReplayModOnline {
@Mod.EventHandler
public void preInit(FMLPreInitializationEvent event) {
logger = event.getModLog();
LOGGER = event.getModLog();
core = ReplayMod.instance;
replayModule = ReplayModReplay.instance;
@@ -69,12 +71,12 @@ public class ReplayModOnline {
public void init(FMLInitializationEvent event) {
if (!getDownloadsFolder().exists()){
if (!getDownloadsFolder().mkdirs()) {
logger.warn("Failed to create downloads folder: " + getDownloadsFolder());
LOGGER.warn("Failed to create downloads folder: " + getDownloadsFolder());
}
}
new GuiHandler(this).register();
MinecraftForge.EVENT_BUS.register(this);
FMLCommonHandler.instance().bus().register(this);
}
@Mod.EventHandler
@@ -82,7 +84,10 @@ public class ReplayModOnline {
// Initial login prompt
if (!core.getSettingsRegistry().get(Setting.SKIP_LOGIN_PROMPT)) {
if (!isLoggedIn()) {
new GuiLoginPrompt(apiClient, null, null, false).display();
core.runLater(() -> {
GuiScreen parent = GuiScreen.wrap(getMinecraft().currentScreen);
new GuiLoginPrompt(apiClient, parent, parent, false).display();
});
}
}
}
@@ -96,7 +101,7 @@ public class ReplayModOnline {
}
public Logger getLogger() {
return logger;
return LOGGER;
}
public ApiClient getApiClient() {

View File

@@ -2,8 +2,7 @@ package com.replaymod.online.api.replay.holders;
public enum MinecraftVersion {
MC_1_8("Minecraft 1.8", "1.8"),
MC_1_9_4("Minecraft 1.9.4", "1.9.4");
MC_1_8("Minecraft 1.8", "1.8");
private String niceName, apiName;

View File

@@ -21,7 +21,7 @@ public class GuiLoginPrompt extends AbstractGuiScreen<GuiLoginPrompt> {
private GuiLabel noAccountLabel = new GuiLabel(this).setI18nText("replaymod.gui.login.noacc");
private GuiLabel statusLabel = new GuiLabel(this);
private GuiButton loginButton = new GuiButton(this).setI18nLabel("replaymod.gui.login").setSize(150, 20).setEnabled(false);
private GuiButton cancelButton = new GuiButton(this).setI18nLabel("replaymod.gui.cancel").setSize(150, 20);
public GuiButton cancelButton = new GuiButton(this).setI18nLabel("replaymod.gui.cancel").setSize(150, 20);
private GuiButton registerButton = new GuiButton(this).setI18nLabel("replaymod.gui.register").setSize(150, 20);
private GuiTextField username = new GuiTextField(this).setSize(145, 20).setMaxLength(16).setFocused(true);
private GuiPasswordField password = new GuiPasswordField(this).setSize(145, 20)

View File

@@ -110,7 +110,7 @@ public class GuiRegister extends AbstractGuiScreen<GuiRegister> {
@Override
public void run() {
String status = null;
if (usernameInput.getText().length() < 5) {
if (usernameInput.getText().length() < 1) {
status = "replaymod.gui.register.error.shortusername";
} else if(!Patterns.ALPHANUMERIC_UNDERSCORE.matcher(usernameInput.getText().trim()).matches()) {
status = "replaymod.gui.register.error.invalidname";

View File

@@ -28,6 +28,7 @@ import de.johni0702.minecraft.gui.container.GuiScreen;
import de.johni0702.minecraft.gui.element.GuiButton;
import de.johni0702.minecraft.gui.element.GuiImage;
import de.johni0702.minecraft.gui.element.GuiLabel;
import de.johni0702.minecraft.gui.element.GuiTooltip;
import de.johni0702.minecraft.gui.element.IGuiButton;
import de.johni0702.minecraft.gui.element.advanced.GuiResourceLoadingList;
import de.johni0702.minecraft.gui.layout.CustomLayout;
@@ -36,8 +37,6 @@ import de.johni0702.minecraft.gui.layout.VerticalLayout;
import de.johni0702.minecraft.gui.popup.GuiYesNoPopup;
import de.johni0702.minecraft.gui.utils.Colors;
import de.johni0702.minecraft.gui.utils.Consumer;
import net.minecraftforge.fml.common.FMLLog;
import org.apache.commons.io.FilenameUtils;
import org.apache.logging.log4j.core.helpers.Strings;
import org.lwjgl.util.Dimension;
import org.lwjgl.util.ReadableDimension;
@@ -50,6 +49,8 @@ import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import static com.replaymod.online.ReplayModOnline.LOGGER;
public class GuiReplayCenter extends GuiScreen {
private final ReplayModOnline mod;
private final ApiClient apiClient;
@@ -109,6 +110,7 @@ public class GuiReplayCenter extends GuiScreen {
public void run() {
GuiReplayEntry selected = list.getSelected();
replayButtonPanel.forEach(IGuiButton.class).setEnabled(selected != null);
replayButtonPanel.forEach(IGuiButton.class).setTooltip(null);
if (selected != null) {
int replayId = selected.fileInfo.getId();
boolean favorited = favoritedReplays.contains(replayId);
@@ -123,10 +125,22 @@ public class GuiReplayCenter extends GuiScreen {
favoriteButton.setI18nLabel("replaymod.gui.center." + (favorited ? "unfavorite" : "favorite"));
// Only allow button usage for either unfavorite or favorite after they've actually downloaded it
favoriteButton.setEnabled(favorited || selected.downloaded);
if (favoriteButton.isEnabled()) {
favoriteButton.setTooltip(null);
} else {
favoriteButton.setTooltip(new GuiTooltip().setI18nText("replaymod.gui.center.downloadrequired"));
}
// Similar for like/dislike buttons
likeButton.setEnabled(selected.downloaded);
dislikeButton.setEnabled(selected.downloaded);
if (likeButton.isEnabled()) {
likeButton.setTooltip(null);
dislikeButton.setTooltip(null);
} else {
likeButton.setTooltip(new GuiTooltip().setI18nText("replaymod.gui.center.downloadrequired"));
dislikeButton.setTooltip(new GuiTooltip().setI18nText("replaymod.gui.center.downloadrequired"));
}
likeButton.setI18nLabel("replaymod.gui." + (liked ? "removelike" : "like"));
dislikeButton.setI18nLabel("replaymod.gui." + (disliked ? "removedislike" : "dislike"));
}
@@ -322,7 +336,7 @@ public class GuiReplayCenter extends GuiScreen {
}
});
} catch (Exception e) {
FMLLog.getLogger().error("Could not load Replay File " + fileInfo.getId(), e);
LOGGER.error("Could not load Replay File {}", fileInfo.getId(), e);
}
}
}
@@ -403,7 +417,7 @@ public class GuiReplayCenter extends GuiScreen {
this.downloaded = downloaded;
ReplayMetaData metaData = fileInfo.getMetadata();
name.setText(ChatFormatting.UNDERLINE + FilenameUtils.getBaseName(fileInfo.getName()));
name.setText(ChatFormatting.UNDERLINE + Utils.fileNameToReplayName(fileInfo.getName()));
author.setI18nText("replaymod.gui.center.author",
"" + ChatFormatting.GRAY + ChatFormatting.ITALIC, fileInfo.getOwner());
if (Strings.isEmpty(metaData.getServerName())) {

View File

@@ -2,6 +2,7 @@ package com.replaymod.online.gui;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.replaymod.core.utils.Utils;
import de.johni0702.minecraft.gui.container.GuiPanel;
import de.johni0702.minecraft.gui.container.GuiScreen;
import de.johni0702.minecraft.gui.element.GuiButton;
@@ -27,7 +28,7 @@ public class GuiSaveModifiedReplay extends GuiScreen {
@Override
public void run() {
String resultName = name.getText().trim().replace("[^a-zA-Z0-9\\.\\- ]", "_");
final File resultFile = new File(file.getParentFile(), resultName + ".mcpr");
final File resultFile = new File(file.getParentFile(), Utils.replayNameToFileName(resultName));
if (resultFile.exists()) {
Futures.addCallback(GuiYesNoPopup.open(GuiSaveModifiedReplay.this,
new GuiLabel().setI18nText("replaymod.gui.replaymodified.warning1", resultName).setColor(Colors.BLACK),

View File

@@ -17,7 +17,12 @@ import com.replaymod.replaystudio.studio.ReplayStudio;
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.*;
import de.johni0702.minecraft.gui.element.GuiButton;
import de.johni0702.minecraft.gui.element.GuiCheckbox;
import de.johni0702.minecraft.gui.element.GuiImage;
import de.johni0702.minecraft.gui.element.GuiLabel;
import de.johni0702.minecraft.gui.element.GuiTextField;
import de.johni0702.minecraft.gui.element.GuiTooltip;
import de.johni0702.minecraft.gui.element.advanced.GuiDropdownMenu;
import de.johni0702.minecraft.gui.element.advanced.GuiProgressBar;
import de.johni0702.minecraft.gui.element.advanced.GuiTextArea;
@@ -33,7 +38,6 @@ import net.minecraft.client.settings.KeyBinding;
import net.minecraft.crash.CrashReport;
import net.minecraft.util.ReportedException;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import javax.annotation.Nullable;
@@ -130,7 +134,7 @@ public class GuiUploadReplay extends GuiScreen {
}
// Apply to gui
name.setText(FilenameUtils.getBaseName(file.getName()));
name.setText(Utils.fileNameToReplayName(file.getName()));
int secs = metaData.getDuration() / 1000;
durationLabel.setI18nText("replaymod.gui.upload.duration", secs / 60, secs % 60);
hideServerIP.setEnabled(!metaData.isSingleplayer());
@@ -234,6 +238,8 @@ public class GuiUploadReplay extends GuiScreen {
});
validateInputs();
name.onTextChanged(s -> validateInputs());
tags.onTextChanged(s -> validateInputs());
}
public void validateInputs() {

View File

@@ -14,9 +14,11 @@ import net.minecraft.client.gui.GuiMainMenu;
import net.minecraft.client.resources.I18n;
import net.minecraftforge.client.event.GuiScreenEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import java.io.File;
import java.util.List;
public class GuiHandler {
private static final int BUTTON_REPLAY_CENTER = 17890236;
@@ -28,23 +30,26 @@ public class GuiHandler {
}
public void register() {
FMLCommonHandler.instance().bus().register(this);
MinecraftForge.EVENT_BUS.register(this);
}
@SubscribeEvent
public void injectIntoMainMenu(GuiScreenEvent.InitGuiEvent event) {
if (!(event.getGui() instanceof GuiMainMenu)) {
if (!(event.gui instanceof GuiMainMenu)) {
return;
}
GuiButton button = new GuiButton(BUTTON_REPLAY_CENTER, event.getGui().width / 2 - 100,
event.getGui().height / 4 + 10 + 4 * 24, I18n.format("replaymod.gui.replaycenter"));
event.getButtonList().add(button);
@SuppressWarnings("unchecked")
List<GuiButton> buttonList = event.buttonList;
GuiButton button = new GuiButton(BUTTON_REPLAY_CENTER, event.gui.width / 2 - 100,
event.gui.height / 4 + 10 + 4 * 24, I18n.format("replaymod.gui.replaycenter"));
buttonList.add(button);
}
@SubscribeEvent
public void injectIntoReplayViewer(GuiScreenEvent.InitGuiEvent.Post event) {
AbstractGuiScreen guiScreen = GuiScreen.from(event.getGui());
AbstractGuiScreen guiScreen = GuiScreen.from(event.gui);
if (!(guiScreen instanceof GuiReplayViewer)) {
return;
}
@@ -70,15 +75,15 @@ public class GuiHandler {
@SubscribeEvent
public void onButton(GuiScreenEvent.ActionPerformedEvent.Pre event) {
if(!event.getButton().enabled) return;
if(!event.button.enabled) return;
if (event.getGui() instanceof GuiMainMenu) {
if (event.getButton().id == BUTTON_REPLAY_CENTER) {
if (event.gui instanceof GuiMainMenu) {
if (event.button.id == BUTTON_REPLAY_CENTER) {
GuiReplayCenter replayCenter = new GuiReplayCenter(mod);
if (mod.isLoggedIn()) {
replayCenter.display();
} else {
new GuiLoginPrompt(mod.getApiClient(), GuiScreen.wrap(event.getGui()), replayCenter, true).display();
new GuiLoginPrompt(mod.getApiClient(), GuiScreen.wrap(event.gui), replayCenter, true).display();
}
}
}

View File

@@ -4,6 +4,7 @@ import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.SettableFuture;
import com.replaymod.core.ReplayMod;
import com.replaymod.core.utils.Utils;
import com.replaymod.replay.ReplayModReplay;
import com.replaymod.replaystudio.pathing.PathingRegistry;
import com.replaymod.replaystudio.pathing.path.Path;
@@ -11,7 +12,11 @@ import com.replaymod.replaystudio.pathing.path.Timeline;
import com.replaymod.replaystudio.replay.ReplayFile;
import de.johni0702.minecraft.gui.GuiRenderer;
import de.johni0702.minecraft.gui.RenderInfo;
import de.johni0702.minecraft.gui.container.*;
import de.johni0702.minecraft.gui.container.AbstractGuiClickableContainer;
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.container.GuiVerticalList;
import de.johni0702.minecraft.gui.element.GuiButton;
import de.johni0702.minecraft.gui.element.GuiLabel;
import de.johni0702.minecraft.gui.element.GuiTextField;
@@ -41,9 +46,16 @@ public class GuiKeyframeRepository extends GuiScreen implements Closeable {
public final GuiButton overwriteButton = new GuiButton(buttonPanel).onClick(new Runnable() {
@Override
public void run() {
timelines.put(selectedEntry.name, currentTimeline);
overwriteButton.setDisabled();
save();
GuiYesNoPopup popup = GuiYesNoPopup.open(GuiKeyframeRepository.this,
new GuiLabel().setI18nText("replaymod.gui.keyframerepo.overwrite").setColor(Colors.BLACK)
).setYesI18nLabel("gui.yes").setNoI18nLabel("gui.no");
Utils.addCallback(popup.getFuture(), doIt -> {
if (doIt) {
timelines.put(selectedEntry.name, currentTimeline);
overwriteButton.setDisabled();
save();
}
}, Throwable::printStackTrace);
}
}).setSize(75, 20).setI18nLabel("replaymod.gui.overwrite").setDisabled();
public final GuiButton saveAsButton = new GuiButton(buttonPanel).onClick(new Runnable() {

View File

@@ -11,7 +11,7 @@ import com.replaymod.replaystudio.pathing.path.Keyframe;
import com.replaymod.replaystudio.pathing.path.Path;
import com.replaymod.replaystudio.pathing.path.Timeline;
import net.minecraft.client.Minecraft;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import javax.annotation.Nullable;
@@ -65,7 +65,7 @@ public abstract class AbstractTimelinePlayer {
}
replayHandler.getReplaySender().setSyncModeAndWait();
MinecraftForge.EVENT_BUS.register(this);
FMLCommonHandler.instance().bus().register(this);
lastTime = 0;
mc.timer = new ReplayTimer(mc.timer);
mc.timer.timerSpeed = 1;
@@ -87,7 +87,7 @@ public abstract class AbstractTimelinePlayer {
mc.timer = ((ReplayTimer) mc.timer).getWrapped();
replayHandler.getReplaySender().setReplaySpeed(0);
replayHandler.getReplaySender().setAsyncMode(true);
MinecraftForge.EVENT_BUS.unregister(this);
FMLCommonHandler.instance().bus().unregister(this);
return;
}
long time = getTimePassed();

View File

@@ -2,7 +2,7 @@ package com.replaymod.pathing.player;
import com.replaymod.core.utils.WrappedTimer;
import net.minecraft.util.Timer;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.common.eventhandler.Event;
/**
@@ -20,7 +20,7 @@ public class ReplayTimer extends WrappedTimer {
copy(this, state); // Save our current state
super.updateTimer(); // Update current state
copy(state, this); // Restore our old state
MinecraftForge.EVENT_BUS.post(new UpdatedEvent());
FMLCommonHandler.instance().bus().post(new UpdatedEvent());
}
public Timer getWrapped() {

View File

@@ -3,9 +3,12 @@ package com.replaymod.recording;
import com.replaymod.core.ReplayMod;
import com.replaymod.core.utils.Restrictions;
import com.replaymod.recording.handler.ConnectionEventHandler;
import com.replaymod.recording.handler.GuiHandler;
import com.replaymod.recording.packet.PacketListener;
import net.minecraftforge.common.MinecraftForge;
import io.netty.channel.ChannelDuplexHandler;
import io.netty.channel.ChannelHandler;
import net.minecraft.network.NetworkManager;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
@@ -17,6 +20,8 @@ import org.lwjgl.input.Keyboard;
@Mod(modid = ReplayModRecording.MOD_ID,
version = "@MOD_VERSION@",
acceptedMinecraftVersions = "@MC_VERSION@",
acceptableRemoteVersions = "*",
clientSideOnly = true,
useMetadata = true)
public class ReplayModRecording {
public static final String MOD_ID = "replaymod-recording";
@@ -51,12 +56,17 @@ public class ReplayModRecording {
@Mod.EventHandler
public void init(FMLInitializationEvent event) {
EventBus bus = MinecraftForge.EVENT_BUS;
EventBus bus = FMLCommonHandler.instance().bus();
bus.register(connectionEventHandler = new ConnectionEventHandler(logger, core));
NetworkRegistry.INSTANCE.newSimpleChannel(Restrictions.PLUGIN_CHANNEL);
new GuiHandler(core).register();
NetworkRegistry.INSTANCE.newChannel(Restrictions.PLUGIN_CHANNEL, new RestrictionsChannelHandler());
}
@ChannelHandler.Sharable
private static class RestrictionsChannelHandler extends ChannelDuplexHandler {}
public void initiateRecording(NetworkManager networkManager) {
connectionEventHandler.onConnectedToServerEvent(networkManager);
}

View File

@@ -40,7 +40,7 @@ public class GuiRecordingOverlay {
*/
@SubscribeEvent
public void renderRecordingIndicator(RenderGameOverlayEvent.Post event) {
if (event.getType() != RenderGameOverlayEvent.ElementType.ALL) return;
if (event.type != RenderGameOverlayEvent.ElementType.ALL) return;
if (settingsRegistry.get(Setting.INDICATOR)) {
FontRenderer fontRenderer = mc.fontRendererObj;
fontRenderer.drawString(I18n.format("replaymod.gui.recording").toUpperCase(), 30, 18 - (fontRenderer.FONT_HEIGHT / 2), 0xffffffff);

Some files were not shown because too many files have changed in this diff Show More