Compare commits

...

102 Commits

Author SHA1 Message Date
Jonas Herzig
ed6e11f106 Merge branch '1.9.4-dev' into 1.10.2-dev 2018-01-19 13:06:15 +01:00
Jonas Herzig
178c6b21a1 Fix member info of WorldClient.playSound mixin 2018-01-19 13:00:44 +01:00
Jonas Herzig
2dce4eb54a Merge branch '1.9.4-dev' into 1.10.2-dev 2018-01-16 22:31:31 +01:00
Jonas Herzig
0ed9a5533e Merge branch '1.10.2-reprod' into 1.10.2-dev 2018-01-16 22:28:17 +01:00
Jonas Herzig
c148076a40 Merge branch '1.8.9-dev' into 1.9.4-dev 2018-01-16 22:22:05 +01:00
Jonas Herzig
e11f8f9e9d Merge branch '1.9.4-reprod' into 1.9.4-dev 2018-01-16 21:56:01 +01:00
Jonas Herzig
604d33d846 Merge branch '1.8-dev' into 1.8.9-dev 2018-01-16 21:52:50 +01:00
Jonas Herzig
ea2427a73c Create screenshot folder it it does not yet exist 2018-01-16 21:52:05 +01:00
Jonas Herzig
1ca91d7ee9 Merge branch '1.8.9-reprod' into 1.8.9-dev 2018-01-16 21:04:12 +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
fd7da227a0 Update reprod to 1.10.2 2017-10-28 17:42:58 +02:00
Jonas Herzig
701e8e8bba Merge branch '1.10.2-dev' into 1.10.2-reprod 2017-10-28 17:26:43 +02:00
Jonas Herzig
4ea0da3fe6 Update reprod to 1.9.4 2017-10-28 17:18:57 +02:00
Jonas Herzig
4f413e34fc Merge branch '1.9.4-dev' into 1.9.4-reprod 2017-10-28 16:15:38 +02:00
Jonas Herzig
45cc789add Update reprod to 1.8.9 2017-10-28 15:52:49 +02:00
Jonas Herzig
24e1f7b9fb Merge branch '1.8.9-dev' into 1.8.9-reprod 2017-10-28 15:27:41 +02: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
b8b4f167ef Merge branch 1.9.4-dev into 1.10.2-dev
263e080 Merge branch 1.8.9-dev into 1.9.4-dev
8fad02c Merge branch 1.8-dev into 1.8.9-dev
1c888aa Add minVersion to mixin configs and bump bundled mixin version
10ce71e Fix mapwriter crash when opening replay for <MC1.12 (fixes #96)
5fb1cf3 Fix half-despawned player entities (see #93) when the entity is moved greater distances
adfe6a2 Fix NPE when spectated non-player entity despawns (fixes #94)
b27af27 Fix player entities being half-despawned after jumping in time (fixes #93)
2017-10-28 11:35:58 +02:00
Jonas Herzig
263e080401 Merge branch 1.8.9-dev into 1.9.4-dev
8fad02c Merge branch 1.8-dev into 1.8.9-dev
1c888aa Add minVersion to mixin configs and bump bundled mixin version
10ce71e Fix mapwriter crash when opening replay for <MC1.12 (fixes #96)
5fb1cf3 Fix half-despawned player entities (see #93) when the entity is moved greater distances
adfe6a2 Fix NPE when spectated non-player entity despawns (fixes #94)
b27af27 Fix player entities being half-despawned after jumping in time (fixes #93)
2017-10-28 11:24:47 +02:00
Jonas Herzig
8fad02cae7 Merge branch 1.8-dev into 1.8.9-dev
1c888aa Add minVersion to mixin configs and bump bundled mixin version
10ce71e Fix mapwriter crash when opening replay for <MC1.12 (fixes #96)
5fb1cf3 Fix half-despawned player entities (see #93) when the entity is moved greater distances
adfe6a2 Fix NPE when spectated non-player entity despawns (fixes #94)
b27af27 Fix player entities being half-despawned after jumping in time (fixes #93)
2017-10-28 11:12:22 +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
689f897930 Merge branch 1.9.4 into 1.10.2
0aed9c3 Merge branch 1.8.9 into 1.9.4
f36ebf1 Merge branch 1.8 into 1.8.9
08170b3 Downgrade FG to 2.1 because FG 2.2 is 1.9+ only
41d2547 Update translations
00e999f Fix replay not being closed when opened via URI scheme handler (fixes #92)
767ea29 Fix book gui not being suppressed during replay (fixes #90)
5b04edb Hide ReplayMod app entry from menus on Linux
6aff99d Fix livelock during netty write to embedded channel (fixes #85)
703805f Fix infinite loop in mc.scheduledTasks (fixes #86)
7a4440c Update ReplayStudio
0b9c56c Fix resource packs not working after first time jumping back in time
933ee5f [Compat] Fix camera entity with BetterSprinting prior to 2.0.0 (fixes #78)
83b1090 Fix hotbar being visible while spectating player (fixes #83)
5c73117 [Compat] Fix invisible entities with Orange's 1.7 Animations (fixes #78)
4704b29 Replace the RenderPlayer hook (used subclassing) with a mixin (fixes #79)
0c226b0 Fix path at end of replay resulting in constant reloading (fixes #56)
1b9b13e Rename render success sound to all lowercase (required for 1.11) (fixes #66)
c2000b3 Fix only front-facing chunks visible for ODS rendering (fixes #67)
aafeecc Fix initial login gui not closing on success (fixes #68)
9292add Use percent-encoding for replay file names (fixes #71)
8499c0f Fix name of invis armor stand with CustomNameVisible not rendering (fixes #72)
b9ea572 Try to handle invalid ffmpeg arguments more gracefully (fixes #77)
a2f8c88 Fix compression packets being recorded (fixes #80)
19629c3 Replace usages of System.out with logger
fe1d9b8 Stop Forge from allowing the mod to load on other MC versions (fixes #82)
1a1e96c Fix server with RM installed refusing clients without RM (fixes #76)
35eb9ca Replace usage of FMLLog with the mod logger
2017-08-26 14:17:14 +02:00
Jonas Herzig
0aed9c3c17 Merge branch 1.8.9 into 1.9.4
f36ebf1 Merge branch 1.8 into 1.8.9
08170b3 Downgrade FG to 2.1 because FG 2.2 is 1.9+ only
41d2547 Update translations
00e999f Fix replay not being closed when opened via URI scheme handler (fixes #92)
767ea29 Fix book gui not being suppressed during replay (fixes #90)
5b04edb Hide ReplayMod app entry from menus on Linux
6aff99d Fix livelock during netty write to embedded channel (fixes #85)
703805f Fix infinite loop in mc.scheduledTasks (fixes #86)
7a4440c Update ReplayStudio
0b9c56c Fix resource packs not working after first time jumping back in time
933ee5f [Compat] Fix camera entity with BetterSprinting prior to 2.0.0 (fixes #78)
83b1090 Fix hotbar being visible while spectating player (fixes #83)
5c73117 [Compat] Fix invisible entities with Orange's 1.7 Animations (fixes #78)
4704b29 Replace the RenderPlayer hook (used subclassing) with a mixin (fixes #79)
0c226b0 Fix path at end of replay resulting in constant reloading (fixes #56)
1b9b13e Rename render success sound to all lowercase (required for 1.11) (fixes #66)
c2000b3 Fix only front-facing chunks visible for ODS rendering (fixes #67)
aafeecc Fix initial login gui not closing on success (fixes #68)
9292add Use percent-encoding for replay file names (fixes #71)
8499c0f Fix name of invis armor stand with CustomNameVisible not rendering (fixes #72)
b9ea572 Try to handle invalid ffmpeg arguments more gracefully (fixes #77)
a2f8c88 Fix compression packets being recorded (fixes #80)
19629c3 Replace usages of System.out with logger
fe1d9b8 Stop Forge from allowing the mod to load on other MC versions (fixes #82)
1a1e96c Fix server with RM installed refusing clients without RM (fixes #76)
35eb9ca Replace usage of FMLLog with the mod logger
2017-08-26 14:16:08 +02:00
Jonas Herzig
f36ebf1d0a Merge branch 1.8 into 1.8.9
41d2547 Update translations
00e999f Fix replay not being closed when opened via URI scheme handler (fixes #92)
767ea29 Fix book gui not being suppressed during replay (fixes #90)
5b04edb Hide ReplayMod app entry from menus on Linux
6aff99d Fix livelock during netty write to embedded channel (fixes #85)
703805f Fix infinite loop in mc.scheduledTasks (fixes #86)
7a4440c Update ReplayStudio
0b9c56c Fix resource packs not working after first time jumping back in time
933ee5f [Compat] Fix camera entity with BetterSprinting prior to 2.0.0 (fixes #78)
83b1090 Fix hotbar being visible while spectating player (fixes #83)
5c73117 [Compat] Fix invisible entities with Orange's 1.7 Animations (fixes #78)
4704b29 Replace the RenderPlayer hook (used subclassing) with a mixin (fixes #79)
0c226b0 Fix path at end of replay resulting in constant reloading (fixes #56)
1b9b13e Rename render success sound to all lowercase (required for 1.11) (fixes #66)
c2000b3 Fix only front-facing chunks visible for ODS rendering (fixes #67)
aafeecc Fix initial login gui not closing on success (fixes #68)
9292add Use percent-encoding for replay file names (fixes #71)
8499c0f Fix name of invis armor stand with CustomNameVisible not rendering (fixes #72)
b9ea572 Try to handle invalid ffmpeg arguments more gracefully (fixes #77)
a2f8c88 Fix compression packets being recorded (fixes #80)
19629c3 Replace usages of System.out with logger
fe1d9b8 Stop Forge from allowing the mod to load on other MC versions (fixes #82)
1a1e96c Fix server with RM installed refusing clients without RM (fixes #76)
35eb9ca Replace usage of FMLLog with the mod logger
2017-08-26 13:37:59 +02:00
Jonas Herzig
08170b38ef Downgrade FG to 2.1 because FG 2.2 is 1.9+ only 2017-08-26 13:35:14 +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
7c719e03cc Update ReplayStudio/MCProtocolLib (Fixes missing ARMOR_STAND MobType) 2017-07-27 15:20:34 +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
97 changed files with 2931 additions and 213 deletions

View File

@@ -6,8 +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
- ./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.cGlwZWxpbmU6CiAgY2xvbmU6CiAgICBpbWFnZTogcGx1Z2lucy9naXQKICAgIHRhZ3M6IHRydWUKICBidWlsZDoKICAgIGltYWdlOiBtYXZlbjozLjMuOS1qZGstOAogICAgY29tbWFuZHM6CiAgICAgIC0gY3VybCAtLWZhaWwgLS1jcmVhdGUtZGlycyAtbyAkSE9NRS8uZ3JhZGxlL2luaXQuZC9taXJyb3IuZ3JhZGxlIGh0dHBzOi8vbWF2ZW4uam9obmkwNzAyLmRlL2NvbmZpZy9ncmFkbGUKICAgICAgLSBjdXJsIC0tZmFpbCAtLWNyZWF0ZS1kaXJzIC1vICRIT01FLy5tMi9zZXR0aW5ncy54bWwgaHR0cHM6Ly9tYXZlbi5qb2huaTA3MDIuZGUvY29uZmlnL21hdmVuCiAgICAgIC0gLi9ncmFkbGV3IDpidWlsZAogIGFyY2hpdmU6CiAgICBpbWFnZTogcGx1Z2lucy9zMwogICAgYWNsOiBwdWJsaWMtcmVhZAogICAgcmVnaW9uOiAidXMtZWFzdC0xIgogICAgYnVja2V0OiAicmVwbGF5bW9kIgogICAgcGF0aF9zdHlsZTogdHJ1ZQogICAgc291cmNlOiBidWlsZC9saWJzLyoKICAgIHN0cmlwX3ByZWZpeDogYnVpbGQvbGlicy8KICAgIHRhcmdldDogLwo.Z6rpaLplJKQ4pzB8AjCnplgci42qEu7L4LeS0fGm4SY
eyJhbGciOiJIUzI1NiJ9.cGlwZWxpbmU6CiAgY2xvbmU6CiAgICBpbWFnZTogcGx1Z2lucy9naXQKICAgIHRhZ3M6IHRydWUKICBidWlsZDoKICAgIGltYWdlOiBtYXZlbjozLjMuOS1qZGstOAogICAgY29tbWFuZHM6CiAgICAgIC0gY3VybCAtLWZhaWwgLS1jcmVhdGUtZGlycyAtbyAkSE9NRS8uZ3JhZGxlL2luaXQuZC9taXJyb3IuZ3JhZGxlIGh0dHBzOi8vbWF2ZW4uam9obmkwNzAyLmRlL2NvbmZpZy9ncmFkbGUKICAgICAgLSBnaXQgY29uZmlnIC0tZ2xvYmFsIHVzZXIuZW1haWwgInJlcGxheW1vZEBkcm9uZSIgJiYgZ2l0IGNvbmZpZyAtLWdsb2JhbCB1c2VyLm5hbWUgIkRyb25lIgogICAgICAtIFNJR05FRF9KQVI9JCghIGdpdCBkZXNjcmliZSAtLWV4YWN0IDI-JjEgPiAvZGV2L251bGw7IGVjaG8gJD8pIFJFUFJPRFVDSUJMRV9CVUlMRD0xIC4vZ3JhZGxldyA6YnVpbGQKICBhcmNoaXZlOgogICAgaW1hZ2U6IHBsdWdpbnMvczMKICAgIGFjbDogcHVibGljLXJlYWQKICAgIHJlZ2lvbjogInVzLWVhc3QtMSIKICAgIGJ1Y2tldDogInJlcGxheW1vZCIKICAgIHBhdGhfc3R5bGU6IHRydWUKICAgIHNvdXJjZTogYnVpbGQvbGlicy8qCiAgICBzdHJpcF9wcmVmaXg6IGJ1aWxkL2xpYnMvCiAgICB0YXJnZXQ6IC8K.cFk9CFCSYjJSwQhcJJp0BqSMwigKYCBd6r-KkvxlQZ0

BIN
.gitignore vendored

Binary file not shown.

4
.gitmodules vendored
View File

@@ -2,10 +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 98bbf92b9d

View File

@@ -38,7 +38,9 @@ minecraft {
runDir = "eclipse"
mappings = "snapshot_20160518"
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 {
@@ -46,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 {
@@ -59,7 +59,7 @@ configurations {
dependencies {
compile 'org.projectlombok:lombok:1.16.4'
compile 'org.spongepowered:mixin:0.6.8-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'
@@ -69,24 +69,20 @@ dependencies {
shade 'org.aspectj:aspectjrt:1.8.2'
compile project(':ReplayStudio')
shade 'com.github.replaymod:ReplayStudio:7d8c2f7'
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")
@@ -107,7 +103,7 @@ jar {
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')
}
}
}
@@ -164,7 +160,7 @@ sourceSets {
resources {
srcDir 'jGui/src/main/resources'
}
refMap = "mixins.replaymod.refmap.json"
ext.refMap = "mixins.replaymod.refmap.json"
}
integrationTest {
compileClasspath += main.runtimeClasspath + main.output

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

@@ -0,0 +1,482 @@
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
259c0b9e7679cefc5fbf9e7fdada3dec5aaeefb28f6f41b09ea22b22809d9765 /com/github/replaymod/ReplayStudio/7d8c2f7/ReplayStudio-7d8c2f7.jar
c1f4e76c40b3cd3b7653b52a5aacbd2ef9561633879c127a5cb86bbe5ac49e7b /com/github/replaymod/ReplayStudio/7d8c2f7/ReplayStudio-7d8c2f7.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
c885ce34249682bc0236b4a7d56efcc12048e6135a5baf7a9cde8ad8cda13fcd /com/google/code/findbugs/jsr305/3.0.1/jsr305-3.0.1.jar
4170a761dc5bfd3981a8e6f7aab9e2acdce82d34fd5aa9bb11e3c090d25314ce /com/google/code/findbugs/jsr305/3.0.1/jsr305-3.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
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
2c149735a093b6c65a27db760896ad5c5b06e29100bb8969937667784fef4ba0 /com/mojang/authlib/1.5.16/authlib-1.5.16.jar
d05175230d79f518b5c4664d24e3d115f5f3888e3806f3b6076cd0b4943e6ca6 /com/mojang/authlib/1.5.16/authlib-1.5.16.pom
dc07988e5bb1609e8e027cc89c2993a19586e219c02ff74ea4298e73e97b0efb /com/mojang/authlib/1.5.22/authlib-1.5.22.jar
3e70bac893bb04ac2992baa6fc438f6fc33c0d0213c4edcc40d295e7938091ca /com/mojang/authlib/1.5.22/authlib-1.5.22.pom
3120fd24c09ab9bc088cb9c1eb2065be86718608450fdbc27b5d371729a619cb /com/mojang/netty/1.6/netty-1.6.jar
568cc3fad81e5e389bad0012a07eca5db073e287200c6c9cb02caf3dc489e9f6 /com/mojang/netty/1.6/netty-1.6.pom
fe558457679bc0734c83a80f579bbe73415d02a83709d19c6d78c011843ca17c /com/mojang/realms/1.9.8/realms-1.9.8.jar
28bcfc79565f33a1b6382f6ae2ed7841f456f088488083e199764de46c99efd6 /com/mojang/realms/1.9.8/realms-1.9.8.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
f2ce9e7cdc3e3598390a495a07cc18aa930a8b9e1480d97bfae31f29e1e75a19 /de/oceanlabs/mcp/mcp/1.10.2/mcp-1.10.2-srg.zip
16f933fe337c265ed20fd616a2acadbd119a0b1d1fb186ca26fc8964aeebe0c2 /de/oceanlabs/mcp/mcp_snapshot/20160518-1.9.4/mcp_snapshot-20160518-1.9.4.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
* /de/oceanlabs/mcp/versions.json
50510e9c9874b539b98ef931fe7eeeb002f6b5b1976ea37669b9493426294561 /io/netty/netty-all/4.0.23.Final/netty-all-4.0.23.Final.jar
990a10af14db6b136d3a539eadca5dc7b4d0ceab9a1c90c5268b0ca8ae27b14b /io/netty/netty-all/4.0.23.Final/netty-all-4.0.23.Final.pom
f7f1bd6f1e1df0b300730f1551b7222f13871e40ba5a464978bd3eed94e2212d /io/netty/netty-parent/4.0.23.Final/netty-parent-4.0.23.Final.pom
b4533f3b4029e480288d85187fc9ee6789f3d362c6633d8e9b092ec455ad2f28 /it/unimi/dsi/fastutil/7.0.12_mojang/fastutil-7.0.12_mojang.jar
2b3db089f1f78a49a628d9015cca6a95e87421fa04262553cd2c4c79d66d04a7 /it/unimi/dsi/fastutil/7.0.12_mojang/fastutil-7.0.12_mojang.pom
09adf7955baa6bddf57a4bdbf9a91cf690261314969b59a18085ece1e05eccf9 /java3d/vecmath/1.5.2/vecmath-1.5.2.jar
a4aee4668f1b127c95c9afe1b922f4c5a0b1ad879ba811077cb7d0e048dce231 /java3d/vecmath/1.5.2/vecmath-1.5.2.pom
a6d2c9c0ddff7702662073b69c6dc4ec83011d22e4eb2dada28aa2d66ee47f97 /jline/jline/2.13/jline-2.13.jar
ba62d78eb858e241a604cdf739594cd312f0572756ea7aba4544c746d7152c43 /jline/jline/2.13/jline-2.13.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
* /mc/game/version_manifest.json
7cdf7fcdc1c92584a233bf3c42bd7f0df1bdad3007d306831fe50410692be1e9 /mc/game/1.10.2/client/dc8e75ac7274ff6af462b0dcec43c307de668e40/client.jar
195f468227c5f9218f3919538b9b16ba34adced67fc7d7b652c508a5e8d07a21 /mc/game/1.10.2/server/3d501b23df53c548254f5e3f66492d178a48db63/server.jar
48841dde28888f147bef0f2656b589427cd1ec6ad355b9434f3bc3038bdb698f /mc/game/1920a2b4e996bae0af1a67d38d63706bac10ac47/1.10.2.json
3bff6a1489b8e54cf130344bc5e8744db331045ad2fc736612576e1d80eb1f48 /net/java/dev/jna/jna/3.4.0/jna-3.4.0.jar
cf4605822bd56d135dd7031603f122a11a0ec772373f466a4f2aac72dd9a1761 /net/java/dev/jna/jna/3.4.0/jna-3.4.0.pom
ea89d5090c8303ba4e9a0056e6d8a20429f3e021411e950bfd9eba3b6e6cf15c /net/java/dev/jna/platform/3.4.0/platform-3.4.0.jar
8f0c14f62912c089d81386015e78cf212f9e96f675b3bc0e519c1e2d92aa8950 /net/java/dev/jna/platform/3.4.0/platform-3.4.0.pom
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
* /net/minecraftforge/forge/json
df07ca74ae02f9879c6e5dd49eac661ddb907e65ba1536694aa0f27932ac9b99 /net/minecraftforge/forge/1.10.2-12.18.2.2099/forge-1.10.2-12.18.2.2099.pom
305dbc9c547d87f650de3b1ded42d48a28533f45c857c9e05f217b61238fc1cb /net/minecraftforge/forge/1.10.2-12.18.2.2099/forge-1.10.2-12.18.2.2099-userdev.jar
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
2082ffb0bb8f276ca164a6363e394f902163a81b7df44ede13aed33d84fdf27e /org/eclipse/jdt/org.eclipse.jdt.core/3.12.0.v20160315-2126/org.eclipse.jdt.core-3.12.0.v20160315-2126.jar
ec467beffac7ffa86b5687a0935b8d3540e8795c9bc0c0d326a1c24cb9be7fe8 /org/eclipse/jdt/org.eclipse.jdt.core/3.12.0.v20160315-2126/org.eclipse.jdt.core-3.12.0.v20160315-2126.pom
d6aba7a1569952e082630de6907f460f476c20d97032cb9f7e4f3e14ddb928e7 /org/eclipse/jetty/jetty-parent/14/jetty-parent-14.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
b1f003f28c3ce1753ea0da22a6f0289197a2c369e7056b32e170af7904eff2c1 /org/fusesource/fusesource-pom/1.8/fusesource-pom-1.8.pom
9e82163ed2fc6257fe627132ce554726e796edee4e5efe9d9e523aee217d60b8 /org/fusesource/jansi/jansi/1.11/jansi-1.11.jar
b0975adc7450698033f3de4792dd6eba72a980c2b56d8e8d36d381385b37a5c9 /org/fusesource/jansi/jansi/1.11/jansi-1.11.pom
8ba9c49b55f979cf4e04d4871092eb50e834b388fca03a2274ccadff12cc9ce8 /org/fusesource/jansi/jansi-project/1.11/jansi-project-1.11.pom
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
833e721817f70d1445eec13d8ce5a86e12af70efac5014356302e2bbc68b3fe2 /org/lwjgl/lwjgl/lwjgl/2.9.4-nightly-20150209/lwjgl-2.9.4-nightly-20150209.jar
65fb24fa8ee4a7efc554b15cfb447753c39e414ff00e9944d347e6f1176f0438 /org/lwjgl/lwjgl/lwjgl/2.9.4-nightly-20150209/lwjgl-2.9.4-nightly-20150209.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
d312147c3999b868fd649887f45203a4195bc10fc563cee4c4f8d22761421f94 /org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-linux.jar
8831b2bd5a53dc343fd6fbed3c18f28ab33d3f28dbe62ebd4a3af81f25c0a5ab /org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar
f2e1f2c6bd7511a7504f389b8b716f5d8dc2fdc71e29c89b52644314cf0a228e /org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-windows.jar
11eeed66c2d56892f3e2046121438153e516dd95d368bcf93c0714f9f2bfdd6f /org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209.pom
034456b132a336b72757325bb7aaf99e075681ee5650d2bea21717bd485de42f /org/lwjgl/lwjgl/lwjgl_util/2.9.4-nightly-20150209/lwjgl_util-2.9.4-nightly-20150209.jar
cb7239de51893ee5abe90c2bc550422cb336140c0866e9d1c899399eeb8a3ba2 /org/lwjgl/lwjgl/lwjgl_util/2.9.4-nightly-20150209/lwjgl_util-2.9.4-nightly-20150209.pom
9cf1643b0d805db942498cebf941d1c43df0a1322137291c258aec6109200858 /org/lwjgl/lwjgl/parent/2.9.1/parent-2.9.1.pom
9b3282d2065e070f5966c8b324bc8ffaa4a3d53c7d39ef7e0a3458b525bc167e /org/lwjgl/lwjgl/parent/2.9.4-nightly-20150209/parent-2.9.4-nightly-20150209.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
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
27901e5d4d60d3502571d5e6358fc89e3fcf874138b69d495d139bcc3e169404 /oshi-project/oshi-core/1.1/oshi-core-1.1.jar
e7e154dd64e5bd87e6ae2652ab52ab88eb53d05606466faee382d11f59d0ab71 /oshi-project/oshi-core/1.1/oshi-core-1.1.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

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,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
deps.add(CONFIG_FFI_DEPS, deps.localGroovy());
}
+ 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/"; // Mojang's Cloudflare front end
+ public static final String URL_LIBRARY = "http://libraries.minecraft.net/"; // Mojang's Cloudflare front end
//public static final String URL_LIBRARY = "https://minecraft-libraries.s3.amazonaws.com/"; // Mojang's AWS server, as Cloudflare is having issues, TODO: Switch back to above when their servers are fixed.
public static final String URL_FORGE_MAVEN = "http://files.minecraftforge.net/maven";
public static final List<String> URLS_MCP_JSON = Arrays.asList(
--
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:4.0-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.2-SNAPSHOT'
- classpath 'org.spongepowered:mixingradle:0.4-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" "ea4ea624672e8b75fb2a78f0fb9105db13d5a4a6" "build/libs/Srg2Source-4.0-SNAPSHOT.jar" "727445a7b946535217be658726c537acf1921f0a9e2ac0ea717dff9b36dc529f" "4ebd7b738f368ee5c25a1028a167257e7012cef7c72c8b5b06149286992c631e"
# 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" "d13a6c892f51937567b3d01d85bea4f3d128e71d" "build/libs/ForgeGradle-2.2-SNAPSHOT.jar" "355a8bd6f49f3d11c40d58da9bb388e05b634ddfac43ab222bf2326aa40f0be4" "45966ee785c42e34c36be3e73046aca1a581a919fb02a9028970d19d35488b18"
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: e2bd90628e...b5fdbb85e1

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

@@ -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.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;
bus.register(new ShaderBeginRender());
bus.register(new DisableFastRender());
bus.register(new HideInvisibleEntities());
DisableBetterSprinting.register();
}
}

View File

@@ -0,0 +1,107 @@
package com.replaymod.compat.bettersprinting;
import com.replaymod.replay.ReplayModReplay;
import com.replaymod.replay.events.ReplayChatMessageEvent;
import net.minecraft.block.state.IBlockState;
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.SoundCategory;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IWorldEventListener;
import net.minecraft.world.World;
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 javax.annotation.Nullable;
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.addEventListener(worldAccessHook);
}
}
@SubscribeEvent(priority = EventPriority.LOW)
public void afterGuiOpenEvent(GuiOpenEvent event) {
if (ReplayModReplay.instance.getReplayHandler() != null && mc.theWorld != null) {
mc.theWorld.addEventListener(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 IWorldEventListener {
@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 notifyBlockUpdate(World worldIn, BlockPos pos, IBlockState oldState, IBlockState newState, int flags) {}
@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 playSoundToAllNearExcept(@Nullable EntityPlayer player, SoundEvent soundIn, SoundCategory category, double x, double y, double z, float volume, float pitch) {}
@Override public void playRecord(SoundEvent soundIn, BlockPos pos) {}
@Override public void spawnParticle(int p_180442_1_, boolean p_180442_2_, double p_180442_3_, double p_180442_5_, double p_180442_7_, double p_180442_9_, double p_180442_11_, double p_180442_13_, int... p_180442_15_) {}
@Override public void onEntityAdded(Entity entityIn) {}
@Override public void broadcastSound(int p_180440_1_, BlockPos p_180440_2_, int p_180440_3_) {}
@Override public void playEvent(EntityPlayer player, int type, BlockPos blockPosIn, int data) {}
@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", false));
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.getEntity().isInvisible()) {
event.setCanceled(true);
}
}
}
}

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) {

View File

@@ -26,6 +26,9 @@ 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;
@@ -36,6 +39,8 @@ import java.util.List;
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 {
@@ -159,9 +164,36 @@ 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 = MinecraftForge.EVENT_BUS;
bus.register(new Object() {
@SubscribeEvent
public void onRenderTick(TickEvent.RenderTickEvent event) {
if (event.phase == TickEvent.Phase.START) {
runLater(runnable);
bus.unregister(this);
}
}
});
return;
}
synchronized (mc.scheduledTasks) {
mc.scheduledTasks.add(ListenableFutureTask.create(runnable, null));
mc.scheduledTasks.add(ListenableFutureTask.create(() -> {
inRunLater = true;
try {
runnable.run();
} finally {
inRunLater = false;
}
}, null));
}
}

View File

@@ -1,5 +1,6 @@
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;
@@ -16,11 +17,14 @@ 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;
@@ -36,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;
@@ -137,6 +143,22 @@ 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);
ResourceLocation skinLocation;

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;
@@ -125,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 {
@@ -220,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

@@ -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 final Map<Class<? extends Extra>, Extra> instances = new HashMap<>();
public static Logger LOGGER;
@Mod.EventHandler
public void preInit(FMLPreInitializationEvent event) {
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);
}
}
}
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,8 +9,6 @@ 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;
@@ -58,12 +56,6 @@ public class PlayerOverview implements Extra {
});
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

@@ -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

@@ -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

@@ -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,7 +71,7 @@ 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());
}
}
@@ -82,7 +84,10 @@ public class ReplayModOnline {
// Initial login prompt
if (!core.getSettingsRegistry().get(Setting.SKIP_LOGIN_PROMPT)) {
if (!isLoggedIn()) {
core.runLater(() -> new GuiLoginPrompt(apiClient, GuiScreen.wrap(getMinecraft().currentScreen), 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

@@ -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

@@ -37,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;
@@ -51,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;
@@ -336,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);
}
}
}
@@ -417,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

@@ -38,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;
@@ -135,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());

View File

@@ -3,6 +3,7 @@ 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 io.netty.channel.ChannelDuplexHandler;
import io.netty.channel.ChannelHandler;
@@ -19,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";
@@ -56,6 +59,8 @@ public class ReplayModRecording {
EventBus bus = MinecraftForge.EVENT_BUS;
bus.register(connectionEventHandler = new ConnectionEventHandler(logger, core));
new GuiHandler(core).register();
NetworkRegistry.INSTANCE.newChannel(Restrictions.PLUGIN_CHANNEL, new RestrictionsChannelHandler());
}

View File

@@ -2,6 +2,7 @@ package com.replaymod.recording.handler;
import com.replaymod.core.ReplayMod;
import com.replaymod.core.utils.ModCompat;
import com.replaymod.core.utils.Utils;
import com.replaymod.recording.Setting;
import com.replaymod.recording.gui.GuiRecordingOverlay;
import com.replaymod.recording.packet.PacketListener;
@@ -74,7 +75,7 @@ public class ConnectionEventHandler {
File folder = core.getReplayFolder();
String name = sdf.format(Calendar.getInstance().getTime());
File currentFile = new File(folder, name + ".mcpr");
File currentFile = new File(folder, Utils.replayNameToFileName(name));
ReplayFile replayFile = new ZipReplayFile(new ReplayStudio(), currentFile);
replayFile.writeModInfo(ModCompat.getInstalledNetworkMods());

View File

@@ -0,0 +1,52 @@
package com.replaymod.recording.handler;
import com.replaymod.core.ReplayMod;
import com.replaymod.core.SettingsRegistry;
import com.replaymod.recording.Setting;
import de.johni0702.minecraft.gui.container.GuiScreen;
import de.johni0702.minecraft.gui.container.VanillaGuiScreen;
import de.johni0702.minecraft.gui.element.GuiCheckbox;
import de.johni0702.minecraft.gui.layout.CustomLayout;
import net.minecraft.client.gui.GuiMultiplayer;
import net.minecraft.client.gui.GuiWorldSelection;
import net.minecraftforge.client.event.GuiScreenEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
public class GuiHandler {
private final ReplayMod mod;
public GuiHandler(ReplayMod mod) {
this.mod = mod;
}
public void register() {
MinecraftForge.EVENT_BUS.register(this);
}
@SubscribeEvent
public void onGuiInit(GuiScreenEvent.InitGuiEvent.Post event) {
if (event.getGui() instanceof GuiWorldSelection || event.getGui() instanceof GuiMultiplayer) {
SettingsRegistry settingsRegistry = mod.getSettingsRegistry();
boolean sp = event.getGui() instanceof GuiWorldSelection;
Setting<Boolean> setting = sp ? Setting.RECORD_SINGLEPLAYER : Setting.RECORD_SERVER;
GuiCheckbox recordingCheckbox = new GuiCheckbox()
.setI18nLabel("replaymod.gui.settings.record" + (sp ? "singleplayer" : "server"))
.setChecked(settingsRegistry.get(setting));
recordingCheckbox.onClick(() -> {
settingsRegistry.set(setting, recordingCheckbox.isChecked());
settingsRegistry.save();
});
VanillaGuiScreen.setup(event.getGui()).setLayout(new CustomLayout<GuiScreen>() {
@Override
protected void layout(GuiScreen container, int width, int height) {
//size(recordingCheckbox, 200, 20);
pos(recordingCheckbox, width - width(recordingCheckbox) - 5, 5);
}
}).addElements(null, recordingCheckbox);
}
}
}

View File

@@ -35,7 +35,8 @@ public abstract class MixinWorldClient extends World implements RecordingEventHa
// but are instead played directly by the client. The server only sends these sounds to
// other clients so we have to record them manually.
// E.g. Block place sounds
@Inject(method = "playSound", at = @At("HEAD"))
@Inject(method = "playSound(Lnet/minecraft/entity/player/EntityPlayer;DDDLnet/minecraft/util/SoundEvent;Lnet/minecraft/util/SoundCategory;FF)V",
at = @At("HEAD"))
public void replayModRecording_recordClientSound(EntityPlayer player, double x, double y, double z, SoundEvent sound, SoundCategory category,
float volume, float pitch, CallbackInfo ci) {
if (player == mc.thePlayer) {

View File

@@ -15,7 +15,12 @@ import net.minecraft.network.EnumPacketDirection;
import net.minecraft.network.Packet;
import net.minecraft.network.PacketBuffer;
import net.minecraft.network.datasync.EntityDataManager;
import net.minecraft.network.play.server.*;
import net.minecraft.network.play.server.SPacketCollectItem;
import net.minecraft.network.play.server.SPacketCustomPayload;
import net.minecraft.network.play.server.SPacketDisconnect;
import net.minecraft.network.play.server.SPacketResourcePackSend;
import net.minecraft.network.play.server.SPacketSpawnMob;
import net.minecraft.network.play.server.SPacketSpawnPlayer;
import net.minecraft.util.text.TextComponentString;
import net.minecraftforge.fml.common.network.internal.FMLProxyPacket;
import org.apache.logging.log4j.LogManager;

View File

@@ -21,6 +21,8 @@ import java.util.List;
@Mod(modid = ReplayModRender.MOD_ID,
version = "@MOD_VERSION@",
acceptedMinecraftVersions = "@MC_VERSION@",
acceptableRemoteVersions = "*",
clientSideOnly = true,
useMetadata = true)
public class ReplayModRender {
public static final String MOD_ID = "replaymod-render";

View File

@@ -2,6 +2,7 @@ package com.replaymod.render;
import com.replaymod.render.frame.RGBFrame;
import com.replaymod.render.rendering.FrameConsumer;
import com.replaymod.render.rendering.VideoRenderer;
import com.replaymod.render.utils.ByteBufferPool;
import com.replaymod.render.utils.StreamPipe;
import net.minecraft.client.Minecraft;
@@ -32,6 +33,7 @@ import static org.apache.commons.lang3.Validate.isTrue;
public class VideoWriter implements FrameConsumer<RGBFrame> {
private final VideoRenderer renderer;
private final RenderSettings settings;
private final Process process;
private final OutputStream outputStream;
@@ -41,8 +43,9 @@ public class VideoWriter implements FrameConsumer<RGBFrame> {
private ByteArrayOutputStream ffmpegLog = new ByteArrayOutputStream(4096);
public VideoWriter(final RenderSettings settings) throws IOException {
this.settings = settings;
public VideoWriter(final VideoRenderer renderer) throws IOException {
this.renderer = renderer;
this.settings = renderer.getRenderSettings();
File outputFolder = settings.getOutputFile().getParentFile();
FileUtils.forceMkdir(outputFolder);
@@ -57,9 +60,13 @@ public class VideoWriter implements FrameConsumer<RGBFrame> {
.replace("%FILTERS%", settings.getVideoFilters());
String executable = settings.getExportCommand().isEmpty() ? findFFmpeg() : settings.getExportCommand();
System.out.println("Starting " + executable + " with args: " + commandArgs);
LOGGER.info("Starting {} with args: {}", executable, commandArgs);
String[] cmdline = new CommandLine(executable).addArguments(commandArgs).toStrings();
process = new ProcessBuilder(cmdline).directory(outputFolder).start();
try {
process = new ProcessBuilder(cmdline).directory(outputFolder).start();
} catch (IOException e) {
throw new NoFFmpegException(e);
}
File exportLogFile = new File(Minecraft.getMinecraft().mcDataDir, "export.log");
OutputStream exportLogOut = new TeeOutputStream(new FileOutputStream(exportLogFile), ffmpegLog);
new StreamPipe(process.getInputStream(), exportLogOut).start();
@@ -152,6 +159,16 @@ public class VideoWriter implements FrameConsumer<RGBFrame> {
if (aborted) {
return;
}
try {
// Check whether this is a failure right at the beginning of the rendering process
// or at some later point (ffmpeg won't print the output file until the first frame
// has been written to stdin, so we can't already check for invalid args in <init>).
getVideoFile();
} catch (FFmpegStartupException e) {
// Possibly invalid ffmpeg arguments
renderer.setFailure(e);
return;
}
CrashReport report = CrashReport.makeCrashReport(t, "Exporting frame");
CrashReportCategory exportDetails = report.makeCategory("Export details");
exportDetails.addCrashSection("Export command", settings.getExportCommand());
@@ -173,7 +190,7 @@ public class VideoWriter implements FrameConsumer<RGBFrame> {
aborted = true;
}
public File getVideoFile() {
public File getVideoFile() throws FFmpegStartupException {
String log = ffmpegLog.toString();
for (String line : log.split("\n")) {
if (line.startsWith("Output #0")) {
@@ -181,6 +198,30 @@ public class VideoWriter implements FrameConsumer<RGBFrame> {
return new File(settings.getOutputFile().getParentFile(), fileName);
}
}
throw new IllegalStateException("No output file found.");
throw new FFmpegStartupException(settings, log);
}
public static class NoFFmpegException extends IOException {
public NoFFmpegException(Throwable cause) {
super(cause);
}
}
public static class FFmpegStartupException extends IOException {
private final RenderSettings settings;
private final String log;
public FFmpegStartupException(RenderSettings settings, String log) {
this.settings = settings;
this.log = log;
}
public RenderSettings getSettings() {
return settings;
}
public String getLog() {
return log;
}
}
}

View File

@@ -0,0 +1,109 @@
package com.replaymod.render.gui;
import com.replaymod.render.RenderSettings;
import com.replaymod.render.VideoWriter;
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.GuiElement;
import de.johni0702.minecraft.gui.element.GuiLabel;
import de.johni0702.minecraft.gui.layout.CustomLayout;
import de.johni0702.minecraft.gui.layout.HorizontalLayout;
import de.johni0702.minecraft.gui.layout.VerticalLayout;
import net.minecraft.crash.CrashReport;
import net.minecraft.crash.CrashReportCategory;
import net.minecraft.util.ReportedException;
import java.util.Arrays;
import java.util.function.Consumer;
import static com.replaymod.render.ReplayModRender.LOGGER;
public class GuiExportFailed extends GuiScreen {
public static GuiExportFailed tryToRecover(VideoWriter.FFmpegStartupException e, Consumer<RenderSettings> doRestart) {
// Always log the error first
LOGGER.error("Rendering video:", e);
RenderSettings settings = e.getSettings();
// Check whether the user has configured some custom ffmpeg arguments
if (settings.getEncodingPreset().getValue().equals(settings.getExportArguments())) {
// If they haven't, then this is probably a faulty ffmpeg installation and there's nothing we can do
CrashReport crashReport = CrashReport.makeCrashReport(e, "Exporting video");
CrashReportCategory details = crashReport.makeCategory("Export details");
details.addCrashSection("Settings", settings);
details.addCrashSection("FFmpeg log", e.getLog());
throw new ReportedException(crashReport);
} else {
// If they have, ask them whether it was intentional
GuiExportFailed gui = new GuiExportFailed(e, doRestart);
gui.display();
return gui;
}
}
private final GuiLabel logLabel = new GuiLabel(this)
.setI18nText("replaymod.gui.rendering.error.ffmpeglog");
private final GuiVerticalList logList = new GuiVerticalList(this).setDrawShadow(true);
private final GuiButton resetButton = new GuiButton().setI18nLabel("gui.yes").setSize(100, 20);
private final GuiButton abortButton = new GuiButton().setI18nLabel("gui.no").setSize(100, 20);
private final GuiPanel info = new GuiPanel(this)
.setLayout(new VerticalLayout().setSpacing(4))
.addElements(new VerticalLayout.Data(0.5),
new GuiLabel().setI18nText("replaymod.gui.rendering.error.ffmpegargs.1"),
new GuiLabel().setI18nText("replaymod.gui.rendering.error.ffmpegargs.2"),
new GuiLabel(),
new GuiPanel().setLayout(new HorizontalLayout(HorizontalLayout.Alignment.CENTER).setSpacing(5))
.addElements(null, resetButton, abortButton)
);
{
setLayout(new CustomLayout<GuiScreen>() {
@Override
protected void layout(GuiScreen container, int width, int height) {
pos(info, width/2 - width(info)/2, (height/2 - height(info) - 30) / 2 + 30);
pos(logLabel, width/2 - width(logLabel)/2, height/2 + 4);
pos(logList, 10, y(logLabel) + height(logLabel) + 4);
size(logList, width - 10 - x(logList), height - 10 - y(logList));
}
});
setTitle(new GuiLabel().setI18nText("replaymod.gui.rendering.error.title"));
setBackground(Background.DIRT);
}
public GuiExportFailed(VideoWriter.FFmpegStartupException e, Consumer<RenderSettings> doRestart) {
logList.getListPanel().addElements(null,
Arrays.stream(e.getLog().replace("\t", " ").split("\n"))
.map(l -> new GuiLabel().setText(l))
.toArray(GuiElement[]::new));
resetButton.onClick(() -> {
RenderSettings oldSettings = e.getSettings();
doRestart.accept(new RenderSettings(
oldSettings.getRenderMethod(),
oldSettings.getEncodingPreset(),
oldSettings.getVideoWidth(),
oldSettings.getVideoHeight(),
oldSettings.getFramesPerSecond(),
oldSettings.getBitRate(),
oldSettings.getOutputFile(),
oldSettings.isRenderNameTags(),
oldSettings.isStabilizeYaw(),
oldSettings.isStabilizePitch(),
oldSettings.isStabilizeRoll(),
oldSettings.getChromaKeyingColor(),
oldSettings.isInject360Metadata(),
oldSettings.getAntiAliasing(),
oldSettings.getExportCommand(),
oldSettings.getEncodingPreset().getValue(),
oldSettings.isHighPerformance()
));
});
abortButton.onClick(() -> {
// Assume they know what they're doing
getMinecraft().displayGuiScreen(null);
});
}
}

View File

@@ -1,8 +1,11 @@
package com.replaymod.render.gui;
import com.google.common.collect.Iterables;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.replaymod.core.utils.Utils;
import com.replaymod.render.ReplayModRender;
import com.replaymod.render.VideoWriter;
import com.replaymod.render.rendering.VideoRenderer;
import com.replaymod.render.utils.RenderJob;
import com.replaymod.replay.ReplayHandler;
@@ -11,6 +14,7 @@ import com.replaymod.replaystudio.util.I18n;
import de.johni0702.minecraft.gui.GuiRenderer;
import de.johni0702.minecraft.gui.RenderInfo;
import de.johni0702.minecraft.gui.container.AbstractGuiClickableContainer;
import de.johni0702.minecraft.gui.container.AbstractGuiScreen;
import de.johni0702.minecraft.gui.container.GuiContainer;
import de.johni0702.minecraft.gui.container.GuiPanel;
import de.johni0702.minecraft.gui.container.GuiVerticalList;
@@ -25,12 +29,10 @@ import de.johni0702.minecraft.gui.popup.GuiYesNoPopup;
import de.johni0702.minecraft.gui.utils.Colors;
import net.minecraft.client.gui.GuiErrorScreen;
import net.minecraft.crash.CrashReport;
import net.minecraft.util.ReportedException;
import org.lwjgl.util.Dimension;
import org.lwjgl.util.ReadableDimension;
import javax.annotation.Nullable;
import java.io.IOException;
import java.util.List;
import static com.replaymod.render.ReplayModRender.LOGGER;
@@ -62,7 +64,8 @@ public class GuiRenderQueue extends AbstractGuiPopup<GuiRenderQueue> {
renameButton, removeButton),
closeButton);
private final GuiContainer container;
private final AbstractGuiScreen container;
private final ReplayHandler replayHandler;
private Entry selectedEntry;
{
@@ -84,9 +87,10 @@ public class GuiRenderQueue extends AbstractGuiPopup<GuiRenderQueue> {
}).addElements(null, title, list, buttonPanel);
}
public GuiRenderQueue(GuiContainer container, GuiRenderSettings guiRenderSettings, ReplayHandler replayHandler, Timeline timeline) {
public GuiRenderQueue(AbstractGuiScreen container, GuiRenderSettings guiRenderSettings, ReplayHandler replayHandler, Timeline timeline) {
super(container);
this.container = container;
this.replayHandler = replayHandler;
LOGGER.trace("Opening render queue popup");
setBackgroundColor(Colors.DARK_TRANSPARENT);
@@ -188,30 +192,46 @@ public class GuiRenderQueue extends AbstractGuiPopup<GuiRenderQueue> {
renderButton.onClick(() -> {
LOGGER.trace("Render button clicked");
// Close all GUIs (so settings in GuiRenderSettings are saved)
getMinecraft().displayGuiScreen(null);
// Start rendering
for (RenderJob renderJob : queue) {
LOGGER.info("Starting render job {}", renderJob);
try {
VideoRenderer videoRenderer = new VideoRenderer(renderJob.getSettings(), replayHandler, renderJob.getTimeline());
videoRenderer.renderVideo();
} catch (IOException e) {
LOGGER.error("Rendering video:", e);
GuiErrorScreen errorScreen = new GuiErrorScreen(I18n.format("replaymod.gui.rendering.error.title"),
I18n.format("replaymod.gui.rendering.error.message"));
getMinecraft().displayGuiScreen(errorScreen);
return;
} catch (Throwable t) {
CrashReport crashReport = CrashReport.makeCrashReport(t, "Rendering video");
throw new ReportedException(crashReport);
}
}
processQueue(queue);
});
updateButtons();
}
private void processQueue(Iterable<RenderJob> queue) {
// Close all GUIs (so settings in GuiRenderSettings are saved)
getMinecraft().displayGuiScreen(null);
// Start rendering
int jobsDone = 0;
for (RenderJob renderJob : queue) {
LOGGER.info("Starting render job {}", renderJob);
try {
VideoRenderer videoRenderer = new VideoRenderer(renderJob.getSettings(), replayHandler, renderJob.getTimeline());
videoRenderer.renderVideo();
} catch (VideoWriter.NoFFmpegException e) {
LOGGER.error("Rendering video:", e);
GuiErrorScreen errorScreen = new GuiErrorScreen(I18n.format("replaymod.gui.rendering.error.title"),
I18n.format("replaymod.gui.rendering.error.message"));
getMinecraft().displayGuiScreen(errorScreen);
return;
} catch (VideoWriter.FFmpegStartupException e) {
int jobsToSkip = jobsDone;
GuiExportFailed.tryToRecover(e, newSettings -> {
// Update current job with fixed ffmpeg arguments
renderJob.setSettings(newSettings);
// Restart queue, skipping the already completed jobs
processQueue(Iterables.skip(queue, jobsToSkip));
});
return;
} catch (Throwable t) {
Utils.error(LOGGER, this, CrashReport.makeCrashReport(t, "Rendering video"), () -> {});
container.display(); // Re-show the queue popup and the new error popup
return;
}
jobsDone++;
}
}
@Override
public void open() {
super.open();

View File

@@ -7,6 +7,7 @@ import com.google.gson.GsonBuilder;
import com.google.gson.InstanceCreator;
import com.replaymod.render.RenderSettings;
import com.replaymod.render.ReplayModRender;
import com.replaymod.render.VideoWriter;
import com.replaymod.render.rendering.VideoRenderer;
import com.replaymod.replay.ReplayHandler;
import com.replaymod.replaystudio.pathing.path.Timeline;
@@ -29,7 +30,6 @@ import de.johni0702.minecraft.gui.utils.Utils;
import net.minecraft.client.gui.GuiErrorScreen;
import net.minecraft.client.resources.I18n;
import net.minecraft.crash.CrashReport;
import net.minecraft.util.ReportedException;
import net.minecraftforge.common.config.Configuration;
import net.minecraftforge.common.config.Property;
import org.lwjgl.util.Color;
@@ -39,11 +39,13 @@ import org.lwjgl.util.ReadableDimension;
import javax.annotation.Nullable;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import static com.replaymod.core.utils.Utils.error;
import static com.replaymod.render.ReplayModRender.LOGGER;
public class GuiRenderSettings extends GuiScreen implements Closeable {
public final GuiPanel contentPanel = new GuiPanel(this).setBackgroundColor(Colors.DARK_TRANSPARENT);
public final GuiVerticalList settingsList = new GuiVerticalList(contentPanel).setDrawSlider(true);
@@ -199,15 +201,21 @@ public class GuiRenderSettings extends GuiScreen implements Closeable {
try {
VideoRenderer videoRenderer = new VideoRenderer(save(false), replayHandler, timeline);
videoRenderer.renderVideo();
} catch (IOException e) {
e.printStackTrace();
} catch (VideoWriter.NoFFmpegException e) {
LOGGER.error("Rendering video:", e);
GuiErrorScreen errorScreen = new GuiErrorScreen(I18n.format("replaymod.gui.rendering.error.title"),
I18n.format("replaymod.gui.rendering.error.message"));
getMinecraft().displayGuiScreen(errorScreen);
} catch (VideoWriter.FFmpegStartupException e) {
GuiExportFailed.tryToRecover(e, newSettings -> {
// Update settings with fixed ffmpeg arguments
exportArguments.setText(newSettings.getExportArguments());
// Restart rendering, this will also save the changed ffmpeg arguments
renderButton.onClick();
});
} catch (Throwable t) {
CrashReport crashReport = CrashReport.makeCrashReport(t, "Rendering video");
throw new ReportedException(crashReport);
error(LOGGER, GuiRenderSettings.this, CrashReport.makeCrashReport(t, "Rendering video"), () -> {});
display(); // Re-show the render settings gui and the new error popup
}
}
}).setSize(100, 20).setI18nLabel("replaymod.gui.render");
@@ -419,7 +427,7 @@ public class GuiRenderSettings extends GuiScreen implements Closeable {
);
}
private File generateOutputFile(RenderSettings.EncodingPreset encodingPreset) {
protected File generateOutputFile(RenderSettings.EncodingPreset encodingPreset) {
String fileName = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss").format(new Date());
File folder = ReplayModRender.instance.getVideoFolder();
return new File(folder, fileName + "." + encodingPreset.getFileExtension());
@@ -439,7 +447,7 @@ public class GuiRenderSettings extends GuiScreen implements Closeable {
config.save();
}
private Property getConfigProperty(Configuration configuration) {
protected Property getConfigProperty(Configuration configuration) {
return configuration.get("rendersettings", "settings", "{}",
"Last state of the render settings GUI. Internal use only.");
}

View File

@@ -4,7 +4,6 @@ import com.coremedia.iso.IsoFile;
import com.coremedia.iso.boxes.*;
import com.google.common.primitives.Bytes;
import com.googlecode.mp4parser.BasicContainer;
import net.minecraftforge.fml.common.FMLLog;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
@@ -13,6 +12,8 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import static com.replaymod.render.ReplayModRender.LOGGER;
public class MetadataInjector {
private static final String STITCHING_SOFTWARE = "Minecraft ReplayMod";
@@ -96,7 +97,7 @@ public class MetadataInjector {
videoFileOutputStream = new FileOutputStream(videoFile);
tempIsoFile.getBox(videoFileOutputStream.getChannel());
} catch(Exception e) {
FMLLog.getLogger().error("360 Degree Metadata couldn't be injected", e);
LOGGER.error("360 Degree Metadata couldn't be injected", e);
} finally {
IOUtils.closeQuietly(tempIsoFile);
IOUtils.closeQuietly(videoFileOutputStream);

View File

@@ -0,0 +1,23 @@
package com.replaymod.render.mixin;
import com.replaymod.render.hooks.EntityRendererHandler;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.culling.Frustum;
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;
@Mixin(Frustum.class)
public abstract class MixinFrustum {
@Inject(method = "isBoxInFrustum", at = @At("HEAD"), cancellable = true)
public void isBoxInFrustum(double minX, double minY, double minZ, double maxX, double maxY, double maxZ, CallbackInfoReturnable<Boolean> ci) {
EntityRendererHandler handler = ((EntityRendererHandler.IEntityRenderer) Minecraft.getMinecraft().entityRenderer).replayModRender_getHandler();
if (handler != null && handler.omnidirectional && handler.data == null) {
// Normally the camera is always facing the direction of the omnidirectional image face that is currently
// getting rendered. With ODS however, the camera is always facing forwards and the turning happens in the
// vertex shader (non-trivial due to stereo). As such, all chunks need to be rendered all the time for ODS.
ci.setReturnValue(true);
}
}
}

View File

@@ -34,7 +34,6 @@ public abstract class MixinRenderGlobal {
do {
setupTerrain(viewEntity, partialTicks, camera, replayModRender_hook.nextFrameId(), playerSpectator);
replayModRender_hook.updateChunks();
} while (displayListEntitiesDirty);

View File

@@ -39,6 +39,7 @@ import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import static com.google.common.collect.Iterables.getLast;
import static com.replaymod.render.ReplayModRender.LOGGER;
import static net.minecraft.client.renderer.GlStateManager.*;
import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT;
import static org.lwjgl.opengl.GL11.GL_DEPTH_BUFFER_BIT;
@@ -66,6 +67,7 @@ public class VideoRenderer implements RenderInfo {
private final GuiVideoRenderer gui;
private boolean paused;
private boolean cancelled;
private volatile Throwable failureCause;
private Framebuffer guiFramebuffer;
private int displayWidth, displayHeight;
@@ -76,7 +78,7 @@ public class VideoRenderer implements RenderInfo {
this.timeline = timeline;
this.gui = new GuiVideoRenderer(this);
this.renderingPipeline = Pipelines.newPipeline(settings.getRenderMethod(), this,
videoWriter = new VideoWriter(settings) {
videoWriter = new VideoWriter(this) {
@Override
public void consume(RGBFrame frame) {
gui.updatePreview(frame);
@@ -89,7 +91,7 @@ public class VideoRenderer implements RenderInfo {
* Render this video.
* @return {@code true} if rendering was successful, {@code false} if the user aborted rendering (or the window was closed)
*/
public boolean renderVideo() {
public boolean renderVideo() throws Throwable {
MinecraftForge.EVENT_BUS.post(new ReplayRenderEvent.Pre(this));
setup();
@@ -138,6 +140,10 @@ public class VideoRenderer implements RenderInfo {
MinecraftForge.EVENT_BUS.post(new ReplayRenderEvent.Post(this));
if (failureCause != null) {
throw failureCause;
}
return !cancelled;
}
@@ -247,7 +253,13 @@ public class VideoRenderer implements RenderInfo {
new SoundHandler().playRenderSuccessSound();
new GuiRenderingDone(ReplayModRender.instance, videoWriter.getVideoFile(), totalFrames, settings).display();
try {
if (!hasFailed()) {
new GuiRenderingDone(ReplayModRender.instance, videoWriter.getVideoFile(), totalFrames, settings).display();
}
} catch (VideoWriter.FFmpegStartupException e) {
setFailure(e);
}
// Finally, resize the Minecraft framebuffer to the actual width/height of the window
mc.resize(displayWidth, displayHeight);
@@ -323,7 +335,7 @@ public class VideoRenderer implements RenderInfo {
return;
}
}
} while (paused);
} while (paused && !hasFailed());
}
private boolean displaySizeChanged() {
@@ -364,6 +376,20 @@ public class VideoRenderer implements RenderInfo {
renderingPipeline.cancel();
}
public boolean hasFailed() {
return failureCause != null;
}
public synchronized void setFailure(Throwable cause) {
if (this.failureCause != null) {
LOGGER.error("Further failure during failed rendering: ", cause);
} else {
LOGGER.error("Failure during rendering: ", cause);
this.failureCause = cause;
cancel();
}
}
private class TimelinePlayer extends AbstractTimelinePlayer {
public TimelinePlayer(ReplayHandler replayHandler) {
super(replayHandler);

View File

@@ -12,7 +12,7 @@ import java.io.InputStream;
public class SoundHandler {
private final ResourceLocation successSoundLocation = new ResourceLocation("replaymod", "renderSuccess.wav");
private final ResourceLocation successSoundLocation = new ResourceLocation("replaymod", "render_success.wav");
public void playRenderSuccessSound() {
playSound(successSoundLocation);

View File

@@ -3,6 +3,7 @@ package com.replaymod.replay;
import com.replaymod.core.utils.WrappedTimer;
import com.replaymod.replay.camera.CameraController;
import com.replaymod.replay.camera.CameraEntity;
import com.replaymod.replay.events.ReplayDispatchKeypressesEvent;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.settings.GameSettings;
@@ -11,6 +12,7 @@ import net.minecraft.crash.CrashReport;
import net.minecraft.util.ReportedException;
import net.minecraft.util.Timer;
import net.minecraftforge.client.ForgeHooksClient;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.common.FMLCommonHandler;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
@@ -122,7 +124,9 @@ public class InputReplayTimer extends WrappedTimer {
}
// Twitch, screenshot, fullscreen, etc. (stuff that works everywhere)
mc.dispatchKeypresses();
if (!MinecraftForge.EVENT_BUS.post(new ReplayDispatchKeypressesEvent.Pre())) {
mc.dispatchKeypresses();
}
if (pressed) {
// This might be subject to change as vanilla shaders are still kinda unused in 1.8

View File

@@ -124,6 +124,8 @@ public class ReplayHandler {
ReplayModReplay.instance.replayHandler = null;
mc.displayGuiScreen(null);
MinecraftForge.EVENT_BUS.post(new ReplayCloseEvent.Post(this));
}

View File

@@ -35,6 +35,8 @@ import java.util.Optional;
@Mod(modid = ReplayModReplay.MOD_ID,
version = "@MOD_VERSION@",
acceptedMinecraftVersions = "@MC_VERSION@",
acceptableRemoteVersions = "*",
clientSideOnly = true,
useMetadata = true)
public class ReplayModReplay {
public static final String MOD_ID = "replaymod-replay";
@@ -46,7 +48,7 @@ public class ReplayModReplay {
private final CameraControllerRegistry cameraControllerRegistry = new CameraControllerRegistry();
private Logger logger;
public static Logger LOGGER;
protected ReplayHandler replayHandler;
@@ -56,7 +58,7 @@ public class ReplayModReplay {
@Mod.EventHandler
public void preInit(FMLPreInitializationEvent event) {
logger = event.getModLog();
LOGGER = event.getModLog();
core = ReplayMod.instance;
core.getSettingsRegistry().register(Setting.class);
@@ -180,6 +182,9 @@ public class ReplayModReplay {
}
public void startReplay(ReplayFile replayFile, boolean checkModCompat) throws IOException {
if (replayHandler != null) {
replayHandler.endReplay();
}
if (checkModCompat) {
ModCompat.ModInfoDifference modDifference = new ModCompat.ModInfoDifference(replayFile.getModInfo());
if (!modDifference.getMissing().isEmpty() || !modDifference.getDiffering().isEmpty()) {
@@ -190,12 +195,16 @@ public class ReplayModReplay {
replayHandler = new ReplayHandler(replayFile, true);
}
public void forcefullyStopReplay() {
replayHandler = null;
}
public ReplayMod getCore() {
return core;
}
public Logger getLogger() {
return logger;
return LOGGER;
}
public CameraControllerRegistry getCameraControllerRegistry() {

View File

@@ -2,15 +2,20 @@ package com.replaymod.replay;
import com.google.common.base.Preconditions;
import com.google.common.io.Files;
import com.google.common.util.concurrent.ListenableFutureTask;
import com.replaymod.core.ReplayMod;
import com.replaymod.core.utils.Restrictions;
import com.replaymod.replay.camera.CameraEntity;
import com.replaymod.replaystudio.io.ReplayInputStream;
import com.replaymod.replaystudio.io.ReplayOutputStream;
import com.replaymod.replaystudio.replay.ReplayFile;
import com.replaymod.replaystudio.studio.ReplayStudio;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufOutputStream;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelDuplexHandler;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelPromise;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityOtherPlayerMP;
import net.minecraft.client.gui.GuiDownloadTerrain;
@@ -20,11 +25,15 @@ import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.network.*;
import net.minecraft.network.play.server.*;
import net.minecraft.util.ClassInheritanceMultiMap;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.world.EnumDifficulty;
import net.minecraft.world.GameType;
import net.minecraft.world.World;
import net.minecraft.world.WorldType;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.IChunkProvider;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent;
@@ -32,10 +41,10 @@ import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
/**
* Sends replay packets to netty channels.
@@ -43,7 +52,7 @@ import java.util.concurrent.Callable;
* the replay restart from the beginning.
*/
@Sharable
public class ReplaySender extends ChannelInboundHandlerAdapter {
public class ReplaySender extends ChannelDuplexHandler {
/**
* These packets are ignored completely during replay.
*/
@@ -100,10 +109,10 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
protected ChannelHandlerContext ctx;
/**
* The data input stream from which new packets are read.
* The replay input stream from which new packets are read.
* When accessing this stream make sure to synchronize on {@code this} as it's used from multiple threads.
*/
protected DataInputStream dis;
protected ReplayInputStream replayIn;
/**
* The next packet that should be sent.
@@ -242,6 +251,7 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
try {
channelInactive(ctx);
ctx.channel().pipeline().close();
FileUtils.deleteDirectory(tempResourcePackFolder);
} catch(Exception e) {
e.printStackTrace();
}
@@ -383,6 +393,13 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
if(BAD_PACKETS.contains(p.getClass())) return null;
if (p instanceof SPacketCustomPayload) {
SPacketCustomPayload packet = (SPacketCustomPayload) p;
if ("MC|BOpen".equals(packet.getChannelName())) {
return null;
}
}
if(p instanceof SPacketResourcePackSend) {
SPacketResourcePackSend packet = (SPacketResourcePackSend) p;
String url = packet.getURL();
@@ -456,22 +473,19 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
}
}
new Callable<Void>() {
new Runnable() {
@Override
@SuppressWarnings("unchecked")
public Void call() {
public void run() {
if (mc.theWorld == null || !mc.isCallingFromMinecraftThread()) {
synchronized(mc.scheduledTasks) {
mc.scheduledTasks.add(ListenableFutureTask.create(this));
}
return null;
ReplayMod.instance.runLater(this);
return;
}
CameraEntity cent = replayHandler.getCameraEntity();
cent.setCameraPosition(ppl.getX(), ppl.getY(), ppl.getZ());
return null;
}
}.call();
}.run();
}
if(p instanceof SPacketChangeGameState) {
@@ -508,9 +522,22 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
FileUtils.deleteDirectory(tempResourcePackFolder);
super.channelInactive(ctx);
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
// The embedded channel's event loop will consider every thread to be in it and as such provides no
// guarantees that only one thread is using the pipeline at any one time.
// For reading the replay sender (either sync or async) is the only thread ever writing.
// For writing it may very well happen that multiple threads want to use the pipline at the same time.
// It's unclear whether the EmbeddedChannel is supposed to be thread-safe (the behavior of the event loop
// does suggest that). However it seems like it either isn't (likely) or there is a race condition.
// See: https://www.replaymod.com/forum/thread/1752#post8045 (https://paste.replaymod.com/lotacatuwo)
// To work around this issue, we just outright drop all write/flush requests (they aren't needed anyway).
// This still leaves channel handlers upstream with the threading issue but they all seem to cope well with it.
promise.setSuccess();
}
@Override
public void flush(ChannelHandlerContext ctx) throws Exception {
// See write method above
}
/**
@@ -568,8 +595,8 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
REPLAY_LOOP:
while (!terminate) {
synchronized (ReplaySender.this) {
if (dis == null) {
dis = new DataInputStream(replayFile.getPacketData());
if (replayIn == null) {
replayIn = replayFile.getPacketData();
}
// Packet loop
while (true) {
@@ -596,7 +623,7 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
// Read the next packet if we don't already have one
if (nextPacket == null) {
nextPacket = new PacketData(dis);
nextPacket = new PacketData(replayIn);
}
int nextTimeStamp = nextPacket.timestamp;
@@ -653,9 +680,9 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
nextPacket = null;
lastPacketSent = System.currentTimeMillis();
replayHandler.restartedReplay();
if (dis != null) {
dis.close();
dis = null;
if (replayIn != null) {
replayIn.close();
replayIn = null;
}
}
}
@@ -738,20 +765,23 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
}
synchronized (this) {
if (timestamp == lastTimeStamp) { // Do nothing if we're already there
return;
}
if (timestamp < lastTimeStamp) { // Restart the replay if we need to go backwards in time
hasWorldLoaded = false;
lastTimeStamp = 0;
if (dis != null) {
dis.close();
dis = null;
if (replayIn != null) {
replayIn.close();
replayIn = null;
}
startFromBeginning = false;
nextPacket = null;
replayHandler.restartedReplay();
}
if (dis == null) {
dis = new DataInputStream(replayFile.getPacketData());
if (replayIn == null) {
replayIn = replayFile.getPacketData();
}
while (true) { // Send packets
@@ -763,7 +793,7 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
nextPacket = null;
} else {
// Otherwise read one from the input stream
pd = new PacketData(dis);
pd = new PacketData(replayIn);
}
int nextTimeStamp = pd.timestamp;
@@ -778,7 +808,7 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
} catch (EOFException eof) {
// Shit! We hit the end before finishing our job! What shall we do now?
// well, let's just pretend we're done...
dis = null;
replayIn = null;
break;
} catch (IOException e) {
e.printStackTrace();
@@ -795,17 +825,80 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
}
protected Packet processPacketSync(Packet p) {
if (p instanceof SPacketUnloadChunk) {
SPacketUnloadChunk packet = (SPacketUnloadChunk) p;
// If the chunk is getting unloaded, we will have to forcefully update the position of all entities
// within. Otherwise, if there wasn't a game tick recently, there may be entities that have moved
// out of the chunk by now but are still registered in it. If we do not update those, they will get
// unloaded even though they shouldn't.
// To make things worse, it seems like players were never supposed to be unloaded this way because
// they will remain glitched in the World#playerEntities list.
World world = mc.theWorld;
IChunkProvider chunkProvider = world.getChunkProvider();
// Get the chunk that will be unloaded
Chunk chunk = chunkProvider.provideChunk(packet.getX(), packet.getZ());
if (!chunk.isEmpty()) {
List<Entity> entitiesInChunk = new ArrayList<>();
// Gather all entities in that chunk
for (ClassInheritanceMultiMap<Entity> entityList : chunk.getEntityLists()) {
entitiesInChunk.addAll(entityList);
}
for (Entity entity : entitiesInChunk) {
// Skip interpolation of position updates coming from server
// (See: newX in EntityLivingBase or otherPlayerMPX in EntityOtherPlayerMP)
// Needs to be called at least 4 times thanks to
// EntityOtherPlayerMP#otherPlayerMPPosRotationIncrements (max vanilla value is 3)
for (int i = 0; i < 4; i++) {
entity.onUpdate();
}
// Check whether the entity has left the chunk
int chunkX = MathHelper.floor_double(entity.posX / 16);
int chunkZ = MathHelper.floor_double(entity.posZ / 16);
if (entity.chunkCoordX != chunkX || entity.chunkCoordZ != chunkZ) {
// Entity has left the chunk
chunk.removeEntityAtIndex(entity, entity.chunkCoordY);
Chunk newChunk = chunkProvider.getLoadedChunk(chunkX, chunkZ);
if (newChunk != null) {
newChunk.addEntity(entity);
} else {
// Entity has left all loaded chunks
entity.addedToChunk = false;
}
}
}
}
}
return p; // During synchronous playback everything is sent normally
}
private static final class PacketData {
private static final ByteBuf byteBuf = Unpooled.buffer();
private static final ByteBufOutputStream byteBufOut = new ByteBufOutputStream(byteBuf);
private static final ReplayOutputStream encoder = new ReplayOutputStream(new ReplayStudio(), byteBufOut);
private final int timestamp;
private final byte[] bytes;
public PacketData(DataInputStream in) throws IOException {
timestamp = in.readInt();
bytes = new byte[in.readInt()];
in.readFully(bytes);
public PacketData(ReplayInputStream in) throws IOException {
com.replaymod.replaystudio.PacketData data = in.readPacket();
timestamp = (int) data.getTime();
// We need to re-encode MCProtocolLib packets, so we can later decode them as NMS packets
// The main reason we aren't reading them as NMS packets is that we want ReplayStudio to be able
// to apply ViaVersion (and potentially other magic) to it.
synchronized (encoder) {
byteBuf.markReaderIndex(); // Mark the current reader and writer index (should be at start)
byteBuf.markWriterIndex();
encoder.write(data); // Re-encode packet, data will end up in byteBuf
encoder.flush();
byteBuf.skipBytes(8); // Skip packet length & timestamp
bytes = new byte[byteBuf.readableBytes()]; // Create bytes array of sufficient size
byteBuf.readBytes(bytes); // Read all data into bytes
byteBuf.resetReaderIndex(); // Reset reader & writer index for next use
byteBuf.resetWriterIndex();
}
}
}
}

View File

@@ -4,6 +4,7 @@ import com.replaymod.core.SettingsRegistry;
public final class Setting<T> extends SettingsRegistry.SettingKeys<T> {
public static final Setting<Boolean> SHOW_CHAT = make("showChat", "showchat", true);
public static final Setting<Boolean> SHOW_SERVER_IPS = new Setting<>("showServerIPs", true);
public static final SettingsRegistry.MultipleChoiceSettingKeys<String> CAMERA =
new SettingsRegistry.MultipleChoiceSettingKeys<>(
"replay", "camera", "replaymod.gui.settings.camera", "replaymod.camera.classic");
@@ -15,4 +16,8 @@ public final class Setting<T> extends SettingsRegistry.SettingKeys<T> {
public Setting(String key, String displayString, T defaultValue) {
super("replay", key, "replaymod.gui.settings." + displayString, defaultValue);
}
public Setting(String key, T defaultValue) {
super("replay", key, null, defaultValue);
}
}

View File

@@ -5,6 +5,7 @@ import com.replaymod.core.events.SettingsChangedEvent;
import com.replaymod.core.utils.Utils;
import com.replaymod.replay.ReplayModReplay;
import com.replaymod.replay.Setting;
import com.replaymod.replay.events.ReplayChatMessageEvent;
import com.replaymod.replaystudio.util.Location;
import lombok.Getter;
import lombok.Setter;
@@ -24,6 +25,7 @@ import net.minecraft.util.EnumHand;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.world.World;
import net.minecraftforge.client.event.EntityViewRenderEvent;
import net.minecraftforge.client.event.RenderGameOverlayEvent;
@@ -158,6 +160,11 @@ public class CameraEntity extends EntityPlayerSP {
if (spectating != null && (view.getUniqueID() != spectating
|| view.worldObj != worldObj)
|| worldObj.getEntityByID(view.getEntityId()) != view) {
if (spectating == null) {
// Entity (non-player) died, stop spectating
ReplayModReplay.instance.getReplayHandler().spectateEntity(this);
return;
}
view = worldObj.getPlayerEntityByUUID(spectating);
if (view != null) {
mc.setRenderViewEntity(view);
@@ -384,6 +391,12 @@ public class CameraEntity extends EntityPlayerSP {
&& (e instanceof EntityPlayer || e instanceof EntityLiving || e instanceof EntityItemFrame);
}
@Override
public void addChatMessage(ITextComponent message) {
if (MinecraftForge.EVENT_BUS.post(new ReplayChatMessageEvent(this))) return;
super.addChatMessage(message);
}
private class EventHandler {
@SubscribeEvent
public void onPreClientTick(TickEvent.ClientTickEvent event) {
@@ -460,5 +473,45 @@ public class CameraEntity extends EntityPlayerSP {
event.setRoll(roll);
}
}
private boolean heldItemTooltipsWasTrue;
@SubscribeEvent
public void preRenderGameOverlay(RenderGameOverlayEvent.Pre event) {
switch (event.getType()) {
case ALL:
heldItemTooltipsWasTrue = mc.gameSettings.heldItemTooltips;
mc.gameSettings.heldItemTooltips = false;
break;
case ARMOR:
case HEALTH:
case FOOD:
case AIR:
case HOTBAR:
case EXPERIENCE:
case HEALTHMOUNT:
case JUMPBAR:
case POTION_ICONS:
event.setCanceled(true);
break;
case HELMET:
case PORTAL:
case CROSSHAIRS:
case BOSSHEALTH:
case BOSSINFO:
case SUBTITLES:
case TEXT:
case CHAT:
case PLAYER_LIST:
case DEBUG:
break;
}
}
@SubscribeEvent
public void postRenderGameOverlay(RenderGameOverlayEvent.Post event) {
if (event.getType() != RenderGameOverlayEvent.ElementType.ALL) return;
mc.gameSettings.heldItemTooltips = heldItemTooltipsWasTrue;
}
}
}

View File

@@ -0,0 +1,14 @@
package com.replaymod.replay.events;
import com.replaymod.replay.camera.CameraEntity;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import net.minecraftforge.fml.common.eventhandler.Cancelable;
import net.minecraftforge.fml.common.eventhandler.Event;
@Cancelable
@RequiredArgsConstructor
public class ReplayChatMessageEvent extends Event {
@Getter
private final CameraEntity cameraEntity;
}

View File

@@ -0,0 +1,10 @@
package com.replaymod.replay.events;
import net.minecraftforge.fml.common.eventhandler.Cancelable;
import net.minecraftforge.fml.common.eventhandler.Event;
public abstract class ReplayDispatchKeypressesEvent extends Event {
@Cancelable
public static class Pre extends ReplayDispatchKeypressesEvent {}
}

View File

@@ -5,9 +5,12 @@ import com.google.common.base.Supplier;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.mojang.realmsclient.gui.ChatFormatting;
import com.replaymod.core.ReplayMod;
import com.replaymod.core.SettingsRegistry;
import com.replaymod.core.gui.GuiReplaySettings;
import com.replaymod.core.utils.Utils;
import com.replaymod.replay.ReplayModReplay;
import com.replaymod.replay.Setting;
import com.replaymod.replaystudio.replay.ReplayFile;
import com.replaymod.replaystudio.replay.ReplayMetaData;
import com.replaymod.replaystudio.replay.ZipReplayFile;
@@ -18,6 +21,7 @@ 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.advanced.GuiResourceLoadingList;
import de.johni0702.minecraft.gui.function.Typeable;
import de.johni0702.minecraft.gui.layout.CustomLayout;
import de.johni0702.minecraft.gui.layout.GridLayout;
import de.johni0702.minecraft.gui.layout.HorizontalLayout;
@@ -28,16 +32,16 @@ import de.johni0702.minecraft.gui.utils.Consumer;
import net.minecraft.client.gui.GuiErrorScreen;
import net.minecraft.client.resources.I18n;
import net.minecraft.util.Util;
import net.minecraftforge.fml.common.FMLLog;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOCase;
import org.apache.commons.io.filefilter.SuffixFileFilter;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.helpers.Strings;
import org.lwjgl.Sys;
import org.lwjgl.input.Keyboard;
import org.lwjgl.util.Dimension;
import org.lwjgl.util.ReadableDimension;
import org.lwjgl.util.ReadablePoint;
import java.awt.*;
import java.awt.image.BufferedImage;
@@ -47,7 +51,9 @@ import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class GuiReplayViewer extends GuiScreen {
import static com.replaymod.replay.ReplayModReplay.LOGGER;
public class GuiReplayViewer extends GuiScreen implements Typeable {
private final ReplayModReplay mod;
public final GuiResourceLoadingList<GuiReplayEntry> list = new GuiResourceLoadingList<GuiReplayEntry>(this).onSelectionChanged(new Runnable() {
@@ -91,7 +97,7 @@ public class GuiReplayViewer extends GuiScreen {
obj.consume(() -> new GuiReplayEntry(file, metaData, theThumb));
}
} catch (Exception e) {
FMLLog.getLogger().error("Could not load Replay File " + file.getName(), e);
LOGGER.error("Could not load Replay File {}", file.getName(), e);
}
}
} catch (IOException e) {
@@ -155,7 +161,7 @@ public class GuiReplayViewer extends GuiScreen {
@Override
public void run() {
final File file = list.getSelected().file;
String name = FilenameUtils.getBaseName(file.getName());
String name = Utils.fileNameToReplayName(file.getName());
final GuiTextField nameField = new GuiTextField().setSize(200, 20).setFocused(true).setText(name);
final GuiYesNoPopup popup = GuiYesNoPopup.open(GuiReplayViewer.this,
new GuiLabel().setI18nText("replaymod.gui.viewer.rename.name").setColor(Colors.BLACK),
@@ -171,16 +177,16 @@ public class GuiReplayViewer extends GuiScreen {
}
}).onTextChanged(obj -> {
popup.getYesButton().setEnabled(!nameField.getText().isEmpty()
&& !new File(file.getParentFile(), nameField.getText() + ".mcpr").exists());
&& !new File(file.getParentFile(), Utils.replayNameToFileName(nameField.getText())).exists());
});
Futures.addCallback(popup.getFuture(), new FutureCallback<Boolean>() {
@Override
public void onSuccess(Boolean delete) {
if (delete) {
// Sanitize their input
String name = nameField.getText().trim().replace("[^a-zA-Z0-9\\.\\- ]", "_");
String name = nameField.getText().trim();
// This file is what they want
File targetFile = new File(file.getParentFile(), name + ".mcpr");
File targetFile = new File(file.getParentFile(), Utils.replayNameToFileName(name));
try {
// Finally, try to move it
FileUtils.moveFile(file, targetFile);
@@ -272,6 +278,18 @@ public class GuiReplayViewer extends GuiScreen {
}
private final GuiImage defaultThumbnail = new GuiImage().setTexture(Utils.DEFAULT_THUMBNAIL);
@Override
public boolean typeKey(ReadablePoint mousePosition, int keyCode, char keyChar, boolean ctrlDown, boolean shiftDown) {
if (keyCode == Keyboard.KEY_F1) {
SettingsRegistry reg = ReplayMod.instance.getSettingsRegistry();
reg.set(Setting.SHOW_SERVER_IPS, !reg.get(Setting.SHOW_SERVER_IPS));
reg.save();
list.load();
}
return false;
}
public class GuiReplayEntry extends AbstractGuiContainer<GuiReplayEntry> implements Comparable<GuiReplayEntry> {
public final File file;
public final GuiLabel name = new GuiLabel();
@@ -302,8 +320,9 @@ public class GuiReplayViewer extends GuiScreen {
public GuiReplayEntry(File file, ReplayMetaData metaData, BufferedImage thumbImage) {
this.file = file;
name.setText(ChatFormatting.UNDERLINE + FilenameUtils.getBaseName(file.getName()));
if (Strings.isEmpty(metaData.getServerName())) {
name.setText(ChatFormatting.UNDERLINE + Utils.fileNameToReplayName(file.getName()));
if (Strings.isEmpty(metaData.getServerName())
|| !ReplayMod.instance.getSettingsRegistry().get(Setting.SHOW_SERVER_IPS)) {
server.setI18nText("replaymod.gui.iphidden").setColor(Colors.DARK_RED);
} else {
server.setText(metaData.getServerName());

View File

@@ -15,6 +15,8 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import static com.replaymod.replay.ReplayModReplay.LOGGER;
public class GuiHandler {
private static final int BUTTON_EXIT_SERVER = 1;
private static final int BUTTON_ACHIEVEMENTS = 5;
@@ -99,6 +101,20 @@ public class GuiHandler {
return;
}
if (mod.getReplayHandler() != null) {
// Something went terribly wrong and we ended up in the main menu with the replay still active.
// To prevent players from joining live servers and using the CameraEntity, try to stop the replay now.
try {
mod.getReplayHandler().endReplay();
} catch (IOException e) {
LOGGER.error("Trying to stop broken replay: ", e);
} finally {
if (mod.getReplayHandler() != null) {
mod.forcefullyStopReplay();
}
}
}
GuiButton button = new GuiButton(BUTTON_REPLAY_VIEWER, event.getGui().width / 2 - 100,
event.getGui().height / 4 + 10 + 3 * 24, I18n.format("replaymod.gui.replayviewer"));
button.width = button.width / 2 - 2;

View File

@@ -1,22 +0,0 @@
package com.replaymod.replay.mixin;
import com.replaymod.replay.camera.CameraEntity;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.entity.RenderArmorStand;
import net.minecraft.entity.item.EntityArmorStand;
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;
@Mixin(RenderArmorStand.class)
public abstract class MixinRenderArmorStand {
@Inject(method = "canRenderName", at = @At("HEAD"), cancellable = true)
private void replayModReplay_canRenderInvisibleName(EntityArmorStand entity, CallbackInfoReturnable<Boolean> ci) {
EntityPlayer thePlayer = Minecraft.getMinecraft().thePlayer;
if (thePlayer instanceof CameraEntity && entity.isInvisible()) {
ci.setReturnValue(false);
}
}
}

View File

@@ -0,0 +1,95 @@
package com.replaymod.restrictions;
import com.replaymod.core.SettingsRegistry;
import com.replaymod.core.utils.Restrictions;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelDuplexHandler;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandler;
import net.minecraft.network.PacketBuffer;
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;
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.PlayerEvent;
import net.minecraftforge.fml.common.network.FMLEmbeddedChannel;
import net.minecraftforge.fml.common.network.FMLOutboundHandler;
import net.minecraftforge.fml.common.network.NetworkRegistry;
import net.minecraftforge.fml.common.network.internal.FMLProxyPacket;
import net.minecraftforge.fml.relauncher.Side;
import org.apache.logging.log4j.Logger;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@Mod(modid = ReplayModRestrictions.MOD_ID,
version = "@MOD_VERSION@",
acceptedMinecraftVersions = "@MC_VERSION@",
acceptableRemoteVersions = "*",
serverSideOnly = true,
useMetadata = true)
public class ReplayModRestrictions {
public static final String MOD_ID = "replaymod-restrictions";
public static Logger LOGGER;
private final SettingsRegistry settingsRegistry = new SettingsRegistry();
private FMLEmbeddedChannel channel;
@Mod.EventHandler
public void preInit(FMLPreInitializationEvent event) {
LOGGER = event.getModLog();
Configuration config = new Configuration(event.getSuggestedConfigurationFile());
config.load();
settingsRegistry.setConfiguration(config);
settingsRegistry.register(Setting.class);
}
@Mod.EventHandler
public void init(FMLInitializationEvent event) {
EventBus bus = FMLCommonHandler.instance().bus();
bus.register(this);
channel = NetworkRegistry.INSTANCE.newChannel(Restrictions.PLUGIN_CHANNEL, new RestrictionsChannelHandler()).get(Side.SERVER);
}
@Mod.EventHandler
public void postInit(FMLPostInitializationEvent event) throws IOException {
settingsRegistry.save(); // Save default values to disk
}
@ChannelHandler.Sharable
private static class RestrictionsChannelHandler extends ChannelDuplexHandler {}
@SubscribeEvent
public void onUserJoin(PlayerEvent.PlayerLoggedInEvent event) {
Map<String, byte[]> restrictions = new HashMap<>();
if (settingsRegistry.get(Setting.NO_XRAY)) restrictions.put("no_xray", new byte[0]);
if (settingsRegistry.get(Setting.NO_NOCLIP)) restrictions.put("no_noclip", new byte[0]);
if (settingsRegistry.get(Setting.ONLY_FIRST_PERSON)) restrictions.put("only_first_person", new byte[0]);
if (settingsRegistry.get(Setting.ONLY_RECORDING_PLAYER)) restrictions.put("only_recording_player", new byte[0]);
if (settingsRegistry.get(Setting.HIDE_COORDINATES)) restrictions.put("hide_coordinates", new byte[0]);
PacketBuffer buf = new PacketBuffer(Unpooled.buffer());
for (Map.Entry<String, byte[]> e : restrictions.entrySet()) {
byte[] bytes = e.getKey().getBytes();
buf.writeByte(bytes.length);
buf.writeBytes(bytes);
buf.writeByte(1);
buf.writeBytes(e.getValue());
}
FMLProxyPacket packet = new FMLProxyPacket(buf, Restrictions.PLUGIN_CHANNEL);
channel.attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.PLAYER);
channel.attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(event.player);
channel.writeAndFlush(packet).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
}
}

View File

@@ -0,0 +1,19 @@
package com.replaymod.restrictions;
import com.replaymod.core.SettingsRegistry;
public final class Setting<T> extends SettingsRegistry.SettingKeys<T> {
public static final Setting<Boolean> NO_XRAY = make("no_xray", false);
public static final Setting<Boolean> NO_NOCLIP = make("no_noclip", false);
public static final Setting<Boolean> ONLY_FIRST_PERSON = make("only_first_person", false);
public static final Setting<Boolean> ONLY_RECORDING_PLAYER = make("only_recording_player", false);
public static final Setting<Boolean> HIDE_COORDINATES = make("hide_coordinates", false);
private static <T> Setting<T> make(String key, T defaultValue) {
return new Setting<>("restrictions", key, defaultValue);
}
public Setting(String category, String key, T defaultValue) {
super(category, key, null, defaultValue);
}
}

View File

@@ -2,8 +2,10 @@ package com.replaymod.simplepathing;
import com.replaymod.core.ReplayMod;
import com.replaymod.core.events.SettingsChangedEvent;
import com.replaymod.replay.ReplayModReplay;
import com.replaymod.replay.events.ReplayCloseEvent;
import com.replaymod.replay.events.ReplayOpenEvent;
import com.replaymod.replay.gui.overlay.GuiReplayOverlay;
import com.replaymod.replaystudio.pathing.path.Keyframe;
import com.replaymod.simplepathing.SPTimeline.SPPath;
import com.replaymod.simplepathing.gui.GuiPathing;
@@ -19,6 +21,8 @@ import org.lwjgl.input.Keyboard;
@Mod(modid = ReplayModSimplePathing.MOD_ID,
version = "@MOD_VERSION@",
acceptedMinecraftVersions = "@MC_VERSION@",
acceptableRemoteVersions = "*",
clientSideOnly = true,
useMetadata = true)
public class ReplayModSimplePathing {
public static final String MOD_ID = "replaymod-simplepathing";
@@ -80,20 +84,34 @@ public class ReplayModSimplePathing {
}
}
private GuiReplayOverlay getReplayOverlay() {
return ReplayModReplay.instance.getReplayHandler().getOverlay();
}
private SPTimeline currentTimeline;
@Getter
private SPPath selectedPath;
@Getter
private long selectedTime;
public SPPath getSelectedPath() {
if (getReplayOverlay().timeline.getSelectedMarker() != null) {
selectedPath = null;
selectedTime = 0;
}
return selectedPath;
}
public boolean isSelected(Keyframe keyframe) {
return selectedPath != null && currentTimeline.getKeyframe(selectedPath, selectedTime) == keyframe;
return getSelectedPath() != null && currentTimeline.getKeyframe(selectedPath, selectedTime) == keyframe;
}
public void setSelected(SPPath path, long time) {
selectedPath = path;
selectedTime = time;
if (selectedPath != null) {
getReplayOverlay().timeline.setSelectedMarker(null);
}
}
public void setCurrentTimeline(SPTimeline newTimeline) {

View File

@@ -124,5 +124,8 @@ public net.minecraft.entity.EntityLivingBase field_184628_bn # activeItemStackUs
# EntityLivingBase
public net.minecraft.client.particle.Particle *
# ScreenShotHelper
public net.minecraft.util.ScreenShotHelper func_74290_a(Ljava/io/File;)Ljava/io/File; # getTimestampedPNGFileForDirectory
# Example
# public net.minecraft.package.ClassName func_some_id(Ljava/lang/Class;IZS)V # methodName

View File

@@ -134,6 +134,22 @@
"screenshots": [],
"dependencies": []
},
{
"modid": "replaymod-restrictions",
"name": "Replay Mod - Restrictions",
"description": "Server-side Restrictions Module of the ReplayMod - Restrict what clients can do in replays",
"version": "${version}",
"mcversion": "${mcversion}",
"url": "https://replaymod.com",
"updateUrl": "https://replaymod.com/download",
"authorList": [
"CrushedPixel",
"johni0702"
],
"logoFile": "replaymod_logo.png",
"screenshots": [],
"dependencies": []
},
{
"modid": "replaymod-compat",
"name": "Replay Mod - Compatibility",

View File

@@ -0,0 +1,12 @@
{
"required": false,
"package": "com.replaymod.compat.mapwriter.mixin",
"mixins": [],
"server": [],
"client": [
"MixinMinecraft"
],
"compatibilityLevel": "JAVA_8",
"minVersion": "0.6.11",
"refmap": "mixins.replaymod.refmap.json"
}

View File

@@ -10,5 +10,6 @@
"MixinShadersRender"
],
"compatibilityLevel": "JAVA_8",
"minVersion": "0.6.11",
"refmap": "mixins.replaymod.refmap.json"
}

View File

@@ -0,0 +1,12 @@
{
"required": true,
"package": "com.replaymod.extras.playeroverview.mixin",
"mixins": [],
"server": [],
"client": [
"MixinRender"
],
"compatibilityLevel": "JAVA_8",
"minVersion": "0.6.11",
"refmap": "mixins.replaymod.refmap.json"
}

View File

@@ -12,5 +12,6 @@
"MixinWorldClient"
],
"compatibilityLevel": "JAVA_8",
"minVersion": "0.6.11",
"refmap": "mixins.replaymod.refmap.json"
}

View File

@@ -1,15 +1,17 @@
{
"required": true,
"package": "com.replaymod.render.mixin",
"mixins": [
"mixins": [],
"server": [],
"client": [
"MixinEntityRenderer",
"MixinFrustum",
"MixinParticleManager",
"MixinRender",
"MixinRenderGlobal",
"MixinRenderManager"
],
"server": [],
"client": [],
"compatibilityLevel": "JAVA_8",
"minVersion": "0.6.11",
"refmap": "mixins.replaymod.refmap.json"
}

View File

@@ -1,11 +1,12 @@
{
"required": true,
"package": "com.replaymod.replay.mixin",
"mixins": [
"mixins": [],
"server": [],
"client": [
"MixinGuiSpectator",
"MixinParticleManager",
"MixinPlayerControllerMP",
"MixinRenderArmorStand",
"MixinRenderArrow",
"MixinRenderItem",
"MixinRenderLivingBase",
@@ -14,8 +15,7 @@
"MixinViewFrustum",
"MixinWorldClient"
],
"server": [],
"client": [],
"compatibilityLevel": "JAVA_8",
"minVersion": "0.6.11",
"refmap": "mixins.replaymod.refmap.json"
}