Compare commits

..

1262 Commits

Author SHA1 Message Date
96bce7f38d free moution blur optimization 2026-07-08 18:10:13 +04:00
4e7c027ec0 add motion blur feature 2026-07-08 02:13:44 +04:00
9be1fd8f6b focus gizmo add 2026-07-08 01:16:31 +04:00
0fae99c535 add FOV feature 2026-07-07 06:35:07 +04:00
9f51c59508 DOF polished 2026-07-07 05:04:16 +04:00
6024227716 Update lang submodule 2026-07-02 08:44:23 +04:00
69013c2124 working DOF 2026-07-01 04:48:45 +04:00
3b070a7efc thin lens aproximation mode MVP 2026-06-30 22:14:05 +04:00
646577e97f test worked 2026-06-30 11:44:24 +04:00
Jonas Herzig
a4c8dafa07 Release 2.6.26 2026-04-14 12:41:25 +02:00
Jonas Herzig
6e64f2acd0 Fix no texture animations when rendering on 1.21.11+ 2026-04-14 12:39:59 +02:00
Jonas Herzig
27d5432fff Update to 26.1 2026-04-14 12:39:59 +02:00
Jonas Herzig
b72fad4055 Update to Gradle 9, Loom 1.15, EGT 0.7 2026-04-06 07:48:51 +02:00
Jonas Herzig
f08607a599 Release 2.6.25 2025-12-16 16:38:50 +01:00
Jonas Herzig
a5dec5db25 Fix hiding of player nametags on 1.21.9+ 2025-12-16 16:35:20 +01:00
Jonas Herzig
dad0ac18a3 Fix missing fabric-resource-loader-v1 dependency 2025-12-16 16:35:20 +01:00
TKD_Kedis
caffd41358 Update to 1.21.11 (#1106)
Co-authored-by: Jonas Herzig <me@johni0702.de>
2025-12-16 16:34:53 +01:00
Jonas Herzig
713db19928 Release 2.6.24 2025-10-20 19:43:35 +02:00
Jonas Herzig
d3929cb6dc Update to 1.21.9/10 2025-10-12 21:26:28 +02:00
Jonas Herzig
e6db9daf80 Update key and mouse handling in preparation for 1.21.9 2025-10-12 20:21:03 +02:00
Jonas Herzig
f299644254 Reimplement runLater without relying on MC's renderTaskQueue
Cause it's gone in 1.21.9, and really not necessary to begin with since
we have our own executor already.
2025-10-12 16:10:29 +02:00
Jonas Herzig
4d644a44c3 Release 2.6.23 2025-07-05 09:40:33 +02:00
Jonas Herzig
85fb0847ee Update to 1.21.7 2025-06-30 18:13:20 +02:00
Jonas Herzig
926f6b6624 Fix depth export on 1.21.5+ 2025-06-14 08:49:46 +02:00
Jonas Herzig
928094bd27 Fix recording in minimal mode on 1.20.6+ 2025-06-13 14:15:03 +02:00
Jonas Herzig
d7b563768f Move replay camera entity creation into dedicated mixin 2025-06-13 14:02:40 +02:00
Jonas Herzig
8246085b84 Fix first person hand missing when shaders are enabled with Iris 1.7+ 2025-06-13 10:49:02 +02:00
Jonas Herzig
55e6044bdd Release 2.6.22 2025-05-13 16:09:25 +02:00
Jonas Herzig
a8c1d19240 Update to 1.21.5 2025-04-28 11:14:37 +02:00
Jonas Herzig
7aad4dcfd9 Update Iris url 2025-04-05 13:10:31 +02:00
Jonas Herzig
b2dde7da97 Release 2.6.21 2024-12-15 10:24:51 +01:00
Jonas Herzig
f21fed031c Update to 1.21.4 2024-12-15 10:24:12 +01:00
Jonas Herzig
7f7b4e1891 Fix camera looking straight down on 1.21.2+ 2024-12-07 17:05:59 +01:00
Jonas Herzig
50cfcbabfb Release 2.6.20 2024-11-03 18:17:58 +01:00
Jonas Herzig
8cf598d781 Fix transfer packet log spam 2024-11-03 17:44:39 +01:00
Jonas Herzig
14229ef1fe Fix LoginHelloS2CPacket being recorded on some servers 2024-11-03 17:44:39 +01:00
Jonas Herzig
17d87faa34 Update to 1.21.2 2024-11-03 17:44:28 +01:00
Jonas Herzig
193e51b3c2 Release 2.6.19 2024-09-09 13:27:52 +02:00
Jonas Herzig
a0c5f25e61 Update ReplayStudio 2024-09-09 13:22:04 +02:00
Jonas Herzig
8503ff0e67 Remove unnecessary manual mappings 2024-09-09 13:22:04 +02:00
Jonas Herzig
73fe633819 Update preprocessor 2024-09-09 13:22:04 +02:00
Jonas Herzig
9f5a8c3d0f Release 2.6.18 2024-07-12 12:42:10 +02:00
Jonas Herzig
5959da8744 Fix LoginSuccess packet being recorded with incorrect id on 1.20.2-4 2024-07-12 12:38:17 +02:00
Jonas Herzig
6de0e37d96 Release 2.6.17 2024-07-10 22:06:28 +02:00
Jonas Herzig
5b766b4fe7 Fix included mod jars being exploded into outer jar
Caused by this stupid behavior of the shadow plugin:
https://github.com/johnrengelman/shadow/issues/111

Fixes #976
2024-07-10 22:04:38 +02:00
Jonas Herzig
203aad687d Release 2.6.16 2024-07-10 19:37:17 +02:00
Jonas Herzig
1836b7fb18 Fix Iris shader animation time on 1.21 2024-07-10 19:07:19 +02:00
Jonas Herzig
ca6ae4b983 Fix ODS export with Iris 1.7 2024-07-10 19:07:00 +02:00
Jonas Herzig
d2cdcb02fc Remove unnecessary isTransitive exclusion
Now that it's using Modrinth maven, there won't be any transitive
dependencies anyway.
2024-07-10 18:20:19 +02:00
Jonas Herzig
b537822d3c Enable Gradle daemon
Now that we no longer have to deal with ForgeGradle, we can actually use
this pretty fundamental Gradle feature again.
2024-07-10 17:36:01 +02:00
Jonas Herzig
6b5993ad64 Fix post-screenshot popup being invisible while HUD is hidden 2024-07-07 11:02:41 +02:00
Jonas Herzig
b4ead9e064 Update ReplayStudio
1e96fda Fix SquashFilter dropping config-phase custom packets
2024-07-07 10:32:55 +02:00
Jonas Herzig
8adb65d724 Move old mapping files to standard location 2024-07-01 12:48:23 +02:00
Jonas Herzig
329530de0e Update ReplayStudio so it works via includeBuild 2024-07-01 12:24:53 +02:00
Jonas Herzig
a04fd5b00b Move ReplayStudio submodule into libs folder 2024-06-30 20:27:59 +02:00
Jonas Herzig
486056de24 Fix recording whith login-phase custom packets 2024-06-25 10:31:12 +02:00
Jonas Herzig
2b2ab2ba8b Fix time keyframe lines rendering below timeline 2024-06-25 10:30:43 +02:00
Jonas Herzig
d70e41006d Add ReplayStudio as submodule instead of JitPack
Because JitPack breaks Gradle variants so we get the Java 17 jar even
when we use the Java 8 variant.

This works for building via Gradle. However it does not work for usage
from IntelliJ, where you must currently publishToMavenLocal ReplayStudio
and then depend on that version. Still looking for a better solution
there.
2024-06-23 21:41:18 +02:00
Jonas Herzig
a4e0abec7f Update to 1.21 2024-06-23 20:33:41 +02:00
Jonas Herzig
1433fccaf1 Update EGT to 0.6.1 2024-06-23 20:24:57 +02:00
Jonas Herzig
310dc90e11 Remove WrappedTimer 2024-06-23 20:24:57 +02:00
Jonas Herzig
454e990849 Replace InputReplayTimer with Mixin 2024-06-23 20:24:57 +02:00
Jonas Herzig
76a68b7867 Prevent pausing in the middle of a bundle packet
Because certain actions (e.g. switching to Quick Mode) will fail in this
state.
2024-06-23 20:24:57 +02:00
Jonas Herzig
5218feb6b6 Update to 1.20.6 2024-06-23 20:24:57 +02:00
Jonas Herzig
3f12413c6b De-duplicate recording channel configuration 2024-06-23 20:07:57 +02:00
Jonas Herzig
675134e6d6 Split outbound handler from FullReplaySender
This because with 1.20.6, MC will require outbound messages to reach its
handlers to switch between protocol versions. So we need our drop
handler two be at the very end of the write processing chain.
2024-06-23 20:07:57 +02:00
Jonas Herzig
4df627029c Fix race condition in PacketListener
The ChannelHandlerContext was only set on the next received packet,
however `save` could be called before that happened.
2024-06-23 20:07:57 +02:00
Jonas Herzig
046a50f326 Target WorldRenderer in Mixin_PostRenderWorldCalback 2024-06-23 20:07:57 +02:00
Jonas Herzig
f388e4af54 Update MixinExtras and include it on all Fabric versions 2024-06-23 20:07:57 +02:00
Jonas Herzig
8900d5a4fb Split MixinGameRenderer into multiple mixins 2024-06-18 14:50:34 +02:00
Jonas Herzig
acd56a7ba3 Remove player list packet entry workaround
No longer using ForgeGradle \o/
2024-05-13 17:33:06 +02:00
Jonas Herzig
c74ef8c0e4 Let Minecraft handle packet decoding during recording
We've done this ourselves only because it was easier at the beginning.
However with 1.20.5, Minecraft's packet decoding became substantially
more sophisticated, to the point that it's probably a bad idea to try
to do it ourselves.

Additionally, getting the packet ids, which we require for identifying
the packets which we want to decode, has becomes significantly more
difficult too, and this way it's a simple instanceof check.
2024-05-13 17:01:03 +02:00
Jonas Herzig
fe0677923c Let Minecraft handle packet decoding during playback
We've done this ourselves only because it was easier at the beginning.
However by now (and especially with 1.20.5), Minecraft's packet decoding
has become substantially more sophisticated, to the point that it's
probably a bad idea to try to do it ourselves.

This commit gives back that responsibility to Minecraft by adding the
standard decoder (and encoder because it's required for proper
connection state management on modern versions) to our channel pipeline,
changes the full and the quick replay sender to send raw `ByteBuf`s into
the front of the channel, and moves the posititon of the full replay
sender in the channel pipeline such that it can see and modify packets
after Minecraft has decoded them.
2024-05-13 15:25:50 +02:00
Jonas Herzig
ad49a69f37 Switch from FG to archloom + essential-gradle-toolkit
- Upgrade Gradle to 8.7
- Increase build daemon max memory to 8GB because archloom can compile a lot
  more projects at the same time.
- Disable Minecraft 1.8 (not 1.8.9) because archloom fails to set up for that
2024-05-12 14:24:43 +02:00
Jonas Herzig
706d46f6a9 Release 2.6.15 2024-03-10 18:05:59 +01:00
Jonas Herzig
c11fffedc1 Update ReplayStudio
95a7c07 Process PlayerPositionRotation packet in SquashFilter
603bdce Create dedicated class for PacketPlayerPositionRotation
88343aa Fix incorrect order of ViaVersion-emitted packets
9ebaa97 Fix 1.20 to 1.20.2 ViaVersion conversion
c490e9f Update ViaVersion
bcccb2c Fix Reconfigure packets not being filtered out
a0df6c9 Fix ConfigFinish being emitted before other config packets
a672023 Separate pre-join-game packets from login-phase packets
a70161c Emit Reconfigure packet when required
074d78d Separate "emit first" list from "login phase" list
20a3bf9 Reorder loginPhase and configurationPhase code
2024-03-10 18:02:19 +01:00
Jonas Herzig
ba6078e080 Update jGui, fixes JPG loading on 1.20.4+ 2024-03-10 16:30:25 +01:00
Jonas Herzig
f8379fa317 Fix thread-unsafe server resource pack playback 2024-03-10 16:29:31 +01:00
Jonas Herzig
61ef87eebe Release 2.6.14 2023-12-12 15:11:49 +01:00
Jonas Herzig
6e5536305b Bump 1.20.2 fabric-api to version 0.92.2 2023-12-09 10:43:26 +01:00
Jonas Herzig
1bf1e0d7be Port to 1.20.4 2023-12-09 10:43:26 +01:00
Jonas Herzig
faebeb525a Port to 1.20.3-rc1 2023-12-03 18:51:37 +01:00
Jonas Herzig
43576efeb3 Convert JPG images to PNG
Minecraft 1.20.3 no longer supports loading JPG images.
2023-12-03 16:28:28 +01:00
Jonas Herzig
b8ab7aa5a7 Port to 1.20.2 2023-11-27 19:40:42 +01:00
Jonas Herzig
e8f9234bf0 Fix EXR rendering failing on Windows on MC 1.20+ 2023-11-27 17:55:13 +01:00
Jonas Herzig
329ac51309 Fix rubber-banding on rotation of entity in vehicle (fixes #846) 2023-11-13 13:51:47 +01:00
Jonas Herzig
f506d5ac65 Fix missing networking-api-v1 on 1.16.4/5
We recently bumped the fabric-api version there, and newer versions of the v0
api just delegate to the v1 one now, so we need to include that there as well.
2023-10-18 12:09:59 +02:00
Jonas Herzig
96dbc54a53 Fix Iris dependency
Seems like it no longer builds on JitPack and their cache has expired.
2023-10-18 12:09:13 +02:00
Jonas Herzig
094ca1ce01 Release 2.6.13 2023-06-20 09:44:55 +02:00
Jonas Herzig
24237557f1 Port to 1.20.1 2023-06-20 09:31:07 +02:00
Jonas Herzig
d8c6ce9b5e Clean up 1.17 .gitkeep file 2023-06-12 11:04:25 +02:00
Jonas Herzig
7726550131 Port to MC 1.20 2023-06-12 10:28:08 +02:00
Jonas Herzig
96a05e256f Add MixinExtras on 1.16.4+
We'll use it in 1.20 mixins.
Unclear what minimal fabric-loader version it requires, so in the interest of
keeping older versions compatible with OptiFabric (old versions of which aren't
compatible with the latest fabric-loader), we'll add it to 1.16.4+ only.
2023-06-12 10:28:08 +02:00
Jonas Herzig
587eff59fe Rewrite main menu button injection code (closes #577, fixes #621)
For 1.16.4+ only because we use parts of fabric-screen-api.
2023-06-12 10:23:21 +02:00
Jonas Herzig
f92d6f5281 Fix overlay gui elements not moving on resize (fixes #841) 2023-06-12 09:07:45 +02:00
Jonas Herzig
fb4ae1b60a Delegate bindTexture to jGui's MCVer 2023-06-12 09:05:42 +02:00
Jonas Herzig
0c5009db8d Drop 1.17 in favor of 1.17.1
Primarily because fabric-api for 1.17 never received any updates, so
fabric-screen-api isn't available for it.
2023-06-12 08:49:15 +02:00
Jonas Herzig
81509a9acf Release 2.6.12 2023-03-28 12:24:16 +02:00
Jonas Herzig
fd740a4af6 Update ReplayStudio 2023-03-28 12:23:18 +02:00
Jonas Herzig
36741b97fa Release 2.6.11 2023-03-26 19:43:21 +02:00
Jonas Herzig
bf32672536 Fix active timeline changes affecting render queue (fixes #814)
The `Timeline` type is mutable, so we need to create a copy before we pass it to
GuiKeyframeRepository because we don't want anything stored in there (or more
specifically in render queue which can also be added to from that gui) to be
affected by subsequent changes.
2023-03-26 19:21:30 +02:00
Jonas Herzig
8037a9ad30 Fix ridden boat missing when joining 1.18+ Spigot server 2023-03-26 18:59:14 +02:00
Jonas Herzig
78bd060249 Port to MC 1.19.4 2023-03-26 18:58:49 +02:00
Jonas Herzig
ae5f893014 Release 2.6.10 2022-12-09 13:16:17 +01:00
Jonas Herzig
043664ab0c Fix multiplayer recording on 1.19.3 (fixes #803) 2022-12-09 13:14:56 +01:00
Jonas Herzig
9a5b88fd48 Release 2.6.9 2022-12-07 16:35:51 +01:00
Jonas Herzig
77ce90b2b0 Disable MixinShaderRenderChunk on 1.18+
It's only required for legacy Optifine doesn't even apply any more as of 1.18,
so we can just disable it on modern versions so it doesn't spam the log.
2022-12-07 16:34:55 +01:00
Jonas Herzig
3816671207 Fix depth export on 1.14.4 2022-12-07 16:34:55 +01:00
Jonas Herzig
000ff19749 Fix depth export while spectating on 1.12.2 and below (fixes #785) 2022-12-07 16:34:55 +01:00
Jonas Herzig
ffcca61b5b Fix running in 1.14.4 dev environment
First version of modmenu in its repo appears to be for 1.15, so we need to
disable it in 1.14.
2022-12-07 16:34:55 +01:00
Jonas Herzig
d571e8fed5 Port to MC 1.19.3
Building against 1.19.3-rc3 for now because 1.19.3 has yet to release.
ReplayStudio/ViaVersion is already targeting the release version though.
2022-12-07 16:34:55 +01:00
Jonas Herzig
e8ea70aabc Port to MC 1.19.2 (fixes #801) 2022-12-07 16:34:50 +01:00
Jonas Herzig
e0a682a5df Fix armor missing after dimension change (fixes #791)
The respawn packet re-creates the player entity, so we need to re-send its
armor (and technically also the riding and sleeping state, though that probably
wouldn't ever have caused issues in practice because a respawn will implicitly
reset those, unlike your inventory which is preserved).
2022-12-06 18:01:07 +01:00
Jonas Herzig
19404032fe Fix jGui resource pack when using per-version run folder 2022-12-06 17:51:55 +01:00
Jonas Herzig
bee13fc9a1 Replace projection matrix Redirect with ModifyArg
Should be better for compatibility because multiple mods can ModifyArg but only
one can Redirect, and will be easier to port to 1.19.3.
2022-12-06 17:37:15 +01:00
Jonas Herzig
3cec8fde9f Release 2.6.8 2022-08-10 14:29:15 +02:00
Jonas Herzig
cce65ec76d Ignore expired player public keys during replay
These would otherwise fail to be initialized and cause the game to disconnect
itself on the first chat message from the corresponding player.
2022-08-10 14:22:21 +02:00
Jonas Herzig
06f1e0c36c Fix chat message validation failure when Show Chat is off on 1.19.1+ 2022-08-10 14:22:21 +02:00
Jonas Herzig
35d1b7f24b Fix game crashing if client disconnects from replay during jump 2022-08-10 13:47:47 +02:00
Jonas Herzig
82d4408567 Add missing MC 1.19.1 .gitkeep file 2022-07-31 14:38:54 +02:00
Jonas Herzig
e8ff8a2066 Release 2.6.7 2022-07-31 13:46:49 +02:00
Jonas Herzig
ff98260216 Fix build on MC 1.8 2022-07-31 13:46:01 +02:00
Jonas Herzig
c34f75d95a Fix item staying visually equipped after being dropped (fixes #658) 2022-07-31 13:03:43 +02:00
Jonas Herzig
62b9cd0538 Use DefaultedList for equipment tracking
Because on 1.11+ a `null` item stack is not something that should exist.
This then also allows us to compare item stacks by value rather than only by
reference, potentially saving a few redundant entity equipment update
packets (but more importantly, also allows us to store a copy instead of the
original, which will be important for the next commit).
2022-07-31 13:03:43 +02:00
Jonas Herzig
42d04d123c Deduplicate code 2022-07-31 12:55:54 +02:00
Jonas Herzig
7550e3dcb7 Fix race conditions in movement packet filtering (fixes #760)
We cannot filter this packet purely on the netty thread because our filter
depends on the current camera position (if it's too far, we do want to teleport
it closer) and accessing the camera is only safe from the main thread.

Previously the second part had not been considered which could lead to race
conditions where the camera may not yet exist on the netty thread at time of
handling. These appear to have gotten the wholly inappropriate "just put a null
check around it" treatment, but that means that the filter sometimes doesn't
work (hence the bug report).

This commit changes handling such that all access to `allowMovement` is always
done on the main thread and then moves the filtering there as well. And
therefore filtering should now work properly.
2022-07-31 12:55:54 +02:00
Jonas Herzig
af3f6ddbe2 Always handle PlayerPositionLookS2CPacket manually 2022-07-31 12:48:39 +02:00
Jonas Herzig
962f08718f Fix "Show Chat" setting on 1.19+ (fixes #757) 2022-07-31 10:38:14 +02:00
Jonas Herzig
a9401a9779 Update ModMenu 2022-07-31 10:38:07 +02:00
Jonas Herzig
400ec6bda5 Port to MC 1.19.1 2022-07-31 10:37:22 +02:00
Jonas Herzig
bdea84b9a2 Remove unused GuiMainMenuAccessor 2022-07-31 10:22:20 +02:00
Jonas Herzig
6db47ee070 Updated broken forge docs link 2022-07-31 10:22:11 +02:00
Jonas Herzig
a95edaa31d Update translations 2022-07-31 09:30:19 +02:00
Kepler-17c
89d771fdbf Updated the compatibility section on shaders 2022-07-17 23:10:24 +02:00
bela333
f0299fed66 Update documentation to include compatible Sodium 2022-07-17 23:06:17 +02:00
bela333
05387b0ac7 Modified FREX notice 2022-07-17 23:05:27 +02:00
Jonas Herzig
738320e896 Update translations 2022-07-17 23:03:44 +02:00
Jonas Herzig
6e3d30e41b Fix thread unsafety in OpenGlToBitmapProcessor
Sharing the temporary `row` and `rowSwap` buffers between different calls to the
processor is not safe because it will be used by multiple threads.
As a result some of the rows in the image could randomly get corrupted.

This commit gets rid of the cached buffers (the value of which questionable
anyway) and simply re-uses the same code which other processors use.
2022-07-17 17:08:03 +02:00
Jonas Herzig
633ac10d89 Fix main hand in first person spectator view (fixes #731) 2022-07-17 17:08:03 +02:00
Jonas Herzig
42aef017c1 Fix skin in Player Overview and first person on 1.8.9 (fixes #749)
No clue why `getResourceLocationForPlayerUUID` was implemented the way it was,
that commit dates back to 2015 (332c36a), but if the skin isn't loaded yet, it
won't load it, so sometimes it just won't show properly in first person and in
the Player Overview.
This commit just calls `AbstractClientPlayer.getSkinTexture` instead.

Unclear which MC versions are affected. At some point before 1.16.4 something
else was introduced which loads the skin for us, hence why modern versions were
not affected.
2022-07-17 16:02:41 +02:00
Jonas Herzig
3526ec526c Release 2.6.6 2022-06-26 14:49:13 +02:00
Jonas Herzig
7457f9c13b Increase maximum camera speed by about an order of magnitude 2022-06-26 13:54:52 +02:00
Jonas Herzig
08c86ce574 Enable compression for OpenEXR if we have the cpu power for it 2022-06-26 13:33:13 +02:00
Jonas Herzig
517591d72a Encode OpenEXR and PNG frames in parallel 2022-06-26 13:32:58 +02:00
Jonas Herzig
a3f4049322 Reduces minimum speed of classic camera controller
Two blocks per second is still quite fast, so this commit reduces the minimum to
a tenth of that, allowing for much finer control.
2022-06-26 12:30:23 +02:00
Jonas Herzig
4f9a730b6d Fix classic camera speed changing way too quickly (fixes #719)
On my system, a single scroll tick results in 120 calls, which is fine for the
vanilla camera controller because it has a range of 2000, but the classic
controller only has a range of 36, making it impossible to select anything but
the extremes.
This commit changes the size of the range to match that of the vanilla controller.
2022-06-26 12:28:07 +02:00
Jonas Herzig
40f07279cf Load tinyexr in its own class loader
That way we can simply use whatever version we want and aren't tied to the
version of lwjgl which MC provides.

This fixes the OpenEXR export on 1.19 crashing either due to the windows
workaround or due to differing lwjgl versions (depending on OS).
And also enables OpenEXR export on MC versions using lwjgl2 (1.12.2 and below).
2022-06-26 11:57:24 +02:00
Jonas Herzig
814d0b7c17 Update ReplayStudio
Fixes fatal QuickMode error introduced with the 1.19 update.
2022-06-15 14:18:23 +02:00
Jonas Herzig
13ac8dcf0a Record raw packets instead of re-encoding decoded packets
Until now, recording worked by injecting right before the vanilla packet
handler. At that point it was receiving packet classes and had to re-encode them
to store them in the replay file. However, not all decoded packets can
necessarily be re-encoded without errors, requiring us to have a bunch of
workarounds.

This commit changes the way recording works by injecting right before the
decoder. It therefore receives the raw bytebufs and no longer has to deal with
the re-encode issue.
2022-06-15 14:18:23 +02:00
Jonas Herzig
df11ba2e36 Port to MC 1.19 2022-06-12 13:47:41 +02:00
Jonas Herzig
9ce25f711f Port to MC 1.19-pre3 2022-05-27 10:05:50 +02:00
Jonas Herzig
9f8957f468 Migrate away from deprecated fabric-api modules 2022-05-26 08:19:34 +02:00
Jonas Herzig
f595d9ca23 Release 2.6.5 2022-05-01 21:25:21 +02:00
Jonas Herzig
716df74893 Fix first person (cross)bow model animation on 1.9+ (fixes #708) 2022-05-01 21:06:24 +02:00
Jonas Herzig
4364347a19 Update ReplayStudio
6fc8e20 Fix incorrect relative packet order in squash filter (fixes #718)
2022-05-01 20:34:26 +02:00
Jonas Herzig
8b2d42f801 Fix broken fog when using Chroma Key with Sodium (fixes #726) 2022-05-01 20:05:00 +02:00
Jonas Herzig
f2c96174bc Fix terrain culling not being updated for omnidirectional rendering
Terrain culling is only updated when the camera position or rotation changes.
For omnidirectional rendering, we don't change the camera directly though, we
rotate way earlier so we can consistently get before any other effects. As a
result, the terrain frustum culling wasn't updated between render passes
resulting in missing terrain.
This was largely masked by the fact that we used to call GameRenderer.onResize
every pass (even when the size hadn't changed) but fixing that made this issue
become apparent.
2022-04-17 12:01:40 +02:00
Jonas Herzig
497b8440ca Call Window.onFramebufferSizeChanged to resize (fixes #705)
Instead of setting the the values via accessor and calling the handler directly.
This allows mods like ResolutionControl+ to properly resize its internal
framebuffers as well.
2022-04-17 12:01:40 +02:00
Jonas Herzig
5be57681af Completely bypass Minecraft when window is resized during rendering
Should fix issues where resizing affects the render result.
2022-04-17 12:01:40 +02:00
Jonas Herzig
fd9be55f79 Remove caching of ScaledResolution from Window shim
It'll become stale if the code holds on to the Window shim object for a longer
duration, and there's no reliable mechanism to invalidate it.
2022-04-17 12:01:40 +02:00
Jonas Herzig
4558793030 Remove unless window size tracking
The only thing we care about is the framebuffer size, cause that will differ
between game and progress gui rendering. The window size will be the same (real)
size for both.
2022-04-17 12:01:40 +02:00
Jonas Herzig
fb36fc2ba8 Fix render progress framebuffer never being deleted 2022-04-10 18:20:26 +02:00
Jonas Herzig
01d37ab2cb Split gui window/framebuffer management code from VideoRenderer 2022-04-10 18:20:16 +02:00
Jonas Herzig
a6c09bcb8a Fix crash when window is minimized on Windows 2022-04-10 15:33:42 +02:00
Jonas Herzig
fb38a20465 Fix path separator in replay name
Would probably have been caught by the write check as well, except in the
specific case where the folder exists, e.g. `../`
2022-04-10 13:52:14 +02:00
Jonas Herzig
d6c6220bdd Fix invalid characters in replay name on Windows (fixes #715) 2022-04-10 13:48:47 +02:00
Jonas Herzig
463b947c2b Suppress fabric-screen-handler-api during playback (fixes #713) 2022-04-10 13:36:50 +02:00
Jonas Herzig
8e140e8d01 Release 2.6.4 2022-03-09 07:09:00 +01:00
Jonas Herzig
c010a437fc Orient camera for ODS in game instead of in vertex shader
This makes it work more like regular 360 mode and is generally more compatible
because it doesn't require the frustum culling workarounds which the GPU
solution needs.
In particular, this fixes frustum culling with newer sodium versions (which no
longer use the vanilla intersection checking method) and fixes the clouds on
modern Iris (which seems to be using a different shader program for clouds).
2022-03-09 07:08:02 +01:00
Jonas Herzig
f2425a693a DRY (Iris)ODSFrameCapturer 2022-03-09 07:08:02 +01:00
Jonas Herzig
9df2035ca9 Update translations 2022-03-09 07:08:02 +01:00
Jonas Herzig
4aa667fe04 Port to MC 1.18.2 (closes #697) 2022-03-09 07:08:02 +01:00
Jonas Herzig
1fa027f362 Enable Quick Mode for 1.8.x 2022-03-06 13:39:49 +01:00
Jonas Herzig
74049dad77 Update ReplayStudio
9c5dec8 Fix writing of empty chunk load packet on 1.8.x (fixes #636)
3d8573f Fix writing of respawn packet on 1.8.x
39a85f7 Fix exception when cache file has invalid gzip header (fixes #535)
2022-03-06 13:39:49 +01:00
Jonas Herzig
c146aa145c Fix stereoscopic eye offset on 1.16+
The mapping between intermediary name on 1.15.2 and yarn on 1.16.1 has already
been added in the previous commit.
2022-03-06 13:39:49 +01:00
Jonas Herzig
ee6b53b247 Fix incorrect FOV and aspect during 360 render on 1.16+ 2022-03-06 13:39:49 +01:00
Jonas Herzig
1efb17e144 Fix ODS rendering on Iris 1.1.3+ (fixes #693) 2022-03-06 13:39:49 +01:00
Jonas Herzig
8573a9b208 Prevent jumping while path is playing (closes #694) 2022-03-06 13:39:49 +01:00
Jonas Herzig
0356fef61d Fix crash when receiving resource pack on 1.8-1.12.2 (fixes #86) 2022-03-06 13:39:49 +01:00
Jonas Herzig
f9c58a1165 Try raw file name before percent encoding it (closes #536) 2022-03-06 13:39:49 +01:00
Jonas Herzig
d178c0980e Log when replays are opened (closes #565) 2022-03-06 13:39:49 +01:00
Jonas Herzig
b8cf7e6df4 Fix scrolling while replay paused on 1.12.2 and below (fixes #590) 2022-03-06 13:39:49 +01:00
Jonas Herzig
2e34a2abd9 Fix render timer breaking when system time changes (fixes #633)
Unlike `currentTimeMillis`, `nanoTime` is guaranteed to be relative to a
fixed point in time, regardless of system or wall-clock time.
2022-03-06 13:39:49 +01:00
Jonas Herzig
e26480f041 Fix "Please wait" when jumping not being centered (fixes #646) 2022-03-06 13:39:49 +01:00
Jonas Herzig
a8d05a2bca Skip mod compat warning screen when in render queue (fixes #653) 2022-03-06 13:39:49 +01:00
Jonas Herzig
7615499cef Add option to preserve alpha channel in export (closes #661)
Default off cause it being on by default had confused quite a few people.
2022-03-06 13:39:49 +01:00
Jochem
d9da2e135c Sync world border animation & movement to Replay speed
Fixes an issue where the world border would move at normal speed when speeding up or slowing down the replay, and also at an incorrect speed when rendering the replay, causing it to get out of sync with the rest of the world.

Co-authored-by: Jonas Herzig <me@johni0702.de>
2022-03-06 13:39:49 +01:00
Jonas Herzig
fe67d7fa14 Link to our docs in the "Missing ffmpeg" screen (closes #663) 2022-03-06 13:39:49 +01:00
Jonas Herzig
fb7900d805 Fix missing hand with Iris 1.1.3 and above (fixes #638) 2022-03-06 13:39:49 +01:00
Jonas Herzig
4a5df2ad6d Use GameRenderer.renderHand boolean field instead of mixin
Should be more compatible with mods which replace the entire renderHand
method (thereby making our mixin non-applicable), at least as long as these mods
check `renderHand` as well (Iris explicitly does).

This will become important once #638 is fixed.
2022-03-06 13:39:10 +01:00
Jonas Herzig
6cc370a117 Workaround Java breaking with symlinks (fixes #660) 2022-03-05 17:21:38 +01:00
Jonas Herzig
abfb3d46f3 Use per-version folder for pack.mcmeta
Comments are not supported here, and depending on the exact environment, that
may break stuff (seems to only happen on fabric in dev).
2022-03-05 17:21:38 +01:00
Jonas Herzig
0b8a2a107c Use separate thread to send packets, even in sync mode (fixes #674) 2022-03-05 17:21:38 +01:00
Andrew S
7e9a1e7c13 Fix Render GUI on Retina Screens (fixes #338)
window.getFramebufferWidth/Height() should be used instead of window.getWidth/Height()

Co-authored-by: Jonas Herzig <me@johni0702.de>
2022-02-27 11:14:57 +01:00
Jonas Herzig
e378ae8f93 Fix entities disappearing on 1.16.1 and 1.15.2 client (fixes #657) 2022-02-27 10:57:49 +01:00
Jonas Herzig
9528a5761c Update old ModMenu versions
To use the new maven group and for compatibility with newer fabric-loader.
2022-02-27 10:54:19 +01:00
Jonas Herzig
39ccea931d Release 2.6.3 2021-12-11 11:19:41 +01:00
Jonas Herzig
841c99148e Fix initial entity rotation getting lost (fixes #619)
This fixes the rotation of already existing entities that just got sent to the
client. Those get spawned with their rotation, which we didn't capture. This
commit fixes that by initializing our tracked rotation to NaN and returning the
original rotation until the tracked one is initialized (we do it this way rather
than initializing during the spawn packet handling because there are many spawn
packets, especially with modded, and we cannot possibly inject into all of
them).
This does not fix the rotation of newly placed entities (cause they seem to get
spawned with 0/0 and then get teleported to their correct rotation). The
previous commit fixed that case by capturing the rotation from the teleport
packet.
2021-12-11 11:00:57 +01:00
Jonas Herzig
e472713d1c Fix rotation from entity teleport getting lost (related to #619)
This fixes the rotation of newly placed entities (cause they seem to get spawned
with 0/0 and then get teleported to their correct rotation, which we didn't
capture).
This does not fix the rotation of already existing entities that just got sent
to the client, those already get spawned with their rotation, which we don't yet
capture. The following commit fixes that.
2021-12-11 10:52:30 +01:00
Jonas Herzig
1d76427a4d Release 2.6.2 2021-12-10 11:52:58 +01:00
Jonas Herzig
f943d11661 Bump to MC 1.18.1 2021-12-10 11:51:25 +01:00
Jonas Herzig
2df9049e6b Fix error when loading old replay on Java 9+ (fixes #578)
By updating the shadow plugin used in ReplayStudio.

java.lang.IncompatibleClassChangeError: Inconsistent constant pool data in classfile for class com/replaymod/replaystudio/lib/viaversion/libs/kyori/adventure/text/Component. Method 'boolean lambda$static$0(com.replaymod.replaystudio.lib.viaversion.libs.kyori.adventure.text.Component, com.replaymod.replaystudio.lib.viaversion.libs.kyori.adventure.text.Component)' at index 1064 is CONSTANT_MethodRef and should be CONSTANT_InterfaceMethodRef
2021-12-08 17:30:36 +01:00
Jonas Herzig
ad62e51ab3 Fix lighting when block is placed in same frame as chunk load 2021-12-08 16:22:06 +01:00
Jonas Herzig
59ac665c81 Disable auto-sync if there is no stable position (closes #488)
Cause not doing anything is better than flickering between different parts of
the timeline every frame.
2021-12-08 16:04:47 +01:00
Jonas Herzig
f4196748f5 Fix recording controls on menu-less pause screen (fixes #575) 2021-12-08 16:04:47 +01:00
Jonas Herzig
3d9d40656e Fix recording of riptide animation (fixes #581)
This code supposedly meant for recording when a player was eating/blocking was
never needed to begin with cause the server echos all data in DataTracker
anyway, and now it broke the riptide animation because that's part of the
living flags as well but wasn't considered here, i.e. unconditionally
overwritten.
2021-12-08 16:04:47 +01:00
Jonas Herzig
bd68a80152 Fix chroma key rendering for 1.12.2 and below (fixes #589)
Forge naming strikes again, there's two different `updateCameraAndRender` in
1.14.4 forge, which lead us to use `updateCameraAndRender` for the older version
as well even though our desired method had a different name back then.
2021-12-08 16:04:47 +01:00
Jonas Herzig
96f7b78a38 Fix spectator hand jittering in 1.12.2 and below 2021-12-08 16:04:47 +01:00
Jonas Herzig
1b18b5c952 Fix spectator hand jumping when rotating across 0 yaw boundary, take 2
The `yaw` value of non-client-players is constraint to [0; 360), so when that
boundary is crossed, the `renderYaw` starts interpolating to its goal the
incorrect way round (instead of crossing the 360 boundary as well).

To fix that, we now add the difference between the current `renderYaw` and the
desired one, modulo 360 (but with range (-180; 180]), to the current
`renderYaw`. That way we always take the short way round.
Additionally, because for rendering MC looks at the difference without modulo,
afterwards (and when a new `yaw` is set) we wrap the result around such that the
actual difference is always less than 180 and therefore rendered as intended.
2021-12-08 16:04:47 +01:00
Jonas Herzig
51aa07e01e Revert "Fix spectator hand jumping when rotating across 0 yaw boundary" (fixes #601)
This reverts commit 411eaa4ca8.

The given solution does not work in old versions because those did not use
`getYaw` for hand rendering. Even worse, their headYaw does wrap around and it
does it in a different way than their yaw value, giving a worse result than
without this commit.
2021-12-08 16:04:47 +01:00
Jonas Herzig
29ef38213f Fix vanilla entity update packet handling (fixes #607) 2021-12-08 16:04:47 +01:00
Jonas Herzig
b10b4fd25a Fix crash when render queue is not saved properly (fixes #617) 2021-12-07 13:35:36 +01:00
Jonas Herzig
9fa5adf395 Bump to MC 1.18 2021-12-07 13:35:36 +01:00
Jonas Herzig
d6cd917d9d Fix passengers getting stuck in unloaded chunks (fixes #606)
We need to update the vehicle before its passengers.
2021-12-07 13:35:36 +01:00
Jonas Herzig
88a23222b6 Fix vanilla 1.18 bug causing entities to get stuck outside sim range
MC uses the client-side position of an entity to determine whether it is inside
the simulation range and therefore whether it will get ticked. For some (most)
entities it interpolates the client-side position to match the server-side one
inside of the tick method... no prices for guessing where this goes wrong.

Somewhat similar to the issue we have with chunk unloads which we work around in
FullReplaySender but worse cause they'll get stuck if they ever leave the sim
range even for a single tick, rather then just when their chunk is unloaded.
2021-12-07 13:35:36 +01:00
Jonas Herzig
ff5c0f594e Fix chunks missing on first frame when rendering without Sodium 2021-12-07 13:35:36 +01:00
Jonas Herzig
58ba590c84 Fix replay being restarted when resuming path playback 2021-12-07 13:35:36 +01:00
Jonas Herzig
549996b270 Fix underwater visibility (fixes #572)
Used to always be super short because that method returns 0 when `isSubmergedIn`
returns false.
2021-12-07 13:35:31 +01:00
Jonas Herzig
bd0dd10942 Ensure we cannot accidentally open a replay file twice
E.g. from the Replay Viewer while it is still being recovered.
Because that would potentially corrupt it.
2021-11-29 17:42:44 +01:00
Jonas Herzig
31817bcf11 Split replay folder and file management into their own classes 2021-11-29 17:42:44 +01:00
Jonas Herzig
ce5886a427 Port to MC 1.18-rc4 2021-11-29 17:42:44 +01:00
Jonas Herzig
b6f623efb8 Update Gradle to 7.3 2021-11-29 16:22:37 +01:00
Jonas Herzig
2ee8fe49c5 Update FG 2.1 to download MCP from Forge maven
Cause the MCP site is now offline.
2021-11-29 16:22:37 +01:00
Jonas Herzig
090778ca63 Fix build for 1.15.x and below 2021-11-29 16:22:37 +01:00
Jonas Herzig
dd055e5c5b Fix build for 1.8 2021-11-29 16:22:37 +01:00
Jonas Herzig
6e1febdab8 Port to MC 1.18-pre1 2021-11-14 17:27:35 +01:00
Jonas Herzig
d2f27e3918 Update Loom to 0.10 2021-11-14 16:09:37 +01:00
Jonas Herzig
55f3a15db6 Release 2.6.1 2021-08-21 15:32:42 +02:00
Jonas Herzig
33328adc9f Fix recording of 4-8 block teleports on 1.8.9 and below (fixes #525) 2021-08-21 15:11:55 +02:00
Jonas Herzig
5f9297b78e Improve lang resource pack injection point (closes #532)
Previously we injected it as a regular builtin resource pack (like the
Programmer Art pack) and hid it on the resource pack screen but this is bad for
several reasons. The most significant one being that it can be re-ordered and
makes the resource pack list ordering weird if you don't know that there is an
invisible pack there.
It also unnecessarily messes with other mods which make certain assumptions
about configurable resource packs (e.g. EBE, though in that case, it merely
triggers an existing bug in EBE).

We now instead inject it into the final resource pack list which gets
constructed from the configured packs, but never as a configurable pack itself.
2021-08-21 15:11:55 +02:00
Jonas Herzig
411eaa4ca8 Fix spectator hand jumping when rotating across 0 yaw boundary
The `yaw` value of non-client-players is constraint to [0; 360), so when that
boundary is crossed, the `renderYaw` starts interpolating to its goal the
incorrect way round (instead of crossing the 360 boundary as well).

Instead we now use the `headYaw` value, which does not wrap around and as such
does not have this issue.
2021-08-21 15:11:55 +02:00
Jonas Herzig
6428416bc4 Fix between-ticks position of hand when spectating (fixes #563) 2021-08-21 15:11:55 +02:00
Jonas Herzig
0e5de6c816 Update ReplayStudio
c9de2f5 Fix incorrect initial version for Combat* packets (fixes #568)
a22df13 Fix off-by-3 in quick mode chunk unloading code
2e2cac4 Guard against bad chunk light masks (fixes #557)
2021-08-21 15:11:41 +02:00
Jonas Herzig
0ceb95a5e2 Abort path preview when opening render screen (fixes #524) 2021-08-21 15:11:41 +02:00
Jonas Herzig
de3f4dab7e Pause path playback while resource pack is loading (closes #540) 2021-08-21 15:11:41 +02:00
Jonas Herzig
612a90681e Reset camera inventory when no longer spectating (fixes #546) 2021-08-21 15:11:29 +02:00
Jonas Herzig
88dece679d Fix scissor state not including scissor bounds (fixes #556)
This caused the bounds to not be relaxed after e.g. lists and as such the scroll
bar and shadows would not render properly.
2021-08-15 17:25:23 +02:00
Jonas Herzig
82c7da8739 Fix advanced screenshot GUI not opening on 1.17.1 (fixes #559) 2021-08-15 16:53:12 +02:00
Jonas Herzig
b243dfc625 Workaround soft-lock when REI screen is closed (fixes #560) 2021-08-15 16:41:50 +02:00
Jonas Herzig
27f365a60a Change skin-caching feature to be fail-safe (fixes #561) 2021-08-15 13:53:31 +02:00
Jonas Herzig
463c51be85 Convert getDefaultRenderSettings into default constructor
Allows us to completely get rid of the custom Gson instance and is more
idiomatic anyway.
2021-08-15 11:45:23 +02:00
Jonas Herzig
9626a4c442 Fix parsing of render queue with chroma key (fixes #564)
By simply replacing the private field with a concrete type, so we do not need to
manually register one when constructing the gson instance (which is evidently
too easy to forget about).
2021-08-15 11:39:10 +02:00
Jonas Herzig
3db8c28505 Fix .no_recover files never being cleaned up (fixes #497) 2021-08-15 11:28:11 +02:00
Jonas Herzig
110199044f Fix nametags not rendering in screenhots (fixes #498)
No clue why this extra hud hiding was even there in the first place, the
renderer already takes care of properly hiding the hud (without hiding the
nametags) as it does for videos as well.
2021-08-15 11:19:52 +02:00
Jonas Herzig
4a587eed74 Workaround crash with REI and MainMenuScale (fixes #501, fixes #473) 2021-08-15 11:07:19 +02:00
Jonas Herzig
e2b0422965 Fix timeline not saving when completely overwritten (fixes #505)
Either when it is cleared or when it is loaded from the keyframe repository, if
you exit the replay without any further changes, this used to not be saved.
2021-08-15 10:47:34 +02:00
Jonas Herzig
a793cbee0d Remove RM 2.6+ for MC 1.7.10 from versions.json 2021-08-01 16:59:51 +02:00
Jonas Herzig
f95a943589 Release 2.6.0 2021-07-31 16:01:48 +02:00
Jonas Herzig
c88b4c1e76 Add missing .gitkeep files 2021-07-31 16:01:11 +02:00
Jonas Herzig
a457bccf12 Fix Java 9+ ABI being used for Java 8 versions 2021-07-31 15:31:43 +02:00
Jonas Herzig
3cba99068e Increase default bitrate to from 10 to 20mbps 2021-07-31 14:37:10 +02:00
Jonas Herzig
e9bf75b4d6 Remove ModCore
That was never actually finished and we do not need to keep it around anymore.
Whether we add its successor once that is ready for production use remains to be
seen.
2021-07-24 19:15:08 +02:00
Jonas Herzig
5bede327f3 Update jGui (fixes textures with Sodium) 2021-07-24 17:09:16 +02:00
Jonas Herzig
0cb14a9106 Re-introduce entity-in-wrong-chunk-at-unload workaround (fixes #548)
Nope, this was not fixed, they just changed where the chunkCoords are stored but
the interpolation issue remains.
2021-07-24 17:06:46 +02:00
Jonas Herzig
35fef5176d Fix skins of server-only NPCs being unreliable (fixes #486) 2021-07-24 14:43:38 +02:00
Jonas Herzig
3ef355a267 Failure to hide cache folder should never be fatal (closes #512) 2021-07-24 13:17:14 +02:00
Jonas Herzig
4090e7b540 Search for homebrew in /opt as well (fixes #496) 2021-07-24 13:14:23 +02:00
Jonas Herzig
2891c4e8fa Remove MP4 Default Quality preset (closes #475)
Similar to High Quality, it is too unpredictable, sometimes giving bad quality
and sometimes being unbearably slow. We should just encourage everyone to set
their bitrate manually.
2021-07-24 12:59:06 +02:00
Jonas Herzig
83cb459957 Fix keyframes being required to open render queue window
Half the reason we swapped the render queue / settings parent relationship was
so we don't need to go through the settings screen to access the queue. But for
some reason I stopped half way through and didn't also move the "You need at
last two keyframes." popup. This commit rectifies that.
2021-07-24 12:46:13 +02:00
Jonas Herzig
3f4dae05db Fix missing preprocessor comments 2021-07-24 11:30:34 +02:00
Jonas Herzig
2f4360a2a1 Fix Mixin_PreserveDepthDuringGuiRendering for 1.14-16 2021-07-24 11:29:27 +02:00
Jonas Herzig
2415a886e2 Update to 1.17.1 2021-07-24 11:05:39 +02:00
Jonas Herzig
927db36baa Use same fabric-loader version across all MC versions 2021-07-24 11:05:00 +02:00
Jonas Herzig
d0620091d2 Add support for FREX Flawless Frames API (fixes #150) 2021-07-24 09:11:34 +02:00
Jonas Herzig
96bb1abc1d Update ReplayStudio
0e72e36 Add workaround for lack of way to determine global palette size
872bc75 Update vanilla global palette size
19d3dab Fix OOB when converting local palette storage to global palette (fixes #509)
c93a370 Fix incorrect packet release during SquashFilter.flush (fixes #490, fixes #492)
2021-07-01 14:05:52 +02:00
Jonas Herzig
7a52a29ef3 Fix race condition in resource pack recording (fixes #521)
If the server sends the resource pack right on connect (rather than when
switching to a sub-server), then `mc.getNetworkHandler()` will be null.
2021-07-01 14:05:52 +02:00
Jonas Herzig
7ab2edd738 Implement ODS rendering via Iris Shader for MC 1.17 2021-07-01 14:05:52 +02:00
Jonas Herzig
f462a5b391 Fix 1.12 shim Window.getScaledHeight 2021-07-01 14:05:52 +02:00
Jonas Herzig
e85618a27c Change frame time (used by Iris) to be based on replay or video time
Iris derives that one from the frameStartNanos argument passed to the render
method and shaders usually use it to do animations. Prior to this commit we
always pass 0 which effectively froze any shader animations.

With this commit, we now compute the frameStartNanos based on the
FPS of the video we are rendering (so animations will happen in real time when
watching the video) or based on the time in the replay (so animations will
be influenced by playback speed / be frozen if the replay is frozen).
We default to the video time based approach because the replay time one may
produce undesirable results when it comes to things like motion blur and TAA.
2021-07-01 14:05:52 +02:00
Jonas Herzig
3f2456ba65 Use GameRenderer.render instead of renderWorld, improves compat
In particular, Iris updates its frame counter and timer in the outer method, so
if we only call the inner one, then its shadows and sky will not update
properly.
Since the render method also renders the GUI, we set the current screen to null
and cancel the HUD during rendering. MC also clears the depth before rendering
the HUD, which we don't want because it breaks the depth map export, so we
cancel that as well.

This also allows Vanilla post-processing (aka Super Secret Settings, aka Vanilla
Shaders) as well as entity outlines to function properly cause those are applied
in that method as well.
Should have done this a long time ago but better late than never.

Closes #321
2021-07-01 14:05:52 +02:00
Jonas Herzig
ed99e240ec Bundle missing transitive fabric-api dependency 2021-06-28 19:06:26 +02:00
Jonas Herzig
0fcb27c6b2 Fix keyPressed/keyReleased injection targets 2021-06-28 19:06:26 +02:00
Jonas Herzig
5289026313 Bump MC to 1.17 proper 2021-06-28 19:06:26 +02:00
Jonas Herzig
2be47e9810 Change ReplayButton icon to be white with shadow for better contrast
The previous one, blue with no shadow, had horrible contrast with the button
background and did not fit well with any of the other buttons.
Now it does (except that it's not yet in the 20-pixel width/height style).
2021-06-28 19:06:26 +02:00
Jonas Herzig
1af4add932 Update ReplayStudio
- MC 1.17
- Updated ViaVersion
- Quick Mode supports multiple worlds now (and no longer needs a manual Respawn)
2021-06-28 19:06:26 +02:00
Jonas Herzig
8d3d705fed Switch to commons-lang Pair instead of the ViaVersion one
Cause that one will be removed in a future version, and the lang one is just
fine.
2021-06-28 14:35:57 +02:00
Jonas Herzig
766d3346ee Pin FG5 version because its maintainers cannot be trusted
Versions after 5.0.5 emit tsrg2 instead of tsrg, breaking anything which reads
those files (e.g. Mixin and the preprocessor), later versions even bump the
required Gradle version.
2021-06-27 14:44:16 +02:00
Jonas Herzig
08165252d5 Switch to new Quick Mode backend 2021-06-06 10:42:16 +02:00
Jonas Herzig
1802b1a7d0 Port to 1.17-pre1 2021-06-06 10:42:16 +02:00
Jonas Herzig
5f2dca08d1 Fix "Cannot register receiver while client is not logging in!"
Since MC provides no reliable way to get the connection while still in the login
phase, Fabric API tries to determine it either from MinecraftClient's connection
field (for the integrated server) or from the ConnectScreen (for multiplayer).
However, neither is present during a replay, leading to the aforementioned
error.

To fix this, we store our ClientConnection in MinecraftClient's connection
field. This should have no significant effect on vanilla behavior.

Also remove the dead Forge 1.14 code which was in the same place.
2021-06-05 23:01:16 +02:00
Jonas Herzig
25a6cdc502 Fix RenderSettings (de)serialization with Java 16 (fixes #520)
Turns out we were relying on the implementation detail of the File class, and
Java 16 ensures we cannot do that.
2021-06-05 23:01:16 +02:00
Jonas Herzig
9d3583293b Bundle Gson on 1.11.2 and below (fixes #421)
Decided to go with 1.11.2 because the Gson from that version is the first to not
have the JsonAdapter annotiation, which we want for fixing #520.
2021-06-05 23:01:16 +02:00
Jonas Herzig
e380907334 Switch preprocessor config to flat style 2021-06-05 23:01:16 +02:00
Jonas Herzig
4cdbfb7c46 Update Gradle to 7.0.2 2021-06-05 23:01:16 +02:00
Jonas Herzig
59fb58c6fc Disable 1.7.10 for now
Continued support would require porting FG1.2 to Gradle 7 / Java 16.
2021-06-05 22:57:46 +02:00
Jonas Herzig
f5af283492 Update for new forge maven repo 2021-04-22 14:09:58 +02:00
Jonas Herzig
3440b8d8a8 Update loom to 0.6 2021-03-14 12:13:06 +01:00
Jonas Herzig
537795f9ca Backport contextual key bindings to 1.12.2 and below (closes #478) 2021-03-14 12:12:53 +01:00
Jonas Herzig
dda6bd41b6 Implement ffmpeg-independent PNGWriter (closes #476)
Creates a dedicated folder for each video and does not depend on ffmpeg, just
like the EXRWriter (but supporting all MC versions).

Also does 32 bit depth export by chunking the 32-bit float into the 8-bit BGRA
component channels.
2021-03-14 12:12:53 +01:00
Jonas Herzig
8ff27437af Add configurable, small Replay Viewer button (closes #471) 2021-03-14 12:12:53 +01:00
Jonas Herzig
c6b41d76fa Document valid values for MultipleChoiceSettings in config file 2021-03-14 12:12:53 +01:00
Jonas Herzig
4ca4f2def6 Auto-reload config file on changes (Fabric only) 2021-03-14 12:12:53 +01:00
Jonas Herzig
61d67a5e80 Remove OpenEye (closes #465)
It is not available for Fabric and we stopped using it.
2021-03-14 12:12:53 +01:00
Jonas Herzig
b7309283e9 Rename MixinRendererLivingEntity -> Mixin_HideNameTags_LivingEntity 2021-03-14 12:12:53 +01:00
Jonas Herzig
a97190de1e Move MixinRendererLivingEntity into 1.8.9 project 2021-03-14 12:12:53 +01:00
Jonas Herzig
c17fc79ab2 Rename MixinRender -> Mixin_HideNameTags 2021-03-14 12:12:53 +01:00
Jonas Herzig
1924963d75 Move MixinOpenGlHelper into 1.7.10 project 2021-03-14 12:12:53 +01:00
Jonas Herzig
aba34d6c6f Rename Mixin_CubicRotation -> Mixin_Omnidirectional_Rotation 2021-03-14 12:12:53 +01:00
Jonas Herzig
db5708f338 Rename MixinFrustum -> Mixin_Omnidirectional_DisableFrustumCulling 2021-03-14 12:12:53 +01:00
Jonas Herzig
6974f8e60c Rename MixinCamera -> Mixin_StabilizeCamera 2021-03-14 12:12:53 +01:00
Jonas Herzig
3ec81d5c35 Split MixinEntityRenderer into multiple, more focused files 2021-03-14 12:12:53 +01:00
Jonas Herzig
fad89626e5 Move 1.7.10 code from MixinEntityRenderer to Mixin_ForceChunkLoading 2021-03-14 12:12:53 +01:00
Jonas Herzig
e7a1fafdf9 Extract Mixin_ChromaKeyDisableFog from other mixins 2021-03-14 12:12:53 +01:00
Jonas Herzig
cf1d7537e8 Move MixinEffectRenderer into 1.8.9 project 2021-03-14 12:12:53 +01:00
Jonas Herzig
10426f9d39 Move MixinChunkRenderWorker into 1.14.4 project 2021-03-14 12:12:53 +01:00
Jonas Herzig
2fb4f73ae4 Move ChunkRenderDispatcherAccessor into 1.14.4 project 2021-03-14 12:12:53 +01:00
Jonas Herzig
6289545d84 Remove forge/fml event bus from MCVer 2021-03-14 12:12:53 +01:00
Jonas Herzig
cfb9e15b8a Make use of new @Pattern feature to centralize version-aware code
That is, most of the business code should not be aware that it is being compiled
to multiple versions even when it heavily interacts with MC, preprocessor
statements should be an escape hatch, not the norm.
Similarly, code should not be forced to do `MCVer.getWindow(mc)` instead of the
much more intuitive `mc.getWindow()`, and a new preprocessor (technically remap)
feature makes this possible by defining "search and replace"-like patterns (but
smarter in that they are type-aware) in one or more central places (the
"Patterns.java" files) which then are applied all over the code base.

In a way, this is another step in the automatic back-porting process where
preprocessor statements are used when we cannot yet do something automatically.
Previously we "merely" automatically converted between different mapping, this
new feature now also allows us to automatically perform simple refactoring
tasks like changing field access to a getter+setter (e.g. `mc.getWindow()`), or
changing how a method is called (e.g. `BufferBuilder.begin`), or changing a
method call chain (e.g. `dispatcher.camera.getYaw()`), or most other
search-and-replace-like changes and any combination of those.
The only major limitation is that the replacement itself is not smart, so
arguments must be kept in same order (or be temporarily assigned to local
variables which then can be used in any order).
2021-03-14 12:12:51 +01:00
Jonas Herzig
06a46e6f38 Use callback-style events for crosshair and hotbar render events 2021-02-28 09:52:19 +01:00
Jonas Herzig
da16b0fb78 Add 1.14.4 <> 1.12.2 mapping for Option <> GameSettings.Options 2021-02-28 09:52:19 +01:00
Jonas Herzig
f34b88cf7e Move MixinShader into 1.7.10 project 2021-02-28 09:52:19 +01:00
Jonas Herzig
d7dde42add Move HideInvisibleEntities into 1.12.2 project 2021-02-28 09:52:19 +01:00
Jonas Herzig
5f652ec7f2 Move DisableBetterSprinting into 1.12.2 project 2021-02-28 09:52:19 +01:00
Jonas Herzig
05d7971332 Move mapwriter.MixinMinecraft into 1.12.2 project 2021-02-28 09:52:19 +01:00
Jonas Herzig
4eeaca5af1 Use MainWindowAccessor across all versions 2021-02-28 09:52:19 +01:00
Jonas Herzig
e4da7f331b DRY main MC window resizing 2021-02-28 09:52:19 +01:00
Jonas Herzig
3fbb4b50ea Rename ChunkLoadingRenderGlobal → ForceChunkLoadingHook
More descriptive, less MCP.
2021-02-28 09:52:19 +01:00
Jonas Herzig
ab5b101f96 Add stub ChunkLoadingRenderGlobal for 1.7.10
Allows us to get rid of all preprocessor guards around its usages.
2021-02-28 09:52:19 +01:00
Jonas Herzig
c729654f04 Split off 1.14.4 overwrite from ChunkLoadingRenderGlobal 2021-02-28 09:52:19 +01:00
Jonas Herzig
f19ee8ba63 Split off 1.14.4 overwrite from Mixin_ForceChunkLoading 2021-02-28 09:52:19 +01:00
Jonas Herzig
90bbc68443 Replace reflection in ChunkLoadingRenderGlobal with mixin 2021-02-28 09:52:19 +01:00
Jonas Herzig
4b4d18026b Move GLStateTracker into 1.7.10 project 2021-02-28 09:52:19 +01:00
Jonas Herzig
74580e6649 Remove redundant preprocessor statements 2021-02-28 09:52:19 +01:00
Jonas Herzig
87b55e187c Replace a few //#if statements with mapping file entries 2021-02-28 09:52:19 +01:00
Jonas Herzig
026bc1fdcb Move MixinWorldClient into 1.12.2 project 2021-02-28 09:52:19 +01:00
Jonas Herzig
470669b1f7 Move MixinRenderManager into 1.12.2 project 2021-02-23 01:21:44 +01:00
Jonas Herzig
b8bcb4967f Move MixinFMLClientHandler into 1.7.10 project 2021-02-23 01:05:48 +01:00
Jonas Herzig
6fa746a2e3 Move MixinEntityRenderer into 1.7.10 project 2021-02-23 01:01:55 +01:00
Jonas Herzig
01d47279fd Split off 1.12.2 overwrite from MixinCamera 2021-02-23 00:59:56 +01:00
Jonas Herzig
06db2ebb92 Move MixinS26PacketMapChunkBulk into 1.7.10 project 2021-02-23 00:47:01 +01:00
Jonas Herzig
6068aabea7 Move MixinPlayerControllerMP into 1.12.2 project 2021-02-23 00:45:12 +01:00
Jonas Herzig
6bc130312a Move MixinNetworkDispatcher into 1.12.2 project 2021-02-23 00:41:22 +01:00
Jonas Herzig
ba7c478da1 Split off 1.12.2 overwrite from MixinNetHandlerLoginClient 2021-02-23 00:41:22 +01:00
Jonas Herzig
25247a2371 Move MixinGuiScreen into 1.7.10 project 2021-02-23 00:41:22 +01:00
Jonas Herzig
22d1048999 Move FMLHandshakeFilter into 1.12.2 project 2021-02-23 00:41:22 +01:00
Jonas Herzig
6094422792 Split off highly version-dependent code from ModCompat 2021-02-23 00:41:22 +01:00
Jonas Herzig
029b228b26 Move ReplayModTweaker into 1.12.2 project 2021-02-23 00:41:22 +01:00
Jonas Herzig
9bde5fae49 Move ResourcePackRepositoryAccessor into 1.7.10 project 2021-02-23 00:41:22 +01:00
Jonas Herzig
f15eaf95c1 Split off 1.12.2 overwrite from MixinKeyboardListener 2021-02-23 00:41:22 +01:00
Jonas Herzig
9e152f2655 Move GLStateTrackerTransformer into 1.7.10 project 2021-02-23 00:41:22 +01:00
Jonas Herzig
1329f2d703 Move GLErrorTransformer into 1.7.10 project 2021-02-23 00:41:22 +01:00
Jonas Herzig
66c1f63219 Move GuiFactory into 1.12.2 project 2021-02-23 00:41:22 +01:00
Jonas Herzig
633bc19650 Use callback-style events throughout all versions
Removes the need for //#if statements on each and every event handler.
Instead we now always use the equivalent Callback and have one central 1.12.2
class which forwards Forge events to the callbacks.
2021-02-23 00:41:22 +01:00
Jonas Herzig
0be2082fe7 Split off highly version dependent code from ReplayMod 2021-02-20 00:43:49 +01:00
Jonas Herzig
bc9d8cb3d1 Split off highly version dependent code from SettingsRegistry 2021-02-20 00:43:46 +01:00
Jonas Herzig
9a67a64555 Drop server-side restrictions implementation
I don't think this sees sufficient use to justify updating.
Especially because it's non-trivial with forge's network changes.
Ping me if you actually used this.
2021-02-20 00:43:46 +01:00
Jonas Herzig
1a35234b0a Move LoadingPlugin into 1.12.2 project 2021-02-19 23:02:39 +01:00
Jonas Herzig
9d81265213 Update preprocessor plugin 2021-02-19 23:01:43 +01:00
Jonas Herzig
bcde675775 Update jGui 2021-02-19 17:32:41 +01:00
Jonas Herzig
8c2d7d096c Merge branch 'stable' into develop 2021-02-19 11:58:28 +01:00
Jonas Herzig
ff47174fd6 Release 2.5.2 2021-02-17 21:56:30 +01:00
Jonas Herzig
c0a95d278e Add toString implementation to RenderSettings
We print them to the log in a few places, that's fairly useless without a
toString implementation.
2021-02-17 21:53:07 +01:00
Jonas Herzig
fed90b5597 Update ReplayStudio
a1f82a7 Properly handle same-dimension respawns in squash and quick mode (fixes #139, fixes #455)
7b84461 Fix NPE if there is a block change at time 0 (fixes #446)
ee9d7d5 Switch to LGPLv3+ as primary license
2021-02-17 18:20:48 +01:00
Jonas Herzig
51a4ade37e Fix slow drifting in FullReplaySender replay time (fixes #451) 2021-02-17 15:16:33 +01:00
Jonas Herzig
2f0160c4f6 Update loom to 0.5 (closes #453) 2021-02-17 11:39:57 +01:00
Jonas Herzig
56e5df65d5 Use vanilla sound engine to play render success sound (fixes #286) 2021-02-17 11:27:09 +01:00
Jonas Herzig
5f0218929b Process sub-selection of render jobs in displayed order (fixes #488) 2021-02-17 03:33:14 +01:00
Jonas Herzig
6d0d50f5b3 Fix "Render All" button in render queue (fixes #447) 2021-02-17 03:06:52 +01:00
Jonas Herzig
c54638db30 Update ReplayStudio (fixes #368)
e7d5bf5 Fix wrap around for LinearInterpolator
2021-02-17 02:57:10 +01:00
Jonas Herzig
cdb93a1716 Fix spectating via clicking on forge (fixes #432) 2021-02-17 02:55:49 +01:00
Jonas Herzig
02a731e018 Update jGui (fixes #429)
3596f15 Improve timeline time indicators for really long (1h+) timelines
2021-02-17 01:39:38 +01:00
Jonas Herzig
ae0b0e3f13 Allow any entity to be spectated on 1.8+ (fixes #382)
Idk why this was restricted in the first place, ask Marius: 163faddd
2021-02-17 01:19:29 +01:00
Jonas Herzig
a9a0c2ddc3 Update jGui (fixes #428)
e3cd741 Re-open GuiOverlay if externally closed while `!closeable`
5a90b8b Fix GuiOverlay.closeable not being respected on 1.14+
2021-02-17 01:19:29 +01:00
Jonas Herzig
72d5d43ad2 Suppress CancellationException when stopping camera path 2021-02-17 01:19:29 +01:00
Jonas Herzig
a5f874e571 Fix crash with certain render output file values (fixes #396) 2021-02-17 01:19:29 +01:00
Jonas Herzig
9dfdfd6fe3 Update bundled mixin version (fixes #438) 2021-02-17 01:19:29 +01:00
Jonas Herzig
d8cae487c2 Rename build scripts: build -> root and common -> build
This way it's easier for people not familiar with the preprocessor setup to find
what they are looking for.
2021-02-17 00:13:42 +01:00
Jonas Herzig
7e5734067f Remove jcenter repo, it will be shutting down
We have only been using it for the shadow plugin which is also available in the
plugins.gradle.org repo.
2021-02-17 00:13:42 +01:00
Daniel N. Werner
159f0e259f Update common.gradle
Stable and develop are returning 520 from CloudFlare, looks like they've switched the maven repository to use https.
2021-02-16 22:43:55 +01:00
Jonas Herzig
19ff1ef38b Do not bother recovering useless replays (fixes #444)
Useless replays being those for which auto-recording was disabled and Start
never pressed.
2021-02-16 22:38:39 +01:00
Jonas Herzig
57c7362e34 Merge branch 'stable' into develop 2020-11-22 17:10:27 +01:00
Jonas Herzig
dabb64340e Release 2.5.1 2020-11-22 16:19:28 +01:00
Jonas Herzig
99b1528dcc Update doRelease task for current branching model 2020-11-22 16:18:22 +01:00
Jonas Herzig
673964ea6a Hide Saving Replay popup when no output is produced (fixes #420)
I.e. if the had Auto-Recording disabled and never pressed start, there won't be
any replays and it would just be the Done button, which is pointless.
2020-11-22 16:04:14 +01:00
Jonas Herzig
c3c59ec1c0 Trim video file extension from glb file name (fixes #422) 2020-11-22 15:18:41 +01:00
Jonas Herzig
d06ef47f1c Update ReplayStudio (fixes #426) 2020-11-22 15:15:41 +01:00
Jonas Herzig
68ca92e8a2 Update changelog URL 2020-11-22 15:06:28 +01:00
Jonas Herzig
f7f20ee6cb Add setting to disable Saving Replay rename dialog (closes #423) 2020-11-22 15:03:24 +01:00
Jonas Herzig
f895a13b61 Apply Saving Replay dialog when pressing Enter (closes #424) 2020-11-22 14:55:07 +01:00
Jonas Herzig
4739d2278b Fix render settings not saving when rendering (fixes #425)
Clicking Cancel or Add to Queue does save them but clicking Render does not.

This is caused by the fact that the GuiRenderSettings are now a popup and no
longer their own screen, so to close them, we need to call its close method, not
close the entire screen.
2020-11-22 14:53:40 +01:00
Jonas Herzig
d4b7fdf949 Update remap (fixes #414)
Support remapping of mixin targets declared in static fields (specifically
`core.MixinKeyboardListener:ON_KEY_PRESSED`).

String literals in annotations can be specified in a static final field instead
of inline (so you can e.g. use the same literal in multiple places).
This commit adds support for remapping those external literals.
2020-11-22 14:31:03 +01:00
Jonas Herzig
ee02944391 Fix crash when rendering ODS without depth export (fixes #418) 2020-11-22 13:00:37 +01:00
Jonas Herzig
36276d32b6 Fix camera path export roll being inverted (fixes #427) 2020-11-22 09:14:51 +01:00
Jonas Herzig
6879729633 Fix OpenEXR export option throwing UnsatisfiedLinkError on Windows 2020-11-15 13:17:00 +01:00
Jonas Herzig
4a5d971be5 Release 2.5.0 2020-11-14 10:01:46 +01:00
Jonas Herzig
bcaf946f13 Move .gitkeep from 1.16.3 to 1.16.4 folder (fixup c620e2c) 2020-11-14 09:55:36 +01:00
Jonas Herzig
514c4fb30d Merge pull request #412 from LindaJuffermans/docs-201110-labymod370
LabyMod update 3.7.x has been tested with ReplayMod and works.
2020-11-10 13:35:55 +01:00
LindaJuffermans
6552fc68c0 LabyMod update 3.7.x has been tested with ReplayMod and works. 2020-11-10 09:32:32 +01:00
Jonas Herzig
0f67ba157e Merge pull request #408 from LindaJuffermans/docs-201107-direct-ffmpeg-link
Update ffmpeg link to the essential release ZIP file directly.
2020-11-08 10:15:42 +01:00
Jonas Herzig
1b4e68e4b2 Merge pull request #410 from LindaJuffermans/docs-201107-quickmode-194
Quick Mode is only available for MC 1.9.4 and up.
2020-11-08 10:13:24 +01:00
LindaJuffermans
f1e197b830 Quick Mode is only available for MC 1.9.4 and up. 2020-11-07 20:34:37 +01:00
Jonas Herzig
d3f1ce92b9 Merge pull request #407 from LindaJuffermans/docs-201107-resourceloader
Resource Loader is not compatible
2020-11-07 16:02:27 +01:00
LindaJuffermans
3cc2a90b64 Update ffmpeg link to the essential release ZIP file directly. 2020-11-07 15:55:09 +01:00
LindaJuffermans
28b2f87324 Resource Loader is not compatible 2020-11-07 15:49:59 +01:00
Jonas Herzig
ec862f0596 Update jGui 2020-11-07 13:18:10 +01:00
Jonas Herzig
6308b8a859 Add line between time keyframes and replay timeline (closes #351) 2020-11-06 18:54:55 +01:00
Jonas Herzig
3911ff4058 Fix crash when jumping to 00:00 (closes #227) 2020-11-06 18:54:55 +01:00
Jonas Herzig
c620e2cf9e Update to MC 1.16.4 (closes #406) 2020-11-06 18:54:55 +01:00
Jonas Herzig
4bff201307 Show warning if first keyframe is not placed at 00:00 (closes #352) 2020-11-06 18:54:55 +01:00
Jonas Herzig
577e59fd41 Add undo/redo to keyframe timeline (closes #305) 2020-11-06 18:54:55 +01:00
Jonas Herzig
28facc430e Allow raw key handlers to cancel keybindings (required for #305)
So that when you press e.g. Ctrl+Z, it doesn't trigger the keybinding bound to
Z (currently full brightness).
2020-11-06 18:54:54 +01:00
Jonas Herzig
ccb08d37a7 Store server name (in addition to address) in replays (closes #324) 2020-11-06 18:54:54 +01:00
Jonas Herzig
6e6af1dcbb Allow keyframe timeline cursor sync to be toggled (closes #290) 2020-11-06 18:54:54 +01:00
Jonas Herzig
214100840e Auto-scroll keyframe timeline to cursor where possible (closes #291) 2020-11-06 18:54:54 +01:00
Jonas Herzig
e7eef08512 When tabbing into text field, select all its text (closes #211) 2020-11-06 18:54:54 +01:00
Jonas Herzig
fa8266f71c Fix sync not working when triggered via hotkey buttons (fixes #399) 2020-11-06 18:54:54 +01:00
Jonas Herzig
dd5935649d Do not rely on error handling popup for sodium info (fixes #392)
Instead we now disable all the Render buttons and give them a tooltip. Much more
user-friendly.
2020-11-06 18:54:54 +01:00
Jonas Herzig
76bec31cd8 Move cache folders into central (hidden) location (closes #343) 2020-11-06 18:54:54 +01:00
Jonas Herzig
3ce10d4855 Get rid of thumb magic (closes #237) 2020-11-06 18:54:54 +01:00
Jonas Herzig
4402650971 Split hotkey button text over two lines if necessary (fixes #353) 2020-11-06 18:54:53 +01:00
Jonas Herzig
6016ebece7 Fix label of non-letter keys in hotkey buttons 2020-11-06 18:54:53 +01:00
Jonas Herzig
f51f6032ca Use empty hotkey button when key is unbound across all versions
This happened to already be the case in 1.16.3 (because of another bug), this
commit makes it intentional and consistent across all versions.
Using the empty label over NONE or another label because it doesn't change the
width of the button and therefore fits nicer with all the other buttons.
2020-11-06 18:54:53 +01:00
Jonas Herzig
e86a583558 Fix crash when clicking hotkey button; introduced in 83690f4 2020-11-06 18:54:53 +01:00
Jonas Herzig
6fc7b8fb0f Fix incorrect layering of vanilla gui additions (fixes #385) 2020-11-06 18:54:53 +01:00
Jonas Herzig
8f094000fe Fix camera FOV not matching configured FOV
This is because the camera is considered flying which causes MC to increase its
FOV slightly.
2020-11-06 18:54:52 +01:00
Jonas Herzig
d3230e1e38 Add camera path export (closes #391) 2020-11-06 18:54:52 +01:00
Jonas Herzig
d8135d9038 Add depth map export (closes #371) 2020-11-06 11:41:38 +01:00
Jonas Herzig
a7d424679b Remove duplicate code between Simple and MultiFrame PBO capturer 2020-11-06 11:41:38 +01:00
Jonas Herzig
2b6d1b2359 Add OpenEXR export option
In preparation for depth map export.
2020-11-06 11:41:38 +01:00
Jonas Herzig
f57286043d Merge pull request #401 from LindaJuffermans/docs-201028-modlinks
Removed links to other mods which may trigger Chrome's safe browsing block.
2020-10-28 21:54:26 +01:00
LindaJuffermans
57900edf31 Fixed linebreak after Lunar Client 2020-10-28 19:49:33 +01:00
LindaJuffermans
3b428c7574 Removed links to other mods which may trigger Chrome's safe browsing block. 2020-10-28 19:47:22 +01:00
Jonas Herzig
5bd85e4c09 Merge pull request #400 from LindaJuffermans/docs-201026-futureclient
Future Client crashes on the Mixin
2020-10-28 19:15:04 +01:00
LindaJuffermans
d9ba1d24f5 Future Client crashes on the Mixin 2020-10-26 16:40:27 +01:00
Jonas Herzig
ad6c2aa3d9 Merge pull request #394 from LindaJuffermans/docs-1021-17animations
1.7 Animations w/shaders can cause floating glass and water
2020-10-21 18:30:42 +02:00
Jonas Herzig
45922acbc1 Merge pull request #393 from LindaJuffermans/docs-1021-ffmpeg43
Removed old issue from zeranoe's ffmpeg 4.3 missing libx264
2020-10-21 18:30:32 +02:00
LindaJuffermans
d7e309bca4 Removed old issue from zeranoe's ffmpeg 4.3 missing libx264 2020-10-21 15:55:04 +02:00
LindaJuffermans
716ec321ca 1.7 Animations w/shaders can cause floating glass and water 2020-10-21 15:52:25 +02:00
Jonas Herzig
17e554b67c Rename VideoWriter -> FFmpegWriter 2020-10-03 14:52:58 +02:00
Jonas Herzig
aee486c4f3 Stop assuming that our render pipeline will only process RGB frames
For one, we have already switched to RGBA some time ago, so the name was
technically incorrect already.
But the main reason is that we'll want to use them for depth maps as well (and
potentially maybe even for HDR images if that's possible with canvas?).
2020-10-03 14:50:44 +02:00
Jonas Herzig
4c4c052d8a Record into separate folder so replays only show once fully saved 2020-10-03 12:30:44 +02:00
Jonas Herzig
1486fe7fd0 Refresh ReplayViewer list after replay is saved (closes #379) 2020-10-03 10:58:17 +02:00
Jonas Herzig
b488e0b059 Fix render queue not being persisting after edit (fixes #362) 2020-10-03 10:38:08 +02:00
Jonas Herzig
094b20d69a Merge pull request #381 from LindaJuffermans/Branch_docs-0930-liteloader (closes #263)
Added LiteLoader compatibility information and workaround steps.
2020-09-30 11:41:48 +02:00
LindaJuffermans
41390b02e7 Added LiteLoader compatibility information and workaround steps. 2020-09-30 11:20:02 +02:00
Jonas Herzig
9af562957f Merge branch 'stable' into develop 2020-09-27 18:48:54 +02:00
Jonas Herzig
9cf8ec4e06 Release 2.4.5 2020-09-27 18:26:06 +02:00
Jonas Herzig
d7788b675a Fix missing blocks pre-1.14 in Quick Mode and Edit (fixes #374) 2020-09-27 17:28:29 +02:00
Jonas Herzig
5721b6f8c9 Fix realms notification icon offsets (fixes #373) 2020-09-27 15:58:43 +02:00
Jonas Herzig
a55320030f Fix thread-unsafe mc method call in FullReplaySender (fixes #370) 2020-09-27 15:28:08 +02:00
Jonas Herzig
1382e9fb31 Fix VanillaGuiScreen not resetting when resized (fixes #369) 2020-09-27 15:17:24 +02:00
Jonas Herzig
a62100071f Fix camera getting stuck spectating itself (fixes #300)
This bug was introduced when we started to record the login phase because it
contains the UUID of the local player. In the replay case this will be the UUID
of the camera entity but also the one of the recording player, so if the
recording player despawns while it is being spectated (e.g. because of a
backwards jump), then the camera snaps onto itself and gets stuck in place until
one presses Shift.
2020-09-27 14:41:10 +02:00
Jonas Herzig
afd0c27af9 Fix incorrect rotation when jumping to marker (fixes #310) 2020-09-27 14:16:58 +02:00
Jonas Herzig
49b0cbe4f8 Fix jumping to marker position when time already matches 2020-09-27 14:14:49 +02:00
Jonas Herzig
85ea757253 Fix incorrect jump behavior when jumping small distances beyond 5s 2020-09-27 14:08:39 +02:00
Jonas Herzig
fb447dc252 Fix incorrect extension for custom screenshot file name (fixes #337) 2020-09-27 13:45:03 +02:00
Jonas Herzig
d9e3622254 Fix crash when screenshots folder does not yet exist (fixes #377)
Happens when you open the output file dialog for the first time and haven't
taken any screenshots before.
2020-09-27 13:27:06 +02:00
Jonas Herzig
12a49a4a5e Fix crash due to double-close after ODS rendering (fixes #376) 2020-09-27 13:13:39 +02:00
Jonas Herzig
2c2af8a6a6 Fix outer skin layer when spectating in first person (fixes #363) 2020-09-27 13:11:57 +02:00
Jonas Herzig
f42f4d468d Fix editing a replay twice with the same name (fixes #342) 2020-09-27 12:36:16 +02:00
Jonas Herzig
e24c4cd860 Fix incorrect latest version in minimal mode popup (fixes #375)
Also clean up the `1.7.6-1.7.10` to just `1.7.10`.
2020-09-27 12:31:05 +02:00
Jonas Herzig
9abbea7fb9 Merge branch 'mc-1.16.3' into release-2.4.5 2020-09-27 12:01:25 +02:00
Jonas Herzig
39a2fba921 Merge pull request #372 from LindaJuffermans/docs-0804-ffmpeg-431
Updated location of windows binaries for ffmpeg now that zeranoe is discontinued.
2020-09-25 15:41:07 +02:00
LindaJuffermans
ba4bffda2a Updated location of windows binaries for ffmpeg now that zeranoe is discontinued. 2020-09-25 14:53:45 +02:00
Jonas Herzig
cff6034079 Merge pull request #366 from altrisi/patch-1
Don't create an empty directory with no modcore available
2020-09-20 08:00:56 +02:00
altrisi
0561a9f53c Don't create an empty directory with no modcore...
...version available for the current MCVersion.
2020-09-19 15:10:23 +02:00
Jonas Herzig
3db25abe48 Merge branch 'mc-1.16.3' into develop 2020-09-10 17:34:48 +02:00
Jonas Herzig
efd1cebff3 Update to MC 1.16.3 2020-09-10 17:32:21 +02:00
Jonas Herzig
83690f4024 Refactor key binding registrations to be more easily expandable 2020-09-06 11:45:37 +02:00
Jonas Herzig
f623bb3ee7 Add reset button to export command settings (closes #356) 2020-09-06 11:45:37 +02:00
Jonas Herzig
00cb2b43a8 Rewrite main menu button offset to be more compatible (closes #341)
In particular, we now position it relative to the realms (fallback to
multiplayer) button.
This removes the need for special-casing ModMenu and fixes compatibility with
Better Mod Button.
2020-09-06 11:45:37 +02:00
Jonas Herzig
e5c0ca501b Add option to process multiple render queues in on go (closes #349) 2020-09-06 11:45:37 +02:00
Jonas Herzig
fcd1224fa0 Allow replay to be started in sync mode (required for #349) 2020-09-06 11:45:37 +02:00
Jonas Herzig
76a8623531 Show content of replay's render queue in Replay Viewer
As part of #349.
2020-09-06 11:45:37 +02:00
Jonas Herzig
9eb69375bd Add multi-select to Replay Viewer list (closes #354) 2020-09-06 11:45:37 +02:00
Jonas Herzig
6878cefadc Add type-to-filter functionality to Replay Viewer list 2020-09-06 11:45:37 +02:00
Jonas Herzig
29653c7ccc Render border of focused text field in white to match vanilla 2020-09-06 11:45:37 +02:00
Jonas Herzig
b54645e5b7 Replace "Settings" button with textured button in top left corner
The texture of this button is based on the settings button of the ModMenu mod
and was originally under the MIT license "Copyright (c) 2018-2020 Prospector".
The derived version is licensed as any other file in this repository.
2020-09-06 11:45:37 +02:00
Jonas Herzig
000048cc8f Support 1.15 button hover style for textured buttons 2020-09-04 20:56:05 +02:00
Jonas Herzig
8fac84bfe9 Merge branch 'release-2.4.4' into develop 2020-09-04 12:01:56 +02:00
Jonas Herzig
ebcf2bfa7b Release 2.4.4 2020-09-04 11:47:02 +02:00
Jonas Herzig
8ef3ab8647 Stop relying on fabric-api internals to inject resource packs
Fixes compatibility with fabric-api 0.20+
2020-09-04 11:37:25 +02:00
Jonas Herzig
d039009a9f Workaround Optifine breaking charTyped events 2020-09-01 12:54:30 +02:00
Jonas Herzig
9211fb524c Persist render queue in replay file (closes #317) 2020-08-29 21:21:34 +02:00
Jonas Herzig
4a6c0acc8b Add "Add to Queue" button to keyframe repository (closes #168) 2020-08-29 19:13:59 +02:00
Jonas Herzig
a92aa9cbbd Add Edit button to render queue 2020-08-29 19:13:04 +02:00
Jonas Herzig
f13e8834d6 Have render job name be determined directly by output file name 2020-08-29 19:13:04 +02:00
Jonas Herzig
1188ce4360 Swap parent relation between render settings and queue
Previously you'd access the render queue from the render settings screen which
was arguably the wrong way around (e.g. you weren't able to access the queue
when your current keyframes were incorrect even if you only wanted to render
those in the queue).

Now the render button opens the queue which can open a new settings popup. To
save people who don't need the queue from always having to go through it, the
queue will immediately open a new settings popup if does not yet have any jobs.
2020-08-29 19:13:04 +02:00
Jonas Herzig
ae63b32268 Allow rendering of selected entries in render queue gui 2020-08-29 19:13:04 +02:00
Jonas Herzig
fbed279e34 Add multi-select to render queue gui 2020-08-29 14:46:04 +02:00
Jonas Herzig
d95af541c7 Default render queue job name to output file name (closes #267) 2020-08-29 14:27:07 +02:00
Jonas Herzig
db9db0280b Find ffmpeg.exe anywhere in .minecraft folder (closes #347)
Thanks to Lucky56 for testing!
2020-08-29 14:27:07 +02:00
Jonas Herzig
098300f0db Stop blocking all UI during path playback (closes #269)
Instead, just copy the timeline before playback.
2020-08-29 14:27:07 +02:00
Jonas Herzig
9314eab7ff Make video timeline length configurable (closes #261) 2020-08-29 14:27:07 +02:00
Jonas Herzig
c9b57dbcd7 Handle Ctrl+A, Ctrl+C and Ctrl+V in the keyframe repository 2020-08-29 14:27:07 +02:00
Jonas Herzig
9f590e93ce Add copy/paste buttons to keyframe repository (closes #318) 2020-08-29 14:27:07 +02:00
Jonas Herzig
e294ebe8c9 Add multi-select to keyframe repository (see #318) 2020-08-29 14:27:07 +02:00
Jonas Herzig
fbf53d3842 Add option to use night vision for full brightness (closes #315) 2020-08-29 10:34:12 +02:00
Jonas Herzig
9a27138e78 Fix crash when config is missing a value 2020-08-29 10:19:01 +02:00
Jonas Herzig
9c6f040364 Change F1 while replay gui is focused to only hide it (closes #259)
Previously pressing F1 while the replay gui is focused (i.e. while the mouse is
visible) would toggle the global hudHidden state.
Now it only toggles the hidden state for the replay itself, allowing the
remainder to still be recorded with e.g. OBS where a full render isn't needed.
2020-08-29 09:32:18 +02:00
Jonas Herzig
39f958a7bb Fix F1 not functioning on 1.14+ while replay gui is focused 2020-08-29 09:30:57 +02:00
Jonas Herzig
103d2204d6 Load replays in order of last modified (closes #346) 2020-08-29 09:09:10 +02:00
Jonas Herzig
c2d4ac20dc Add rename/discard options to "Replay Saving" gui (closes #319) 2020-08-28 21:21:25 +02:00
Jonas Herzig
ab2b89f838 Add per-server overwrite for auto-recording setting (closes #313) 2020-08-28 18:31:25 +02:00
Jonas Herzig
ebe6da28fb Run recovery in background with progress indicator (closes #326) 2020-08-28 16:34:09 +02:00
Jonas Herzig
26f3c3639c Add progress bar to "Saving Replay" indicator (closes #325) 2020-08-28 16:15:39 +02:00
Jonas Herzig
739d5b2807 Add key hints to buttons which have corresponding keybindings 2020-08-28 15:58:02 +02:00
Jonas Herzig
fd48e56238 Add keybindings for the two keyframe buttons (closes #312)
And one to add a position keyframe even when spectating.
And one to press both buttons with a single key.
2020-08-28 15:45:34 +02:00
Jonas Herzig
c2f51d41fa ./gradlew :1.16.2:setCoreVersion 2020-08-28 14:55:40 +02:00
Jonas Herzig
9001fdc9de Cleanup 1.15.2 <-> 1.16.2 conversion 2020-08-28 14:50:28 +02:00
Jonas Herzig
16c759f1dd Drop lombok, it has been causing too much confusion
Basically the result of the Delombok function, except we use IntelliJ's equals,
hashCode and toString and don't re-organize imports (cause that breaks the
preprocessor) and a bunch of manual cleanup was necessary (and half the classes
weren't even converted).
2020-08-28 14:06:31 +02:00
Jonas Herzig
23e51d7099 Release 2.4.3 2020-08-22 17:17:40 +02:00
Jonas Herzig
1208fb92a1 Add .gitkeep file to 1.16.2 folder 2020-08-22 17:12:32 +02:00
Jonas Herzig
27edfcb4f3 Fix incompatibility with mods which mixin into Main (fixes #327) 2020-08-22 14:04:05 +02:00
Jonas Herzig
34b0369775 Merge branch 'mc-1.16.2' into release-2.4.3 2020-08-22 13:40:43 +02:00
Jonas Herzig
0edebdc8d3 Merge pull request #279 from LindaJuffermans:docs-0721-quickmode-icon 2020-08-22 13:40:02 +02:00
Jonas Herzig
7c229c0216 Enable git's autocrlf 2020-08-22 13:36:16 +02:00
Jonas Herzig
2a8c802d43 Merge pull request #257 from LindaJuffermans:develop 2020-08-22 13:33:18 +02:00
Jonas Herzig
8ffb98efd1 Fix recording of client-triggered world events in 1.16+ (fixes #333) 2020-08-16 10:03:55 +02:00
Jonas Herzig
da275a6080 Update to 1.16.2 2020-08-11 18:16:08 +02:00
Jonas Herzig
0e77235ef9 Update to MC 1.16.2-rc1 2020-08-09 13:55:00 +02:00
Jonas Herzig
3ba37ab05c Merge pull request #308 from LindaJuffermans/docs-0804-ffmpeg-431
ffmpeg 4.3.1 supports h264/h265
2020-08-04 16:08:09 +02:00
LindaJuffermans
6537c30d6b Removed mentioning of an ffmpeg version 2020-08-04 16:03:18 +02:00
LindaJuffermans
17f5771906 ffmpeg 4.3.1 supports h264/h265 2020-08-04 15:17:01 +02:00
Jonas Herzig
d065868abb Release 2.4.2 2020-08-03 10:31:36 +02:00
LindaJuffermans
9c3c76e70d Added NULL check for missing encodingPreset (fixes #288) 2020-08-03 10:23:50 +02:00
Jonas Herzig
eb2c2f2e6b Merge pull request #306 from LindaJuffermans/docs-0801-sodium
Sodium cannot be enable during rendering.
2020-08-01 21:33:36 +02:00
LindaJuffermans
d26c9e508b Sodium cannot be enable during rendering. 2020-08-01 20:51:13 +02:00
Jonas Herzig
9dc5e62b64 Merge pull request #297 from LindaJuffermans/docs-0730-screens
Updated screenshots to latest version of ReplayMod
2020-07-30 16:27:17 +02:00
Jonas Herzig
21dbafb860 Merge pull request #298 from LindaJuffermans/docs-0730-camera-symbol
Path preview icon is not shown when the path is shown.
2020-07-30 16:24:58 +02:00
LindaJuffermans
d54c1c2be2 Path preview icon is not shown when the path is shown. 2020-07-30 13:51:59 +02:00
LindaJuffermans
8ccffb9bd3 Updated screenshots to latest version of RM 2020-07-30 13:32:44 +02:00
Jonas Herzig
bd5af16e1e Merge pull request #293 from LindaJuffermans/docs-0728-randompatches
Crash using ReplayMod with RandomPatches
2020-07-29 11:06:37 +02:00
LindaJuffermans
0295257fc0 Crash using ReplayMod with RandomPatches 2020-07-28 15:44:36 +02:00
Jonas Herzig
335eb93858 Merge pull request #285 from LindaJuffermans/docs-0726-baritone
Crash using ReplayMod with Baritone
2020-07-26 11:01:10 +02:00
LindaJuffermans
cc3e950d6a Crash using ReplayMod with Baritone 2020-07-26 10:55:59 +02:00
Jonas Herzig
621587c65e Release 2.4.1 2020-07-25 22:40:32 +02:00
Jonas Herzig
fd7b6030f9 Fix keybinding conflicts on 1.14+ (fixes #268)
This fixes both, replay-exclusive keybindings blocking vanilla ones as well as
vanilla keybindings blocking replay-exclusive ones.

The magic happens in Mixin_ContextualKeyBindings.
2020-07-25 21:40:02 +02:00
Jonas Herzig
063657af4c Fix DELETE keybinding on 1.14+ (fixes #270) 2020-07-25 19:52:18 +02:00
Jonas Herzig
8d82953c0b Fix hands always rendering with 1.16 OF shaders (fixes #280) 2020-07-25 19:33:19 +02:00
Jonas Herzig
a4b6e92627 Position recording control buttons relative to Exit (fixes #281) 2020-07-25 18:43:33 +02:00
Jonas Herzig
35cc78c70c Fix crash due to invalid characters in video file name (fixes #265)
037d54f Prevent FileChooserPopup from selecting invalid file names
2020-07-25 17:19:38 +02:00
Jonas Herzig
5983d99354 Fix jittering once a tick during rendering pre-1.16 (fixes #264)
The fetching of the ticks variable was accidentally moved to before the timer
update while updating to 1.16, this caused the interpolation to be off by one
tick each frame in which the timer advances to the next tick.
2020-07-25 17:02:56 +02:00
Jonas Herzig
fc1ae0e109 Hide unsupported render methods in settings gui (fixes #284) 2020-07-25 17:02:24 +02:00
Jonas Herzig
34a7465b8e Merge pull request #283 from LindaJuffermans/docs-0722-oldanimations
Crash using ReplayMod with OldAnimationsMod
2020-07-22 21:38:48 +02:00
Jonas Herzig
2957f46ade Merge branch 'stable' into docs-0722-oldanimations 2020-07-22 21:38:29 +02:00
Jonas Herzig
83cc4a035a Merge pull request #282 from LindaJuffermans/docs-0722-patchermod
Crash using ReplayMod with Patcher
2020-07-22 21:37:37 +02:00
LindaJuffermans
3981fa3ada Removed extra empty lines 2020-07-22 21:24:19 +02:00
LindaJuffermans
bc5182f98b Removed extra empty lines 2020-07-22 21:23:45 +02:00
LindaJuffermans
fda09358da Crash using ReplayMod with OldAnimationsMod 2020-07-22 21:22:31 +02:00
LindaJuffermans
e177333af4 Crash using ReplayMod with Patcher 2020-07-22 21:18:50 +02:00
Jonas Herzig
f578f0df20 Merge pull request #277 from LindaJuffermans/docs-0721-accounts
Added Accounts section to explain discontinuing and new Discord support structure.
2020-07-21 21:53:34 +02:00
LindaJuffermans
a2342071b3 Updated to fixed Discord link from the main site 2020-07-21 21:52:24 +02:00
Jonas Herzig
7510f717a4 Merge pull request #278 from LindaJuffermans/docs-0721-quickmode
Added Quick Mode section and reference from timeline jumping
2020-07-21 21:50:10 +02:00
LindaJuffermans
3d7d51e2e0 Added Quick Mode section and reference from timeline jumping; including clock icon 2020-07-21 21:49:56 +02:00
LindaJuffermans
a0e9f0b61b Added Quick Mode section and reference from timeline jumping 2020-07-21 21:47:48 +02:00
LindaJuffermans
d49b06856f Added Accounts section to explain discontinuing and new Discord support structure. 2020-07-21 21:44:27 +02:00
Jonas Herzig
72bc8c87ee Merge pull request #276 from LindaJuffermans/docs-0721-thumbnails
Removed Replay Center reference in Thumbnails
2020-07-21 21:44:05 +02:00
LindaJuffermans
70494f3c6a Removed Replay Center reference in Thumbnails 2020-07-21 21:42:21 +02:00
Jonas Herzig
3273b3c239 Merge pull request #275 from LindaJuffermans/docs-0721-ffmpeg-notes3
Added ffmpeg details
2020-07-21 21:38:40 +02:00
LindaJuffermans
f61bfc4648 Added ffmpeg details 2020-07-21 21:35:53 +02:00
LindaJuffermans
169c4857b3 Fixed order of methods in quickmode change; no longer relying on local variable, instead pulling current state from ReplayHandler before updating. 2020-07-17 17:23:02 +02:00
LindaJuffermans
b79848936b Implemented review changes 2020-07-17 16:32:12 +02:00
LindaJuffermans
3aea7cdca4 Tweaked the indicator positions 2020-07-15 21:44:48 +02:00
LindaJuffermans
a94f417822 Fixed for 1.15.2 2020-07-15 21:07:30 +02:00
LindaJuffermans
2dcfbd6435 Changed Replay Viewer panel button (from play button to hamburger)
Added quickmode indicator (bottom-right with night vision indicator)
2020-07-15 15:49:44 +02:00
Jonas Herzig
2ab92f554f Release 2.4.0 2020-07-14 13:59:13 +02:00
Jonas Herzig
d3ad55eb79 Add run directory to gitignore 2020-07-14 13:57:49 +02:00
Jonas Herzig
9ea52eadc7 Move .gitkeep from 1.16 to 1.16.1 2020-07-14 13:57:10 +02:00
Jonas Herzig
a04ef22945 Fix broken frame after teleport during rendering (fixes #225) 2020-07-13 20:23:21 +02:00
Jonas Herzig
294f24c71e Fix jGui resources in 1.16 dev env 2020-07-13 20:23:21 +02:00
Jonas Herzig
b8618b6165 Fix dead-lock when rendering outside of loaded chunks (fixes #197) 2020-07-13 19:22:28 +02:00
Jonas Herzig
d8e4b89413 Fix forge handshake being reordered by MarkerProcessor (fixes #253)
For one, the forge handshake takes place *after* login phase (but before the
JoinGame packet), so we must ensure that the SquashFilter does not reorder
those.
Secondly, we were ignoring the initial packet (timestamp = 0) in marker
processor when it should have been passed to the SquashFilter. This was not an
issue before cause the SquashFilter did not rely on it. Now however the
SquashFilter needs to be able to see a login phase packet, so it knows that the
following packets till the JoinGame packet are part of the forge handshake.

In ReplayStudio:
20b5183 Fix forge handshake being reordered to after the JoinGame packet
2020-07-13 19:04:32 +02:00
Jonas Herzig
88fab6a91d Fix fastutil being relocated in 1.14+ (fixes #248) 2020-07-13 19:04:32 +02:00
Jonas Herzig
da59c75f8b Update jGui (fixes #249)
20e11e0 Remove length limit from GuiFileChooserPopup text field
2020-07-13 19:04:32 +02:00
Jonas Herzig
e090e8f4f3 Fix crash when video file name contains whitespace (fixes #250) 2020-07-13 19:04:32 +02:00
Jonas Herzig
f1885ece41 Fix non-player entity freezing on chunk unload in 1.14+ (fixes #203) 2020-07-13 19:03:41 +02:00
Jonas Herzig
dc31605b29 Change forge run dir from "eclipse" to "run"
I don't even know why it was at "eclipse" in the first place.
2020-07-13 16:07:48 +02:00
Jonas Herzig
f83216ab91 Include only the mod meta data file for the respective loader
Also clean up the entire processResources block in the process cause it was a
mere coincidence that it has worked properly.
2020-07-13 16:07:48 +02:00
Jonas Herzig
ecee63491c Remove mods.toml (modlauncher was never supported anyway) 2020-07-13 16:07:48 +02:00
Jonas Herzig
9c49fdf4d1 Remove explicit FAPI dep and instead bundle the required modules
Also need to update ModMenu because the version we depended on still bundled the
snapshot FAPI and that was only fine because we overwrote it with our version.
2020-07-13 16:07:48 +02:00
Jonas Herzig
62bbf0efd6 Update IDEA setup instructions
Configuring the annotation processor is done automatically as of IDEA 2020.1.

Run configs for 1.14+ versions should now be generated automatically once the
referenced PR is merged (or when using a local build of it).
2020-07-13 16:07:48 +02:00
Jonas Herzig
e83805bee6 Remove MP4_HIGH preset (fixes #254)
It results in unreasonably high bit rates which regularly confuses users.
The Custom preset should generally be preferred.
2020-07-13 16:04:39 +02:00
Jonas Herzig
f1f1f5dde2 Fix tests failing because they cannot access jGui classes 2020-07-13 16:01:28 +02:00
Jonas Herzig
9b98575c0b Get rid of preshadow plugin, it doesn't play nice with recent IDEA 2020-07-13 16:01:28 +02:00
Jonas Herzig
ffa66dd905 Remove long broken reprod gradle setup 2020-07-13 16:01:28 +02:00
Jonas Herzig
54b515fd2b Merge remote-tracking branch 'origin/develop' into snapshot 2020-07-13 16:01:01 +02:00
Jonas Herzig
23849bc8c4 Merge pull request #247 from LindaJuffermans/develop
Minor doc changes
2020-07-04 19:36:54 +02:00
Linda Juffermans
e27c19f781 Rephrased tickrate mod incompatibility 2020-07-03 09:42:25 +02:00
Linda Juffermans
faf9b454d2 Fixed FFmpeg path in Windows 2020-07-03 09:20:39 +02:00
Linda Juffermans
241b086ec4 Added some known issues, unsupported launchers and incompatible mods. 2020-07-03 09:16:43 +02:00
Jonas Herzig
5bf6773655 Merge remote-tracking branch 'origin/develop' into snapshot 2020-06-28 22:07:49 +02:00
Jonas Herzig
7118d55d62 Update to 1.16.1 2020-06-28 21:57:45 +02:00
Jonas Herzig
a4af8c2610 Release 2.3.2 2020-06-28 21:31:47 +02:00
Jonas Herzig
bc05566d2e Update ReplayStudio
fc8a66d Fix handling of view pos/dist packets in MC 1.14+ quick mode
2828174 Fix reading and writing of unload chunk packets pre-1.9 (fixes #210)
42bd0fe Fix map data being swallowed by squash filter (fixes #232)
2020-06-28 21:12:12 +02:00
Jonas Herzig
0ab1db9517 Improve handling of CrashException in runLater (fixes #205) 2020-06-28 21:12:12 +02:00
Jonas Herzig
a6f5931e7e Fix output file render setting not being saved (fixes #229) 2020-06-28 21:12:12 +02:00
Jonas Herzig
513f53f1ee Open output file popup in folder and with name of current file 2020-06-28 21:12:12 +02:00
Jonas Herzig
6038d3c4df [1.14+] Fix resource pack loading during rendering (fixes #182) 2020-06-28 21:12:12 +02:00
Jonas Herzig
72b44c368b [1.8] Fix incorrect event bus for deferred runLater (fixes #206) 2020-06-28 21:12:12 +02:00
Jonas Herzig
058346d247 Workaround a bug in MC where light is not updated (fixes #209)
MC stores server light data and only applies it during the next frame.
Therefore, if there is no frame between receiving the chunk and block changes in
it (like when jumping in replays), then the light update from the block change
gets lost.
2020-06-28 21:12:12 +02:00
Jonas Herzig
0ba651d19c Fix recording of client player's metadata after respawn (fixes #212)
1.15 removed the data tracker syncing from the spawn packet, so we now need to
send that explicitly.
2020-06-28 21:12:12 +02:00
Jonas Herzig
8e1f9f5a9c Fix quick mode sending async-mode packets when paused
This wasn't much of on issue because no tick events are fired normally while
paused. When seeking we do however manually run a tick for better result, and
this manual tick would cause this async sending code to run and seek wildly into
the future.
2020-06-28 21:12:12 +02:00
Jonas Herzig
c04f3ab185 Fix shift+play camera path requiring time keyframes (fixes #218) 2020-06-28 21:12:12 +02:00
Jonas Herzig
bad79ab286 Throw IOException when ImageIO.read return null (fixes #201) 2020-06-28 21:12:12 +02:00
Jonas Herzig
9f3808f0ff Render gui overlay even when event was cancelled (fixes #170)
Cause Lunatrius' InGame-Info-XML mod cancels it and we don't actually care about the event, just about when it's called.
2020-06-28 21:12:12 +02:00
Jonas Herzig
5f284fcd3d Fix spectating when clicking with unlocked cursor (fixes #224)
> If you misclick the add keyframe button or something, you end up specating
instead and you have to find the camera angle again
2020-06-28 21:12:12 +02:00
Jonas Herzig
04c902a792 [1.8.9] Fix launching in development environment 2020-06-28 21:12:12 +02:00
Jonas Herzig
33ec18ad1e Merge pull request #240 from ThomasBerends/feature/docs-upgrade
Overall upgrade of documentation
2020-06-25 20:47:01 +02:00
Thomas Berends
5c446bbb8d Processed feedback 2020-06-25 20:41:09 +02:00
Thomas Berends
d79c66cdd1 Update docs/content.md
Co-authored-by: Jonas Herzig <me@johni0702.de>
2020-06-25 20:27:20 +02:00
Thomas Berends
175efa55fe Update docs/content.md
Co-authored-by: Jonas Herzig <me@johni0702.de>
2020-06-25 20:27:07 +02:00
Thomas Berends
b79c835d53 Overall upgrade of documentation 2020-06-25 19:07:57 +02:00
Jonas Herzig
dc9fcb11cd Update to 1.16-rc1 2020-06-21 15:29:07 +02:00
Jonas Herzig
82200a7c34 Update to 1.16-pre6 2020-06-15 21:12:06 +02:00
Jonas Herzig
30aa992ddb Update to 1.16-pre5 2020-06-15 11:14:30 +02:00
Jonas Herzig
2ffde14c60 Update to 1.16-pre1 2020-06-15 09:44:37 +02:00
Jonas Herzig
14b84c5e1b Fix remapping of jGui using incorrect mappings
We used to include the raw jGui source in our jar and then had the main remapJar
task remap both of them to intermediary. This however does not work properly
when jGui needs additional mapping (e.g. because of mixin), resulting in
non-remapped mixins with fail to apply at runtime.

With this commit, we no longer include jGui in our raw jar and instead now have
shadowJar depend on jGui's remapJar task.
2020-06-15 08:58:02 +02:00
Jonas Herzig
88be6b3935 Update to 20w22a (minimal mode only) 2020-06-04 13:03:34 +02:00
Jonas Herzig
6210cb09aa Fix recording in minimal mode 2020-06-04 11:44:54 +02:00
Jonas Herzig
20b410f963 Release 2.3.1 2020-05-24 14:08:45 +02:00
Jonas Herzig
ef13d020a2 Fix incorrect screen and crash when encountering replay restrictions 2020-05-24 13:39:15 +02:00
Jonas Herzig
fabe4783c8 Make Replay Viewer button work with CustomMainMenu (fixes #195) 2020-05-24 13:38:10 +02:00
Jonas Herzig
ef79331037 Remove online features, they're no longer available 2020-05-24 12:38:57 +02:00
Jonas Herzig
244aeb244f Fix incorrect 1.14.4-forge to 1.12.2 mapping
This causes the reverse conversion to incorrect results again but I cannot
currently be bothered to fix that.
2020-05-23 23:24:24 +02:00
Jonas Herzig
ea95863b4a Update ReplayStudio (fixes #173) 2020-05-23 22:54:11 +02:00
Jonas Herzig
3c526a6cd4 Support MM1 in addition to MM2 (fixes #162)
Cause the latest OptiFabric on 1.14.4 still ships that and it has no support for
entrypoints.
2020-05-23 22:31:01 +02:00
Jonas Herzig
363a8d595c Apply OF chunk building bug fix only during rendering (fixes #164) 2020-05-23 22:05:42 +02:00
Jonas Herzig
d1ff98c76a Fix 1.12.2 to 1.14.4-forge conversion 2020-05-23 20:13:54 +02:00
Jonas Herzig
1123341182 Fix RM not loading another mod loads mixin first (fixes #181) 2020-05-23 20:06:18 +02:00
Jonas Herzig
a23f18d92e Fix fabric dependency declaration (fixes #187) 2020-05-23 14:37:44 +02:00
Jonas Herzig
154952a8ac Change ModCore messages cause people keep thinking those are errors 2020-05-23 14:37:44 +02:00
Jonas Herzig
b68d077b38 Update preprocess plugin and enable parallel builds by default 2020-05-23 13:25:37 +02:00
Jonas Herzig
c0be8da65b Release 2.3.0 2020-05-08 13:09:42 +02:00
Jonas Herzig
b534d1395d Update ReplayStudio, fixes squashing of empty columns (fixes #151) 2020-05-08 12:23:35 +02:00
Jonas Herzig
4e5122db5d Close packet output stream before saving replay
Aside from being best practice, this is necessary for the recording CRC to be
written to the replay file (cause that only happens on close).

Also potentially fixes https://github.com/ReplayMod/ReplayMod/issues/144 though
that should already be covered by ZipReplayFile tracking and closing all of its
`OutputStream`s before saving.
2020-05-08 11:38:12 +02:00
Jonas Herzig
8193006aea Update ReplayStudio, fixes cache invalidation when recording changes 2020-05-08 11:29:33 +02:00
Jonas Herzig
4aa256d53b Cleanup raw and cache files after some time (fixes #143) 2020-05-08 10:57:34 +02:00
Jonas Herzig
62c6b36f08 Fix crash when minimizing on Windows during rendering (fixes #140)
Hopefully, haven't actually tried it cause, you know, Windows (and minimizing
with just xfwm4 doesn't exhibit the same behavior).
2020-05-08 10:17:49 +02:00
Jonas Herzig
a1cee391fb Render GuiOverlays before (i.e. behind) debug overlay
Also fixes https://github.com/ReplayMod/ReplayMod/issues/155
2020-05-08 09:45:06 +02:00
Jonas Herzig
d4192b354c [1.15] Fix dead-lock due to data race during rendering (fixes #156) 2020-05-08 09:45:06 +02:00
Jonas Herzig
d24800160b Improve MarkerProcessor output generation (fixes multiple issues)
In particular:
- No longer generate any replays when auto-recording is off and recording is
never enabled from the ingame menu (fixes #138)
- Do not generate an additional empty replay file when recording was stopped in
ingame menu (fixes #147)
- only do squash if there are further output replays (fixes #142)
- Use the input file name as output file name even if there was a split (as long
as it's the only output file, e.g. because recording was never un-paused after
the split)
2020-05-08 09:45:06 +02:00
Jonas Herzig
9fb4dce367 Reset export arguments when upgrading from old version (fixes #148) 2020-05-08 09:45:06 +02:00
Jonas Herzig
811f52dc17 Throw helpful error message when rendering with sodium (see #150) 2020-05-08 09:45:06 +02:00
Jonas Herzig
72ce522813 Ensure task queue is not locked during rendering (fixes #157)
Similar to 3fedc22 in effect and cause. However tasks are executed, they just
cannot be submitted pre-1.14 because MC would continuously hold the lock on the
scheduledTasks queue for the entire renderVideo call.
2020-05-07 14:11:02 +02:00
Jonas Herzig
316f4e2c3c Prevent keyframe time from being set out of bounds (fixes #152) 2020-05-07 11:45:01 +02:00
Jonas Herzig
0962f1895e Fix 1.14.4 forge and fabric jars having the same name (fixes #149)
This caused one of them to be deployed at random, e.g. forge for 2.3.0-b1,
obviously resulting in an unusable build.
2020-05-07 11:20:20 +02:00
Jonas Herzig
8e05a67c5e Pre-release 1 of 2.3.0 2020-04-22 10:48:44 +02:00
Jonas Herzig
715bd8d366 Fix doRelease gradle task 2020-04-22 10:48:07 +02:00
Jonas Herzig
195942cd62 Add .gitkeep files to versions/{1.14.4,1.15.2} 2020-04-22 10:38:58 +02:00
Jonas Herzig
9dfd25c3fd Update README 2020-04-22 10:10:01 +02:00
Jonas Herzig
3d71f7c526 [Pre-1.12] Include less-outdated netty library for ReplayStudio
On 1.12+ MC's bundled version is sufficiently up-to-date but before that it
didn't have e.g. `ByteBuf.retainedSlice`.
2020-04-21 23:08:04 +02:00
Jonas Herzig
05f617a885 Use ReplayOutputStream for packet writing
We didn't used to do that because it would have required us to serialize and
then de-serialize as MCProtocolLib only to re-serialize each packet.
With ReplayStudio v2, we only have to convert to from MC's ByteBuf types to
ReplayStudio's ByteBuf (fairly trivial).

This also allows us to automatically make use of ReplayStudio's backwards
compatibility features: We didn't used to record the login phase pre-1.14 and we
still don't, so we now would have to inject a fake login packet (because we're
no longer generating legacy-version replay files) but ReplayOutputStream can
do that for us.
Without this commit, any pre-1.14 replays generated are unplayable due to the
missing LoginSuccess packet.
2020-04-21 22:58:55 +02:00
Jonas Herzig
c8b7e5b213 [Forge] Fix saving of CustomPayload packets 2020-04-21 22:04:01 +02:00
Jonas Herzig
1249ca4167 Add ModCore integration 2020-04-21 21:30:24 +02:00
Jonas Herzig
b852a1787d Downgrade pre-1.12 back to Mixin 0.7.10 2020-04-21 21:11:31 +02:00
Jonas Herzig
a733d301fd Update preview gui framebuffer size regardless of performance mode
This used to be more of an issue in the past but `displaySizeChanged` has gotten
pretty cheap by now and not updating it will basically make the rendering GUI
useless once you resize even once.
2020-04-17 13:56:19 +02:00
Jonas Herzig
059063430c Update ReplayStudio (fixes #134)
9117411 ReplayOutputStream must not change ByteBuf reader index of packet
2020-04-17 01:24:46 +02:00
Jonas Herzig
7c35e1c7d1 Set CameraEntity.noClip depending on spectator state (fixes #136)
This field is used to decide whether or not to render the inside-block overlay,
as such we want it to be set while we're in spectator mode).

This wasn't a problem before 1.15 because we also cancel the renderHand call
while we're in spectator mode and the same method which renders your hand also
renders the overlay, so we were inadvertently canceling that at the same time.
With 1.15, that's still the case except when using OF, which splits the method
apart by adding three boolean arguments indicating which part to execute.
2020-04-16 23:59:00 +02:00
Jonas Herzig
3b72a67d2b Persist gradle (and loom) cache between Jenkins jobs 2020-04-16 18:51:01 +02:00
Jonas Herzig
808793a121 Switch from Drone to Jenkins 2020-04-16 18:50:59 +02:00
Jonas Herzig
023a1bcf0f Fix :1.7.10:setup{CI,Decomp}Workspace
For details see the referenced FG commit.
Related commit for 1.8+: 190210f
2020-04-16 18:50:51 +02:00
Jonas Herzig
5953435dc5 [1.14+] Fix reading of lang files with CRLFs (mitigates #132) 2020-04-16 14:55:46 +02:00
Jonas Herzig
0d3a689f17 [1.14+] Fix "Player Overview" title
We used to remap the old language key layout for inputs to the one used by
fabric but didn't consider that we might still be directly referencing the old
key somewhere else (e.g. for the Player Overview title).

With this commit, we retain the original and add the new mapping.
2020-04-16 14:48:23 +02:00
Jonas Herzig
f8b22d449c [1.14] Work around bug in mixin causing Accessors to not resolve
This intentionally breaks the mixin in a development environment but makes the
compiled jar work in a live environment (which is probably more useful given the
primary version is 1.15 now).
2020-04-15 19:47:12 +02:00
Jonas Herzig
f96ed03f12 Update loom: 0.2.2 → 0.2.6 2020-04-15 19:41:21 +02:00
Jonas Herzig
3fedc22899 Execute task queue even when rendering a paused replay (fixes #129)
The task queue is executed by MC each frame, not just each tick, so we should do
so as well. Most async actions also rely on it to re-synchronize with the
rendering thread, e.g. skins won't load if we never poll the task queue.
2020-04-15 18:42:39 +02:00
Jonas Herzig
a514e53d11 [1.7.10] Disable tests for now 2020-04-15 18:34:25 +02:00
Jonas Herzig
4586cb5382 Only update timeline when default iterp type changed (fixes #127) 2020-04-15 17:40:26 +02:00
Jonas Herzig
6ccb576637 Update lombok (see #127) 2020-04-15 17:26:53 +02:00
Jonas Herzig
82f86122c8 Handle third-party buttons without text in ingame menu (see #120) 2020-04-15 16:56:16 +02:00
Jonas Herzig
39ccf60f15 Update ReplayStudio
6990c48 SquashFilter: Fix leaking of MapData packets
2020-04-08 23:49:13 +02:00
Jonas Herzig
f5afeb918c Fixup mixin config changes of c119392
- Remove MixinRenderGlobal, it's now called Mixin_ForceChunkLoading
- Re-add MixinChunkRenderWorker (1.8-1.14) which was accidentally removed
2020-04-08 23:26:02 +02:00
Jonas Herzig
dafbeb34d4 Workaround a bug in OF which incorrectly queues chunks (fixes #123) 2020-04-08 22:43:02 +02:00
Jonas Herzig
5aa1d7be53 Update 1.14.4 fabric-api version to 0.4.3 (fixes #101) 2020-04-08 17:46:01 +02:00
Jonas Herzig
c5476025ec Fix terrain not rendering with OF shaders enabled (fixes #122)
This was caused by us setting `needsTerrainUpdate` to false during the shadow
pass in order to break out of the ForceChunkLoading loop (cause OF doesn't
update chunks during the shadow pass). However, this inadvertently caused the
chunk updates to be skipped during the normal pass as well if there didn't
happen to be another reasons for updating.

To fix this, we simply move the shadow pass check into the ForceChunkLoading
mixin and skip the entire loop during the shadow pass.
2020-04-08 17:45:06 +02:00
Jonas Herzig
8f7d263ad9 Fix livelock caused by OF not properly resetting ChunkVisibility
This can lead to a livelock when rendering with shaders after exiting a
singleplayer world (3/4 chance of breakage on each exit).
2020-04-08 14:18:25 +02:00
Jonas Herzig
97f901408e Reduce mixin plugin log message verbosity to debug level 2020-04-08 12:59:59 +02:00
Jonas Herzig
1d7a49907c Fix compilation with Mixin 0.8 on ForgeGradle 2020-04-07 17:20:04 +02:00
Jonas Herzig
9970ac798a Update 1.14.4 fabric-loader (for Mixin 0.8) 2020-04-07 15:40:42 +02:00
Jonas Herzig
5d0ea19c72 Fix rendering not being cancelled until unpaused (fixes #125) 2020-04-07 15:30:40 +02:00
Jonas Herzig
7613fdd4c3 Abort rendering when window receives close request even when paused
Previously we'd get stuck in the paused render loop even when window close was
requested.
2020-04-07 15:26:07 +02:00
Jonas Herzig
31caa68b34 Fix hover pos not respecting gui scale in render gui (fixes #124) 2020-04-07 15:25:19 +02:00
Jonas Herzig
b6ff3855a1 Fix rendering gui framebuffer size when not paused (fixes #126) 2020-04-07 15:10:29 +02:00
Jonas Herzig
3be3072082 Run video rendering from runLater
Prevents any issues arising from the fact that we would otherwise be somewhere
deep in the GUI lib button handling call stack.
2020-04-07 14:51:16 +02:00
Jonas Herzig
3f4156b91b Stop using interrupts to abort the rendering process (fixes #119)
They ended up lingering around and breaking any further blocking operations,
resulting in random errors afterwards. And using them was really unnecessary
anyway.
2020-04-06 20:56:22 +02:00
Jonas Herzig
e3f621b86a Work around the fact that our mixins may be loaded before Optifabric 2020-04-06 20:39:15 +02:00
Jonas Herzig
27bdc78688 Give up on end portal animation mixin when OF is installed 2020-04-06 20:38:53 +02:00
Jonas Herzig
ed6ba740bb Workaround OF breaking spectator hand mixin 2020-04-06 20:37:45 +02:00
Jonas Herzig
4c577c4559 Update non-fabric versions to Mixin 0.8 2020-04-06 20:33:44 +02:00
Jonas Herzig
51e10d890a Update ReplayStudio (fixes #121) 2020-04-06 15:21:39 +02:00
Jonas Herzig
b4a2c1b266 Fix race condition between inbound and injected packets (fixes #118)
In the case of #118, this was resulting in the EntityTrackerUpdate packet (which
contains info on which skin layers should be visible) sometimes ending up before
the SpawnPlayer packet, hence the players outer skin layers being invisible at
the start of the recording.
2020-04-06 15:14:47 +02:00
Jonas Herzig
ee68a63233 Fix Redirect target in MixinRenderLivingBase for 1.15 (see #120)
For some reason this applied fine in a development environment (even though the
method signature changed significantly), hence why I didn't notice it being
broken. It did not work (just like one would expect) in a live environment.
2020-04-06 13:19:11 +02:00
Jonas Herzig
b119d2d127 ./gradlew :1.15.2:setCoreVersion
Also `./gradlew :jGui:1.15.2:setCoreVersion`.
2020-04-06 13:18:37 +02:00
Jonas Herzig
f3c4092c72 Update preprocessor 2020-04-06 12:14:05 +02:00
Jonas Herzig
065d713e94 Update ReplayStudio
338c5a8 RandomAccessReplay: Handle light packets arriving after chunk packet
1658b5e SquashFilter: Fix entity delta position not being reset on teleport
2020-04-02 15:34:56 +02:00
Jonas Herzig
de40b5aa47 Fix spectating via point&click on fabric 2020-04-02 15:31:59 +02:00
Jonas Herzig
c119392c92 Implement chunk forcing during rendering for 1.15 2020-04-02 14:15:05 +02:00
Jonas Herzig
4ea13051fd Disable Blend render mode on 1.15 for now 2020-04-02 10:54:19 +02:00
Jonas Herzig
6113336c37 Disable ContainerLocalRenderInformationAccessor in 1.15 for now
It appears to suffer from https://github.com/SpongePowered/Mixin/issues/390 and
since we don't yet support the ChunkExporter, it's not yet needed anyway.
2020-04-02 10:51:14 +02:00
Jonas Herzig
724c236524 Cache configureRelocation output so we can do up-to-date checks
Saves us from having to run it every time even if the shadowJar task would be
up-to-date anyway.
2020-04-02 10:12:02 +02:00
Jonas Herzig
0b31e8c9df Implement MCVer.getProtocolVersion() for MC<11400 2020-04-02 02:00:18 +02:00
Jonas Herzig
8ce84e39e2 Fix shadowJar task using incorrect jar with loom 2020-04-02 01:59:32 +02:00
Jonas Herzig
c0e27634f4 Fix particle orientation during omnidirectional rendering in 1.15 2020-04-02 00:11:06 +02:00
Jonas Herzig
bf6f71ef89 Fix packet reference counting in MarkerProcessor 2020-04-02 00:11:06 +02:00
Jonas Herzig
2dbd5cde02 Update ReplayStudio 2020-04-02 00:11:06 +02:00
Jonas Herzig
c9285ab4a1 Fix end portal texture animation while replay is paused
Figured out where they moved it.
2020-04-02 00:11:06 +02:00
Jonas Herzig
d5fcdfb8c2 Fix ODS rendering in 1.15 2020-04-02 00:11:06 +02:00
Jonas Herzig
ad523009b4 Fix entity rendering with larger/smaller than actual resolution 2020-04-02 00:11:06 +02:00
Jonas Herzig
4116a3a7c9 Fix path preview rendering in 1.15 2020-04-02 00:11:06 +02:00
Jonas Herzig
b11b9db548 Fix frustum culling during non-ODS omnidirectional rendering
Not sure when this changed (probably with 1.14 update) but it definitely was
before the 1.15 update.
2020-04-02 00:11:06 +02:00
Jonas Herzig
2c3697c2ec Fix cubic rendering orientation 2020-04-02 00:11:06 +02:00
Jonas Herzig
d6559a21fc Get all 1.15 mixins applying 2020-04-02 00:11:06 +02:00
Jonas Herzig
a3e1792fe7 More 1.15 mapping fixes 2020-04-02 00:11:06 +02:00
Jonas Herzig
5315c66943 Cleanup 1.15.2 → 1.14.4 remapping 2020-04-02 00:11:06 +02:00
Jonas Herzig
9e7dc61d20 #ifdef DEV_ENV is no longer applicable since 8bc0b0a
There is no longer a dedicated "core" project where DEV_ENV would be defined,
instead whichever is the currently selected version automatically becomes the
main project using the main src folder.
2020-04-02 00:11:06 +02:00
Jonas Herzig
b69cd9fb81 Fix mode of various files
None of these should be executable, I blame Marius.
2020-04-02 00:11:06 +02:00
Jonas Herzig
527562549b Update 1.14.4 yarn 2020-04-02 00:11:02 +02:00
Jonas Herzig
ba83aa97b3 Update preprocessor plugin, enable configure-on-demand 2020-04-02 00:10:25 +02:00
Jonas Herzig
b3b73609cb Migrate 1.15.1 project to 1.15.2 2020-03-31 14:04:50 +02:00
Jonas Herzig
78ba9bd55e Fix misc preprocessor directives 2020-03-30 15:30:22 +02:00
Jonas Herzig
190210f950 Fix setupCIWorkspace/setupDecompWorkspace
See the linked commits in our FG fork for details.

`:1.8:setupDecompWorkspace` (and only that one) still fails with an unrelated
NPE which I can't be bothered to fix.
2020-03-30 12:46:36 +02:00
Jonas Herzig
9107485c14 Fix compilation for 1.7.10 2020-03-30 12:40:07 +02:00
Jonas Herzig
823e04a858 Fix compilation of 1.9.4 2020-03-30 03:20:13 +02:00
Jonas Herzig
4c6684236b Fix compilation of 1.11.2 2020-03-30 03:18:00 +02:00
Jonas Herzig
8b7ef8d1e3 1.13 is dead (followup to 8bc0b0a) 2020-03-30 02:52:47 +02:00
Jonas Herzig
49ea1ae40a Fix compilation of 1.12.2 2020-03-30 02:52:21 +02:00
Jonas Herzig
13283fb5d2 Fix compilation of 1.14.4-forge 2020-03-30 02:52:13 +02:00
Jonas Herzig
eb1fbed0d8 Fix compilation of 1.15.1 2020-03-30 01:05:26 +02:00
Jonas Herzig
5c13995e59 Fix compilation of 1.14.4 2020-03-30 01:03:46 +02:00
Jonas Herzig
82bbf7b495 Fix ReplayStudio dependency group id 2020-03-29 21:32:44 +02:00
Jonas Herzig
af8803d6b5 WIP 1.15 and ReplayStudio v2 update 2020-03-13 14:18:19 +01:00
Jonas Herzig
8bc0b0a4df Update preprocessor and replace 1.13.2 subproject with 1.14.4-forge
The new preprocessor version brings first-party support for fabric, in
particular for automatically fetching mappings loom and for
automatically remapping between MC versions via intermediary mappings.
This will come in handy when updating to 1.15.

It also supports automatic remapping between fabric and forge on the
same MC version (by going mcp<->srg<->mojang<->intermediary<->yarn).
Therefore this commit replaces the previous 1.13.2 (forge) subproject
with a 1.14.4-forge one. Instead of manually providing full mappings for
1.14.4-fabric to 1.13.2-forge and partial (classes) for 1.13.2-forge to
1.12.2-forge, we now only need partial (classes) for 1.12.2-forge to
1.14.4-forge and preprocessor will take care of the forge to fabric
step (in fact, our mapping file for that is currently completely empty).

In an attempt to write an IDE (IntelliJ) plugin for quicker and easier
working with the preprocessor (e.g. immediately mapping single files
from within the IDE, jumping between different versions for the same
file), the preprocessor gradle plugin declaration now requires you to
explicitly specify variables in the common.gradle and the overall
relationship between projects in the build.gradle (latter is required
anyway, so the plugin can know where it should map between forge and
fabric and which subprojects are which versions).
Since that necessitated some changes to the build.gradle file, I took
the opportunity to convert it to Kotlin. As such we now also use
Gradle's newer plugin-block with the pluginManagement-block instead of
manually declaring buildScript (not for the common.gradle though), which
imo is nicer anyway and comes with various advantages (see gradle docs).

There were also some remapping bugs fixed and some new ones
introduced (e.g. manually declared inner class mappings seem to no
longer function properly under certain conditions).
There's also support for remapping Kotlin now. Just saying.
2020-01-12 23:34:10 +01:00
Jonas Herzig
f51298e2a3 Update Mixin (fixes GH-66) 2019-08-04 17:16:52 +02:00
Jonas Herzig
d8ce4275af Update ReplayStudio for misc MCProtocolLib fixes 2019-08-04 17:13:56 +02:00
Jonas Herzig
c7b0780111 Fix playback once end has been reached on 1.8 (and some above) 2019-08-04 15:06:27 +02:00
Jonas Herzig
94d6e7cb4b Fix mouse wheel speed outside of gui screen on 1.13+ 2019-07-27 11:51:39 +02:00
Jonas Herzig
ea6e452dd0 Pre-release 7 of 2.2.0 2019-07-19 22:44:05 +02:00
Jonas Herzig
7d6c263ce0 Update MCProtocolLib for modded entity attribute types on 1.12.2
E.g. "forge.swimSpeed" introduced in some later 1.12.2 Forge
2019-07-19 21:49:10 +02:00
Jonas Herzig
9c25396016 Gracefully handle incomplete QuickMode cache 2019-07-19 21:49:10 +02:00
Jonas Herzig
1245f38267 Fix 360 camera stabilization on 1.13+ 2019-07-19 21:49:10 +02:00
Jonas Herzig
5bd9b0cb6b Fix LoginCompressionS2CPacket being recorded in replay file on 1.13+ 2019-07-19 21:49:10 +02:00
Jonas Herzig
08f09dca6e Update MCProtocolLib to fix certain chunk unload packets on 1.8(.9) 2019-07-19 19:34:25 +02:00
Jonas Herzig
3cd21b8a78 Guard against corrupted config files on 1.14 2019-07-19 14:48:00 +02:00
Jonas Herzig
67d7af2dc3 Update to MC 1.14.4 2019-07-19 14:25:42 +02:00
Jonas Herzig
c4c4b75022 Pre-release 6 of 2.2.0 2019-07-12 21:06:27 +02:00
Jonas Herzig
4a115cd1a5 Fix NoSuchMethodError due to OpenNBT binary incompatibility on MC<1.12 2019-07-12 19:50:47 +02:00
Jonas Herzig
06fe165249 Fix toString call which breaks due to Windows not defaulting to UFT8 2019-07-12 19:18:32 +02:00
Jonas Herzig
aea222d176 Fix deadlock when jumping backwards in 1.7.10 under certain conditions
Not entirely sure how to fulfill those conditions but the fix should be
fairly self-explanatory anyway.
2019-07-08 14:52:42 +02:00
Jonas Herzig
ac60e58da2 Fix nested runLater on 1.7.10 2019-07-08 11:58:55 +02:00
Jonas Herzig
45ef15359e Fix replay not properly starting during rendering on 1.7.10 2019-07-08 11:30:15 +02:00
Jonas Herzig
6ca1d037c1 Update ReplayStudio (fixes LIGHTNING_BOLT mappings on 1.14) 2019-07-08 10:35:03 +02:00
Jonas Herzig
c4d2be9e89 Make thread requirements of ReplayHandler#setup explicit and fix illegal usage 2019-07-08 09:53:47 +02:00
Jonas Herzig
8261767657 Pre-release 5 of 2.2.0 2019-07-06 22:16:53 +02:00
Jonas Herzig
cdf6ff4419 Update ReplayStudio 2019-07-06 21:36:54 +02:00
Jonas Herzig
a0e397d1d5 Add support for camera roll on 1.7.10 2019-07-06 21:24:26 +02:00
Jonas Herzig
8a75edb218 Fix vanilla keys being handled by VanillaGuiScreen's internal screen
This becomes an issue once e.g. Esc is overwritten to return to the
parent screen instead of no screen (e.g. pressing Esc in JEI recipe).
2019-07-06 20:28:52 +02:00
Jonas Herzig
e497e5930b Fix event dispatching between layered VanillaGuiScreen on MC<=1.12.2 2019-07-06 20:00:22 +02:00
Jonas Herzig
989a54b067 Fix stack overflow after entity tracker popup has been shown
Failure to load the entity tracker usually (not always) results in
`entityTracker` remaining to be `null`, so there has to be an additional
condition for aborting the thenRun-loadEntityTracker-…-recursion.
2019-07-06 17:37:28 +02:00
Jonas Herzig
31d327efc7 Fix entity tracker loading error popup never being shown 2019-07-06 17:35:10 +02:00
Jonas Herzig
d47c899ef8 Fix advanced screenshot writer (switch from rgb to bgra) 2019-07-06 13:59:46 +02:00
Jonas Herzig
55924c1d46 Fix serialization of settings on Fabric 2019-07-06 13:05:20 +02:00
Jonas Herzig
731ea1ab9f Fix NPE when adding marker during recording before player is spawned
Can happen e.g. when auto-recording is disabled
2019-07-06 12:56:39 +02:00
Jonas Herzig
67e300bcff Fix NPE in MarkerProcessor when unnamed markers are present 2019-07-06 12:50:31 +02:00
Jonas Herzig
dc86da7a20 Pre-release 4 of 2.2.0 2019-06-30 22:20:38 +02:00
Jonas Herzig
7eecb2664d Fix rendering of sky (or anything with textures disabled) during ODS 2019-06-30 20:32:54 +02:00
Jonas Herzig
7299ecd0ce Fix main/offhand items of spectated player not being updated 2019-06-30 15:46:52 +02:00
Jonas Herzig
4fe2fee456 Fix constant equip sound when spectating player with head gear in replay 2019-06-30 15:46:09 +02:00
Jonas Herzig
b2b0ca1cd1 Fix recording of certain mobs on Hypixel
For some reason hypixel is sending duplicate entity meta data entries
in their spawn packets.
We'll now be ignoring all but the last one for each id (should match
how vanilla handles these).
2019-06-30 13:14:47 +02:00
Jonas Herzig
7241036e61 AWT is forbidden on 1.13+ (this includes BufferedImage)
Instead use NativeImage on 1.13+ via newly introduced Image class.
See Image docs for details.

Also fixes an issue with thumbnail taking on 1.13+: The original
ScreenshotHelper method is now async, luckily there's a sync
variant and as a bonus it directly returns a NativeImage so we can
skip having to read the screenshot from disk.
2019-06-30 12:12:13 +02:00
Jonas Herzig
732e1ab32e Update ReplayStudio to fix illegal reflection issue on JDK12 2019-06-29 15:09:31 +02:00
Jonas Herzig
954052aaa0 Pre-release 3 of 2.2.0 2019-06-28 18:28:23 +02:00
Jonas Herzig
c051b0ba3b Fix crash when quickly double-clicking the "Load"-replay button
This has previously been fixed for quadruple-clicking on the replay
itself but for some reason has not been fixed for simply double-clicking
the "Load" button.
2019-06-28 17:38:55 +02:00
Jonas Herzig
801f0871d5 Fix framebuffer resizing for rendering on 1.13+ 2019-06-28 17:23:07 +02:00
Jonas Herzig
fcb8cc329b Fix second column of RM settings being displaced by long dropdown labels 2019-06-28 16:57:25 +02:00
Jonas Herzig
a9f7e09e64 Fix RM settings being shown in random order 2019-06-28 16:56:15 +02:00
Jonas Herzig
2351698b66 Show popup when replay saving/postprocessing fails
because asking people for logs turned out to not be a viable strategy
when they can figure out how to get back their replay on their own…
2019-06-28 16:43:13 +02:00
Jonas Herzig
94d2e523ab Fix crash when converting position for newly appended element
E.g. happens when clicking on newly added elements in a resource loading
list before those were rendered at least once.
2019-06-28 16:10:33 +02:00
Jonas Herzig
9320bd931b Fix container GUIs opening in 1.14+
Not sure why MC has yet another packet for those now but tbh idc.
2019-06-28 15:29:40 +02:00
Jonas Herzig
654a640a60 Fix tracking of enabled state for primary texture 2019-06-28 15:01:45 +02:00
Jonas Herzig
214da6ba59 Update to MC 1.14.3 2019-06-24 18:36:12 +02:00
Jonas Herzig
1f547f92ce Fix core module not being included in 1.7.10
Probably a remnant of when we used a different gradle version for it.
2019-06-24 17:15:33 +02:00
Jonas Herzig
862c8d9b36 Update preprocessor
- Switch from ECJ to IDEA (with potential for kotlin)
- Can pull SRG mappings from FG, reducing amount of manual mappings (basically just class mappings and fixing errors in SRG mappings)
2019-06-24 17:15:33 +02:00
Jonas Herzig
b846d5308e Fix FullBrightness having no effect during rendering 2019-06-21 22:20:45 +02:00
Jonas Herzig
e7deed73b5 Fix NPE when jumping to beginning of replay (before player is spawned) 2019-06-21 22:14:22 +02:00
Jonas Herzig
4213d37c76 Fix race-condition-induced dead lock on replay restart in 1.14+
MC clears it scheduled tasks on disconnect. If we don't wait for
that to have happened on the async sender, then we might loose
some of the initial handshake packets (resulting in a dead lock in
fabric's registry syncing code).
2019-06-21 22:06:04 +02:00
Jonas Herzig
25ec311c86 Pre-release 2 of 2.2.0 2019-06-21 15:01:51 +02:00
Jonas Herzig
4ec5ef75a1 Fix various replay editor issues caused by shadow plugin bug 2019-06-21 15:00:08 +02:00
Jonas Herzig
75c4c7213f Fix NPE applying camera keyframes when camera entity is not yet loaded
Still not sure when this can happen but users are reporting it:
https://www.replaymod.com/forum/thread/2548#post10627
2019-06-21 12:05:05 +02:00
Jonas Herzig
f1f760a0e9 [1.14] Fix ingame menu buttons with ModMenu installed 2019-06-21 07:34:22 +02:00
Jonas Herzig
b8d319eba9 Skip world during video rendering if it has not yet been loaded 2019-06-21 07:34:22 +02:00
Jonas Herzig
de0f40f4dd [1.14] Allow opening of replay settings via ModMenu 2019-06-20 18:44:38 +02:00
Jonas Herzig
5305352b77 [1.14] Mark mod as client-side-only in ModMenu 2019-06-20 18:44:26 +02:00
Jonas Herzig
44a70c8ecf [1.14] Fix invalid mod icon (icons on fabric must be square) 2019-06-20 18:44:26 +02:00
Jonas Herzig
481b7b4c9d [1.14] Fix ModMenu buttons clashing with RM buttons on main menu 2019-06-20 18:44:10 +02:00
Jonas Herzig
b7136e6d70 [1.14] Fix camera entity after restarting replay (same as 1eafc3f) 2019-06-20 18:44:10 +02:00
Jonas Herzig
70acd79431 Allow continued use of most of pathing even if entity tracker fails
The failing entity tracker really only breaks spectator keyframes.
This is also very desirable for minimal mode where entity tracker
failure is highly likely.
2019-06-20 18:44:10 +02:00
Jonas Herzig
af55951f42 Introduce minimal mode (allows RM to run on unsupported MC versions)
by disabling various version-specific features (i.e. everything which
requires the ReplayStudio).
2019-06-20 18:44:10 +02:00
Jonas Herzig
357501e5db Qualify some (remapped) field references which the preprocesser ignored
The preprocessor should have complained about these but it didn't for
some reason. This commit isn't fixing any imminent bug, it's just
precautionary (and required to compile once the preprocessor is fixed).
2019-06-17 12:04:51 +02:00
Jonas Herzig
679e4805a0 Fix error popup in replay editor being off-screen 2019-06-17 12:01:39 +02:00
Jonas Herzig
e59b5db859 Fix the replay editor now showing non-IO exceptions during processing
Instead it just froze which is unhelpful if people don't look at the log.
2019-06-17 11:52:47 +02:00
Jonas Herzig
d417c58d00 Pre-release 1 of 2.2.0 2019-06-14 22:35:44 +02:00
Jonas Herzig
bf2d72976c Fix rendering with OF F1_pre13 (via OptiFabric) installed
Note that to run it in dev env, one must switch back fabric-api to 0.2.
2019-06-14 22:16:18 +02:00
Jonas Herzig
d02b239e74 Fix incorrect RM config location
While I might wish it was `configs`, the world (forge) has settled on
`config`.
2019-06-14 22:09:56 +02:00
Jonas Herzig
73723ed9e2 Guard against broken render settings file 2019-06-14 22:09:56 +02:00
Jonas Herzig
8112c852ef [1.14] Fix NPE in FullBrightness
Turns out fabric's init runs earlier than forge so mc.options is still
null.
Instead we just store mc and access the options when needed (thanks to
the preprocessor that's even shorter than before).
2019-06-14 22:09:56 +02:00
Jonas Herzig
a76268138a [1.14] Fix recording player's hand not swinging 2019-06-14 22:09:56 +02:00
Jonas Herzig
1eafc3fadf [1.14] Fix closing of replay not actually fully shutting down the world 2019-06-14 22:09:56 +02:00
Jonas Herzig
4dd02f8299 [1.14] Fix recording not always being stopped 2019-06-14 22:09:56 +02:00
Jonas Herzig
d15fa6a3f9 Fix notice screen back buttons not being hooked up 2019-06-14 22:09:56 +02:00
Jonas Herzig
a840cadfb7 Fix camera event handler staying registered leading to lack of HUD
When unloading the camera without killing it first (e.g. jumping back
in time), the event handler wouldn't ever get unregistered.
2019-06-14 22:09:56 +02:00
Jonas Herzig
2a08c11598 [1.7.10] Fix dead lock and NPE when jumping backwards in replays
The deadlock is a regression due to login phase inclusion.
Not sure about the NPE, it might have always existed.
2019-06-14 22:09:56 +02:00
Jonas Herzig
c72392fb62 Fix various NPE while in replay on 1.8.9 or below
Nulling the world and calling runTick proved to be too volatile, so
instead let's try performing an early return from runTick via mixin.
2019-06-14 14:49:54 +02:00
Jonas Herzig
560982a14a Fix NPE when replay is closed but camera entity is still being rendered 2019-06-14 14:09:42 +02:00
Jonas Herzig
047f216f73 [1.7.10] Fix event handler visibility 2019-06-14 14:04:52 +02:00
Jonas Herzig
898e29d7a1 [1.7.10] Fix crash when opening replay
Looks to be two regressions, one due to login phase inclusion and one
due to simplification of InputReplayTimer.
2019-06-14 13:35:53 +02:00
Jonas Herzig
208b9c1b60 Update to MC 1.14.2 2019-05-28 11:55:58 +02:00
Jonas Herzig
d89655e69a Remove some more preprocessor statements in favor of remap 2019-05-28 11:25:46 +02:00
Jonas Herzig
f3acf8cde7 Fix realms icon offsets in main menu on 1.14+ 2019-05-25 20:07:27 +02:00
Jonas Herzig
e7d96fca2a Fix lack of hand when spectating player in replay on 1.13+ 2019-05-25 19:45:53 +02:00
Jonas Herzig
cfdc4b9713 Remove workaround for super-super-class remapping bug 2019-05-25 18:57:32 +02:00
Jonas Herzig
26d8c97136 Switch to custom FG fork for Gradle 5 compatibility
Also drop MixinGradle since it supports neither Gradle 5 nor FG1 nor FG3
2019-05-24 16:26:01 +02:00
Jonas Herzig
a57ce21ebb Update Gradle Wrapper to 5.4.1 2019-05-24 16:26:01 +02:00
Jonas Herzig
5f57f3a1e2 Fix incompatible OpenNBT version on 1.12.2 and below 2019-05-24 16:25:24 +02:00
Jonas Herzig
62c673f4bc Update jGui to fix NPE in file chooser gui on windows
Regression introduced in 213ac13627178f49ce9671b29b6a542cb0e4c922
2019-05-24 10:59:55 +02:00
Jonas Herzig
05aec482c9 Fix classic camera movement (regression from switching to lwjgl vecs) 2019-05-22 11:04:10 +02:00
Jonas Herzig
5e407cc9aa Fix translations in replay recovery gui 2019-05-22 10:41:41 +02:00
Jonas Herzig
41251a1e18 Update ReplayStudio to remove ViaVersion server plugin classes 2019-05-21 20:43:28 +02:00
Jonas Herzig
cc9f2828c1 Fix world being set to null on replay restart when in sync mode 2019-05-21 11:04:38 +02:00
Jonas Herzig
8627867b62 Fix render preview (broken due to BGRA changes)
Also de-duplicates some code by combining >=1.13 and <1.13
2019-05-21 10:37:39 +02:00
Jonas Herzig
cf30f39b0e Be explicit about when we expect a login phase and when we don't 2019-05-20 18:57:20 +02:00
Jonas Herzig
2d02948203 Remove old replay editor gui screens 2019-05-20 18:55:07 +02:00
Jonas Herzig
993cdeab73 Work around mixin bug where a non-@Shadow field is treated as @Shadow
Note: Happens on 1.12.2 (different mappings than 1.14.1) and probably
only in dev env.
2019-05-20 18:37:40 +02:00
Jonas Herzig
fc1d99f985 Fix mouse input to overlays while the replay is paused in 1.8-1.12.2 2019-05-20 17:34:07 +02:00
Jonas Herzig
3a45147974 Move Mixins which exist specifically for jGui from RM to jGui repo 2019-05-20 17:18:12 +02:00
Jonas Herzig
1ef4f605d7 Fix accidental relocating of guava, commons-io and apache-logging (all provided by MC) 2019-05-20 17:08:19 +02:00
Jonas Herzig
e5ee6a3d94 Update to MC 1.14.1
The ReplayStudio update also fixes an issue with reading the
PlayerListEntryPacket leading to NPEs during Quick Mode.
2019-05-20 14:59:31 +02:00
Jonas Herzig
0e086d91a6 Use own event distribution system instead abusing fabric's one 2019-05-20 14:59:13 +02:00
Jonas Herzig
7cbf7f7c94 Switch core to 1.14 (generated via ./gradlew :1.14:setCoreVersion) 2019-05-10 14:09:22 +02:00
Jonas Herzig
7f7d33def8 Fail hard if versions/core/mcVersion is missing 2019-05-10 14:06:40 +02:00
Jonas Herzig
5f37ba48ff Reduce amount of 'relocate' statements for far better build times 2019-05-09 18:47:45 +02:00
Jonas Herzig
69e80fb3f4 Update Preprocessor to fix parallel builds 2019-05-09 17:45:26 +02:00
Jonas Herzig
7b97d9ea85 Use FG1.2 fork with Gradle 4.9 fixes so we can build everything at once 2019-05-08 14:00:46 +02:00
Jonas Herzig
362f61a337 Sign .drone.yml
Forgot to do it in f1527c51
2019-05-07 13:29:58 +02:00
Jonas Herzig
f1527c51fe Fix -dirty suffix of 1.7.10 build on CI 2019-05-07 12:49:53 +02:00
Jonas Herzig
d54905713f Fix mouse scroll and screenshot mixin targets 2019-05-07 12:48:36 +02:00
Jonas Herzig
6ba05f3d99 Fix resource pack recorder mixin
The old targets weren't inside the method but inside an inner class.
2019-05-07 11:59:06 +02:00
Jonas Herzig
2463e5dbf0 Work around bug in fabric's mapping provider (or Mixin itself?)
See https://github.com/FabricMC/fabric-mixin-compile-extensions/issues/1
2019-05-07 11:21:33 +02:00
Jonas Herzig
0f9150d7ce Fix modifier of scroll handler method 2019-05-07 10:30:20 +02:00
Jonas Herzig
2c843f4b45 Fix spectated player hand swinging 2019-05-06 23:31:35 +02:00
Jonas Herzig
6b9b9c2131 Get rid of annotation workaround (by not referencing affected classes) 2019-05-06 23:31:35 +02:00
Jonas Herzig
bd91d0d3bd Get rid of all the ATs in favor of Mixins 2019-05-06 22:46:21 +02:00
Jonas Herzig
2094c518a0 Fix :shadowJar task. Take 2.
This time, wait for the subprojects to be evaluated before trying
to get their shadowJar tasks (otherwise they won't be there).
2019-05-06 13:31:50 +02:00
Jonas Herzig
1d21002eb0 Run shadowJar and setCoreVersion in same gradle invocation on CI 2019-05-06 11:33:40 +02:00
Jonas Herzig
b55dce280c Fix :shadowJar task
It now copies any shadowed jar in any configured subprojects
instead of requiring all subprojects
2019-05-06 11:05:33 +02:00
Jonas Herzig
a65f3efbc5 Fix fetching of remap in jGui 2019-05-05 13:33:23 +02:00
Jonas Herzig
a02fe4e985 More FG build classpath workarounds
Though this one seems to have a different cause from the previous
one.
2019-05-05 13:26:53 +02:00
Jonas Herzig
2b4bee84f0 Fix preprocessor version in jGui 2019-05-04 20:41:25 +02:00
Jonas Herzig
08ff063a3b Fix 1.7.10 jar not being archived after drone build 2019-05-04 20:31:53 +02:00
Jonas Herzig
220b22869a Fix replay initialization with login phase on 1.11.2 and below
While this commit also considerably simplifies/cleans the setup
method, the actual fix is that the networkManager is now added
to the channel pipeline with under the "packet_handler" key,
whereas before it was unnamed causing issues when transitioning
to the play state.
2019-05-04 19:22:41 +02:00
Jonas Herzig
af86faeaf9 Fix webm encoding preset (caused by BGRA changes) 2019-05-04 15:27:03 +02:00
Jonas Herzig
3d009e45c7 Update to MC 1.14 / Fabric 2019-05-04 15:27:03 +02:00
Jonas Herzig
17fe5b345f Replace all ATs with Mixin on 1.13+ in preparation for Fabric 2019-04-26 12:04:33 +02:00
Jonas Herzig
d5b9e60c4d Workaround class loader errors by loading single guava in the root scope
Possibly related to gradle/gradle#4823 as it only appeared after
using evaluationDependsOn (via The Preprocessor and on jGui).
2019-04-25 09:17:07 +02:00
Jonas Herzig
2d572f6740 Get restrictions module "compiling" on 1.13 2019-04-24 19:26:43 +02:00
Jonas Herzig
6f15df8081 Get compat module compiling on 1.13 2019-04-24 19:26:43 +02:00
Jonas Herzig
df6f744d51 Update preprocessor to fix encoding issues 2019-04-24 17:17:53 +02:00
Jonas Herzig
7cff2e0cf3 Get 1.7.10 working with source remapping
Requires changing the 'core' version to 1.8 before compiling
2019-04-24 17:17:53 +02:00
Jonas Herzig
2ee91515f7 Make use of the source remapping feature of The Preprocessor plugin 2019-04-24 15:38:34 +02:00
Jonas Herzig
6127e0a027 Replace dev-only reflection with access transformer entry 2019-04-24 14:03:17 +02:00
Jonas Herzig
fa8f8f52aa Stop using @SneakyThrows since it breaks the JDT used for source remap 2019-04-24 13:41:06 +02:00
Jonas Herzig
9968f81073 Split source preprocessor into separate gradle plugin 2019-04-21 01:40:39 +02:00
Jonas Herzig
73597dd031 Fix camera being reset to 0/0/0 when jumping in quick mode in 1.13 2019-03-27 11:04:41 +01:00
Jonas Herzig
b8c892fcd4 Fix initialization of quick mode with login phase
Replay is always already past the login phase when quick mode is
enabled, hence the LoginSuccess packet must not be sent.
2019-03-27 10:58:37 +01:00
Jonas Herzig
2c0ae426de Fix drone build 2019-03-15 19:04:54 +01:00
Jonas Herzig
cf592bdedb Skip netty when shading libs (MC already provides it) 2019-03-15 17:50:22 +01:00
Jonas Herzig
2997d3e8f6 Update ReplayStudio for ViaVersion 1.12.2 and 1.13.2 support 2019-03-15 17:12:15 +01:00
Jonas Herzig
44151876cd Add task which collects shadowed jars in root project build/libs folder 2019-03-15 14:50:56 +01:00
Jonas Herzig
f795b27251 Use shadow gralde plugin on 1.8+ and enable its minimize option
Cuts RM jar sizes in half.
2019-03-15 13:43:05 +01:00
Jonas Herzig
fc0f070721 Make our non-shading of Mixin's deps explicit 2019-03-15 10:51:15 +01:00
Jonas Herzig
2e29632fab Merge branch 'johni/blend' into johni/1.13-pre 2019-03-15 10:49:38 +01:00
Jonas Herzig
1e1104f4d3 Add blend export to GuiRenderSettings 2019-03-14 18:20:17 +01:00
Jonas Herzig
7cc62b13c1 Fix blend compilation on pre-1.13 2019-03-14 18:20:17 +01:00
Jonas Herzig
3cb1d8189b Preshadow lwjgl_util instead of copying source of specific classes 2019-03-14 18:20:17 +01:00
Jonas Herzig
dc6de5bd5f Apply rotation and scale to entity (livingbase), not its parts
Reduces amount of keyframes per entity and makes it easier to work with.
2019-03-14 11:30:40 +01:00
Jonas Herzig
cd16e014d1 Vastly improve performance of major block name generation 2019-03-13 22:03:03 +01:00
Jonas Herzig
22ab39c2db Get blend export running on 1.13 2019-03-13 19:10:44 +01:00
Jonas Herzig
4eb5d2d9cf Preshadow lwjgl_util instead of copying source of specific classes 2019-03-13 18:32:05 +01:00
Jonas Herzig
106f14d8c7 Merge branch 'johni/1.13-pre' into johni/blend 2019-03-13 16:07:32 +01:00
Jonas Herzig
443c1ca2af Render to BGRA instead of RGB format for better performance on most GPUs 2019-03-13 15:27:53 +01:00
Jonas Herzig
27efc3c717 Fix pre-1.13 imports 2019-03-13 14:52:11 +01:00
Jonas Herzig
d7f2cba214 Update ReplayStudio to fix SquashFilter as used by MarkerProcessor 2019-03-13 13:55:28 +01:00
Jonas Herzig
2d7696b09e Fix NPE in MarkerProcessor when done 2019-03-13 12:06:35 +01:00
Jonas Herzig
1db94b7871 Fix timestamp of squashed packets in MarkerProcessor 2019-03-13 11:50:18 +01:00
Jonas Herzig
681e803d44 Update ReplayStudio for custom entity attribs and binary tracker cache 2019-03-13 11:46:12 +01:00
Jonas Herzig
1d88ca044d Add "Edit" button to replay viewer gui 2019-03-12 20:11:07 +01:00
Jonas Herzig
51c073012e Re-work Replay Editor UI 2019-03-12 19:44:34 +01:00
Jonas Herzig
eb6e7b79d0 Add start/stop/pause/resume recording functionality
Using automatically applied, ReplayStudio-based post processing.
2019-03-12 13:29:21 +01:00
Jonas Herzig
fe68f76bd1 Remove accidentally added mixin-hack subproject inclusion 2019-03-11 18:52:00 +01:00
Jonas Herzig
9d315134fc Fix packet re-encoding in pre-1.13 versions 2019-03-11 18:16:23 +01:00
Jonas Herzig
32de147ae2 Update ReplayStudio for dedicated replay cache
Also change artifact back from localMaven to jitpack
2019-03-11 17:51:53 +01:00
Jonas Herzig
fde807f8ff Fix pack.mcmeta for pre-1.13 versions 2019-03-11 17:29:22 +01:00
Jonas Herzig
79f02b5dfb Fix regression in MixinRenderItem redirect method signature 2019-03-11 15:48:11 +01:00
Jonas Herzig
8526264dab Disable reproducible builds for now since people keep breaking it
Need to re-enable it before 1.13 release since it's required for sigs.
2019-03-11 15:24:55 +01:00
Jonas Herzig
4da57dceb0 Fix GSON dependency configuration for FG3 2019-03-11 15:13:31 +01:00
Jonas Herzig
0f3a6253e0 Complete all currently actionable 1.13.2 FIXMEs 2019-03-11 15:13:31 +01:00
Jonas Herzig
e9ca1bb47e Fix FOV during 360 rendering 2019-03-11 15:13:31 +01:00
Jonas Herzig
5f0bd1cf5d Only update uniforms when ODS shader is bound (fixes GL errors) 2019-03-11 15:13:31 +01:00
Jonas Herzig
cdcd6f6893 Get render module mostly working 2019-03-10 16:59:59 +01:00
Jonas Herzig
f8fc3462e8 Get recording and replay working 2019-03-10 14:15:14 +01:00
Jonas Herzig
8705bbad9a Re-enable and fix building for older MC versions 2019-03-09 13:08:47 +01:00
Jonas Herzig
528791c91f fixup snapshot 2019-03-02 15:10:15 +01:00
Jonas Herzig
f13f2dda1c Get extras module compiling on 1.13
Remove LocalizationExtra (too much update work for too little gain)
2019-03-02 09:59:57 +01:00
Jonas Herzig
c8cf4d66c5 Get editor module compiling on 1.13 2019-03-01 17:22:50 +01:00
Jonas Herzig
cae970ec6b Get online module compiling on 1.13 2019-03-01 17:22:50 +01:00
Jonas Herzig
1727702de4 Get simplepathing module compiling on 1.13 2019-03-01 17:22:50 +01:00
Jonas Herzig
344a550dc1 Get render module compiling on 1.13 2019-03-01 17:22:50 +01:00
Jonas Herzig
641014b0d1 Get pathing module compiling 2019-03-01 17:22:50 +01:00
Jonas Herzig
c1fefdeb3c Get core, recording and replay modules compiling on 1.13.2 2019-03-01 17:22:50 +01:00
Jonas Herzig
b6a4206816 Update FG3 and Forge from git version to first official snapshots 2019-03-01 17:22:50 +01:00
Jonas Herzig
1e584769af Misc 1.13 progress 2019-03-01 17:22:50 +01:00
Jonas Herzig
1470123ec9 Get replay module compiling on 1.13 2019-03-01 17:22:50 +01:00
Jonas Herzig
9655677972 Start update to 1.13 2019-03-01 17:22:50 +01:00
Jonas Herzig
65295b311e Merge branch 'spherical-fov' into develop 2018-12-19 10:20:23 +01:00
Jonas Herzig
3bc9bb32b9 Merge branch 'fix-bitrate-label' into develop 2018-12-19 10:18:01 +01:00
Jonas Herzig
c575049bd9 Merge branch 'johni/quick-mode' into develop 2018-12-19 10:17:45 +01:00
Jonas Herzig
3f7818aeec Auto-save the current timeline after changes and on exit
This auto-saved timeline is loaded when the replay is opened the next time.
2018-12-18 15:04:21 +01:00
Jonas Herzig
c1b4964978 Handle entity position interpolation when jumping in quick mode 2018-12-18 13:32:26 +01:00
Jonas Herzig
1da7060bb2 Fix entity head rotation in quick mode 2018-12-18 12:55:51 +01:00
Jonas Herzig
5366758cf6 Compress packets to reduce quick mode memory usage by ~80% 2018-12-18 12:43:39 +01:00
Jonas Herzig
60ef8df523 Add Quick Mode keybinding translation key 2018-12-18 10:48:31 +01:00
Jonas Herzig
2737077828 Retain camera position when switching to and from quick mode 2018-12-18 10:44:57 +01:00
Jonas Herzig
1670ed4e80 Fix dead lock when switching from async to quick mode 2018-12-18 10:44:42 +01:00
Jonas Herzig
c30520ad3d Fix previous block state of BlockChange being loaded incorrectly 2018-12-18 10:04:46 +01:00
Jonas Herzig
e989b60ea8 Properly handle non-full chunks in QuickReplaySender 2018-12-18 10:04:46 +01:00
Jonas Herzig
c8ecd17fe9 Re-write QuickReplaySender caching to be significantly more memory efficient 2018-12-18 10:04:46 +01:00
Jonas Herzig
3319d4263c Ensure replay has ended when MP GUI is opened (fixes #134) 2018-12-17 15:01:01 +01:00
Jonas Herzig
c94f5d17f4 Fix packet data being trashed by Restore Replay GUI (fixes #129) 2018-12-17 14:42:03 +01:00
Jonas Herzig
d791eedae9 Replace dropdown replay selection with popup in ReplayEditor (fixes #132) 2018-12-17 14:00:44 +01:00
CrushedPixel
2f44d5f380 GuiRenderSettings: Fix bitrate label 2018-12-06 14:47:29 +01:00
CrushedPixel
7c3fcd4e42 Adjustments for consistency 2018-12-06 14:18:55 +01:00
CrushedPixel
a7ec6524b7 Add FOV slider for spherical render methods
Before uploading to YouTube, convert all spherical non-mp4 files to mp4 to be able to inject metadata
Properly re-throw errors during the rendering pipeline
2018-12-06 01:29:31 +01:00
Jonas Herzig
ef368254cd Merge branch 'stable' into johni/quick-mode 2018-08-31 12:44:00 +02:00
Jonas Herzig
20dfebbc2a Release 2.1.4 2018-08-25 14:23:32 +02:00
Jonas Herzig
8e2b0c304c Merge branch 'johni/fix-optifine-e1' into develop 2018-08-25 13:48:05 +02:00
Jonas Herzig
a9e32a53ea Update jGui (fixes "Cannot convert pos unless rendered at least once.") 2018-08-25 13:47:31 +02:00
Jonas Herzig
85a167a0d5 Fix camera position being able to become NaN with classic controls
To reproduce, hold A for about a second, then release A and press D in the same frame.
2018-08-25 11:06:24 +02:00
Jonas Herzig
73c52b5cf0 Backport quick mode to 1.9.4+ and disable below 2018-08-22 17:40:57 +02:00
Jonas Herzig
b6a7d3bcda Disable maven artifact checksum verification because Mojang keeps breaking it
(and so do some maven repos) and I can't be bothered to constantly fix it.
2018-08-22 14:07:48 +02:00
Jonas Herzig
34343a809f Update ReplayStudio (fixes #131) 2018-08-22 13:32:42 +02:00
Jonas Herzig
3db9d58f8f Handle Respawn packet in QuickReplaySender 2018-07-28 13:07:57 +02:00
Jonas Herzig
ec5ffe3e02 Add caching to the quick replay sender 2018-07-28 12:59:58 +02:00
Jonas Herzig
42a2ae35ed fixup quick weather 2018-07-27 21:26:55 +02:00
Jonas Herzig
12605f51de Add GUI popup for initializing quick mode and signaling failures 2018-07-27 19:50:40 +02:00
Jonas Herzig
6cb207fd47 Also track weather and time during quick replay mode 2018-07-27 18:49:06 +02:00
Jonas Herzig
ad9c82c991 Fix compatibility with Optifine 1.12.2 E1
Optifine has changed some package names, this commit deals with that.
2018-07-20 11:05:21 +02:00
Jonas Herzig
edc54ce6d4 Add quick replay mode
Allows very quick forwards and backwards jumping at the cost of only
replaying entity positions and block updates.

Still needs to be backported from 1.12.2 and contains FIXMEs
2018-07-18 21:55:03 +02:00
Jonas Herzig
8314803cda Use "-dirty" for marking dirty builds because Windows doesn't like "*" 2018-06-12 22:24:57 +02:00
Jonas Herzig
832413dda0 Set default memory for gradle JVM (fixes #32)
See: https://github.com/MinecraftForge/MinecraftForge/pull/3361
2018-06-12 22:24:05 +02:00
Jonas Herzig
c48187e784 Disable .blend export for 1.7.10 2018-06-11 00:31:50 +02:00
Jonas Herzig
c5229628e3 Merge branch 'stable' into blend 2018-06-11 00:31:25 +02:00
Jonas Herzig
f96e715b0b Release 2.1.3 2018-06-10 17:59:22 +02:00
Jonas Herzig
16b40a5725 Only try to sign jars if the current call built any 2018-06-10 17:59:22 +02:00
Jonas Herzig
38892026c5 Add .gitkeep to versions/1.7.10 directory
This is required for it to be included in the versions.json
on the master branch for the next release.
2018-06-10 16:43:37 +02:00
Jonas Herzig
ab4153f375 Update ReplayStudio to fix custom potion effects (fixes #126) 2018-06-10 16:06:45 +02:00
Jonas Herzig
5e6a85d475 Update dependency checksums 2018-06-10 13:39:21 +02:00
Jonas Herzig
1b9d430176 Handle unbalanced quotes in ffmpeg arguments (fixes #119) 2018-06-10 13:12:42 +02:00
Jonas Herzig
62d2ce4b37 Fix crash when in replay with Optifine 1.12.2 DX (fixes #120)
Re-creating the RenderChunk lost any custom data Optifine had in them which
resulted in NPEs.
The reason we re-create the RenderChunks is because otherwise, once it's
assigned an empty chunk once, it's not getting any further update even when
moving back to filled chunks. Since just calling setNeedsUpdate works as well,
this commit changes the whole mixin to doing that instead.
2018-06-09 23:55:39 +02:00
Jonas Herzig
efaa5b7c41 Shouldn't release jars be final..
Well, looks like the jcenter repo doesn't care because the hash for
one of its jars has changed (a few bits in the jar were flipped).
Maven Central is still serving the original version, so we have to allow
both hashes.
2018-04-03 16:17:33 +02:00
Jonas Herzig
fb1254ce12 Merge branch 'johni/1.7.10' into johni/develop 2018-04-02 11:53:06 +02:00
Jonas Herzig
277e55a241 [1.7.10] Workaround for crash when loading replay with TCNodeTracker (fixes #118) 2018-04-02 11:52:11 +02:00
Jonas Herzig
3f00c1f977 [1.7.10] Update ReplayStudio to fix custom entity types (fixes #117) 2018-04-02 11:51:42 +02:00
Jonas Herzig
feb39f02ec Fix Optifine language data missing when localization extra is enabled (fixes #109) 2018-03-22 14:52:12 +01:00
Jonas Herzig
65e3d45c9b Switch submodules from ssh to https 2018-03-16 17:34:24 +01:00
Jonas Herzig
8b044b344a [1.7.10] Remove unnecessary pre-MixinGradle configuring in common.gradle 2018-03-16 16:59:15 +01:00
Jonas Herzig
9631f1cf5f [1.7.10] Fix recording player y position 2018-03-16 16:57:08 +01:00
Jonas Herzig
63b2f3abcc Add transformer exclusion for transformers and fix transforming of null classes 2018-03-16 16:57:08 +01:00
Jonas Herzig
0b262d1a74 [1.7.10] Fix reobf task missing fields due to incorrect classpath
The reobf task was not handling certain fields because it was missing
the respective classes on its classpath because we removed MC&deps
from the compile configuration.
2018-03-16 16:55:19 +01:00
Jonas Herzig
75a14a7488 Catch _all_ errors during recording setup 2018-03-16 16:55:19 +01:00
Jonas Herzig
031582957f Merge branch 'stable' into develop-1.7.10 2018-03-16 13:03:22 +01:00
Jonas Herzig
e32dab8749 Add 1.7.10 to reprod / drone build 2018-03-16 13:01:33 +01:00
Jonas Herzig
3e23826c8d [1.7.10] Fix recording of chunk packets in MP (fixes #98) 2018-03-16 13:01:33 +01:00
Jonas Herzig
eb04eb47dc Add 1.7.10 version 2018-03-16 13:01:33 +01:00
Jonas Herzig
0a26f59c9c Release 2.1.2 2018-03-15 23:12:53 +01:00
Jonas Herzig
9cdd1bbca8 Sign jars based on current commit instead of tag 2018-03-15 22:56:40 +01:00
Jonas Herzig
31a9e4eaf6 Fix preprocessor not processing ifdef 2018-03-15 22:17:51 +01:00
Jonas Herzig
221991bf2c Do not shade gson lib (fixes #115)
The gson lib is provided by MC anyway.
Additionally, by shading it, we relocate the lib via the FG reobfJar
task which doesn't properly handle annotations causing the Mixin
lib's MixinConfig to no longer parse properly.
2018-03-15 22:17:28 +01:00
Jonas Herzig
48b39fe551 Update MCProtocolLib (via ReplayStudio)
Primarily because of
1728e10 Default to no team color when receiving unknown values.
63e06fa Remove hard bitsPerEntry limit, enforce minimum of 4.
6de0593 Add CustomStatistic as fallback for custom or unimplemented statistic IDs.
2018-03-11 20:57:00 +01:00
Jonas Herzig
76be6c1d2e Fix dead lock when jumping backwards in time during rendering
A jump backwards in time entails unloading the current world and with it
the ChunkRenderDispatcher that the ChunkLoadingRenderGlobal has locked.
2018-03-11 13:45:19 +01:00
Jonas Herzig
13d5586583 Fix trimming of replays not actually removing any packets (fixes #113)
The init method of the Squash filter has never been called therefore it had
never registered its packets and was never able to properly function.
2018-03-11 12:29:51 +01:00
Jonas Herzig
34172cd737 Fix race condition due to ReplaySender in async mode during setup()
The ReplaySender used to be started in async mode even before the call
to setup(). If the ReplaySender restarts the replay before the setup()
call finishes, that call may instead produce a NPE in
clientToServerHandshake().
To fix this race condition, the ReplaySender is always started in sync
mode and only switched to async after the setup() call.
2018-03-11 12:17:18 +01:00
Jonas Herzig
fbbca76099 Remove :versions prefix from gradle projects and remove duplicated build code 2018-03-06 12:39:24 +01:00
Jonas Herzig
8ed9c75ba1 Release 2.1.1 2018-03-05 12:12:07 +01:00
Jonas Herzig
e7b5ba9e72 Update blend export for all remaining MC versions 2018-03-04 16:28:35 +01:00
Jonas Herzig
40da0d10c8 Parse raw buffer instead of intercepting all BufferBuilder calls 2018-03-04 16:28:35 +01:00
Jonas Herzig
1bdf7da525 Update blend export to 1.12.2 2018-03-04 16:28:29 +01:00
Jonas Herzig
6794b58524 Add .blend export 2018-03-04 15:30:50 +01:00
Jonas Herzig
78ad02bc84 Change from tag-based versioning to commit/file based 2018-03-03 12:33:50 +01:00
Jonas Herzig
9c76f0fcc0 Unload old world when restarting replay, fixes floating heads 2018-03-03 09:50:13 +01:00
Jonas Herzig
5d9dc9eb95 Fix half-despawned non-player entities if they are inside an unloading chunk (see #111) 2018-03-03 09:11:16 +01:00
Jonas Herzig
66312e4d40 Fix half-despawned player entities if they are inside an unloading chunk (fixes #111) 2018-03-02 15:54:21 +01:00
Jonas Herzig
180fda20d7 Do not shade lombok 2018-03-02 10:40:45 +01:00
Jonas Herzig
94c33df308 Exclude guava from ReplayStudio deps 2018-03-02 10:40:45 +01:00
Jonas Herzig
598827f074 Do not relocate javax package 2018-02-28 23:06:46 +01:00
Jonas Herzig
49c756b97d Fix version replacement in source and resources 2018-02-28 22:53:41 +01:00
Jonas Herzig
5ce08874d6 Do not relocate mixin lib 2018-02-28 21:56:57 +01:00
Jonas Herzig
da6d9e8167 Only replace FG2.1 when not a reprod build 2018-02-28 21:15:37 +01:00
Jonas Herzig
2fa2d2f745 Remove superfluous opening of MainMenu on replay exit (fixes #110) 2018-02-28 20:16:09 +01:00
Jonas Herzig
e508ac40cf Fix formatting/typos in README 2018-02-28 19:33:03 +01:00
Jonas Herzig
f0d4d93936 Replace FG 2.1 with custom fork for Gradle 3 compatibility 2018-02-28 19:20:48 +01:00
Jonas Herzig
95877be3e6 Replace FG 2.0 with custom fork for Gradle 3 compatibility 2018-02-28 11:55:59 +01:00
Jonas Herzig
d9f318623c Update README for single tree 2018-02-28 11:55:59 +01:00
Jonas Herzig
dd26163a7c Update .drone.yaml for single tree build 2018-02-28 11:55:59 +01:00
Jonas Herzig
5f4c15de2b Update proxy-witness and disable its cache 2018-02-28 08:36:02 +01:00
Jonas Herzig
7546d421b0 Use https for downloading gradle wrapper 2018-02-28 08:36:02 +01:00
Jonas Herzig
943fa45bbc Change project version to partially depend on the MC version 2018-02-28 08:36:02 +01:00
Jonas Herzig
ad6345de88 Re-write reprod to support all versions in one tree 2018-02-28 08:36:02 +01:00
Jonas Herzig
aabc3b52fe Replace reprod patched mixingradle with specific upstream version 2018-02-22 18:25:36 +01:00
Jonas Herzig
2f96694a73 Replace reprod patched mixin with upstream + gradle task for fixing refmap 2018-02-22 18:25:36 +01:00
Jonas Herzig
c5ad912a79 Relocate shaded libs 2018-02-22 18:25:36 +01:00
Jonas Herzig
aa1900bee6 Remove unused lombok dependency 2018-02-22 18:25:36 +01:00
Jonas Herzig
748b9da443 Combine all versions into a single tree 2018-02-22 18:25:36 +01:00
Jonas Herzig
ec50efec10 Merge branch '1.12.1-dev' into 1.12.2-dev 2018-01-19 19:50:18 +01:00
Jonas Herzig
d7e3c4d242 Merge branch '1.12-dev' into 1.12.1-dev 2018-01-19 19:48:36 +01:00
Jonas Herzig
b176dd9879 Manually repack jar file after reobfJar task for reproducibility 2018-01-19 19:45:57 +01:00
Jonas Herzig
a090a00360 Merge branch '1.12.1-dev' into 1.12.2-dev 2018-01-19 13:17:31 +01:00
Jonas Herzig
ddeaf37e8e Merge branch '1.12-dev' into 1.12.1-dev 2018-01-19 13:16:56 +01:00
Jonas Herzig
d0e4475b40 Merge branch '1.11.2-dev' into 1.12-dev 2018-01-19 13:15:40 +01:00
Jonas Herzig
00adf7f083 Merge branch '1.11-dev' into 1.11.2-dev 2018-01-19 13:10:55 +01:00
Jonas Herzig
7458e46e07 Merge branch '1.10.2-dev' into 1.11-dev 2018-01-19 13:09:31 +01:00
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
5f2366e49d Merge branch '1.12.1-dev' into 1.12.2-dev 2018-01-17 20:46:34 +01:00
Jonas Herzig
f6b4ea015d Merge branch '1.12.2-reprod' into 1.12.2-dev 2018-01-17 20:13:05 +01:00
Jonas Herzig
638cc59097 Merge branch '1.12-dev' into 1.12.1-dev 2018-01-17 20:02:27 +01:00
Jonas Herzig
3a2abf05cb Merge branch '1.12.1-reprod' into 1.12.1-dev 2018-01-17 19:49:37 +01:00
Jonas Herzig
0f004537af Whitelist version.json checksum
Why is there even a sha1 value in the URL if the file can change?
2018-01-17 19:37:34 +01:00
Jonas Herzig
dc1bc1ee8e Merge branch '1.11.2-dev' into 1.12-dev 2018-01-17 00:18:04 +01:00
Jonas Herzig
87335cd243 Add lombok-1.16.4.jar to checksums list 2018-01-17 00:13:40 +01:00
Jonas Herzig
06bebda557 Merge branch '1.11-dev' into 1.11.2-dev 2018-01-16 23:28:46 +01:00
Jonas Herzig
430a5044f5 Merge branch '1.11.2-reprod' into 1.11.2-dev 2018-01-16 23:25:23 +01:00
Jonas Herzig
e7ce03e85f Merge branch '1.10.2-dev' into 1.11-dev 2018-01-16 23:15:31 +01:00
Jonas Herzig
bab1d3463e Merge branch '1.11-reprod' into 1.11-dev 2018-01-16 22:45:52 +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
Jonas Herzig
c07080650a Fix realms notifications not being offset with button (fixes #22 GH) 2017-11-03 09:24:57 +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
4ac418cdd5 Update reprod to 1.12.2 2017-10-28 21:13:01 +02:00
Jonas Herzig
42aa0d9b61 Merge branch '1.12.2-dev' into 1.12.2-reprod 2017-10-28 19:52:54 +02:00
Jonas Herzig
117dc6191f Update reprod to 1.12.1 2017-10-28 19:51:02 +02:00
Jonas Herzig
903762f042 Merge branch '1.12.1-dev' into 1.12.1-reprod 2017-10-28 19:34:38 +02:00
Jonas Herzig
f9b6fd1ced Update reprod to 1.12 2017-10-28 19:32:26 +02:00
Jonas Herzig
9592c6b8ea Merge branch '1.12-dev' into 1.12-reprod 2017-10-28 18:28:19 +02:00
Jonas Herzig
5f7e4fd9dd Update reprod to 1.11.2 2017-10-28 18:25:22 +02:00
Jonas Herzig
e70ef7a601 Merge branch '1.11.2-dev' into 1.11.2-reprod 2017-10-28 18:06:00 +02:00
Jonas Herzig
b0a65b1103 Update reprod to 1.11 2017-10-28 18:04:27 +02:00
Jonas Herzig
134c10f39e Merge branch '1.11-dev' into 1.11-reprod 2017-10-28 17:44:35 +02: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
c8dc70af56 Merge branch 1.12.1-dev into 1.12.2-dev
db1717f Merge branch 1.12-dev into 1.12.1-dev
d7dc2ba Merge branch 1.11.2-dev into 1.12-dev
b1c6098 Merge branch 1.11-dev into 1.11.2-dev
caf6051 Merge branch 1.9.4-dev into 1.11-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 12:50:29 +02:00
Jonas Herzig
db1717ffdd Merge branch 1.12-dev into 1.12.1-dev
d7dc2ba Merge branch 1.11.2-dev into 1.12-dev
b1c6098 Merge branch 1.11-dev into 1.11.2-dev
caf6051 Merge branch 1.9.4-dev into 1.11-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 12:47:13 +02:00
Jonas Herzig
d7dc2badf8 Merge branch 1.11.2-dev into 1.12-dev
b1c6098 Merge branch 1.11-dev into 1.11.2-dev
caf6051 Merge branch 1.9.4-dev into 1.11-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 12:28:58 +02:00
Jonas Herzig
b1c6098205 Merge branch 1.11-dev into 1.11.2-dev
caf6051 Merge branch 1.9.4-dev into 1.11-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 12:13:04 +02:00
Jonas Herzig
caf6051ab7 Merge branch 1.9.4-dev into 1.11-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:43:25 +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
f2755f6e1f Update to 1.12.2 2017-09-19 10:37:19 +02:00
Jonas Herzig
cfb990ad43 Remove ReplayStudio submodule and depend on it via maven instead 2017-09-19 10:21:07 +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
b1a2826cb4 Merge branch 1.12 into 1.12.1
0d6c1ca Merge branch 1.11.2 into 1.12
13bb0bd Merge branch 1.11-staging into 1.11.2-staging
5257a41 Merge branch 1.10.2 into 1.11
689f897 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)
922c039 Fix server with RM installed refusing clients without RM (fixes #76)
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)
d56fa9b Update ReplayStudio/MCProtocolLib (Fixes missing ARMOR_STAND MobType)
7c719e0 Update ReplayStudio/MCProtocolLib (Fixes missing ARMOR_STAND MobType)
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:53:36 +02:00
Jonas Herzig
0d6c1caffc Merge branch 1.11.2 into 1.12
13bb0bd Merge branch 1.11-staging into 1.11.2-staging
5257a41 Merge branch 1.10.2 into 1.11
689f897 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)
d56fa9b Update ReplayStudio/MCProtocolLib (Fixes missing ARMOR_STAND MobType)
7c719e0 Update ReplayStudio/MCProtocolLib (Fixes missing ARMOR_STAND MobType)
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:44:16 +02:00
Jonas Herzig
13bb0bde13 Merge branch 1.11-staging into 1.11.2-staging
5257a41 Merge branch 1.10.2 into 1.11
689f897 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)
d56fa9b Update ReplayStudio/MCProtocolLib (Fixes missing ARMOR_STAND MobType)
7c719e0 Update ReplayStudio/MCProtocolLib (Fixes missing ARMOR_STAND MobType)
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:37:33 +02:00
Jonas Herzig
5257a412a5 Merge branch 1.10.2 into 1.11
689f897 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)
7c719e0 Update ReplayStudio/MCProtocolLib (Fixes missing ARMOR_STAND MobType)
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:28:30 +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
922c039e43 Fix server with RM installed refusing clients without RM (fixes #76) 2017-08-23 21:11:12 +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
0b462280fc Update to 1.12.1 2017-08-04 09:10:48 +02:00
Jonas Herzig
d56fa9b88f Update ReplayStudio/MCProtocolLib (Fixes missing ARMOR_STAND MobType) 2017-08-01 21:25:55 +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
Jonas Herzig
cae95d1c8f Fix usage of deprecated netty method 2017-06-29 10:48:47 +02:00
Jonas Herzig
67b7872c4d Update to first Forge 1.12 RB 2017-06-29 10:32:12 +02:00
Jonas Herzig
9b04d317c5 Suppress advancement and crafting unlocks (fixes #69) 2017-06-27 15:17:57 +02:00
Jonas Herzig
a6ffae2148 Update to Forge Build 2375 (fixes #70) 2017-06-27 15:07:54 +02:00
Jonas Herzig
6109960d4a Fix integration test failing because of conflicting keybindings 2017-06-15 20:44:10 +02:00
Jonas Herzig
4dcecc5697 Do not show OpenEye offer gui if there's no OpenEye for the current MC version 2017-06-15 16:28:44 +02:00
Jonas Herzig
bef5e41a8d Update mappings 2017-06-15 16:15:01 +02:00
Jonas Herzig
6ecb87e8dd Add workaround for race condition preventing us from joining SP (see MinecraftForge/MinecraftForge#3974)
This is done by preventing all calls to ChannelConfig.setAutoRead(false) during
the call to FMLNetworkHandler.fmlClientHandshake (the two @Redirects in
MixinNetworkDispatcher) and manually issuing the call before handleLoginSuccess
returns (at which point the NetHandlerPlayClient has been set).

This commit should be reverted once the issue mentioned above has been fixed.
2017-06-15 16:15:01 +02:00
Jonas Herzig
921c9e0098 Update to 1.12 2017-06-15 16:15:01 +02:00
Jonas Herzig
5dd31f4cac Merge branch '1.11' into 1.11.2
2a47f57 Merge branch '1.10.2' into 1.11
96b2904 Merge branch '1.9.4' into 1.10.2
6c8c779 Merge branch '1.8.9' into 1.9.4
aa16e42 Add workaround for setupCIWorkspace not being sufficient
ed56673 Merge branch '1.8' into 1.8.9
91573d9 Update jGui, ReplayStudio and Translations
d71358b Add confirmation dialog before overwriting path presets (fixes #65)
1a55983 Move addCallback method from integration test Utils to main Utils
18c5bcd Be more cooperative with other mods on the ingame menu (fixes #42)
c054fe8 Register keys for simplepathing only once (fixes #63)
f13297c Fix default interpolator handling in keyframe gui and after loading (fixes #64)
391f304 Show error popup if entity tracker fails to load
0e0eaaa Fix entity tracker being set even if it failed loading (fixes #50)
a34bbbc Fix NPE when spectating a player without a camera entity
60879fb Change local class to be an inner class because Srg2Source breaks with it
dfafbec Load translations from github repo, only reload language not all resource packs
8a6ec51 Add missing tooltips to player overview and various missing chat messages
5677fc5 Re-add warning to replay editor
748a91e Fix missing tooltips on fav/like/dislike buttons in replay center
ee24866 Fix upload replay button not being updated when name/tags change
dba085c Move translations into separate repo
3f0e3e7 Fix NPE when receiving Replay|Restrict messages (fixes #16 GH)
40e1d85 Fix crash when saving the last keyframe in the edit gui (fixes #61)
03aada1 Update Mixin to 0.6.8 (fixes #9 GH)
0c1dc65 Fix interpolator being lost when moving keyframe to the end (fixes #62)
fcbbbc9 Add integration test. Run with ./gradlew runIntegrationTest
fe6ded0 Fix movement of keyframe via GuiEditKeyframe not updating selected keyframe
f58fa8f Fix Login GUI not respecting other GUIs opened on startup
4fc3a31 Fix OpenEye being installed into working dir instead of mcDataDir
2017-06-01 15:32:37 +02:00
Jonas Herzig
2a47f579a9 Merge branch '1.10.2' into 1.11
96b2904 Merge branch '1.9.4' into 1.10.2
6c8c779 Merge branch '1.8.9' into 1.9.4
aa16e42 Add workaround for setupCIWorkspace not being sufficient
ed56673 Merge branch '1.8' into 1.8.9
91573d9 Update jGui, ReplayStudio and Translations
d71358b Add confirmation dialog before overwriting path presets (fixes #65)
1a55983 Move addCallback method from integration test Utils to main Utils
18c5bcd Be more cooperative with other mods on the ingame menu (fixes #42)
c054fe8 Register keys for simplepathing only once (fixes #63)
f13297c Fix default interpolator handling in keyframe gui and after loading (fixes #64)
391f304 Show error popup if entity tracker fails to load
0e0eaaa Fix entity tracker being set even if it failed loading (fixes #50)
a34bbbc Fix NPE when spectating a player without a camera entity
60879fb Change local class to be an inner class because Srg2Source breaks with it
dfafbec Load translations from github repo, only reload language not all resource packs
8a6ec51 Add missing tooltips to player overview and various missing chat messages
5677fc5 Re-add warning to replay editor
748a91e Fix missing tooltips on fav/like/dislike buttons in replay center
ee24866 Fix upload replay button not being updated when name/tags change
dba085c Move translations into separate repo
3f0e3e7 Fix NPE when receiving Replay|Restrict messages (fixes #16 GH)
40e1d85 Fix crash when saving the last keyframe in the edit gui (fixes #61)
03aada1 Update Mixin to 0.6.8 (fixes #9 GH)
0c1dc65 Fix interpolator being lost when moving keyframe to the end (fixes #62)
fcbbbc9 Add integration test. Run with ./gradlew runIntegrationTest
fe6ded0 Fix movement of keyframe via GuiEditKeyframe not updating selected keyframe
f58fa8f Fix Login GUI not respecting other GUIs opened on startup
4fc3a31 Fix OpenEye being installed into working dir instead of mcDataDir
2017-05-31 21:18:22 +02:00
Jonas Herzig
96b2904e4b Merge branch '1.9.4' into 1.10.2
6c8c779 Merge branch '1.8.9' into 1.9.4
aa16e42 Add workaround for setupCIWorkspace not being sufficient
ed56673 Merge branch '1.8' into 1.8.9
91573d9 Update jGui, ReplayStudio and Translations
d71358b Add confirmation dialog before overwriting path presets (fixes #65)
1a55983 Move addCallback method from integration test Utils to main Utils
18c5bcd Be more cooperative with other mods on the ingame menu (fixes #42)
c054fe8 Register keys for simplepathing only once (fixes #63)
f13297c Fix default interpolator handling in keyframe gui and after loading (fixes #64)
391f304 Show error popup if entity tracker fails to load
0e0eaaa Fix entity tracker being set even if it failed loading (fixes #50)
a34bbbc Fix NPE when spectating a player without a camera entity
60879fb Change local class to be an inner class because Srg2Source breaks with it
dfafbec Load translations from github repo, only reload language not all resource packs
8a6ec51 Add missing tooltips to player overview and various missing chat messages
5677fc5 Re-add warning to replay editor
748a91e Fix missing tooltips on fav/like/dislike buttons in replay center
ee24866 Fix upload replay button not being updated when name/tags change
dba085c Move translations into separate repo
3f0e3e7 Fix NPE when receiving Replay|Restrict messages (fixes #16 GH)
40e1d85 Fix crash when saving the last keyframe in the edit gui (fixes #61)
03aada1 Update Mixin to 0.6.8 (fixes #9 GH)
0c1dc65 Fix interpolator being lost when moving keyframe to the end (fixes #62)
fcbbbc9 Add integration test. Run with ./gradlew runIntegrationTest
fe6ded0 Fix movement of keyframe via GuiEditKeyframe not updating selected keyframe
f58fa8f Fix Login GUI not respecting other GUIs opened on startup
4fc3a31 Fix OpenEye being installed into working dir instead of mcDataDir
2017-05-31 21:10:35 +02:00
Jonas Herzig
6c8c779983 Merge branch '1.8.9' into 1.9.4
ed56673 Merge branch '1.8' into 1.8.9
91573d9 Update jGui, ReplayStudio and Translations
d71358b Add confirmation dialog before overwriting path presets (fixes #65)
1a55983 Move addCallback method from integration test Utils to main Utils
18c5bcd Be more cooperative with other mods on the ingame menu (fixes #42)
c054fe8 Register keys for simplepathing only once (fixes #63)
f13297c Fix default interpolator handling in keyframe gui and after loading (fixes #64)
391f304 Show error popup if entity tracker fails to load
0e0eaaa Fix entity tracker being set even if it failed loading (fixes #50)
a34bbbc Fix NPE when spectating a player without a camera entity
60879fb Change local class to be an inner class because Srg2Source breaks with it
dfafbec Load translations from github repo, only reload language not all resource packs
8a6ec51 Add missing tooltips to player overview and various missing chat messages
5677fc5 Re-add warning to replay editor
748a91e Fix missing tooltips on fav/like/dislike buttons in replay center
ee24866 Fix upload replay button not being updated when name/tags change
dba085c Move translations into separate repo
3f0e3e7 Fix NPE when receiving Replay|Restrict messages (fixes #16 GH)
40e1d85 Fix crash when saving the last keyframe in the edit gui (fixes #61)
03aada1 Update Mixin to 0.6.8 (fixes #9 GH)
0c1dc65 Fix interpolator being lost when moving keyframe to the end (fixes #62)
fcbbbc9 Add integration test. Run with ./gradlew runIntegrationTest
fe6ded0 Fix movement of keyframe via GuiEditKeyframe not updating selected keyframe
f58fa8f Fix Login GUI not respecting other GUIs opened on startup
4fc3a31 Fix OpenEye being installed into working dir instead of mcDataDir
2017-05-31 20:49:04 +02:00
Jonas Herzig
aa16e42a4f Add workaround for setupCIWorkspace not being sufficient 2017-05-31 11:19:22 +02:00
Jonas Herzig
ed566732df Merge branch '1.8' into 1.8.9
91573d9 Update jGui, ReplayStudio and Translations
d71358b Add confirmation dialog before overwriting path presets (fixes #65)
1a55983 Move addCallback method from integration test Utils to main Utils
18c5bcd Be more cooperative with other mods on the ingame menu (fixes #42)
c054fe8 Register keys for simplepathing only once (fixes #63)
f13297c Fix default interpolator handling in keyframe gui and after loading (fixes #64)
391f304 Show error popup if entity tracker fails to load
0e0eaaa Fix entity tracker being set even if it failed loading (fixes #50)
a34bbbc Fix NPE when spectating a player without a camera entity
60879fb Change local class to be an inner class because Srg2Source breaks with it
dfafbec Load translations from github repo, only reload language not all resource packs
8a6ec51 Add missing tooltips to player overview and various missing chat messages
5677fc5 Re-add warning to replay editor
748a91e Fix missing tooltips on fav/like/dislike buttons in replay center
ee24866 Fix upload replay button not being updated when name/tags change
dba085c Move translations into separate repo
3f0e3e7 Fix NPE when receiving Replay|Restrict messages (fixes #16 GH)
40e1d85 Fix crash when saving the last keyframe in the edit gui (fixes #61)
03aada1 Update Mixin to 0.6.8 (fixes #9 GH)
0c1dc65 Fix interpolator being lost when moving keyframe to the end (fixes #62)
fcbbbc9 Add integration test. Run with ./gradlew runIntegrationTest
fe6ded0 Fix movement of keyframe via GuiEditKeyframe not updating selected keyframe
f58fa8f Fix Login GUI not respecting other GUIs opened on startup
4fc3a31 Fix OpenEye being installed into working dir instead of mcDataDir
2017-05-31 09:36:46 +02:00
Jonas Herzig
91573d9487 Update jGui, ReplayStudio and Translations
jGui:
9e84e72 Fix inversion of empty selection

ReplayStudio:
ff12b1d Remove invalid filter from services files
c6a9325 Proper value wrapping in CatmullRomSplineInterpolator (fixes #8 GH)
2017-05-31 09:16:19 +02:00
Jonas Herzig
d71358bcba Add confirmation dialog before overwriting path presets (fixes #65) 2017-05-21 19:34:46 +02:00
Jonas Herzig
1a55983986 Move addCallback method from integration test Utils to main Utils 2017-05-21 19:34:46 +02:00
Jonas Herzig
18c5bcd469 Be more cooperative with other mods on the ingame menu (fixes #42) 2017-05-21 18:59:29 +02:00
Jonas Herzig
c054fe83f6 Register keys for simplepathing only once (fixes #63) 2017-05-21 17:11:15 +02:00
Jonas Herzig
f13297c5a5 Fix default interpolator handling in keyframe gui and after loading (fixes #64) 2017-05-21 16:29:59 +02:00
Jonas Herzig
391f304c5f Show error popup if entity tracker fails to load 2017-05-21 12:42:13 +02:00
Jonas Herzig
0e0eaaa9a7 Fix entity tracker being set even if it failed loading (fixes #50) 2017-05-21 12:27:20 +02:00
Jonas Herzig
a34bbbcd68 Fix NPE when spectating a player without a camera entity 2017-05-21 11:57:30 +02:00
Jonas Herzig
60879fbbed Change local class to be an inner class because Srg2Source breaks with it 2017-04-21 17:24:43 +02:00
Jonas Herzig
dfafbecf35 Load translations from github repo, only reload language not all resource packs 2017-04-21 16:36:47 +02:00
Jonas Herzig
8a6ec5191b Add missing tooltips to player overview and various missing chat messages 2017-04-21 16:36:47 +02:00
Jonas Herzig
5677fc54cb Re-add warning to replay editor 2017-04-21 16:36:47 +02:00
Jonas Herzig
748a91e7b2 Fix missing tooltips on fav/like/dislike buttons in replay center 2017-04-21 16:36:47 +02:00
Jonas Herzig
ee24866f29 Fix upload replay button not being updated when name/tags change 2017-04-21 16:36:47 +02:00
Jonas Herzig
dba085c700 Move translations into separate repo 2017-04-21 16:36:47 +02:00
Jonas Herzig
3f0e3e725e Fix NPE when receiving Replay|Restrict messages (fixes #16 GH) 2017-04-21 13:38:08 +02:00
johni0702
40e1d850da Fix crash when saving the last keyframe in the edit gui (fixes #61) 2017-04-14 17:31:16 +02:00
johni0702
03aada1f5f Update Mixin to 0.6.8 (fixes #9 GH) 2017-04-14 17:31:16 +02:00
johni0702
0c1dc658ad Fix interpolator being lost when moving keyframe to the end (fixes #62) 2017-04-14 17:31:16 +02:00
johni0702
fcbbbc9ea1 Add integration test. Run with ./gradlew runIntegrationTest 2017-04-14 17:31:15 +02:00
johni0702
fe6ded0143 Fix movement of keyframe via GuiEditKeyframe not updating selected keyframe
Selecting a keyframe, double clicking it to open the gui, changing the
timestamp, saving and then clicking the Add/Remove Keyframe button used to
crash the client. This is fixed by updating the selection whenever the time is
changed.
2017-04-13 18:18:17 +02:00
johni0702
f58fa8f9c2 Fix Login GUI not respecting other GUIs opened on startup
Previously the Login GUI would simply replace the currently active GUI.
Now the currently active GUI is stored and then re-opened after login.
2017-04-13 18:12:07 +02:00
johni0702
4fc3a3166c Fix OpenEye being installed into working dir instead of mcDataDir 2017-04-13 18:06:21 +02:00
johni0702
cda8493df1 Merge branch '1.11' into 1.11.2
0c36022 Merge branch '1.10.2' into 1.11
325d041 Merge branch '1.9.4' into 1.10.2
d9d57e2 Merge branch '1.8.9' into 1.9.4
24c58cb Merge branch '1.8' into 1.8.9
1ffeb01 Update jGui
c122d30 Merge branch '1.8-path-segments' into 1.8
27fd25a Fix crash when server responds with garbage to language query (fixes #51)
db6b0ff Fix / by 0 when two spectator keyframes are closer than 50ms (fixes #60)
d61d0ac Fix hand of invisible spectated player being visible (fixes #59)
f7460f9 Re-enable time path after path playback (fixes #55)
bdbffd5 Add Catmull-Rom spline interpolator to simplepathing
5cbfd28 Generate interpolator settings from InterpolatorType enum
6095aef Fix loading and storing of default interpolator with settings
3f52336 Revert "Fix AbstractMethodError caused by FG2.0 not supporting lambdas (fixes #58)"
c6293bc Update to FG2.2
c8126ed Merge '1.8' into 1.8.9
64898ce Fix NPE when saving recorded resource pack
70e3e54 Fix AbstractMethodError caused by FG2.0 not supporting lambdas (fixes #58)
3f2b3d6 Fix replacing source file in Replay Editor (fixes #57)
d2def94 Fix duration of replays corrupted because of JVM/OS crash
2c64030 Refactor simple pathing timeline logic into dedicated class with unit tests Fix logic for user-set interpolators
4deb374 Enable validation on focus change for all number input fields
5302bca Fix id and text of Replay Editor button in docs
057edcc Manually inject root cert for cross-signed LetsEncrypt cert in requests
cd16211 Register new Property to imply that the path segment following a keyframe has a user-set interpolator instead of the default Modified Keyframe GUI to allow for custom Path interpolator
2017-01-29 13:46:06 +01:00
johni0702
0c36022b47 Merge branch '1.10.2' into 1.11
325d041 Merge branch '1.9.4' into 1.10.2
d9d57e2 Merge branch '1.8.9' into 1.9.4
24c58cb Merge branch '1.8' into 1.8.9
1ffeb01 Update jGui
c122d30 Merge branch '1.8-path-segments' into 1.8
27fd25a Fix crash when server responds with garbage to language query (fixes #51)
db6b0ff Fix / by 0 when two spectator keyframes are closer than 50ms (fixes #60)
d61d0ac Fix hand of invisible spectated player being visible (fixes #59)
f7460f9 Re-enable time path after path playback (fixes #55)
bdbffd5 Add Catmull-Rom spline interpolator to simplepathing
5cbfd28 Generate interpolator settings from InterpolatorType enum
6095aef Fix loading and storing of default interpolator with settings
3f52336 Revert "Fix AbstractMethodError caused by FG2.0 not supporting lambdas (fixes #58)"
c6293bc Update to FG2.2
c8126ed Merge '1.8' into 1.8.9
64898ce Fix NPE when saving recorded resource pack
70e3e54 Fix AbstractMethodError caused by FG2.0 not supporting lambdas (fixes #58)
3f2b3d6 Fix replacing source file in Replay Editor (fixes #57)
d2def94 Fix duration of replays corrupted because of JVM/OS crash
2c64030 Refactor simple pathing timeline logic into dedicated class with unit tests Fix logic for user-set interpolators
4deb374 Enable validation on focus change for all number input fields
5302bca Fix id and text of Replay Editor button in docs
057edcc Manually inject root cert for cross-signed LetsEncrypt cert in requests
cd16211 Register new Property to imply that the path segment following a keyframe has a user-set interpolator instead of the default Modified Keyframe GUI to allow for custom Path interpolator
2017-01-29 13:25:19 +01:00
johni0702
325d041bd9 Merge branch '1.9.4' into 1.10.2
d9d57e2 Merge branch '1.8.9' into 1.9.4
24c58cb Merge branch '1.8' into 1.8.9
1ffeb01 Update jGui
c122d30 Merge branch '1.8-path-segments' into 1.8
27fd25a Fix crash when server responds with garbage to language query (fixes #51)
db6b0ff Fix / by 0 when two spectator keyframes are closer than 50ms (fixes #60)
d61d0ac Fix hand of invisible spectated player being visible (fixes #59)
f7460f9 Re-enable time path after path playback (fixes #55)
bdbffd5 Add Catmull-Rom spline interpolator to simplepathing
5cbfd28 Generate interpolator settings from InterpolatorType enum
6095aef Fix loading and storing of default interpolator with settings
3f52336 Revert "Fix AbstractMethodError caused by FG2.0 not supporting lambdas (fixes #58)"
c6293bc Update to FG2.2
c8126ed Merge '1.8' into 1.8.9
64898ce Fix NPE when saving recorded resource pack
70e3e54 Fix AbstractMethodError caused by FG2.0 not supporting lambdas (fixes #58)
3f2b3d6 Fix replacing source file in Replay Editor (fixes #57)
d2def94 Fix duration of replays corrupted because of JVM/OS crash
2c64030 Refactor simple pathing timeline logic into dedicated class with unit tests Fix logic for user-set interpolators
4deb374 Enable validation on focus change for all number input fields
5302bca Fix id and text of Replay Editor button in docs
057edcc Manually inject root cert for cross-signed LetsEncrypt cert in requests
cd16211 Register new Property to imply that the path segment following a keyframe has a user-set interpolator instead of the default Modified Keyframe GUI to allow for custom Path interpolator
2017-01-29 13:01:09 +01:00
johni0702
d9d57e283c Merge branch '1.8.9' into 1.9.4
24c58cb Merge branch '1.8' into 1.8.9
1ffeb01 Update jGui
c122d30 Merge branch '1.8-path-segments' into 1.8
27fd25a Fix crash when server responds with garbage to language query (fixes #51)
db6b0ff Fix / by 0 when two spectator keyframes are closer than 50ms (fixes #60)
d61d0ac Fix hand of invisible spectated player being visible (fixes #59)
f7460f9 Re-enable time path after path playback (fixes #55)
bdbffd5 Add Catmull-Rom spline interpolator to simplepathing
5cbfd28 Generate interpolator settings from InterpolatorType enum
6095aef Fix loading and storing of default interpolator with settings
3f52336 Revert "Fix AbstractMethodError caused by FG2.0 not supporting lambdas (fixes #58)"
c6293bc Update to FG2.2
c8126ed Merge '1.8' into 1.8.9
64898ce Fix NPE when saving recorded resource pack
70e3e54 Fix AbstractMethodError caused by FG2.0 not supporting lambdas (fixes #58)
3f2b3d6 Fix replacing source file in Replay Editor (fixes #57)
d2def94 Fix duration of replays corrupted because of JVM/OS crash
2c64030 Refactor simple pathing timeline logic into dedicated class with unit tests Fix logic for user-set interpolators
4deb374 Enable validation on focus change for all number input fields
5302bca Fix id and text of Replay Editor button in docs
057edcc Manually inject root cert for cross-signed LetsEncrypt cert in requests
cd16211 Register new Property to imply that the path segment following a keyframe has a user-set interpolator instead of the default Modified Keyframe GUI to allow for custom Path interpolator
2017-01-29 12:53:31 +01:00
johni0702
24c58cbbe7 Merge branch '1.8' into 1.8.9
1ffeb01 Update jGui
c122d30 Merge branch '1.8-path-segments' into 1.8
27fd25a Fix crash when server responds with garbage to language query (fixes #51)
db6b0ff Fix / by 0 when two spectator keyframes are closer than 50ms (fixes #60)
d61d0ac Fix hand of invisible spectated player being visible (fixes #59)
f7460f9 Re-enable time path after path playback (fixes #55)
bdbffd5 Add Catmull-Rom spline interpolator to simplepathing
5cbfd28 Generate interpolator settings from InterpolatorType enum
6095aef Fix loading and storing of default interpolator with settings
2c64030 Refactor simple pathing timeline logic into dedicated class with unit tests Fix logic for user-set interpolators
cd16211 Register new Property to imply that the path segment following a keyframe has a user-set interpolator instead of the default Modified Keyframe GUI to allow for custom Path interpolator
2017-01-29 11:25:30 +01:00
johni0702
1ffeb010d5 Update jGui 2017-01-29 11:14:54 +01:00
johni0702
c122d30065 Merge branch '1.8-path-segments' into 1.8 2017-01-29 11:12:06 +01:00
johni0702
27fd25ae84 Fix crash when server responds with garbage to language query (fixes #51) 2017-01-28 13:18:36 +01:00
johni0702
db6b0ff5a6 Fix / by 0 when two spectator keyframes are closer than 50ms (fixes #60) 2017-01-28 13:12:28 +01:00
johni0702
d61d0ac670 Fix hand of invisible spectated player being visible (fixes #59) 2017-01-28 12:54:42 +01:00
johni0702
f7460f9bf5 Re-enable time path after path playback (fixes #55) 2017-01-28 11:46:11 +01:00
johni0702
bdbffd5c33 Add Catmull-Rom spline interpolator to simplepathing 2017-01-28 11:03:59 +01:00
johni0702
5cbfd2884e Generate interpolator settings from InterpolatorType enum 2017-01-28 10:51:24 +01:00
johni0702
6095aef3d1 Fix loading and storing of default interpolator with settings 2017-01-28 10:33:45 +01:00
johni0702
3f52336852 Revert "Fix AbstractMethodError caused by FG2.0 not supporting lambdas (fixes #58)"
This reverts commit 70e3e54038.

As of c6293bc, this branch uses FG2.2 which fully supports lambdas.
2017-01-24 13:29:09 +01:00
johni0702
c6293bcbb0 Update to FG2.2 2017-01-24 13:27:57 +01:00
johni0702
c8126edbb2 Merge '1.8' into 1.8.9
64898ce Fix NPE when saving recorded resource pack
70e3e54 Fix AbstractMethodError caused by FG2.0 not supporting lambdas (fixes #58)
3f2b3d6 Fix replacing source file in Replay Editor (fixes #57)
d2def94 Fix duration of replays corrupted because of JVM/OS crash
4deb374 Enable validation on focus change for all number input fields
5302bca Fix id and text of Replay Editor button in docs
057edcc Manually inject root cert for cross-signed LetsEncrypt cert in requests
2017-01-24 13:25:53 +01:00
johni0702
64898ce288 Fix NPE when saving recorded resource pack 2017-01-24 13:08:55 +01:00
johni0702
70e3e54038 Fix AbstractMethodError caused by FG2.0 not supporting lambdas (fixes #58)
Lambdas are not properly re-obfuscated prior to FG2.2 causing said errors
when used. This is the only instance of such a lambda.
FG2.2 only supports MC 1.8.8 and up as such the lambda was replaced with
an anonymous inner class to solve the problem.
2017-01-24 13:07:50 +01:00
johni0702
3f2b3d62f7 Fix replacing source file in Replay Editor (fixes #57) 2017-01-24 09:43:14 +01:00
johni0702
d2def94fc1 Fix duration of replays corrupted because of JVM/OS crash
A JVM or OS crash can lead to incomplete packets at the end of a recording.
The duration of a corrupted replay file is not restored properly if that file
contains an incomplete packet. Furthermore, the entity tracker does not load
properly with such an incomplete packet. Both bugs are fixed with this commit.

To fix these bugs for replays that have already been recovered, simply open
them in the Replay Viewer, modify them somehow (save a new path) and force
the game to quit forcefully. The replays will be recovered the next time the
game starts and both bugs will be fixed.
2017-01-23 18:00:38 +01:00
johni0702
2c64030459 Refactor simple pathing timeline logic into dedicated class with unit tests
Fix logic for user-set interpolators
2017-01-21 13:30:47 +01:00
johni0702
4deb374a7f Enable validation on focus change for all number input fields 2017-01-20 16:16:01 +01:00
johni0702
5302bcaed4 Fix id and text of Replay Editor button in docs 2017-01-20 16:02:42 +01:00
johni0702
057edccf26 Manually inject root cert for cross-signed LetsEncrypt cert in requests
JREs prior to 8u101 do not ship with the root certificate that cross-signed
the LetsEncrypt X3 CA used to sign server certificates.
As the standard native Minecraft launcher for Windows and OSX ship with an
older Java version, this commit imports the required root cert and uses it
wherever communication with the replaymod.com server is established.

Effectively reverts 682fb4b
2017-01-19 17:07:14 +01:00
johni0702
33cb1405d5 Update to 1.11.2 2017-01-15 01:23:44 +01:00
johni0702
b6cf42c3be Merge branch '1.10.2' into 1.11
c6dec95 Merge branch '1.9.4' into 1.10.2
4fdfa9e Merge branch '1.8.9' into 1.9.4
44d4a25 Merge branch '1.8' into 1.9.4
01acbc6 Update to 1.8.9
1c60687 Update ReplayStudio and jGui
d9b796d Mixin'd the Shader's mods ShadersRender class to only render hands if the Forge event isn't cancelled
6bbff3b Updated Mixin to 0.6.4-SNAPSHOT and set mixin target level
6f3ac71 Add CustomMainMenu compatibility info to docs
b0a1cdf Search for ffmpeg executable in common locations to simplify setup
d465891 Fixed GuiEditPositionKeyframe's width to fit on all screen sizes Centered all rows of GuiEditPositionKeyframe's VerticalLayout
1b099f9 Add render queue
03534c6 Update docs
4388d69 Only try to create the downloads folder if it does not yet exist
7ad19aa Add mod version and accepted MC version directly to the @Mod annotation
655bea0 Replace @Mod.Instance with direct static references
458dad6 Merge pull request #4 from ReplayMod/1.8-editor
eb5ccb2 Add Replay Editor (for now, trimming only)
6498d62 Fix server game data snapshot being restored in singleplayer (fixes #44)
2c898a8 Prevent rendering without sufficient keyframes (fixes #45)
5d520a5 Fix deserialization of chroma key color (fixes #43)
c681742 Use caching maven proxy for faster and more stable drone builds
fbf165e Added Anti-Aliasing to the Render Settings
2017-01-15 00:20:20 +01:00
johni0702
c6dec95a57 Merge branch '1.9.4' into 1.10.2
4fdfa9e Merge branch '1.8.9' into 1.9.4
44d4a25 Merge branch '1.8' into 1.9.4
01acbc6 Update to 1.8.9
1c60687 Update ReplayStudio and jGui
d9b796d Mixin'd the Shader's mods ShadersRender class to only render hands if the Forge event isn't cancelled
6bbff3b Updated Mixin to 0.6.4-SNAPSHOT and set mixin target level
6f3ac71 Add CustomMainMenu compatibility info to docs
b0a1cdf Search for ffmpeg executable in common locations to simplify setup
d465891 Fixed GuiEditPositionKeyframe's width to fit on all screen sizes Centered all rows of GuiEditPositionKeyframe's VerticalLayout
1b099f9 Add render queue
03534c6 Update docs
4388d69 Only try to create the downloads folder if it does not yet exist
7ad19aa Add mod version and accepted MC version directly to the @Mod annotation
655bea0 Replace @Mod.Instance with direct static references
458dad6 Merge pull request #4 from ReplayMod/1.8-editor
eb5ccb2 Add Replay Editor (for now, trimming only)
6498d62 Fix server game data snapshot being restored in singleplayer (fixes #44)
2c898a8 Prevent rendering without sufficient keyframes (fixes #45)
5d520a5 Fix deserialization of chroma key color (fixes #43)
c681742 Use caching maven proxy for faster and more stable drone builds
fbf165e Added Anti-Aliasing to the Render Settings
2017-01-14 23:56:14 +01:00
johni0702
4fdfa9ec87 Merge branch '1.8.9' into 1.9.4 2017-01-14 23:48:02 +01:00
johni0702
44d4a250eb Merge branch '1.8' into 1.9.4
d9b796d Mixin'd the Shader's mods ShadersRender class to only render hands if the Forge event isn't cancelled
6bbff3b Updated Mixin to 0.6.4-SNAPSHOT and set mixin target level
6f3ac71 Add CustomMainMenu compatibility info to docs
b0a1cdf Search for ffmpeg executable in common locations to simplify setup
d465891 Fixed GuiEditPositionKeyframe's width to fit on all screen sizes Centered all rows of GuiEditPositionKeyframe's VerticalLayout
1b099f9 Add render queue
03534c6 Update docs
4388d69 Only try to create the downloads folder if it does not yet exist
7ad19aa Add mod version and accepted MC version directly to the @Mod annotation
655bea0 Replace @Mod.Instance with direct static references
458dad6 Merge pull request #4 from ReplayMod/1.8-editor
eb5ccb2 Add Replay Editor (for now, trimming only)
6498d62 Fix server game data snapshot being restored in singleplayer (fixes #44)
2c898a8 Prevent rendering without sufficient keyframes (fixes #45)
5d520a5 Fix deserialization of chroma key color (fixes #43)
c681742 Use caching maven proxy for faster and more stable drone builds
fbf165e Added Anti-Aliasing to the Render Settings
2017-01-14 23:28:28 +01:00
johni0702
01acbc6f1f Update to 1.8.9 2017-01-14 22:52:53 +01:00
johni0702
1c606874ff Update ReplayStudio and jGui
ReplayStudio:
2344abe Fix OOM when saving large EntityPositionTrackers (fixes #46)

jGui:
94e4b4c Fix render offset in text area and field being out of bounds after resize
2017-01-14 22:33:44 +01:00
CrushedPixel
d9b796db5e Mixin'd the Shader's mods ShadersRender class to only render hands if the Forge event isn't cancelled
This fixes player hands being rendered while spectating an entity in a replay while having Shaders enabled
2017-01-14 16:30:15 +01:00
CrushedPixel
6bbff3bba7 Updated Mixin to 0.6.4-SNAPSHOT and set mixin target level 2017-01-14 16:30:15 +01:00
johni0702
6f3ac71a8b Add CustomMainMenu compatibility info to docs 2017-01-13 18:30:00 +01:00
johni0702
503b308043 Replace @Mod.Instance with direct static references
(cherry picked from commit 4b605cc)
2017-01-13 17:02:18 +01:00
CrushedPixel
cd16211309 Register new Property to imply that the path segment following a keyframe has a user-set interpolator instead of the default
Modified Keyframe GUI to allow for custom Path interpolator
2017-01-13 12:05:07 +01:00
johni0702
b0a1cdfce2 Search for ffmpeg executable in common locations to simplify setup 2017-01-02 14:22:47 +01:00
CrushedPixel
d46589193e Fixed GuiEditPositionKeyframe's width to fit on all screen sizes
Centered all rows of GuiEditPositionKeyframe's VerticalLayout
2017-01-02 14:13:39 +01:00
johni0702
1b099f9ef6 Add render queue 2016-12-31 16:29:17 +01:00
johni0702
03534c6515 Update docs 2016-12-30 14:29:07 +01:00
johni0702
4388d6977d Only try to create the downloads folder if it does not yet exist 2016-12-30 12:11:53 +01:00
johni0702
7ad19aa025 Add mod version and accepted MC version directly to the @Mod annotation 2016-12-30 12:10:43 +01:00
johni0702
655bea0b2d Replace @Mod.Instance with direct static references 2016-12-30 12:10:13 +01:00
Marius Metzger
458dad6f9a Merge pull request #4 from ReplayMod/1.8-editor
Add Replay Editor (for now, trimming only)
2016-12-29 15:13:14 +01:00
johni0702
eb5ccb2fd5 Add Replay Editor (for now, trimming only) 2016-12-26 20:35:50 +01:00
johni0702
6498d625ad Fix server game data snapshot being restored in singleplayer (fixes #44) 2016-12-24 11:22:01 +01:00
johni0702
2c898a8192 Prevent rendering without sufficient keyframes (fixes #45) 2016-12-24 01:44:51 +01:00
johni0702
5d520a5a3c Fix deserialization of chroma key color (fixes #43) 2016-12-24 01:24:55 +01:00
johni0702
c681742a69 Use caching maven proxy for faster and more stable drone builds 2016-12-23 20:40:23 +01:00
CrushedPixel
7b491d188d Enabled recording on Realms Servers 2016-12-20 15:00:35 +01:00
CrushedPixel
fbf165e618 Added Anti-Aliasing to the Render Settings 2016-12-17 03:22:37 +01:00
johni0702
fb4140a123 Merge branch '1.10.2' into 1.11
905ae75 Merge branch '1.9.4' into 1.10.2
72e1fe0 Merge branch '1.8' into 1.9.4
6163585 Update ReplayStudio to fix dependencies
2016-12-16 22:09:16 +01:00
johni0702
905ae75330 Merge branch '1.9.4' into 1.10.2
72e1fe0 Merge branch '1.8' into 1.9.4
6163585 Update ReplayStudio to fix dependencies
2016-12-16 21:47:30 +01:00
johni0702
72e1fe0d6c Merge branch '1.8' into 1.9.4
6163585 Update ReplayStudio to fix dependencies
2016-12-16 21:27:43 +01:00
johni0702
6163585fe5 Update ReplayStudio to fix dependencies 2016-12-16 20:48:43 +01:00
johni0702
2428c01c9c Merge branch '1.10.2' into 1.11
372206f Merge branch '1.9.4' into 1.10.2
4a1ccea Merge branch '1.8' into 1.9.4
fb39a06 Add drone ci config
030c71c Automatically disable and re-enable Optifine's Fast Render setting before rendering a video
1fef12d Include FML handshake in recording
e86c66d Move README.md, LICENSE.md and user docs from master branch to 1.8
2016-12-10 20:28:23 +01:00
johni0702
260720d5ba Update Forge to latest recommended build (2188) 2016-12-10 20:25:33 +01:00
johni0702
372206fdff Merge branch '1.9.4' into 1.10.2
4a1ccea Merge branch '1.8' into 1.9.4
fb39a06 Add drone ci config
030c71c Automatically disable and re-enable Optifine's Fast Render setting before rendering a video
1fef12d Include FML handshake in recording
e86c66d Move README.md, LICENSE.md and user docs from master branch to 1.8
2016-12-10 19:54:55 +01:00
johni0702
58b7c44a33 Update to 1.11 2016-12-03 21:12:08 +01:00
johni0702
9f7ccb9d07 Merge branch '1.9.4' into 1.10.2
ca2bbca Merge branch '1.8' into 1.9.4
5b3284f Update jGui and ReplayStudio (fixes #33)
61d6fd4 Close replay file zip after recording (fixes #32)
00bcc9e Fix paths of files that are supposed to be in the mc data dir (fixes #40)
e6a789d Fix camera rotation when jumping in time (fixes #39)
50b53fc Add a way to register key bindings triggered every render tick (fixes #31)
a817c73 Prevent GUIs of other mods from opening during replay
d64ef8b Hide NPCs in the Player Overview GUI (fixes #29)
1f2c05e Fix spectating player entities past death and respawn (fixes #36)
ad2893b Fix vanilla bug caused by unremovable entities in the entityList of ClientWorld (fixes #29)
75c0e7b Fix particles being visible after world change when jumping in time (fixes #35)
c934cb9 Fix spawn player packet being sent twice
6efbf91 Handle F1 properly while mouse is visible in the replay overlay (fixes #30)
9add2af Deselect keyframe when pressing "V" aka. sync timelines (fixes #27)
2016-11-29 22:49:35 +01:00
johni0702
ce313596db Add 1.10.2 version to ReplayCenter search (fixes #38) 2016-11-12 19:30:26 +01:00
johni0702
b1661e359a Merge branch '1.9.4' into 1.10.2
e20dfa6 Merge branch '1.8' into 1.9.4
682fb4b Download OpenEye via http because of outdated java versions
0c48d6a Make ShaderReflection init fail fast, not printing out unneeded exceptions
2016-11-11 18:15:54 +01:00
johni0702
7cc0ee523a Merge branch '1.9.4' into 1.10.2
54790d3 Merge branch '1.8' into 1.9.4
0ba5b0a Merge branch '1.8-shaders' into 1.8
1658617 Merge branch '1.8' into 1.9.4
0db1b9e Fix opening a replay multiple times by quickly double clicking (fixes #25)
5014eda Remove javascript comments from mcmod.info
e5eb982 Add Optifine compatibility to rendering by disabling their separate chunk loading queue Add compatibility to shaders that utilize the Shadow Map by manually setting displayListEntitiesDirty to false Call Shaders.beginRender in an Event Handler to avoid calling all of EntityRenderer#renderWorld
3a28c5b Draw the GuiVideoRenderer on a separate framebuffer that has the actual size of the window instead of MC's framebuffer which may have a different size
636ce7b Add compatibility for GLSL Shaders
92eb11a Change video preview to be compatible with Optifine
9ff767b Fix spectated player having the arm model of the camera player
d82cef3 Make sure video folder exists before rendering (fixes #24)
cc65b26 Replace custom update system with forge update checker
c8b71dc Add tooltips to ingame buttons
b240f8a Fix camera path always playing from the beginning regardless of ctrl key
4805e5e Fix crash when setting two keyframes to the same time via the edit keyframe gui
18f8303 Fix crash when moving the last keyframe
fcd4c07 Add error popup when trying to play path with reversed time keyframes Update jGui
9c605ba Update jGui Fix handling of ESC key in popups (fixes #17)
721fdc4 Allow moving the keyframe timeline cursor by dragging (fixes #18)
1851e97 Allow deletion of selected keyframes by pressing the DELETE key (fixes #19)
d547098 Fix markers not being removed
b2c7faa Fix marker not being deselected when clicking anywhere else
4e6b387 Update jGui Fix popups being drawn outside of the actually visible element (fixes #21)
21bbeb2 Fix bitrate field always being active regardless of selected preset (fixes #20)
b5a6d8b Fix camera player head being visible while in third person
dd0537b Center star between resolution fields in render settings gui
e35bfca Increase spacing between rows in the render settings gui
6d0cdfb Update jGui (fixes #15)
2016-11-10 22:00:36 +01:00
johni0702
09f167f10e Update to 1.10.2 2016-10-17 22:23:44 +02:00
675 changed files with 36421 additions and 10876 deletions

View File

@@ -1,18 +0,0 @@
pipeline:
clone:
image: plugins/git
tags: true
build:
image: openjdk:8
commands:
- JAVA_OPTS=-Xmx1516M ./gradlew setupDecompWorkspace
- ./gradlew :build
archive:
image: plugins/s3
acl: public-read
region: "us-east-1"
bucket: "replaymod"
path_style: true
source: build/libs/*
strip_prefix: build/libs/
target: /

View File

@@ -1 +0,0 @@
eyJhbGciOiJIUzI1NiJ9.cGlwZWxpbmU6CiAgY2xvbmU6CiAgICBpbWFnZTogcGx1Z2lucy9naXQKICAgIHRhZ3M6IHRydWUKICBidWlsZDoKICAgIGltYWdlOiBvcGVuamRrOjgKICAgIGNvbW1hbmRzOgogICAgICAtIEpBVkFfT1BUUz0tWG14MTUxNk0gLi9ncmFkbGV3IHNldHVwRGVjb21wV29ya3NwYWNlCiAgICAgIC0gLi9ncmFkbGV3IDpidWlsZAogIGFyY2hpdmU6CiAgICBpbWFnZTogcGx1Z2lucy9zMwogICAgYWNsOiBwdWJsaWMtcmVhZAogICAgcmVnaW9uOiAidXMtZWFzdC0xIgogICAgYnVja2V0OiAicmVwbGF5bW9kIgogICAgcGF0aF9zdHlsZTogdHJ1ZQogICAgc291cmNlOiBidWlsZC9saWJzLyoKICAgIHN0cmlwX3ByZWZpeDogYnVpbGQvbGlicy8KICAgIHRhcmdldDogLwo.Q_jQxd73CuNh8ZTGTw31yMmBIzWprIagmaddFYovDrc

1
.gitattributes vendored Normal file
View File

@@ -0,0 +1 @@
* text=auto

BIN
.gitignore vendored

Binary file not shown.

7
.gitmodules vendored
View File

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

30
Jenkinsfile vendored Normal file
View File

@@ -0,0 +1,30 @@
pipeline {
agent {
docker { image 'openjdk:8-jdk' }
}
stages {
stage('Build') {
environment {
GRADLE_USER_HOME = '.gradle/user_home'
}
steps {
cache(maxCacheSize: 4096, caches: [
[$class: 'ArbitraryFileCache', excludes: 'modules-2/modules-2.lock,*/plugin-resolution/**', includes: '**/*', path: '.gradle/user_home/caches'],
[$class: 'ArbitraryFileCache', excludes: '', includes: '**/*', path: '.gradle/user_home/wrapper'],
[$class: 'ArbitraryFileCache', excludes: '', includes: '**/*', path: '.gradle/loom-cache'],
]) {
// sh './gradlew :jGui:1.7.10:setupCIWorkspace :1.7.10:setupCIWorkspace'
sh './gradlew --parallel'
}
archiveArtifacts 'versions/*/build/libs/*.jar'
}
}
stage('Deploy') {
steps {
withAWS(endpointUrl: 'https://minio.johni0702.de', credentials: 'minio') {
s3Upload bucket: 'replaymod', includePathPattern: '*.jar', workingDir: 'build/libs', acl: 'PublicRead', pathStyleAccessEnabled: true
}
}
}
}
}

View File

@@ -4,46 +4,38 @@ A Minecraft mod to record game sessions and replay them afterwards from any pers
## Building ## Building
Make sure your sub-projects are up-to-date: `git submodule update --init --recursive` Make sure your sub-projects are up-to-date: `git submodule update --init --recursive`
For each branch you visit the first time, running `./gradlew setupDecompWorkspace` is necessary. For compiling 1.7.10, you must run `./gradlew :jGui:1.7.10:setupDecompWorkspace :1.7.10:setupDecompWorkspace` once after the initial clone. This may take quite some time.
This will also be necessary if the `replaymod_at.cfg` file has been changed (getting errors about code that is trying
to access private fields is a good indication that this has happened).
### No IDE ### No IDE
You can build the mod by running `./gradlew :build`. You can then find the final jar files in `build/libs/`. You can build the mod by running `./gradlew build` (or just `./gradlew bundleJar`). You can then find the final jar files in `versions/$MCVERSION/build/libs/`.
You can also build single versions by running `./gradlew :1.8:build` (or just `./gradlew :1.8:bundleJar`) (builds the MC 1.8 version).
### IntelliJ ### IntelliJ
For the initial setup run `./gradlew preshadowJar idea genIntellijRuns`. Ensure you have at least IDEA 2020.1.
You also need to enable the Mixin annotation processor: Build the mod via Gradle as explained above at least once (`./gradlew compileJava` should be sufficient). This will ensure that the sources for all MC versions are generated.
1. Go to File -> Settings -> Build, Execution, Deployment -> Compiler -> Annotation Processors Then import the Gradle project from within IDEA: File -> Open -> build.gradle -> Open as Project
2. Tick "Enable annotation processing" Finally configure IDEA to build everything by itself instead of delegating it to Gradle (cause that is slow): File -> Settings -> Build, Execution, Deployment -> Build Tools -> Gradle -> Build and run using: IntelliJ IDEA
3. Add a new entry to the "Annotation Processor options"
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.
### Eclipse ### Eclipse
## Development ## Development
### Branches ### Branches
New features are developed on the `1.8` branch and merged upwards for release. Larger features are developed on their Loosely based on [this branching model](http://nvie.com/posts/a-successful-git-branching-model/) with `stable` instead of `master`.
own branch that is based on `1.8` and then merged back once it's finished.
Features or bug fixes that apply only to a specific Minecraft version are fixed on the branch corresponding to that TL;DR:
version and reverted when merging upwards. Main development happens on the `develop` branch, snapshots are built from this branch.
The `stable` branch contains the most recent release.
Both subprojects follow a similar branching model.
The user documentation (`docs` folder) is only committed to on the current development branch. Any changes committed on
a branch for a more recent Minecraft version are not kept up to date on the website and should only be
of importance once support for the previous Minecraft version is dropped.
The `master` branch is solely to be used for the `version.json` file that contains a list of all versions The `master` branch is solely to be used for the `version.json` file that contains a list of all versions
used by the clients to check for updates of this mod. used by the clients to check for updates of this mod.
### The Preprocessor
To support multiple Minecraft versions with the ReplayMod, a [JCP](https://github.com/raydac/java-comment-preprocessor)-inspired preprocessor is used.
It has by now acquired a lot more sophisticated features to make it as noninvasive as possible.
Please read the [preprocessor's README](https://github.com/ReplayMod/preprocessor/blob/master/README.md) to understand how it works.
### Versioning ### Versioning
The ReplayMod uses the versioning scheme outlined [here](http://mcforge.readthedocs.io/en/latest/conventions/versioning/) The ReplayMod uses the versioning scheme outlined [here](https://docs.minecraftforge.net/en/1.12.x/conventions/versioning/)
with three changes: with three changes:
- No `MAJORAPI`, the ReplayMod does not provide any external API - No `MAJORAPI`, the ReplayMod does not provide any external API
- "Updating to a new Minecraft version" should not increment `MAJORMOD`, we maintain one version of the ReplayMod - "Updating to a new Minecraft version" should not increment `MAJORMOD`, we maintain one version of the ReplayMod
@@ -52,19 +44,18 @@ keep the version name the same for all of them (with the exception of `MCVERSION
"Multiple Minecraft Version" section does not apply. "Multiple Minecraft Version" section does not apply.
- For pre-releases the shorter `-bX` is used instead of `-betaX` - For pre-releases the shorter `-bX` is used instead of `-betaX`
When a new version is (pre-)release, a new annotated tag should be added with the name of the version and the When a new version is (pre-)release, a new commit modifying the `version.txt` file should be added and the
`versions.json` file in the `master` branch should be updated. To simplify this process the gradle task `doRelease` can `versions.json` file in the `master` branch should be updated. To simplify this process the gradle task `doRelease` can
be used: `./gradlew -PreleaseVersion=1.8-2.0.0-rc1 doRelease`. It will create the tag and update the version.json be used: `./gradlew -PreleaseVersion=2.0.0-rc1 doRelease`. It will create the commit and update the version.json
accordingly. accordingly.
Care should be taken that the updated `version.json` is not pushed before a jar file is available on the Care should be taken that the updated `version.json` is not pushed before a jar file is available on the
download page (or Jenkins) as it will inform the users of the update. download page (or Jenkins) as it will inform the users of the update.
### Bugs ### Bugs
Bugs in the mod are tracked via [Bugzilla](https://bugs.replaymod.com/). GitHub should generally be used to report bugs.
GitHub should only be used for issues that are generally not likely to affect any end users.
Bug numbers in commits such as `(fixes #42)` refer to Bugzilla unless noted otherwise. In the past, bugs were tracked via [Bugzilla](https://bugs.replaymod.com/), so bug numbers in commits prior to 2020 such as `(fixes #42)` generally referred to Bugzilla unless noted otherwise.
## License ## License
The ReplayMod is provided under the terms of the GNU General Public License Version 3 or (at your option) any later version. The ReplayMod is provided under the terms of the GNU General Public License Version 3 or (at your option) any later version.

Submodule ReplayStudio deleted from c4df3c1320

View File

@@ -1,282 +0,0 @@
import groovy.json.JsonOutput
import java.util.zip.ZipInputStream
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/"
}
}
dependencies {
classpath 'net.minecraftforge.gradle:ForgeGradle:2.2-SNAPSHOT'
classpath 'org.spongepowered:mixingradle:0.4-SNAPSHOT'
}
}
apply plugin: 'net.minecraftforge.gradle.forge'
apply plugin: 'org.spongepowered.mixin'
sourceCompatibility = 1.8
targetCompatibility = 1.8
version = gitDescribe()
group= "com.replaymod"
archivesBaseName = "replaymod"
minecraft {
coreMod = 'com.replaymod.core.LoadingPlugin'
version = '1.9.4-12.17.0.1976'
runDir = "eclipse"
mappings = "snapshot_20160518"
}
repositories {
maven {
name = "SpongePowered Repo"
url = "http://repo.spongepowered.org/maven/"
}
maven {
url 'https://repo.spacehq.org/content/repositories/snapshots/'
}
}
configurations {
shade
compile.extendsFrom shade
}
dependencies {
compile 'org.projectlombok:lombok:1.16.4'
compile 'org.spongepowered:mixin:0.5.9-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'
shade 'com.google.api-client:google-api-client-gson:1.20.0'
shade 'com.google.api-client:google-api-client-java6:1.20.0'
shade 'com.google.oauth-client:google-oauth-client-jetty:1.20.0'
shade 'org.aspectj:aspectjrt:1.8.2'
compile project(':ReplayStudio')
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")
doFirst {
noticeDir.deleteDir()
noticeDir.mkdirs()
shade().collect { it.isDirectory() ? fileTree(it) : zipTree(it) }.each {
it.matching { include '**/NOTICE*' }.each {
new File(noticeDir, 'NOTICE.txt') << it.getText('UTF-8') + '\n'
}
}
}
from noticeDir
def langDir = file("$buildDir/languages")
doFirst {
try {
langDir.deleteDir()
langDir.mkdirs()
def dir = new File(langDir, 'assets/replaymod/lang/')
dir.mkdirs()
def zip = new ZipInputStream(new URL('http://replaymod.com/api/grab_languages').openStream())
def e;
while ((e = zip.nextEntry) != null) {
new File(dir, e.getName()) << zip
zip.closeEntry()
}
} catch(Exception e) {
e.printStackTrace();
}
}
from (langDir) {
exclude '**/en_US.lang'
}
from ({shade().collect { it.isDirectory() ? it : zipTree(it) }}) {
exclude '**/NOTICE*'
// exclude everything taken in from jGui for running the mod in a dev environment
exclude { new File(file('jGui/src/main/resources'), it.relativePath.pathString).exists() }
eachFile {
if (getName() == 'LICENSE.txt') {
setName(getFile().getParentFile().getName().split('-')[0] + '-LICENSE.txt')
}
}
}
manifest {
attributes 'TweakClass': 'org.spongepowered.asm.launch.MixinTweaker',
'TweakOrder': '0',
'FMLCorePluginContainsFMLMod': 'true',
'FMLAT': 'replaymod_at.cfg'
}
}
def gitDescribe() {
try {
def stdout = new ByteArrayOutputStream()
exec {
commandLine 'git', 'describe', '--always', '--dirty=*'
standardOutput = stdout
}
return stdout.toString().trim()
} catch (e) {
return "unknown"
}
}
processResources
{
// this will ensure that this task is redone when the versions change.
inputs.property "version", project.version
inputs.property "mcversion", project.minecraft.version
// replace stuff in mcmod.info, nothing else
from(sourceSets.main.resources.srcDirs) {
include 'mcmod.info'
// replace version and mcversion
expand 'version': project.version, 'mcversion': project.minecraft.version
}
// copy everything else, thats not the mcmod.info
from(sourceSets.main.resources.srcDirs) {
exclude 'mcmod.info'
}
}
sourceSets {
main {
// Directly include jGui into main build
// This could also be done by including it as a gradle subproject, however
// doing so caused classpath issues on some IntelliJ versions.
java {
srcDir 'jGui/src/main/java'
}
resources {
srcDir 'jGui/src/main/resources'
}
refMap = "mixins.replaymod.refmap.json"
}
}
task copySrg(type: Copy, dependsOn: 'genSrgs') {
from {project.tasks.genSrgs.mcpToSrg}
into 'build'
}
setupDecompWorkspace.dependsOn copySrg
setupDevWorkspace.dependsOn copySrg
project.tasks.idea.dependsOn copySrg
def generateVersionsJson() {
// List all tags
def stdout = new ByteArrayOutputStream()
project.exec {
commandLine 'git', 'for-each-ref', '--sort=taggerdate', '--format=%(refname:short)', 'refs/tags'
standardOutput = stdout
}
def versions = stdout.toString().tokenize('\n').reverse()
def mcVersions = versions.collect {it.substring(0, it.indexOf('-'))}.unique().reverse()
def root = [
homepage: 'https://www.replaymod.com/download/',
promos: [:]
]
mcVersions.forEach { mcVersion ->
def mcVersionRoot = [:]
def latest
def recommended
versions.forEach {
def (thisMcVersion, modVersion, preVersion) = it.tokenize('-')
if (thisMcVersion == mcVersion) {
mcVersionRoot[it] = "See https://github.com/ReplayMod/ReplayMod/releases/$it"
if (latest == null) latest = it
if (preVersion == null) {
if (recommended == null) recommended = it
}
}
}
root[mcVersion] = mcVersionRoot
root.promos[mcVersion + '-latest'] = latest
if (recommended != null) {
root.promos[mcVersion + '-recommended'] = recommended
}
}
root
}
task doRelease() {
doLast {
// Parse version
def version = project.releaseVersion as String
if (project.version.endsWith('*')) {
throw new InvalidUserDataException('Git working tree is dirty. Make sure to commit all changes.')
}
def (mcVersion, modVersion, preVersion) = version.tokenize('-')
preVersion = preVersion != null && preVersion.startsWith('b') ? preVersion.substring(1) : null
// Create new tag
if (preVersion != null) {
project.exec {
commandLine 'git', 'tag',
'-m', "Pre-release $preVersion of $modVersion for Minecraft $mcVersion",
"$mcVersion-$modVersion-b$preVersion"
}
} else {
project.exec {
commandLine 'git', 'tag',
'-m', "Release $modVersion for Minecraft $mcVersion",
"$mcVersion-$modVersion"
}
}
// Switch to master branch to update versions.json
project.exec { commandLine 'git', 'checkout', 'master' }
// Generate versions.json content
def versionsRoot = generateVersionsJson()
def versionsJson = JsonOutput.prettyPrint(JsonOutput.toJson(versionsRoot))
// Write versions.json
new File('versions.json').write(versionsJson)
// Commit changes
project.exec { commandLine 'git', 'add', 'versions.json' }
project.exec { commandLine 'git', 'commit', '-m', "Update versions.json for $version" }
// Return to previous branch
project.exec { commandLine 'git', 'checkout', '-' }
}
}
defaultTasks 'build'

377
build.gradle.kts Normal file
View File

@@ -0,0 +1,377 @@
import com.replaymod.gradle.preprocess.PreprocessTask
import gg.essential.gradle.util.*
import net.fabricmc.loom.task.RemapJarTask
plugins {
java
id("com.gradleup.shadow") apply false
id("gg.essential.multi-version")
id("gg.essential.defaults.repo")
id("gg.essential.defaults.java")
id("gg.essential.defaults.loom")
}
val mcVersion = platform.mcVersion
var jGuiVersion = project.name
if (jGuiVersion in listOf("1.10.2", "1.11", "1.11.2")) jGuiVersion = "1.9.4"
if (jGuiVersion in listOf("1.12.1", "1.12.2")) jGuiVersion = "1.12"
val jGui = project.evaluationDependsOn(":jGui:$jGuiVersion")
version = "${project.name}-${rootProject.version}"
base.archivesName.set("replaymod")
java.withSourcesJar()
loom {
noServerRunConfigs()
}
if (!platform.isUnobfuscated) {
loom.mixin.useLegacyMixinAp = true
loom.mixin.defaultRefmapName.set("mixins.replaymod.refmap.json")
}
if (platform.isLegacyForge) {
loom.runs.named("client") {
property("fml.coreMods.load", "com.replaymod.core.LoadingPlugin")
}
}
repositories {
mavenLocal()
maven("https://repo.spongepowered.org/maven/")
maven("https://maven.terraformersmc.com/releases/") {
content {
includeGroup("com.terraformersmc")
}
}
maven("https://jitpack.io") {
content {
includeGroupByRegex("com\\.github\\..*")
}
}
exclusiveContent {
forRepository {
maven("https://api.modrinth.com/maven")
}
filter {
includeGroup("maven.modrinth")
}
}
}
// Include dep in fat jar without relocation and, when forge supports it, without exploding (TODO)
val shade by configurations.creating
// Include dep in fat jar with relocation and minimization
val shadow by configurations.creating {
exclude(group = "net.fabricmc", module = "fabric-loader")
exclude(group = "com.google.guava", module = "guava-jdk5")
exclude(group = "com.google.guava", module = "guava") // provided by MC
exclude(group = "com.google.code.gson", module = "gson") // provided by MC (or manually bundled for 1.11.2 and below)
}
dependencies {
if (platform.isFabric) {
val fabricApiVersion = when (mcVersion) {
11404 -> "0.4.3+build.247-1.14"
11502 -> "0.5.1+build.294-1.15"
11601 -> "0.14.0+build.371-1.16"
11603 -> "0.17.1+build.394-1.16"
11604 -> "0.42.0+1.16"
11701 -> "0.46.1+1.17"
11800 -> "0.43.1+1.18"
11801 -> "0.43.1+1.18"
11802 -> "0.47.9+1.18.2"
11900 -> "0.55.3+1.19"
11901 -> "0.58.5+1.19.1"
11902 -> "0.68.0+1.19.2"
11903 -> "0.68.1+1.19.3"
11904 -> "0.76.0+1.19.4"
12001 -> "0.83.1+1.20.1"
12002 -> "0.91.2+1.20.2"
12004 -> "0.91.2+1.20.4"
12006 -> "0.98.0+1.20.6"
12100 -> "0.100.3+1.21"
12102 -> "0.106.1+1.21.2"
12104 -> "0.111.0+1.21.4"
12105 -> "0.119.9+1.21.5"
12107 -> "0.128.1+1.21.7"
12110 -> "0.135.0+1.21.10"
12111 -> "0.139.5+1.21.11"
26_01_00 -> "0.144.3+26.1"
else -> throw UnsupportedOperationException()
}
val fabricApiModules = mutableListOf(
"api-base",
"networking-v0",
"keybindings-v0",
"resource-loader-v0",
)
if (mcVersion >= 11600) {
fabricApiModules.remove("keybindings-v0")
fabricApiModules.add("key-binding-api-v1")
}
if (mcVersion >= 11604) {
fabricApiModules.add("screen-api-v1")
fabricApiModules.add("networking-api-v1")
}
if (mcVersion >= 11700) {
fabricApiModules.remove("networking-v0")
}
if (mcVersion >= 12109) {
fabricApiModules.add("resource-loader-v1")
}
if (mcVersion >= 26_01_00) {
fabricApiModules.remove("key-binding-api-v1")
fabricApiModules.add("key-mapping-api-v1")
}
for (module in fabricApiModules) {
val dep = fabricApi.module("fabric-$module", fabricApiVersion)
modImplementation(dep)
"include"(dep)
}
}
if (!platform.isFabric) {
// Mixin 0.8 is no longer compatible with MC 1.11.2 or older
val mixinVersion = if (mcVersion >= 11200) "0.8.2" else "0.7.11-SNAPSHOT"
compileOnly("org.spongepowered:mixin:$mixinVersion")
implementation(shade("org.spongepowered:mixin:$mixinVersion") {
isTransitive = false // deps should all be bundled with MC
})
}
if (platform.isFabric) {
"include"(implementation(annotationProcessor("io.github.llamalad7:mixinextras-fabric:0.3.6")!!)!!)
}
implementation(shadow("com.googlecode.mp4parser:isoparser:1.1.7")!!)
implementation(shadow("org.apache.commons:commons-exec:1.3")!!)
implementation(shadow("com.google.apis:google-api-services-youtube:v3-rev178-1.22.0")!!)
implementation(shadow("com.google.api-client:google-api-client-gson:1.20.0")!!)
implementation(shadow("com.google.api-client:google-api-client-java6:1.20.0")!!)
implementation(shadow("com.google.oauth-client:google-oauth-client-jetty:1.20.0")!!)
val lwjgl by configurations.creating
for (suffix in listOf("", ":natives-linux", ":natives-windows", ":natives-macos", ":natives-macos-arm64")) {
lwjgl("org.lwjgl:lwjgl:3.3.1$suffix")
lwjgl("org.lwjgl:lwjgl-tinyexr:3.3.1$suffix")
}
compileOnly("org.lwjgl:lwjgl-tinyexr:3.3.1")
shadow(prebundle(lwjgl, "com/replaymod/render/utils/lwjgl.jar"))
if (mcVersion < 11200) {
// The version which MC ships is too old, we'll need to ship our own
implementation(shadow("com.google.code.gson:gson:2.8.7")!!)
}
implementation(shadow("com.github.javagl.JglTF:jgltf-model:3af6de4")!!)
if (platform.isFabric) {
implementation(shadow("org.apache.maven:maven-artifact:3.6.1")!!)
}
implementation(shadow("org.aspectj:aspectjrt:1.8.2")!!)
implementation(shadow("com.github.ReplayMod.JavaBlend:2.79.0:a0696f8")!!)
implementation(shadow("com.github.ReplayMod:ReplayStudio")!!)
// FIXME hack because I don't know how to get this to be inherited properly
implementation(rootProject.files("libs/ReplayStudio/.gradle/prebundled-jars/viaVersion.jar"))
implementation(project(path = jGui.path, configuration = if (platform.isUnobfuscated) null else "namedElements"))
implementation(shadow("com.github.ReplayMod:lwjgl-utils:27dcd66")!!)
if (platform.isFabric) {
val modMenuVersion = when {
mcVersion >= 26_01_00 -> "18.0.0-alpha.8"
mcVersion >= 12111 -> "17.0.0-alpha.1"
mcVersion >= 12110 -> "16.0.0-rc.1"
mcVersion >= 12107 -> "15.0.0-beta.3"
mcVersion >= 12105 -> "14.0.0-rc.2"
mcVersion >= 12104 -> "13.0.0-beta.1"
mcVersion >= 12102 -> "12.0.0-beta.1"
mcVersion >= 12100 -> "11.0.0-rc.4"
mcVersion >= 12006 -> "10.0.0-beta.1"
mcVersion >= 12003 -> "9.0.0-pre.1"
mcVersion >= 12002 -> "8.0.0"
mcVersion >= 12000 -> "7.0.1"
mcVersion >= 11904 -> "6.1.0-rc.4"
mcVersion >= 11903 -> "5.0.0-alpha.4"
mcVersion >= 11901 -> "4.0.5"
mcVersion >= 11900 -> "4.0.4"
mcVersion >= 11802 -> "3.1.0"
mcVersion >= 11800 -> "3.0.0"
mcVersion >= 11700 -> "2.0.0-beta.7"
mcVersion >= 11602 -> "1.16.8"
mcVersion >= 11600 -> null // maven doesn't have one for this version (only 1.16.5)
mcVersion >= 11500 -> "1.10.6"
else -> null
}
if (modMenuVersion != null) {
modCompileOnly("com.terraformersmc:modmenu:$modMenuVersion")
} else {
// Oldest modmenu on their maven is 1.10.5 for MC 1.15.2; for older versions we won't run it in dev
modCompileOnly("com.terraformersmc:modmenu:1.10.6")
}
// Lacks maven dependencies
if (mcVersion == 12006) {
//modRuntimeOnly("net.fabricmc.fabric-api:fabric-api:0.98.0+1.20.6")
}
}
val irisVersion = when {
mcVersion >= 26_01_00 -> "1.10.8+26.1-fabric"
mcVersion >= 12000 -> "1.7.2+1.20.1"
mcVersion >= 11600 -> "1.18.x-v1.2.0"
else -> null
}
if (irisVersion != null) {
modCompileOnly("maven.modrinth:iris:$irisVersion")
}
testImplementation("junit:junit:4.11")
}
preprocess {
keywords.set(mapOf(
".java" to PreprocessTask.DEFAULT_KEYWORDS,
".kt" to PreprocessTask.DEFAULT_KEYWORDS,
".json" to PreprocessTask.DEFAULT_KEYWORDS,
".mcmeta" to PreprocessTask.DEFAULT_KEYWORDS,
".cfg" to PreprocessTask.CFG_KEYWORDS,
".vert" to PreprocessTask.DEFAULT_KEYWORDS,
".frag" to PreprocessTask.DEFAULT_KEYWORDS,
))
patternAnnotation.set("com.replaymod.gradle.remap.Pattern")
}
tasks.jar {
archiveClassifier.set("raw")
if (!platform.isFabric) {
manifest {
attributes(
"TweakClass" to "com.replaymod.core.tweaker.ReplayModTweaker",
"TweakOrder" to "0",
"FMLCorePluginContainsFMLMod" to "true",
"FMLCorePlugin" to "com.replaymod.core.LoadingPlugin",
"FMLAT" to "replaymod_at.cfg",
)
}
}
}
if (!platform.isUnobfuscated) {
tasks.named<RemapJarTask>("remapJar") {
if (platform.isFabric) {
addNestedDependencies.set(true)
}
archiveClassifier.set("obf")
}
}
val configureRelocationOutput = project.layout.buildDirectory.file("configureRelocation")
val configureRelocation by tasks.registering {
dependsOn(tasks.jar)
dependsOn(shadow)
outputs.file(configureRelocationOutput)
doLast {
val pkgs = files(shadow).filter { it.exists() }.map {
val tree = if (it.isDirectory) fileTree(it) else zipTree(it)
val pkgs = mutableSetOf<String>()
tree.visit {
val file = this
if (!file.isDirectory && file.name.endsWith(".class") && file.path.contains("/")) {
val pkg = file.path.substring(0, file.path.lastIndexOf("/")) + "/"
if (pkg.startsWith("com/")) {
if (pkg.startsWith("com/google/")) {
if (!pkg.startsWith("com/google/common")) {
pkgs += pkg.substring(0, pkg.indexOf("/", "com/google/".length))
}
} else if (!pkg.startsWith("com/replaymod")) {
pkgs += pkg.substring(0, pkg.indexOf("/", 4))
}
} else if (pkg.startsWith("net/")) {
if (!pkg.startsWith("net/minecraft")
&& !pkg.startsWith("net/fabric")) {
pkgs += pkg.substring(0, pkg.indexOf("/", "net/".length))
}
} else if (pkg.startsWith("org/")) {
if (pkg.startsWith("org/apache/")) {
if (pkg.startsWith("org/apache/commons/")) {
if (!pkg.startsWith("org/apache/commons/io")) {
pkgs += pkg.substring(0, pkg.indexOf("/", "org/apache/commons/".length))
}
} else if (!pkg.startsWith("org/apache/logging")) {
pkgs += pkg.substring(0, pkg.indexOf("/", "org/apache/".length))
}
} else if (pkg.startsWith("org/lwjgl")) {
return@visit // either bundled with MC or uses natives which we can't relocate
} else if (!pkg.startsWith("org/spongepowered")) {
pkgs += pkg.substring(0, pkg.indexOf("/", 4))
}
} else if (pkg.startsWith("it/unimi/dsi/fastutil") && mcVersion >= 11400) {
return@visit // MC uses this as well
} else if (!pkg.startsWith("javax/")) {
// Note: we cannot just use top level packages as those will be too generic and we'll run
// into this long standing bug: https://github.com/johnrengelman/shadow/issues/232
val i = pkg.indexOf("/")
val i2 = pkg.indexOf("/", i + 1)
if (i2 > 0) {
pkgs += pkg.substring(0, i2)
}
}
}
}
pkgs
}.flatten().toSortedSet()
configureRelocationOutput.get().asFile.writeText(pkgs.joinToString("\n"))
}
}
val bundleJar by tasks.registering(com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar::class) {
from((if (platform.isUnobfuscated) tasks.jar else tasks.named<RemapJarTask>("remapJar")).flatMap { it.archiveFile }.map { zipTree(it) })
from((if (platform.isUnobfuscated) jGui.tasks.jar else jGui.tasks.named<RemapJarTask>("remapJar")).flatMap { it.archiveFile }.map { zipTree(it) }) {
filesMatching("mixins.jgui.json") {
filter { it.replace("de.johni0702", "com.replaymod.lib.de.johni0702") }
}
filesMatching("mixins.jgui.refmap.json") {
filter { it.replace("de/johni0702", "com/replaymod/lib/de/johni0702") }
}
}
relocate("de.johni0702", "com.replaymod.lib.de.johni0702")
manifest.from(tasks.jar.get().manifest)
from(shade.elements.map { it.map { zipTree(it) } })
configurations = listOf(shadow)
exclude("META-INF/INDEX.LIST", "META-INF/*.SF", "META-INF/*.DSA", "META-INF/*.RSA", "module-info.class")
dependsOn(configureRelocation)
inputs.file(configureRelocationOutput)
doFirst {
configureRelocationOutput.get().asFile.forEachLine { pkg ->
val pkgName = pkg.replace("/", ".")
relocate(pkgName, "com.replaymod.lib.$pkgName")
}
}
// No need to shadow netty, MC provides it
// (actually, pre-1.12 ships a netty which is too old, so we need to shade it there anyway)
if (mcVersion >= 11200) {
relocate("com.github.steveice10.netty", "io.netty")
exclude("com/github/steveice10/netty/**")
}
if (mcVersion >= 11400) {
// MC ships this
exclude("it/unimi/dsi/fastutil/**")
}
minimize {
exclude(dependency(".*spongepowered:mixin:.*"))
}
}
tasks.assemble { dependsOn(bundleJar) }

389
docs/content.md Normal file → Executable file
View File

@@ -1,9 +1,14 @@
# Installation [installing] # Installation [installing]
## Installing the Replay Mod [replaymod] ## Installing the Replay Mod [replaymod]
The **ReplayMod** requires **Minecraft Forge** to be installed. ### Minecraft 1.14 and above
The **ReplayMod** for Minecraft 1.14 and above requires **Fabric** to be installed.
For the use with the **Replay Mod**, we recommend using Forge Version `1.8-11.14.3.1450`, which can be downloaded [here](http://files.minecraftforge.net/maven/net/minecraftforge/forge/index_1.8.html) You can find Fabric and the installation instructions [here](https://fabricmc.net/use/).
Other Forge Versions might, but don't necessarily work.
After installing Fabric, simply put the downloaded ReplayMod .jar file into the `/mods` folder of your Minecraft directory.
### Minecraft 1.12.2 and below
For Minecraft 1.12.2 and below it requires **Minecraft Forge** to be installed.
If you don't know how to install Forge, follow [this tutorial](https://www.youtube.com/watch?v=4i7-RystzC4). If you don't know how to install Forge, follow [this tutorial](https://www.youtube.com/watch?v=4i7-RystzC4).
@@ -12,50 +17,44 @@ After installing Forge, simply put the downloaded `ReplayMod.jar` file in the `/
> **Note:** The **Replay Mod** is entirely client side and can not be installed on the servers you play on. > **Note:** The **Replay Mod** is entirely client side and can not be installed on the servers you play on.
## Installing FFmpeg [ffmpeg] ## Installing FFmpeg [ffmpeg]
To use the **Replay Mod**'s [Rendering Feature](#replaying-render), you need to have FFmpeg installed. To render your creations with **Replay Mod** you will need to have FFmpeg installed.
### Windows [windows] ### Windows [windows]
Download the latest **FFmpeg Static Build** for your architecture from <http://ffmpeg.zeranoe.com/builds/>. Download the latest FFmpeg release from https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-essentials.zip.
Then, extract the downloaded `.7z` file in the folder you want to install FFmpeg in.
Next, download this **Batch Script** to quickly install FFmpeg: <https://replaymod.com/files/ffmpeg-path-installer.bat> Extract the downloaded .zip file into your `.minecraft` folder.
> **Note:** If your browser warns you about the download, dismiss the message. It's a simple Batch Script which won't damage your computer. Historically the exact location inside the `.minecraft` folder was important, this is no longer the case.
It is sufficient for the `ffmpeg.exe` to be anywhere inside your `.minecraft` folder.
Put the downloaded script into the folder where you extracted FFmpeg and run itt by double-clicking it. **Notes for alternative launchers**
If you see a success message in the console, you've sucessfully installed **FFmpeg**! - Twitch launcher by default installs Minecraft instances in C:\\Users\\*username*\\Twitch\\Minecraft\\Instances\\*instancename*\\
- GD Launcher by default installs Minecraft instances in C:\\Users\\*username*\\AppData\\Roaming\\gdlauncher_next\\instances\\*instancename*\\
- MultiMC by default installs Minecraft instances in C:\\Program Files (x86)\\MultiMC\\instances\\*Instancename*\\.minecraft\\
For these launchers, make sure FFmpeg exists inside the corresponding folder.
### Mac OSX [mac] ### Mac OSX [mac]
On OSX, you can install **FFmpeg** with **[Homebrew](http://brew.sh/)** using `brew install ffmpeg`. On OSX, you can install **FFmpeg** with **[Homebrew](http://brew.sh/)** using `brew install ffmpeg`.
Alternatively, you can download the latest static build from <https://ffmpeg.org/> and copy the ffmpeg executable to `/usr/local/bin`. Alternatively, you can download the latest static build from <https://ffmpeg.org/> and copy the FFmpeg executable to `/usr/local/bin`.
### Linux [linux] ### Linux [linux]
On Linux, you can install **FFmpeg** using your system's package manager, for example using `apt install ffmpeg`. On Linux, you can install **FFmpeg** using your system's package manager, for example using `apt install ffmpeg`.
If in doubt, consult the documentation of your distribution. If in doubt, consult the documentation of your distribution.
## Compatibility with other Mods [compatibility] ## Settings [settings]
### General information [general] To access the **Replay Mod Settings** from the Main Menu click the **"Replay Viewer"** button and click the **Settings** button.
In General, the Replay Mod _should_ be compatible with most Forge Mods.
However, due to the way that recording works, many Mods that add new Blocks, Mobs or Game Mechanics are not supported.
Mods that simply modify the client (like the [PixelCam Mod](http://www.minecraftforum.net/forums/mapping-and-modding/minecraft-mods/2327429-pixelcam-camera-studio-for-minecraft-1-8)
or the [CommandGroups Mod](http://www.minecraftforum.net/forums/mapping-and-modding/minecraft-mods/2443430-command-groups-mod-order-label-and-color-command)) usually work.
### Optifine [optifine] While playing, you can click the 'Mods' button in the Pause screen to reach **Replay Mod Settings** if you use Minecraft 1.12.2 and below, or have the mod _Mod Menu_ installed.
The **Replay Mod** is compatible with `Optifine 1.8.0 HD U D5`, which can be downloaded at <https://optifine.net/downloads>.
Other Optifine versions for Minecraft 1.8.0 might, but don't have to be compatible as well.
> **Warning:** If you have Optifine installed, you **can not render videos** from within the Replay Mod. When in a Replay, you can either bind a hotkey to the **Replay Mod Settings** in Minecraft's Control settings
This might change in future Replay Mod versions. or use the hotkey GUI by clicking on the hamburger button in the lower left corner.
### Shaders Mod [shaders] ## Accounts [accounts]
You can use the Replay Mod together with [karyonix' Shaders Mod](http://www.minecraftforum.net/forums/mapping-and-modding/minecraft-mods/1286604-shaders-mod-updated-by-karyonix), In previous versions of ReplayMod we used accounts to deliver videos to the **Replay Center**. This has since been discontinued and with that, so have the accounts.
but rendering videos results in **possible crashes** and **malformed videos**.
Therefore, you have to **uninstall the Shaders Mod before rendering**.
## Troubleshooting [troubleshooting] Instead of the forum, you can join our [Discord server](https://discord.gg/5GR7RSb) to get support and answers.
If you need help installing the **Replay Mod** or **FFmpeg**, please read [this forum thread](https://www.replaymod.com/forum/thread/220)
by [bela333](https://www.replaymod.com/user/bela333) - it covers most of the problems that users encountered so far.
# Recording [recording] # Recording [recording]
![](img/recording-indicator.jpg) ![](img/recording-indicator.jpg)
@@ -88,6 +87,8 @@ You can move through block similar to Spectator Mode.
Using the **Mouse Wheel**, you can modify your flying speed. Scrolling **up** causes you to fly faster, while scrolling **down** slows you down. Using the **Mouse Wheel**, you can modify your flying speed. Scrolling **up** causes you to fly faster, while scrolling **down** slows you down.
If you prefer the camera to be controlled similar to vanilla Creative Mode, you can change that in the **Replay Settings**.
### Camera Roll [roll] ### Camera Roll [roll]
![](img/camera-tilted.jpg) ![](img/camera-tilted.jpg)
A Screenshot taken with a **tilted camera** A Screenshot taken with a **tilted camera**
@@ -121,15 +122,13 @@ The minimum Speed value is **0.1 times** the normal Minecraft Tick Speed, and th
To the right of the Speed Slider, there is the **Replay Timeline**. To the right of the Speed Slider, there is the **Replay Timeline**.
On the Replay Timeline, you see a yellow cursor indicating your current position in the Replay. On the Replay Timeline, you see a yellow cursor indicating your current position in the Replay.
By clicking somewhere on this Timeline, you will travel in time towards the specified point in time. By clicking somewhere on this Timeline, you will travel in time towards the specified point in time.
Please note that it takes longer to do larger steps in time or to jump backwards in time. Please note that it takes longer to do larger steps in time or to jump backwards in time (see also [Quick Mode](#replaying-quickmode)).
## Camera Paths [paths] ## Camera Paths [paths]
### Introduction [intro] ### Introduction [intro]
While in a Replay, you can create controlled **Camera Movements** using the Mods's **Keyframe System**. While in a Replay, you can create controlled **Camera Movements** using the Mods's **Keyframe System**.
Those Camera Paths can be rendered to a video later (see [Rendering](#replaying-render)). Those Camera Paths can be rendered to a video later (see [Rendering](#replaying-render)).
Camera Paths are inspired by the [PixelCam Mod](http://www.minecraftforum.net/forums/mapping-and-modding/minecraft-mods/2327429-pixelcam-camera-studio-for-minecraft-1-8) which is based on the Camera Studio Mod.
The **Replay Mod Keyframe System** is similar to many Video Editing Software's Keyframe Systems. The **Replay Mod Keyframe System** is similar to many Video Editing Software's Keyframe Systems.
If you're new to Keyframe Systems, try reading [this Wikipedia article](https://en.wikipedia.org/wiki/Key_frame). If you're new to Keyframe Systems, try reading [this Wikipedia article](https://en.wikipedia.org/wiki/Key_frame).
@@ -148,6 +147,8 @@ If two Keyframes are 5 seconds apart, the Camera Path will take 5 seconds to int
You can drag Keyframes on the **Keyframe Timeline** by left-clicking them, holding the mouse button and moving your mouse. You can drag Keyframes on the **Keyframe Timeline** by left-clicking them, holding the mouse button and moving your mouse.
> **Hint:** Made a mistake? You can use `Ctrl+Z` to undo your changes to the keyframe timeline. Changed you mind? Press `Ctrl+Y` (or `Ctrl+Shift+Z`) to redo them.
### Position Keyframes [place] ### Position Keyframes [place]
The basic components of a Camera Path are **Position Keyframes**. The basic components of a Camera Path are **Position Keyframes**.
A Position Keyframe stores a **Camera Position** (x, y, z, yaw, pitch, roll). A Position Keyframe stores a **Camera Position** (x, y, z, yaw, pitch, roll).
@@ -178,9 +179,6 @@ If you wish to disable smooth interpolation and want to make the Path follow str
You can easily toggle between **Linear** and **Cubic Interpolation** using the `O` key. You can easily toggle between **Linear** and **Cubic Interpolation** using the `O` key.
#### Path Preview [preview] #### Path Preview [preview]
![](img/path-preview-icon.jpg)
While the **Path Preview** is enabled, this camera symbol is displayed in the lower right corner of the screen.
![](img/path-preview.jpg) ![](img/path-preview.jpg)
A normal **Path Preview** A normal **Path Preview**
@@ -251,63 +249,11 @@ The **Keyframe Repository** with two **Path Presets**
Using the `X` key, you can open the **Keyframe Repository**. Every Replay File has a separate Keyframe Repository which can contain several **Keyframe Presets**. Using the `X` key, you can open the **Keyframe Repository**. Every Replay File has a separate Keyframe Repository which can contain several **Keyframe Presets**.
To save the Keyframes currently on your Timeline, click the **"Save current Path"** button. To save the Keyframes currently on your Timeline, click the **"Save as..."** button.
You can change the Preset's name using the Text Input Field in the upper right corner. You can change a Preset's name, select it from the list and click the **"Rename"** button.
To load a Keyframe Preset, select a Preset from the list on the left side and click the **"Load"** button. To load a Keyframe Preset, select a Preset from the list and click the **"Load"** button.
Using the **"Remove"** button, you can permanently delete a Keyframe Preset from the **Keyframe Repository**. Using the **"Remove"** button, you can permanently delete a Keyframe Preset from the **Keyframe Repository**.
## Custom Objects [objects]
[YouTube](_Xdpg828fbE)
### Introduction [introduction]
**Custom Objects** are mainly meant for **video creators**. They allow you to add any image into the Replay World and animate its Position, Opacity and much more.
Instead of using [Motion Tracking](https://en.wikipedia.org/wiki/Match_moving) to add text or pictures to a video, you can directly add these to the rendered file.
### Adding Assets [assets]
![](img/asset-manager.jpg)
The **Asset Manager** with an example Asset
In order to create **Custom Objects**, you first have to add **Assets** to your Replay File.
Therefore, open the **Asset Manager** using the `G` key.
In the **Asset Manager**, you can add **Image Files (.png, .jpg and more)**, so-called **Assets**, to the Replay.
When clicking the **"Add"** button, a File Chooser will show up. Select the image file you want to use.
You can give the Asset a custom name using the Text Input Field in the top right corner.
All of the Assets you added can be used by **Custom Objects**.
### Creating Custom Objects [creating]
![](img/object-manager.jpg)
The **Object Manager** with some **Animation Keyframes**
Using the `F` key, you can open the **Object Manager**. Initially there won't be any Objects in the **Object List**, but you can simply add an Object using the **"Add"** button.
After doing so, you can name the newly created **Custom Object** using the Text Field in the upper right corner.
To define which **Asset File** (i.e. image) the **Custom Object** should use, select the desired **Asset** from the dropdown beneath the Name Input.
If you leave the **Object Manager**, you should see the image in the World somwhere near your position.
### Animating Custom Objects [animating]
![](img/custom-object-animated.gif)
An animated **Custom Image Object**.
Of course, you don't want the image to stay at that position.
herefore, open the **Object Manager** again and select the **Custom Object** you want to modify.
On the lower half of the screen you will see mutliple **Input Fields**, using which you can modify various settings
(so-called **Transformations**), for example the Object's **Position**, **Scale**, **Orientation** and **Opacity**.
When editing these values, you'll notice that on the TImeline to the right, Keyframes appear.
You can set and remove Keyframes for specific settings using its "Add Keyframe" button on the very left of the screen.
The **Object Manager's Keyframe System** is very similar to the **Position Keyframe** and **Time Keyframe** System.
During a **Camera Path**, the **Custom Objects** will interpolate their **Transformation Values** like **Position Keyframes** are interpolated.
While outside the **Object Manager** you can preview the Objects' position by moving the cursor on the **Keyframe Timeline** - the Objects will interpolate to the position they'll be at that timestamp during the **Camera Path**.
Once you got the hang of it, you'll be able to quickly animate **Custom Objects**.
## Rendering [render] ## Rendering [render]
With the **Replay Mod**, you can render **Camera Paths** to videos **without** using a screen recording tool like Fraps. With the **Replay Mod**, you can render **Camera Paths** to videos **without** using a screen recording tool like Fraps.
To get started, first [set up your Camera Path](#replaying-paths) as described in the previous chapters. To get started, first [set up your Camera Path](#replaying-paths) as described in the previous chapters.
@@ -412,16 +358,21 @@ There are **7 Encoding Presets** you can choose from:
While these video files are of perfect quality, most **non-FFmpeg-based video players and video editing software** (e.g. QuickTime Player, Sony Vegas and Adobe Premiere) can't play these videos. Therefore, you should instead use the **MP4 - High Quality** preset in most cases. While these video files are of perfect quality, most **non-FFmpeg-based video players and video editing software** (e.g. QuickTime Player, Sony Vegas and Adobe Premiere) can't play these videos. Therefore, you should instead use the **MP4 - High Quality** preset in most cases.
- **PNG Sequence** - **PNG Sequence**
Exports the sequence as individual frames in the **PNG Format**. Exports the sequence as individual frames in the **PNG Format**.
**Warning:** This can create a huge amount of files, so make sure to save them in a separate folder. The images are of perfect quality.
Depth map images are 32-bit float encoded in the 8-bit components in BGRA order and will need some kind of post-processing to be useful in most editors.
- **OpenEXR Sequence** (Minecraft 1.14 and above)
Exports the sequence as individual frames in the **OpenEXR Format**.
The images are of perfect quality and may contain
additional image layers beyond the visible one (e.g. [depth](#replaying-render-advanced-depth-map)).
As such, this format is a good choice if you have plenty of disk space to spare and want to perform additional editing
on the video in a third-party video editor.
### Advanced Settings [advanced] ### Advanced Settings [advanced]
![](img/rendersettings-advanced.jpg) ![](img/rendersettings-advanced.jpg)
The **Advanced Render Settings** Screen The **Advanced Render Settings**
By clicking the **"Advanced Settings" Button** in the lower right corner, you can access more settings. #### Render Nametags [nametags]
If you don't want to see Entity's Nametags in the rendered video, simply un-tick the checkbox. Hidden Nametags also include Nametags of **Armor Stands** and **Mobs**, **not only Players**!
#### Hide Nametags [nametags]
If you don't want to see Entity's Nametags in the rendered video, simply tick the checkbox. Hidden Nametags also include Nametags of **Armor Stands** and **Mobs**, **not only Players**!
#### Stabilize Camera [stabilize] #### Stabilize Camera [stabilize]
This setting is only applicable for **Cubic Rendering** and **Equirectangular Rendering**. This setting is only applicable for **Cubic Rendering** and **Equirectangular Rendering**.
@@ -441,19 +392,34 @@ Using a **Video Editing Software** like **Adobe After Effects** or **Sony Vegas*
> **Note:** For best results, you should **disable clouds** before rendering, as they are transparent. > **Note:** For best results, you should **disable clouds** before rendering, as they are transparent.
#### Depth Map [depth-map]
![](img/depthmapsuzanne.jpg)
"Suzanne" model added into a scene using Blender
This setting causes depth information to be recorded and included in video formats which support it
(currently only [OpenEXR](#replaying-render-settings-quality)).
Using a video editor which supports it (e.g. [Blender](https://www.blender.org/)), you can then for example (among many
other effects) add arbitrary geometry onto your rendered video in such a way that foreground objects in the
video will still occlude background geometry as if it actually was part of the world.
> **Note:** For best results, avoid semi-transparent blocks in front of your geometry, as they cannot be accurately represented in the depth map.
> **Note:** Anti-aliasing is not supported when exporting depth. Instead simply render and edit your video at a higher resolution and scale it down at the very end.
### Command Line Settings [commandline] ### Command Line Settings [commandline]
![](img/rendersettings-commandline.jpg) ![](img/rendersettings-commandline.jpg)
The **Command Line Render Settings** Screen The **Command Line Render Settings**
> **Note**: This is for advanced users only. If you do not know what your're doing, leave these settings as they are. > **Note**: This is for advanced users only. If you do not know what your're doing, leave these settings as they are.
The **Replay Mod** runs [FFmpeg](http://ffmpeg.org/) via the **Command Line** to encode videos. The **Replay Mod** runs [FFmpeg](http://ffmpeg.org/) via the **Command Line** to encode videos.
You can customize both the **executed Command** and the **Command Line Arguments** in the **Command Line Settings** Tag of the **Render Settings Screen**. You can customize both the **executed Command** and the **Command Line Arguments** in the **Command Line Settings** part of the **Render Settings Screen**.
#### Custom Command [command] #### Custom Command [command]
If you leave the left input field blank, `ffmpeg` will be used as **command**. If you haven't set your **PATH variable** to link to your FFmpeg distribution, simply enter the full path to your FFmpeg executable (e.g. `C:/ffmpeg/ffmpeg.exe` or `/usr/local/bin/ffmpeg`). If you leave the left input field blank, `ffmpeg` will be used as **command**. If you haven't set your **PATH variable** to link to your FFmpeg distribution, simply enter the full path to your FFmpeg executable (e.g. `C:\ffmpeg\ffmpeg.exe` or `/usr/local/bin/ffmpeg`).
#### Command Line Arguments [arguments] #### Command Line Arguments [arguments]
In the right input field, you can input custom **Command Line Arguments** to be used in the console. In the right input field, you can input custom **Command Line Arguments** to be used in the console.
@@ -488,29 +454,6 @@ To use **High Performance Rendering**, hold down the `Ctrl` key (`Cmd` key on M
but only after one rendered seconds (e.g. every 60 frames when rendering with 60fps) but only after one rendered seconds (e.g. every 60 frames when rendering with 60fps)
- Resizing the Minecraft Window does not update the Rendering Gui - Resizing the Minecraft Window does not update the Rendering Gui
### Troubleshooting [troubleshooting]
> If you have trouble with rendering, please first consult the Documentation before asking for help in the Forums.
#### No FFmpeg installation found [ffmpeg]
![](img/ffmpeg-missing.jpg)
The error screen that is displayed when no FFmpeg installation could be found
If the **Replay Mod** tells you to install FFmpeg even though you already have, you have to manually tell the **Replay Mod** where your FFmpeg executable is located.
First, get the full path to your `ffmpeg.exe` (on Windows) or `ffmpeg` executable (on Mac/Linux).
On Windows, this path might look like `C:/ffmpeg/ffmpeg.exe`.
Then, open the **"Command Line Settings" Tab** in the Render Settings and paste this path into the **left input field** and retry rendering.
#### Crash while rendering [crash]
If Minecraft crashes after a few frames of rendering, it most likely means the **FFmpeg** didn't like the **Command Line Arguments** you passed.
If you customized the Command Line Arguments manually, re-check them - it's probably your own fault.
> **Hint:** In your .minecraft folder, you'll find a file called `export.log` which contains information about FFmpeg's rendering process.
If you did **not** customize the **Command Line Arguments**, you might have entered some insanely high (or low) values e.g. for Bitrate or Video Resolution. Try again with other, more reasonable values.
## Ambient Lighting [lighting] ## Ambient Lighting [lighting]
![](img/ambient-lighting-comparison.jpg) ![](img/ambient-lighting-comparison.jpg)
The same setting, onace with **Ambient Lighting** enabled, once with **Ambient Lighting** disabled The same setting, onace with **Ambient Lighting** enabled, once with **Ambient Lighting** disabled
@@ -522,6 +465,14 @@ If you have a Replay in a dark setting (for example at nighttime, or in a cave)
This works as a replacement for the **Night Vision Potion Effect**, without the side effect of a weird sky color. This works as a replacement for the **Night Vision Potion Effect**, without the side effect of a weird sky color.
## Quick Mode [quickmode]
![](img/quickmode-icon.jpg)
In **Quick Mode**, this clock symbol is displayed in the lower right corner of the screen.
When you first enable **Quick Mode** in a replay, an internal reference of certain entity and block properties is stored for quick access, allowing for faster navigation in the **Replay Timeline**.
As a side effect, certain features like particles and second skin layers will not be rendered in the preview.
By default, **Quick Mode** is toggled with `Q`.
## Player Overview [overview] ## Player Overview [overview]
![](img/player-overview.jpg) ![](img/player-overview.jpg)
The **Player Overview** Screen The **Player Overview** Screen
@@ -532,7 +483,7 @@ By clicking on a player's **Name or Head**, you can **spectate** this player.
Next to each player, there's a **checkbox** using which you can toggle the player's **visibility**. Next to each player, there's a **checkbox** using which you can toggle the player's **visibility**.
This way, you can hide certain players from the Replay. This way, you can hide certain players from the Replay.
Above the individual checkboxes, there are two checkbox buttons - one to **hide all players** and one to **show all players**. Below the individual checkboxes, there are two checkbox buttons - one to **hide all players** and one to **show all players**.
If you want to **save the player visibility settings**, check **"Remember Hidden Players" checkbox**. If you want to **save the player visibility settings**, check **"Remember Hidden Players" checkbox**.
If checked, invisible players will stay invisible after closing the Replay (this can of course be reverted), If checked, invisible players will stay invisible after closing the Replay (this can of course be reverted),
@@ -545,11 +496,9 @@ The **Default Thumbnail** which is used if no Thumbnail was created
While in a Replay, you can use the `N` key to create a **Thumbnail** of the current Replay. While in a Replay, you can use the `N` key to create a **Thumbnail** of the current Replay.
A **Thumbnail** is a Screenshot which should give the viewer a good impression of your Replay's content. A **Thumbnail** is a Screenshot which should give the viewer a good impression of your Replay's content.
**Thumbnails** are important when uploading a Replay to the **Replay Center**, **Thumbnails** help keeping your **Replay Viewer** clear and structured.
as other users are much more likely to download your Replay if they can see a preview of it.
They also help keeping your **Replay Viewer** clear and structured.
If no **Thumbnail** is set for a Replay, the **Default Thumbnail** will be displayed in the **Replay Viewer** and in the **Replay Center**. If no **Thumbnail** is set for a Replay, the **Default Thumbnail** will be displayed in the **Replay Viewer**.
## Event Markers [markers] ## Event Markers [markers]
![](img/marker-timeline.jpg) ![](img/marker-timeline.jpg)
@@ -572,84 +521,8 @@ This way, it's even simpler to add structure to your Replays.
You can **delete an Event Marker** by clicking it once to select it and then pressing the `DELETE` key. You can **delete an Event Marker** by clicking it once to select it and then pressing the `DELETE` key.
# Replay Center [center]
The **Replay Center** is where you can **share** your **Minecraft Moments** with others and discover awesome **Replays by other Users**.
To be able to use the **Replay Center**, you need an **account on ReplayMod.com**.
## Authentication [auth]
![](img/auth-login.jpg)
The **Login Screen** which is displayed upon startup
![](img/auth-register.jpg)
The **Register Screen**
When starting Minecraft with the **Replay Mod** installed, you will be asked to login to **ReplayMod.com**.
If you don't want to use the **Replay Center**, you can click the **"Skip" Button** to continue without logging in.
If you want to browse other users' **Replays** and **share your own Replays** however, you need to **Register an account**.
> **Note:** By registering an Account on **ReplayMod.com**, you agree to the Website's [Terms of Service](https://www.replaymod.com/legal/terms)
Please note that you can only create **one ReplayMod.com Account per Minecraft Account**, so choose your username wisely.
Once you've registered, you're automatically going to be logged in. The Mod **remembers your login** until you manually log out from the **Replay Center**, so it won't ask you upon every startup if you logged in once.
## Replay Files [files]
![](img/replay-center.jpg)
The **Replay Center** in the Mod
Once you've logged in, you can use the **"Replay Center" Button** in the Main Menu to access the **Replay Center**.
In the upper half of the screen, there are **5 Buttons** for **5 Tabs** of the **Replay Center**:
- **Recent**
Shows the most recently uploaded Replays in the **Replay Center**
- **Best**
Shows the Replays with the **best rating and most downloads**
- **Downloaded**
Shows all of the Replays you've downloaded locally
- **Favorited**
Shows all of the Replays you favorited
- **Search**
Allows you to search for specific Replays
When you've found an insteresting looking Replay, you can download it using the **"Download" Button** in the lower left corner.
After downloading, you'll automatically join the Replay.
After you've downloaded a Replay, you can rate and favorite it in the **Replay Center** using the respective buttons.
> You are encouraged to rate Replays after you downloaded them to help promoting the best Replays.
## Upload Replays [upload]
![](img/replay-upload.jpg)
The **Replay Upload Screen**
You can share your own **Replay Files** with other users in the **Replay Center**.
Therefore, click the **"Upload" Button** in the **Replay Viewer** after selecting a Replay.
In the **Replay Upload Screen** there are **6 input fields**:
- **Replay Name**
The Replay's Name in the Replay Center
- **Replay Description**
A description of what happens in the Replay. Try to give the user a good impression why your Replay is worth downloading.
- **Category**
The Replay's Category, one of the following: **Survival**, **Build**, **Minigame**, **Miscellaneous**. If none of the other categories fit, use **Miscellaneous**.
- **Tags**
One or more tags that fit your replay, spearated by comma. **Example tags:** pvp,battle,redstone,creative
- **Hide Server IP**
If you've recorded a Replay on a private Server, you can remove the Server IP by checking the respective checkbox.
- **Thumbnail**
While you can't directly edit the Thumbnail when uploading, it is highly recommended that
you [create a Thumbnail](#replaying-thumbnail) before sharing your Replay.
Replays without a Thumbnail are much less likely to be downloaded by other users.
When uploading a Replay File, make sure to follow the [Replay Center Rules](https://www.replaymod.com/rules).
# Frequently Asked Questions [faq] # Frequently Asked Questions [faq]
### Do I need a ReplayMod.com Account to use the mod?
You only need a ReplayMod.com Account to access the [Replay Center](#center).
All of the other features are also available offline.
### For how long can I record? ### For how long can I record?
Theoretically, a Replay File can be up to **24 days, 20 hours, 30 minutes and 23 seconds** long - which is a timespan you'll probably never reach. Theoretically, a Replay File can be up to **24 days, 20 hours, 30 minutes and 23 seconds** long - which is a timespan you'll probably never reach.
@@ -672,3 +545,113 @@ A Replay in which you travelled around and discovered a lot of terrain is signif
An average Replay File of **10 Minutes duration** usually is between **2MB and 10MB large**. An average Replay File of **10 Minutes duration** usually is between **2MB and 10MB large**.
Replays recorded on **Minigame Servers** with lots of particle effects and world changes might be larger. Replays recorded on **Minigame Servers** with lots of particle effects and world changes might be larger.
# Troubleshooting [troubleshooting]
> If you have trouble with rendering, please first consult the Documentation before asking for help in the Discord.
## No FFmpeg installation found [ffmpeg]
![](img/ffmpeg-missing.jpg)
The error screen that is displayed when no FFmpeg installation could be found
If you have not installed FFmpeg, please follow the steps provided [here](#installing-ffmpeg)
If already have installed FFmpeg, you have to manually tell the **Replay Mod** where your FFmpeg executable is located.
First, get the full path to your `ffmpeg.exe` (on Windows) or `ffmpeg` executable (on Mac/Linux).
On Windows, this path might look like `C:\ffmpeg\ffmpeg.exe`.
Then, open the **"Command Line Settings" Section** in the Render Settings and paste this path into the **left input field** and retry rendering.
## Crash while rendering [crash]
If Minecraft crashes after a few frames of rendering, it most likely means the **FFmpeg** didn't like the **Command Line Arguments** you passed.
If you customized the Command Line Arguments manually, re-check them - it's probably your own fault.
> **Hint:** In your .minecraft folder, you'll find a file called `export.log` which contains information about FFmpeg's rendering process.
- If you did **not** customize the **Command Line Arguments**, you might have entered some insanely high (or low) values e.g. for Bitrate or Video Resolution. Try again with other, more reasonable values.
- Make sure the camera doesn't move below Y=0 or above Y=255
## Unsupported Launchers [launchers]
_Future Client_ is not compatible with the Mixin required by ReplayMod.
_Lunar Client_ does not support ReplayMod.
_Badlion Client_ offers a different ReplayMod that is not the same as this one.
## Compatibility with other Mods [compatibility]
### General information [general]
In General, the Replay Mod _should_ be compatible with most Forge and Fabric Mods.
### Shaders Mod [shaders]
_Karyonix' Shaders Mod_ is no longer compatible with Minecraft Forge starting with 1.9.4. As such it is not compatible with the Replay Mod either.
Below Minecraft 1.16 you can try _Optifine_ instead. Note however, that official support has ended and many versions break ReplayMod.
On Minecraft 1.16.5 and up you can use _Iris_, which is fully supported. For the time being, you will have to use it with the custom _Sodium_ provided on our download page. The fix it includes is pending for the official version.
### Custom Main Menu [custom-main-menu]
The _Custom Main Menu_ mod is often used in mod packs to customize their Main Menu with a button layout fitting the background image, links to their website / bug tracker and similar.
If you are familiar with it, the button id for the Replay Mod is: **17890234** (text: `replaymod.gui.replayviewer`).
Due to the nature of this Custom Main Menu mod, buttons added to the Main Menu by 3rd party mods like the **Replay Mod** will not show up by default.
Thus, to access the Replay Viewer/Editor/Center, you need to manually configure the position for those buttons.
To do so, you need to modify the Custom Main Menu configuration file.
Usually, you can find it at `.minecraft/config/CustomMainMenu/mainmenu.json` (if you're using a mod pack launcher, it normally has its own .minecraft folder).
For an explanation of this config file, have a look at Custom Main Menu's page.
You can find a list of already modified config files [here](https://gist.github.com/Johni0702/3f3fab81dbf7ada83d045d9fe8f345aa).
### Tickrate Changer [tickrate-changer]
The _Tickrate Changer_ mod may cause minecraft to freeze when you try to use the Replay Viewer UI.
### LabyMod [labymod]
_LabyMod_ v3.7.x has been reported to be compatible with ReplayMod and other Forge mods.
Lower versions are not compatible.
### OldAnimationsMod [oldanimationsmod]
In case your Minecraft crashes when you are using both ReplayMod and _OldAnimationsMod_, try removing OldAnimationsMod.
### Orange's 1.7 Animations [17animations]
If you use ReplayMod with shaders and _1.7 Animations_ you may see floating water and glass. Remove 1.7 Animations to resolve this.
### Sk1er Club: Patcher [patcher]
We have seen reports of crashes that were related to _Patcher_; in case of crashes try removing Patcher.
### Baritone [baritone]
The _Baritone_ mod can cause a crash when you're trying to load a replay. If you experience such problems, try running without Baritone.
### RandomPatches [randompatches]
Minecraft may crash if you try to use _RandomPatches_ together with ReplayMod. Try removing RandomPatches if Minecraft crashes on startup.
### Sodium [sodium]
ReplayMod can record when _Sodium_ is installed, but currently lacks the FREX Flawless Frames API to render. A modified build of _Sodium_, that supports this API, is available from the ReplayMod downloads, by clicking the `Click to show compatible Sodium versions` button.
### Resource Loader [resourceloader]
The _Resource Loader_ mod is not compatible with ReplayMod.
### LiteLoader [liteloader]
![](img/mutlimc-liteloader.jpg)
The MultiMC interface to place ReplayMod above LiteLoader.
![](img/multimc-addempty.jpg)
The properties for the new *Empty*.
_LiteLoader_ is known to cause issues due to the mixin version it contains.
You can use MultiMC to workaround this problem.
> The MultiMC `Edit` function requires that your computer has a default editor for json files associated.
1: Create your instance then edit the instance
2: Click `Install Forge`
3: Click `Install LiteLoader`
4: Click `Add Empty`; use `ReplayMod` as name and `com.replaymod` as uid
5: Select the new *ReplayMod* and click `Edit`
6: Replace the contents with one of the below snippets
7: Save and close the text editor
8: Move *ReplayMod* up until it is **above** *LiteLoader*
9: Remove the ReplayMod jar from the mods folder if you installed it previously.
** Snippet for 1.8.9 **
`{ "formatVersion": 1, "name": "ReplayMod", "uid": "com.replaymod", "version": "1.8.9-2.4.5", "libraries": [{ "name": "com.replaymod:replaymod:1.8.9-2.4.5", "MMC-absoluteUrl": "https://minio.replaymod.com/replaymod/replaymod-1.8.9-2.4.5.jar" }]}`
** Snippet for 1.12.2 **
`{ "formatVersion": 1, "name": "ReplayMod", "uid": "com.replaymod", "version": "1.12.2-2.4.5", "libraries": [{ "name": "com.replaymod:replaymod:1.12.2-2.4.5", "MMC-absoluteUrl": "https://minio.replaymod.com/replaymod/replaymod-1.12.2-2.4.5.jar" }]}`

Binary file not shown.

After

Width:  |  Height:  |  Size: 573 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 181 KiB

After

Width:  |  Height:  |  Size: 299 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 KiB

After

Width:  |  Height:  |  Size: 147 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 181 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 149 KiB

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 430 KiB

After

Width:  |  Height:  |  Size: 439 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

BIN
docs/img/quickmode-icon.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
docs/img/quickmode-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 598 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 KiB

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 255 KiB

23
docs/package-lock.json generated Normal file
View File

@@ -0,0 +1,23 @@
{
"name": "replaymod-docs",
"version": "0.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"array-findindex-polyfill": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/array-findindex-polyfill/-/array-findindex-polyfill-0.1.0.tgz",
"integrity": "sha1-w2JmW+x2RfItejw6rJeT9xw2Iu8="
},
"md-jml": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/md-jml/-/md-jml-2.0.1.tgz",
"integrity": "sha1-th99rTm1JPVKCmpthnMcTRLOCDo="
},
"string.prototype.endswith": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/string.prototype.endswith/-/string.prototype.endswith-0.2.0.tgz",
"integrity": "sha1-oZwg3uUamHd+mkfhDwm+OTubunU="
}
}
}

10
gradle.properties Normal file
View File

@@ -0,0 +1,10 @@
essential.defaults.loom=0
essential.defaults.loom.fabric-loader=net.fabricmc:fabric-loader:0.18.5
# Sets default memory used for gradle commands. Can be overridden by user or command line properties.
# This is required to provide enough memory for the Minecraft decompilation process.
org.gradle.jvmargs=-Xmx8G
org.gradle.parallel=true
org.gradle.configureondemand=true
loom.ignoreDependencyLoomVersionValidation=true

Binary file not shown.

View File

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

126
gradlew vendored
View File

@@ -1,4 +1,20 @@
#!/usr/bin/env bash #!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
############################################################################## ##############################################################################
## ##
@@ -6,47 +22,6 @@
## ##
############################################################################## ##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
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 # Attempt to set APP_HOME
# Resolve links: $0 may be a link # Resolve links: $0 may be a link
PRG="$0" PRG="$0"
@@ -61,9 +36,49 @@ while [ -h "$PRG" ] ; do
fi fi
done done
SAVED="`pwd`" SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >&- cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`" APP_HOME="`pwd -P`"
cd "$SAVED" >&- cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
@@ -90,7 +105,7 @@ location of your Java installation."
fi fi
# Increase the maximum file descriptors if we can. # Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n` MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
@@ -114,6 +129,7 @@ fi
if $cygwin ; then if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"` APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath # We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
@@ -154,11 +170,19 @@ if $cygwin ; then
esac esac
fi fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules # Escape application args
function splitJvmOpts() { save () {
JVM_OPTS=("$@") for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
} }
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS APP_ARGS=$(save "$@")
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" # Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"

30
gradlew.bat vendored
View File

@@ -1,3 +1,19 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem http://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off @if "%DEBUG%" == "" @echo off
@rem ########################################################################## @rem ##########################################################################
@rem @rem
@@ -8,14 +24,14 @@
@rem Set local scope for the variables with windows NT shell @rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0 set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=. if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0 set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME% set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe @rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome if defined JAVA_HOME goto findJavaFromJavaHome
@@ -46,10 +62,9 @@ echo location of your Java installation.
goto fail goto fail
:init :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 not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args :win9xME_args
@rem Slurp the command line arguments. @rem Slurp the command line arguments.
@@ -60,11 +75,6 @@ set _SKIP=2
if "x%~1" == "x" goto execute if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%* set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute :execute
@rem Setup the command line @rem Setup the command line

2
jGui

Submodule jGui updated: 5c0ca7d7d8...b0e068383c

1
libs/ReplayStudio Submodule

Submodule libs/ReplayStudio added at ca00f8101b

288
root.gradle.kts Executable file
View File

@@ -0,0 +1,288 @@
import groovy.json.JsonOutput
import java.io.ByteArrayOutputStream
import org.gradle.kotlin.dsl.support.serviceOf
import org.gradle.process.ExecOperations
plugins {
id("gg.essential.multi-version.root")
id("gg.essential.loom") version "1.15.48" apply false
kotlin("jvm") version "2.3.20" apply false
id("com.github.hierynomus.license") version "0.15.0"
}
val latestVersion = file("version.txt").readLines().first()
var releaseCommit = providers.exec {
commandLine("git", "blame", "-p", "-l", "version.txt")
}.standardOutput.asText.map { it.trim().split("/n").first().split(" ").first() }.get()
if (latestVersion == "2.1.0") { // First version since change from tag-based
releaseCommit = "35ac26e91689ac9bdf12dbb9902c452464a75108" // git rev-parse 1.12.2-2.1.0
}
val currentCommit = providers.exec {
commandLine("git", "rev-parse", "HEAD")
}.standardOutput.asText.map { it.trim().split("/n").first() }.get()
if (releaseCommit == currentCommit) {
version = latestVersion
} else {
val diff = providers.exec {
commandLine("git", "log", "--format=oneline", "$releaseCommit..$currentCommit")
}.standardOutput.asText.map { it.trim().split("/n").size }.get()
version = "$latestVersion-$diff-g${currentCommit.substring(0, 7)}"
}
val dirty = providers.exec {
commandLine("git", "describe", "--always", "--dirty=*")
}.standardOutput.asText.map { it.trim().endsWith("*") }.get()
if (dirty) {
version = "$version-dirty"
}
group = "com.replaymod"
val bundleJar by tasks.registering(Copy::class) {
into("$buildDir/libs")
}
subprojects {
buildscript {
repositories {
maven("https://jitpack.io")
}
}
if (name == "jGui" || name == "ReplayStudio") {
return@subprojects
}
val (major, minor, patch) = name.split("-")[0].split(".") + listOf("0")
val mcVersion = major.toInt() * 10000 + minor.toInt() * 100 + patch.toInt()
val fabric = mcVersion >= 1_14_00 && !name.endsWith("-forge")
extra.set("loom.platform", if (fabric) "fabric" else "forge")
afterEvaluate {
val projectBundleJar = project.tasks.findByName("bundleJar")
if (projectBundleJar != null && projectBundleJar.hasProperty("archivePath") && project.name != "core") {
bundleJar.configure {
dependsOn(projectBundleJar)
from(projectBundleJar.withGroovyBuilder { getProperty("archivePath") })
}
}
}
}
fun ExecOperations.command(vararg cmd: String): List<String> {
val stdout = ByteArrayOutputStream()
exec {
commandLine(*cmd)
standardOutput = stdout
}
return stdout.toString().trim().split("\n")
}
fun generateVersionsJson(execOps: ExecOperations): Map<String, Any> {
fun command(vararg cmd: String): List<String> =
execOps.command(*cmd)
val versionComparator = compareBy<String>(
{ (it.split(".").getOrNull(0) ?: "0").toInt() },
{ (it.split(".").getOrNull(1) ?: "0").toInt() },
{ (it.split(".").getOrNull(2) ?: "0").toInt() }
)
// Find all tag-style releases by listing all tags
val tagVersions = command("git", "for-each-ref", "--sort=taggerdate", "--format=%(refname:short)", "refs/tags")
// Find all commit-style releases
// List all commits
val releaseCommits =
command("git", "log", "--format=%H", "--date-order", "-E",
"--grep", "Pre-release [0-9]+ of [0-9]+\\.[0-9]+\\.[0-9]+",
"--grep", "Release [0-9]+\\.[0-9]+\\.[0-9]+")
// Find version string and MC versions for each commit hash
val commitVersions = releaseCommits.map { commit ->
val version = command("git", "show", "$commit:version.txt").first()
val mcVersions = command("git", "ls-tree", "-d", "--name-only", "$commit:versions")
// In the past (early days of preprocessor) we used to have an internal "core" project
.filter { it != "core" }
// Internal project used to automatically remap from Forge 1.12.2 to Fabric 1.14.4
.filter { it != "1.14.4-forge" }
// We dropped 1.8 with the switch to archloom but still kept its source in case someone
// volunteers to make it build again
.filterNot { it == "1.8" && versionComparator.compare(version, "2.6.16") >= 0 }
// We dropped 1.7.10 with the Gradle 7 update but still kept its source in case someone
// volunteers to ~~update FG 1.2 to Gradle 7~~ make it work with archloom.
.filterNot { it == "1.7.10" && versionComparator.compare(version, "2.6.0") >= 0 }
val versions = mcVersions.map { "$it-$version" }.toMutableList()
when (version) {
"2.6.7" -> versions.add("1.19.1-2.6.7") // forgot to add the .gitkeep file before merging
}
versions
}.flatten()
val versions = commitVersions + tagVersions.reversed()
val mcVersions = versions
.map {it.substring(0, it.indexOf("-"))}
.distinct()
.sortedWith(versionComparator)
val promos = mutableMapOf<String, String>()
val root = mutableMapOf<String, Any>(
"homepage" to "https://www.replaymod.com/download/",
"promos" to promos
)
mcVersions.forEach { mcVersion ->
var mcVersionRoot = mutableMapOf<String, String>()
var latest: String? = null
var recommended: String? = null
versions.forEach {
val (thisMcVersion, modVersion, preVersion) = it.split("-") + listOf(null, null)
if (thisMcVersion == mcVersion) {
mcVersionRoot[it] = "See https://www.replaymod.com/changelog.txt"
if (latest == null) latest = it
if (preVersion == null) {
if (recommended == null) recommended = it
}
}
}
root[mcVersion] = mcVersionRoot
promos[mcVersion + "-latest"] = latest!!
if (recommended != null) {
promos[mcVersion + "-recommended"] = recommended!!
}
}
return root
}
val writeVersionsJson by tasks.registering {
val execOps = project.serviceOf<ExecOperations>()
doLast {
val versionsRoot = generateVersionsJson(execOps)
val versionsJson = JsonOutput.prettyPrint(JsonOutput.toJson(versionsRoot))
File("versions.json").writeText(versionsJson)
}
}
val doRelease by tasks.registering {
val execOps = project.serviceOf<ExecOperations>()
doLast {
fun command(vararg cmd: String): List<String> =
execOps.command(*cmd)
// Parse version
val version = project.extra["releaseVersion"] as String
if (command("git", "describe", "--always", "--dirty=*").first().endsWith("*")) {
throw InvalidUserDataException("Git working tree is dirty. Make sure to commit all changes.")
}
val (modVersion, preVersion) = if ("-b" in version) {
version.split("-b")
} else {
listOf(version, null)
}
// Merge release branch into stable but do not yet commit (we need to update the version.txt first)
command("git", "checkout", "stable")
command("git", "merge", "--no-ff", "--no-commit", "release-$version")
// Update version.txt
file("version.txt").writeText("$version\n")
command("git", "add", "version.txt")
// Finallize the merge. The message is what is later used to identify releses for building the version.json tree
val commitMessage = if (preVersion != null)
"Pre-release $preVersion of $modVersion"
else
"Release $modVersion"
command("git", "commit", "-m", commitMessage)
// Generate versions.json content
val versionsRoot = generateVersionsJson(execOps)
val versionsJson = JsonOutput.prettyPrint(JsonOutput.toJson(versionsRoot))
// Switch to master branch to update versions.json
command("git", "checkout", "master")
// Write versions.json
File("versions.json").writeText(versionsJson)
// Commit changes
command("git", "add", "versions.json")
command("git", "commit", "-m", "Update versions.json for $version")
// Return to previous branch
command("git", "checkout", "-")
}
}
defaultTasks("bundleJar")
preprocess {
strictExtraMappings.set(true)
val mc26_01_00 = createNode("26.1", 26_01_00, "yarn")
val mc12111 = createNode("1.21.11", 12111, "yarn")
val mc12110 = createNode("1.21.10", 12110, "yarn")
val mc12107 = createNode("1.21.7", 12107, "yarn")
val mc12105 = createNode("1.21.5", 12105, "yarn")
val mc12104 = createNode("1.21.4", 12104, "yarn")
val mc12102 = createNode("1.21.2", 12102, "yarn")
val mc12100 = createNode("1.21", 12100, "yarn")
val mc12006 = createNode("1.20.6", 12006, "yarn")
val mc12004 = createNode("1.20.4", 12004, "yarn")
val mc12002 = createNode("1.20.2", 12002, "yarn")
val mc12001 = createNode("1.20.1", 12001, "yarn")
val mc11904 = createNode("1.19.4", 11904, "yarn")
val mc11903 = createNode("1.19.3", 11903, "yarn")
val mc11902 = createNode("1.19.2", 11902, "yarn")
val mc11901 = createNode("1.19.1", 11901, "yarn")
val mc11900 = createNode("1.19", 11900, "yarn")
val mc11802 = createNode("1.18.2", 11802, "yarn")
val mc11801 = createNode("1.18.1", 11801, "yarn")
val mc11701 = createNode("1.17.1", 11701, "yarn")
val mc11604 = createNode("1.16.4", 11604, "yarn")
val mc11601 = createNode("1.16.1", 11601, "yarn")
val mc11502 = createNode("1.15.2", 11502, "yarn")
val mc11404 = createNode("1.14.4", 11404, "yarn")
val mc11404Forge = createNode("1.14.4-forge", 11404, "srg")
val mc11202 = createNode("1.12.2", 11202, "srg")
val mc11201 = createNode("1.12.1", 11201, "srg")
val mc11200 = createNode("1.12", 11200, "srg")
val mc11102 = createNode("1.11.2", 11102, "srg")
val mc11100 = createNode("1.11", 11100, "srg")
val mc11002 = createNode("1.10.2", 11002, "srg")
val mc10904 = createNode("1.9.4", 10904, "srg")
val mc10809 = createNode("1.8.9", 10809, "srg")
val mc10800 = createNode("1.8", 10800, "srg")
val mc10710 = createNode("1.7.10", 10710, "srg")
mc26_01_00.link(mc12111, file("versions/mapping-fabric-26.1-1.21.11.txt"))
mc12111.link(mc12110, file("versions/mapping-fabric-1.21.11-1.21.10.txt"))
mc12110.link(mc12107, file("versions/mapping-fabric-1.21.10-1.21.7.txt"))
mc12107.link(mc12105)
mc12105.link(mc12104, file("versions/mapping-fabric-1.21.5-1.21.4.txt"))
mc12104.link(mc12102)
mc12102.link(mc12100)
mc12100.link(mc12006)
mc12006.link(mc12004)
mc12004.link(mc12002, file("versions/mapping-fabric-1.20.4-1.20.2.txt"))
mc12002.link(mc12001)
mc12001.link(mc11904, file("versions/mapping-fabric-1.20.1-1.19.4.txt"))
mc11904.link(mc11903, file("versions/mapping-fabric-1.19.4-1.19.3.txt"))
mc11903.link(mc11902, file("versions/mapping-fabric-1.19.3-1.19.2.txt"))
mc11902.link(mc11901)
mc11901.link(mc11900)
mc11900.link(mc11802)
mc11802.link(mc11801)
mc11801.link(mc11701, file("versions/mapping-fabric-1.18.1-1.17.1.txt"))
mc11701.link(mc11604, file("versions/mapping-fabric-1.17.1-1.16.4.txt"))
mc11604.link(mc11601)
mc11601.link(mc11502)
mc11502.link(mc11404, file("versions/mapping-fabric-1.15.2-1.14.4.txt"))
mc11404.link(mc11404Forge)
mc11404Forge.link(mc11202, file("versions/mapping-forge-1.14.4-1.12.2.txt"))
mc11202.link(mc11201)
mc11201.link(mc11200)
mc11200.link(mc11102)
mc11102.link(mc11100)
mc11100.link(mc11002)
mc11002.link(mc10904)
mc10904.link(mc10809, file("versions/mapping-forge-1.9.4-1.8.9.txt"))
mc10809.link(mc10800, file("versions/mapping-forge-1.8.9-1.8.txt"))
mc10800.link(mc10710, file("versions/mapping-forge-1.8-1.7.10.txt"))
}

View File

@@ -1 +0,0 @@
include 'ReplayStudio'

112
settings.gradle.kts Normal file
View File

@@ -0,0 +1,112 @@
pluginManagement {
repositories {
mavenLocal()
gradlePluginPortal()
mavenCentral()
google()
maven("https://jitpack.io")
maven("https://maven.fabricmc.net")
maven("https://maven.architectury.dev/")
maven("https://maven.minecraftforge.net")
maven("https://repo.essential.gg/repository/maven-public")
}
plugins {
id("gg.essential.multi-version.root") version "0.7.0-alpha.4"
id("com.gradleup.shadow") version "9.4.1"
}
}
val jGuiVersions = listOf(
// "1.7.10",
// "1.8",
"1.8.9",
"1.9.4",
"1.12",
"1.14.4-forge",
"1.14.4",
"1.15.2",
"1.16.1",
"1.16.4",
"1.17.1",
"1.18.1",
"1.18.2",
"1.19",
"1.19.1",
"1.19.2",
"1.19.3",
"1.19.4",
"1.20.1",
"1.20.2",
"1.20.4",
"1.20.6",
"1.21",
"1.21.2",
"1.21.4",
"1.21.5",
"1.21.7",
"1.21.10",
"1.21.11",
"26.1",
)
val replayModVersions = listOf(
// "1.7.10",
// "1.8",
"1.8.9",
"1.9.4",
"1.10.2",
"1.11",
"1.11.2",
"1.12",
"1.12.1",
"1.12.2",
"1.14.4-forge",
"1.14.4",
"1.15.2",
"1.16.1",
"1.16.4",
"1.17.1",
"1.18.1",
"1.18.2",
"1.19",
"1.19.1",
"1.19.2",
"1.19.3",
"1.19.4",
"1.20.1",
"1.20.2",
"1.20.4",
"1.20.6",
"1.21",
"1.21.2",
"1.21.4",
"1.21.5",
"1.21.7",
"1.21.10",
"1.21.11",
"26.1",
)
rootProject.buildFileName = "root.gradle.kts"
includeBuild("libs/ReplayStudio")
include(":jGui")
project(":jGui").apply {
projectDir = file("jGui")
buildFileName = "root.gradle.kts"
}
jGuiVersions.forEach { version ->
include(":jGui:$version")
project(":jGui:$version").apply {
projectDir = file("jGui/versions/$version")
buildFileName = "../../build.gradle.kts"
}
}
replayModVersions.forEach { version ->
include(":$version")
project(":$version").apply {
projectDir = file("versions/$version")
buildFileName = "../../build.gradle.kts"
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,25 +1,37 @@
package com.replaymod.compat; package com.replaymod.compat;
import com.replaymod.compat.optifine.DisableFastRender; import com.replaymod.compat.optifine.DisableFastRender;
import com.replaymod.core.Module;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
//#if MC<11400
//$$ import com.replaymod.compat.oranges17animations.HideInvisibleEntities;
//#endif
//#if MC<11400
//$$ import com.replaymod.compat.bettersprinting.DisableBetterSprinting;
//#endif
//#if MC>=10800
import com.replaymod.compat.shaders.ShaderBeginRender; import com.replaymod.compat.shaders.ShaderBeginRender;
import com.replaymod.core.ReplayMod; //#endif
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.eventhandler.EventBus;
@Mod(modid = ReplayModCompat.MOD_ID, useMetadata = true) public class ReplayModCompat implements Module {
public class ReplayModCompat { public static Logger LOGGER = LogManager.getLogger();
public static final String MOD_ID = "replaymod-compat";
@Mod.Instance(ReplayMod.MOD_ID) @Override
private static ReplayMod core; public void initClient() {
//#if MC>=10800
@Mod.EventHandler new ShaderBeginRender().register();
public void init(FMLInitializationEvent event) { //#endif
EventBus bus = MinecraftForge.EVENT_BUS; new DisableFastRender().register();
bus.register(new ShaderBeginRender()); //#if MC<11400
bus.register(new DisableFastRender()); //$$ new HideInvisibleEntities().register();
//#endif
//#if MC<11400
//$$ DisableBetterSprinting.register();
//#endif
} }
} }

View File

@@ -0,0 +1 @@
// 1.12.2 and below

View File

@@ -0,0 +1 @@
// 1.12.2 and below

View File

@@ -1,34 +1,34 @@
package com.replaymod.compat.optifine; package com.replaymod.compat.optifine;
import com.replaymod.render.events.ReplayRenderEvent; import de.johni0702.minecraft.gui.utils.EventRegistrations;
import net.minecraft.client.Minecraft; import com.replaymod.core.versions.MCVer;
import net.minecraftforge.fml.client.FMLClientHandler; import com.replaymod.render.events.ReplayRenderCallback;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraft.client.MinecraftClient;
public class DisableFastRender { public class DisableFastRender extends EventRegistrations {
private final Minecraft mc = Minecraft.getMinecraft(); private final MinecraftClient mc = MinecraftClient.getInstance();
private boolean wasFastRender = false; private boolean wasFastRender = false;
@SubscribeEvent { on(ReplayRenderCallback.Pre.EVENT, renderer -> onRenderBegin()); }
public void onRenderBegin(ReplayRenderEvent.Pre event) { private void onRenderBegin() {
if (!FMLClientHandler.instance().hasOptifine()) return; if (!MCVer.hasOptifine()) return;
try { try {
wasFastRender = (boolean) OptifineReflection.gameSettings_ofFastRender.get(mc.gameSettings); wasFastRender = (boolean) OptifineReflection.gameSettings_ofFastRender.get(mc.options);
OptifineReflection.gameSettings_ofFastRender.set(mc.gameSettings, false); OptifineReflection.gameSettings_ofFastRender.set(mc.options, false);
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
@SubscribeEvent { on(ReplayRenderCallback.Post.EVENT, renderer -> onRenderEnd()); }
public void onRenderEnd(ReplayRenderEvent.Post event){ private void onRenderEnd() {
if (!FMLClientHandler.instance().hasOptifine()) return; if (!MCVer.hasOptifine()) return;
try { try {
OptifineReflection.gameSettings_ofFastRender.set(mc.gameSettings, wasFastRender); OptifineReflection.gameSettings_ofFastRender.set(mc.options, wasFastRender);
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
e.printStackTrace(); e.printStackTrace();
} }

View File

@@ -1,8 +1,9 @@
package com.replaymod.compat.optifine; package com.replaymod.compat.optifine;
import net.minecraft.client.settings.GameSettings; import net.minecraft.client.options.GameOptions;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
public class OptifineReflection { public class OptifineReflection {
@@ -14,7 +15,7 @@ public class OptifineReflection {
// this throws an ignored ClassNotFoundException if Optifine isn't installed // this throws an ignored ClassNotFoundException if Optifine isn't installed
Class.forName("Config"); Class.forName("Config");
gameSettings_ofFastRender = GameSettings.class.getDeclaredField("ofFastRender"); gameSettings_ofFastRender = GameOptions.class.getDeclaredField("ofFastRender");
gameSettings_ofFastRender.setAccessible(true); gameSettings_ofFastRender.setAccessible(true);
} catch (ClassNotFoundException ignore) { } catch (ClassNotFoundException ignore) {
// no optifine installed // no optifine installed
@@ -24,4 +25,20 @@ public class OptifineReflection {
} }
} }
public static void reloadLang() {
try {
Class<?> langClass;
try {
langClass = Class.forName("Lang"); // Pre Optifine 1.12.2 E1
} catch (ClassNotFoundException ignore) {
langClass = Class.forName("net.optifine.Lang"); // Post Optifine 1.12.2 E1
}
langClass.getDeclaredMethod("resourcesReloaded").invoke(null);
} catch (ClassNotFoundException ignore) {
// no optifine installed
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
e.printStackTrace();
}
}
} }

View File

@@ -0,0 +1 @@
// 1.12.2 and below

View File

@@ -1,39 +1,44 @@
//#if MC>=10800
package com.replaymod.compat.shaders; package com.replaymod.compat.shaders;
import com.replaymod.core.events.PreRenderCallback;
import com.replaymod.render.hooks.EntityRendererHandler; import com.replaymod.render.hooks.EntityRendererHandler;
import net.minecraft.client.Minecraft; import de.johni0702.minecraft.gui.utils.EventRegistrations;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraft.client.MinecraftClient;
import net.minecraftforge.fml.common.gameevent.TickEvent;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
public class ShaderBeginRender { public class ShaderBeginRender extends EventRegistrations {
private final Minecraft mc = Minecraft.getMinecraft(); private final MinecraftClient mc = MinecraftClient.getInstance();
/** /**
* Invokes Shaders#beginRender when rendering a video, * Invokes Shaders#beginRender when rendering a video,
* as this would usually get called by EntityRenderer#renderWorld, * as this would usually get called by EntityRenderer#renderWorld,
* which we're not calling during rendering. * which we're not calling during rendering.
*/ */
@SubscribeEvent { on(PreRenderCallback.EVENT, this::onRenderTickStart); }
public void onRenderTickStart(TickEvent.RenderTickEvent event) { private void onRenderTickStart() {
if (event.phase != TickEvent.Phase.START) return;
if (ShaderReflection.shaders_beginRender == null) return; if (ShaderReflection.shaders_beginRender == null) return;
if (ShaderReflection.config_isShaders == null) return; if (ShaderReflection.config_isShaders == null) return;
try { try {
// check if video is being rendered // check if video is being rendered
if (((EntityRendererHandler.IEntityRenderer) mc.entityRenderer).replayModRender_getHandler() == null) if (((EntityRendererHandler.IEntityRenderer) mc.gameRenderer).replayModRender_getHandler() == null)
return; return;
// check if Shaders are enabled // check if Shaders are enabled
if (!(boolean) (ShaderReflection.config_isShaders.invoke(null))) return; if (!(boolean) (ShaderReflection.config_isShaders.invoke(null))) return;
ShaderReflection.shaders_beginRender.invoke(null, mc, mc.timer.elapsedPartialTicks, 0); ShaderReflection.shaders_beginRender.invoke(null, mc,
//#if MC>=11400
mc.gameRenderer.getCamera(),
//#endif
mc.getTickDelta(), 0);
} catch (IllegalAccessException | InvocationTargetException e) { } catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
} }
//#endif

View File

@@ -1,6 +1,11 @@
//#if MC>=10800
package com.replaymod.compat.shaders; package com.replaymod.compat.shaders;
import net.minecraft.client.Minecraft; import net.minecraft.client.MinecraftClient;
//#if MC>=11400
import net.minecraft.client.render.Camera;
//#endif
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
@@ -24,16 +29,23 @@ public class ShaderReflection {
static { static {
try { try {
shaders_frameTimeCounter = Class.forName("shadersmod.client.Shaders") Class<?> shadersClass;
.getDeclaredField("frameTimeCounter"); try {
shadersClass = Class.forName("shadersmod.client.Shaders"); // Pre Optifine 1.12.2 E1
} catch (ClassNotFoundException ignore) {
shadersClass = Class.forName("net.optifine.shaders.Shaders"); // Post Optifine 1.12.2 E1
}
shaders_frameTimeCounter = shadersClass.getDeclaredField("frameTimeCounter");
shaders_frameTimeCounter.setAccessible(true); shaders_frameTimeCounter.setAccessible(true);
shaders_isShadowPass = Class.forName("shadersmod.client.Shaders") shaders_isShadowPass = shadersClass.getDeclaredField("isShadowPass");
.getDeclaredField("isShadowPass");
shaders_isShadowPass.setAccessible(true); shaders_isShadowPass.setAccessible(true);
shaders_beginRender = Class.forName("shadersmod.client.Shaders") shaders_beginRender = shadersClass.getDeclaredMethod("beginRender", MinecraftClient.class,
.getDeclaredMethod("beginRender", Minecraft.class, float.class, long.class); //#if MC>=11400
Camera.class,
//#endif
float.class, long.class);
shaders_beginRender.setAccessible(true); shaders_beginRender.setAccessible(true);
renderGlobal_chunksToUpdateForced = Class.forName("net.minecraft.client.renderer.RenderGlobal") renderGlobal_chunksToUpdateForced = Class.forName("net.minecraft.client.renderer.RenderGlobal")
@@ -51,3 +63,4 @@ public class ShaderReflection {
} }
} }
} }
//#endif

View File

@@ -0,0 +1,32 @@
//#if MC>=11500
package com.replaymod.compat.shaders.mixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Pseudo;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Pseudo
@Mixin(targets = "net/optifine/render/ChunkVisibility", remap = false)
public abstract class MixinChunkVisibility {
@Shadow
private static int counter;
/**
* OF doesn't properly reset the counter when exiting a world.
* It'll only be reset when getMaxChunkY is called which only happens for
* SP worlds (i.e. not in a replay or MP).
* As a result, it may end up in a non-0 state, which will cause isFinished
* to unconditionally return false, therefore unconditionally setting
* needsTerrainUpdate to true on each call to WorldRenderer.setupTerrain,
* therefore unnecessarily consuming resources and live-locking when
* rendering the shader pass.
*/
@Inject(method = "reset", at = @At("HEAD"), remap = false)
private static void replayModCompat_fixImproperReset(CallbackInfo ci) {
MixinChunkVisibility.counter = 0;
}
}
//#endif

View File

@@ -1,18 +1,27 @@
//#if MC>=10800
package com.replaymod.compat.shaders.mixin; package com.replaymod.compat.shaders.mixin;
import com.replaymod.compat.shaders.ShaderReflection; import com.replaymod.compat.shaders.ShaderReflection;
import com.replaymod.replay.ReplayHandler; import com.replaymod.replay.ReplayHandler;
import com.replaymod.replay.ReplayModReplay; import com.replaymod.replay.ReplayModReplay;
import net.minecraft.client.renderer.EntityRenderer; import net.minecraft.client.render.GameRenderer;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(EntityRenderer.class) @Mixin(GameRenderer.class)
public abstract class MixinShaderEntityRenderer { public abstract class MixinShaderEntityRenderer {
@Inject(method = "renderWorldPass", at = @At("HEAD")) //#if MC>=11400
@Inject(method = "renderWorld", at = @At("HEAD"))
//#else
//#if MC>=11400
//$$ @Inject(method = "updateCameraAndRender(FJ)V", at = @At("HEAD"))
//#else
//$$ @Inject(method = "renderWorldPass", at = @At("HEAD"))
//#endif
//#endif
private void replayModCompat_updateShaderFrameTimeCounter(CallbackInfo ignore) { private void replayModCompat_updateShaderFrameTimeCounter(CallbackInfo ignore) {
if (ReplayModReplay.instance.getReplayHandler() == null) return; if (ReplayModReplay.instance.getReplayHandler() == null) return;
if (ShaderReflection.shaders_frameTimeCounter == null) return; if (ShaderReflection.shaders_frameTimeCounter == null) return;
@@ -26,3 +35,4 @@ public abstract class MixinShaderEntityRenderer {
} }
} }
} }
//#endif

View File

@@ -1,28 +1,71 @@
//#if MC>=10800 && MC<11800
package com.replaymod.compat.shaders.mixin; package com.replaymod.compat.shaders.mixin;
import com.replaymod.render.hooks.EntityRendererHandler; import com.replaymod.render.hooks.EntityRendererHandler;
import net.minecraft.client.Minecraft; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.renderer.chunk.RenderChunk;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(RenderChunk.class) //#if MC>=11500
import org.spongepowered.asm.mixin.Shadow;
//#endif
//#if MC>=11500
@Mixin(net.minecraft.client.render.chunk.ChunkBuilder.BuiltChunk.class)
//#else
//$$ @Mixin(net.minecraft.client.render.chunk.ChunkRenderer.class)
//#endif
public abstract class MixinShaderRenderChunk { public abstract class MixinShaderRenderChunk {
private final Minecraft mc = Minecraft.getMinecraft(); private final MinecraftClient mc = MinecraftClient.getInstance();
//#if MC>=11500
@Shadow private int rebuildFrame;
@Shadow public abstract boolean shouldBuild();
/**
* So, for some reason OF though it'd be a good idea to drop the `shouldBuild` check from the chunk traversal in
* the setupTerrain method (see the innermost if of the "iteration" profiler section).
* Hint: It's not a good idea. It'll cause chunks to be queued for building which should not be built. And because
* they don't know any better, they'll even re-queue themselves (which looks like a race condition in vanilla
* MC) causing a live-lock when we try to force-build all chunks (or at least it would cause a lockup if it
* wasn't for the vanilla race condition which slowly causes some of the rebuild tasks to get lost over time,
* eventually, potentially all of them).
* This is the most convenient place to re-introduce the check (setRebuildFrame would normally be called right after
* shouldBuild, if it returns true).
*/
@Inject(method = "setRebuildFrame", at = @At("HEAD"), cancellable = true)
private void replayModCompat_OFHaveYouConsideredWhetherThisChunkShouldEvenBeBuilt(int rebuildFrame, CallbackInfoReturnable<Boolean> ci) {
if (this.rebuildFrame == rebuildFrame) {
// want to keep the fast path
ci.setReturnValue(false);
} else if (!this.shouldBuild()) {
// this is the check which OF removed
// So, I think I figured out the reason why optifine applies this change: It's so chunks which are outside
// the server view distance are still rendered if they've previously compiled. The bug still stands but
// fixing it breaks OF's broken feature, so to reduce the impact of our fix, we only apply it during
// rendering where it affects us the most.
if (((EntityRendererHandler.IEntityRenderer) mc.gameRenderer).replayModRender_getHandler() == null) return;
ci.setReturnValue(false);
}
}
//#endif
/** /**
* Changes the RenderChunk#isPlayerUpdate method that Optifine adds * Changes the RenderChunk#isPlayerUpdate method that Optifine adds
* to always return true while rendering so no chunks are being added * to always return true while rendering so no chunks are being added
* to a separate rendering queue * to a separate rendering queue
*/ */
@Inject(method = "isPlayerUpdate", at = @At("HEAD"), cancellable = true) @Inject(method = "isPlayerUpdate", at = @At("HEAD"), cancellable = true, remap = false)
private void replayModCompat_disableIsPlayerUpdate(CallbackInfoReturnable<Boolean> ci) { private void replayModCompat_disableIsPlayerUpdate(CallbackInfoReturnable<Boolean> ci) {
if (((EntityRendererHandler.IEntityRenderer) mc.entityRenderer).replayModRender_getHandler() == null) return; if (((EntityRendererHandler.IEntityRenderer) mc.gameRenderer).replayModRender_getHandler() == null) return;
ci.setReturnValue(true); ci.setReturnValue(true);
} }
} }
//#endif

View File

@@ -1,40 +0,0 @@
package com.replaymod.compat.shaders.mixin;
import com.replaymod.compat.shaders.ShaderReflection;
import com.replaymod.render.hooks.EntityRendererHandler;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.RenderGlobal;
import net.minecraft.client.renderer.culling.ICamera;
import net.minecraft.entity.Entity;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(RenderGlobal.class)
public abstract class MixinShaderRenderGlobal {
private final Minecraft mc = Minecraft.getMinecraft();
@Shadow
public boolean displayListEntitiesDirty;
@Inject(method = "setupTerrain", at = @At("HEAD"), cancellable = true)
public void replayModCompat_setupTerrain(Entity viewEntity, double partialTicks, ICamera camera,
int frameCount, boolean playerSpectator, CallbackInfo ci) {
if (((EntityRendererHandler.IEntityRenderer) mc.entityRenderer).replayModRender_getHandler() == null) return;
if (ShaderReflection.shaders_isShadowPass == null) return;
// when called by the shadow pass, displayListEntitiesDirty can't be set to false, as no chunk updates
// are being processed. As it's being set to true by ChunkLoadingRenderGlobal#updateChunks, we have to
// set it to false manually to exit the loop imposed by MixinRenderGlobal#replayModRender_setupTerrain.
try {
if ((boolean) ShaderReflection.shaders_isShadowPass.get(null) == true) {
displayListEntitiesDirty = false;
}
} catch (IllegalAccessException ignore) {}
}
}

View File

@@ -0,0 +1 @@
// 1.7.10 and below

View File

@@ -0,0 +1,54 @@
package com.replaymod.compat.shaders.mixin;
import net.minecraft.client.render.GameRenderer;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Pseudo;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
//#if MC>=11600
import net.minecraft.client.render.Camera;
import net.minecraft.client.util.math.MatrixStack;
//#endif
//#if MC>=11400
import com.replaymod.core.events.PreRenderHandCallback;
//#else
//$$ import com.replaymod.core.versions.MCVer;
//$$ import net.minecraftforge.client.ForgeHooksClient;
//#endif
@Pseudo
@Mixin(targets = {
"shadersmod/client/ShadersRender", // Pre Optifine 1.12.2 E1
"net/optifine/shaders/ShadersRender" // Post Optifine 1.12.2 E1
}, remap = false)
public abstract class MixinShadersRender {
@Inject(method = { "renderHand0", "renderHand1" }, at = @At("HEAD"), cancellable = true, remap = false)
private static void replayModCompat_disableRenderHand0(
GameRenderer er,
//#if MC>=11600
MatrixStack stack,
Camera camera,
//#endif
float partialTicks,
//#if MC<11600
//$$ int renderPass,
//#endif
CallbackInfo ci) {
//#if MC>=11400
if (PreRenderHandCallback.EVENT.invoker().preRenderHand()) {
//#else
//#if MC>=11400
//$$ if (ForgeHooksClient.renderFirstPersonHand(MCVer.getMinecraft().renderGlobal, partialTicks)) {
//#else
//$$ if (ForgeHooksClient.renderFirstPersonHand(MCVer.getMinecraft().renderGlobal, partialTicks, renderPass)) {
//#endif
//#endif
ci.cancel();
}
}
}

View File

@@ -0,0 +1,18 @@
//#if FABRIC>=1
package com.replaymod.core;
import net.fabricmc.loader.api.entrypoint.PreLaunchEntrypoint;
// Required for ReplayModMMLauncher.
//
// Chain-loading mixin configurations only works when the first class that is loaded doesn't have any mixins which
// target it. The first class would ordinarily be MC's Main but there are valid use cases for targeting it, see
// e.g. https://github.com/ReplayMod/ReplayMod/issues/327
// So, instead of relying on the bad assumption that Main doesn't have any mixins, we'll instead register this
// dummy pre-launch entry point which is practically guaranteed to not have any mixins and gets called before Main.
public class DummyChainLoadEntryPoint implements PreLaunchEntrypoint {
@Override
public void onPreLaunch() {
}
}
//#endif

View File

@@ -2,107 +2,221 @@ package com.replaymod.core;
import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap; import com.google.common.collect.Multimap;
import net.minecraft.client.settings.KeyBinding; import com.replaymod.core.events.PreRenderCallback;
import net.minecraft.crash.CrashReport; import com.replaymod.core.mixin.KeyBindingAccessor;
import net.minecraft.crash.CrashReportCategory; import de.johni0702.minecraft.gui.function.KeyInput;
import net.minecraft.util.ReportedException; import de.johni0702.minecraft.gui.utils.EventRegistrations;
import net.minecraftforge.fml.client.registry.ClientRegistry; import com.replaymod.core.events.KeyBindingEventCallback;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import com.replaymod.core.events.KeyEventCallback;
import net.minecraftforge.fml.common.gameevent.InputEvent; import net.minecraft.client.options.KeyBinding;
import net.minecraftforge.fml.common.gameevent.TickEvent; import net.minecraft.util.crash.CrashReport;
import org.lwjgl.input.Keyboard; import net.minecraft.util.crash.CrashReportSection;
import net.minecraft.util.crash.CrashException;
//#if FABRIC>=1
import com.replaymod.core.versions.LangResourcePack;
//#if MC>=11600
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
//#else
//$$ import net.fabricmc.fabric.api.client.keybinding.FabricKeyBinding;
//#endif
import net.minecraft.client.util.InputUtil;
import net.minecraft.util.Identifier;
import static com.replaymod.core.ReplayMod.MOD_ID;
import static de.johni0702.minecraft.gui.versions.MCVer.identifier;
//#else
//$$ import net.minecraftforge.fml.client.registry.ClientRegistry;
//#endif
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Function;
public class KeyBindingRegistry { public class KeyBindingRegistry extends EventRegistrations {
private Map<String, KeyBinding> keyBindings = new HashMap<String, KeyBinding>(); //#if MC>=12109
private Multimap<KeyBinding, Runnable> keyBindingHandlers = ArrayListMultimap.create(); //$$ private static final KeyBinding.Category CATEGORY = KeyBinding.Category.create(identifier(MOD_ID, "general"));
private Multimap<KeyBinding, Runnable> repeatedKeyBindingHandlers = ArrayListMultimap.create(); //#else
private Multimap<Integer, Runnable> rawHandlers = ArrayListMultimap.create(); private static final String CATEGORY = "replaymod.title";
//#if FABRIC>=1 && MC<11600
//$$ static { net.fabricmc.fabric.api.client.keybinding.KeyBindingRegistry.INSTANCE.addCategory(CATEGORY); }
//#endif
//#endif
public void registerKeyBinding(String name, int keyCode, Runnable whenPressed) { private final Map<String, Binding> bindings = new HashMap<>();
keyBindingHandlers.put(registerKeyBinding(name, keyCode), whenPressed); private Set<KeyBinding> onlyInReplay = new HashSet<>();
private Multimap<Integer, Function<KeyInput, Boolean>> rawHandlers = ArrayListMultimap.create();
public Binding registerKeyBinding(String name, int keyCode, Runnable whenPressed, boolean onlyInRepay) {
Binding binding = registerKeyBinding(name, keyCode, onlyInRepay);
binding.handlers.add(whenPressed);
return binding;
} }
public void registerRepeatedKeyBinding(String name, int keyCode, Runnable whenPressed) { public Binding registerRepeatedKeyBinding(String name, int keyCode, Runnable whenPressed, boolean onlyInRepay) {
repeatedKeyBindingHandlers.put(registerKeyBinding(name, keyCode), whenPressed); Binding binding = registerKeyBinding(name, keyCode, onlyInRepay);
binding.repeatedHandlers.add(whenPressed);
return binding;
} }
private KeyBinding registerKeyBinding(String name, int keyCode) { private Binding registerKeyBinding(String name, int keyCode, boolean onlyInRepay) {
KeyBinding keyBinding = keyBindings.get(name); Binding binding = bindings.get(name);
if (keyBinding == null) { if (binding == null) {
keyBinding = new KeyBinding(name, keyCode, "replaymod.title"); //#if FABRIC>=1
keyBindings.put(name, keyBinding); if (keyCode == 0) {
ClientRegistry.registerKeyBinding(keyBinding); keyCode = -1;
}
Identifier id = identifier(MOD_ID, name.substring(LangResourcePack.LEGACY_KEY_PREFIX.length()));
//#if MC>=11600
String key = String.format("key.%s.%s", id.getNamespace(), id.getPath());
KeyBinding keyBinding = new KeyBinding(key, InputUtil.Type.KEYSYM, keyCode, CATEGORY);
KeyBindingHelper.registerKeyBinding(keyBinding);
//#else
//$$ FabricKeyBinding fabricKeyBinding = FabricKeyBinding.Builder.create(id, InputUtil.Type.KEYSYM, keyCode, CATEGORY).build();
//$$ net.fabricmc.fabric.api.client.keybinding.KeyBindingRegistry.INSTANCE.register(fabricKeyBinding);
//$$ KeyBinding keyBinding = fabricKeyBinding;
//#endif
//#else
//$$ KeyBinding keyBinding = new KeyBinding(name, keyCode, CATEGORY);
//$$ ClientRegistry.registerKeyBinding(keyBinding);
//#endif
binding = new Binding(name, keyBinding);
bindings.put(name, binding);
if (onlyInRepay) {
this.onlyInReplay.add(keyBinding);
}
} else if (!onlyInRepay) {
this.onlyInReplay.remove(binding.keyBinding);
} }
return keyBinding; return binding;
} }
public void registerRaw(int keyCode, Runnable whenPressed) { public void registerRaw(int keyCode, Function<KeyInput, Boolean> whenPressed) {
rawHandlers.put(keyCode, whenPressed); rawHandlers.put(keyCode, whenPressed);
} }
public Map<String, KeyBinding> getKeyBindings() { public Map<String, Binding> getBindings() {
return Collections.unmodifiableMap(keyBindings); return Collections.unmodifiableMap(bindings);
} }
@SubscribeEvent public Set<KeyBinding> getOnlyInReplay() {
public void onKeyInput(InputEvent.KeyInputEvent event) { return Collections.unmodifiableSet(onlyInReplay);
handleKeyBindings();
handleRaw();
} }
@SubscribeEvent { on(PreRenderCallback.EVENT, this::handleRepeatedKeyBindings); }
public void onTick(TickEvent.RenderTickEvent event) {
if (event.phase != TickEvent.Phase.START) return;
handleRepeatedKeyBindings();
}
public void handleRepeatedKeyBindings() { public void handleRepeatedKeyBindings() {
for (Map.Entry<KeyBinding, Collection<Runnable>> entry : repeatedKeyBindingHandlers.asMap().entrySet()) { for (Binding binding : bindings.values()) {
if (entry.getKey().isKeyDown()) { if (binding.keyBinding.isPressed()) {
invokeKeyBindingHandlers(entry.getKey(), entry.getValue()); invokeKeyBindingHandlers(binding, binding.repeatedHandlers);
} }
} }
} }
public void handleKeyBindings() { { on(KeyBindingEventCallback.EVENT, this::handleKeyBindings); }
for (Map.Entry<KeyBinding, Collection<Runnable>> entry : keyBindingHandlers.asMap().entrySet()) { private void handleKeyBindings() {
while (entry.getKey().isPressed()) { for (Binding binding : bindings.values()) {
invokeKeyBindingHandlers(entry.getKey(), entry.getValue()); while (binding.keyBinding.wasPressed()) {
invokeKeyBindingHandlers(binding, binding.handlers);
invokeKeyBindingHandlers(binding, binding.repeatedHandlers);
} }
} }
} }
private void invokeKeyBindingHandlers(KeyBinding keyBinding, Collection<Runnable> handlers) { private void invokeKeyBindingHandlers(Binding binding, Collection<Runnable> handlers) {
for (final Runnable runnable : handlers) { for (final Runnable runnable : handlers) {
try { try {
runnable.run(); runnable.run();
} catch (Throwable cause) { } catch (Throwable cause) {
CrashReport crashReport = CrashReport.makeCrashReport(cause, "Handling Key Binding"); CrashReport crashReport = CrashReport.create(cause, "Handling Key Binding");
CrashReportCategory category = crashReport.makeCategory("Key Binding"); CrashReportSection category = crashReport.addElement("Key Binding");
category.addCrashSection("Key Binding", keyBinding); category.add("Key Binding", () -> binding.name);
category.setDetail("Handler", runnable::toString); category.add("Handler", runnable::toString);
throw new ReportedException(crashReport); throw new CrashException(crashReport);
} }
} }
} }
public void handleRaw() { { on(KeyEventCallback.EVENT, this::handleRaw); }
int keyCode = Keyboard.getEventKey() == 0 ? Keyboard.getEventCharacter() + 256 : Keyboard.getEventKey(); private boolean handleRaw(KeyInput keyInput, int action) {
for (final Runnable runnable : rawHandlers.get(keyCode)) { if (action != KeyEventCallback.ACTION_PRESS) return false;
for (final Function<KeyInput, Boolean> handler : rawHandlers.get(keyInput.key)) {
try { try {
runnable.run(); if (handler.apply(keyInput)) {
return true;
}
} catch (Throwable cause) { } catch (Throwable cause) {
CrashReport crashReport = CrashReport.makeCrashReport(cause, "Handling Raw Key Binding"); CrashReport crashReport = CrashReport.create(cause, "Handling Raw Key Binding");
CrashReportCategory category = crashReport.makeCategory("Key Binding"); CrashReportSection category = crashReport.addElement("Key Binding");
category.addCrashSection("Key Code", keyCode); category.add("Key Code", () -> "" + keyInput.key);
category.setDetail("Handler", runnable::toString); category.add("Handler", handler::toString);
throw new ReportedException(crashReport); throw new CrashException(crashReport);
} }
} }
return false;
}
public class Binding {
public final String name;
public final KeyBinding keyBinding;
private final List<Runnable> handlers = new ArrayList<>();
private final List<Runnable> repeatedHandlers = new ArrayList<>();
private boolean autoActivation;
private Consumer<Boolean> autoActivationUpdate;
public Binding(String name, KeyBinding keyBinding) {
this.name = name;
this.keyBinding = keyBinding;
}
public String getBoundKey() {
try {
return keyBinding.getBoundKeyLocalizedText().getString();
} catch (ArrayIndexOutOfBoundsException e) {
// Apparently windows likes to press strange keys, see https://www.replaymod.com/forum/thread/55
return "Unknown";
}
}
public boolean isBound() {
//#if MC>=11400
return !keyBinding.isUnbound();
//#else
//$$ return keyBinding.getKeyCode() != 0;
//#endif
}
public void trigger() {
KeyBindingAccessor acc = (KeyBindingAccessor) keyBinding;
acc.setPressTime(acc.getPressTime() + 1);
handleKeyBindings();
}
public void registerAutoActivationSupport(boolean active, Consumer<Boolean> update) {
this.autoActivation = active;
this.autoActivationUpdate = update;
}
public boolean supportsAutoActivation() {
return autoActivationUpdate != null;
}
public boolean isAutoActivating() {
return supportsAutoActivation() && autoActivation;
}
public void setAutoActivating(boolean active) {
if (this.autoActivation == active) {
return;
}
this.autoActivation = active;
this.autoActivationUpdate.accept(active);
}
} }
} }

69
src/main/java/com/replaymod/core/LoadingPlugin.java Executable file → Normal file
View File

@@ -1,68 +1 @@
package com.replaymod.core; // 1.12.2 and below
import net.minecraftforge.fml.relauncher.CoreModManager;
import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin;
import org.apache.logging.log4j.LogManager;
import org.spongepowered.asm.launch.MixinBootstrap;
import org.spongepowered.asm.mixin.Mixins;
import java.io.File;
import java.net.URISyntaxException;
import java.net.URL;
import java.security.CodeSource;
import java.util.Map;
public class LoadingPlugin implements IFMLLoadingPlugin {
public LoadingPlugin() {
MixinBootstrap.init();
Mixins.addConfiguration("mixins.recording.replaymod.json");
Mixins.addConfiguration("mixins.render.replaymod.json");
Mixins.addConfiguration("mixins.replay.replaymod.json");
Mixins.addConfiguration("mixins.compat.shaders.replaymod.json");
CodeSource codeSource = getClass().getProtectionDomain().getCodeSource();
if (codeSource != null) {
URL location = codeSource.getLocation();
try {
File file = new File(location.toURI());
if (file.isFile()) {
// This forces forge to reexamine the jar file for FML mods
// Should eventually be handled by Mixin itself, maybe?
CoreModManager.getIgnoredMods().remove(file.getName());
}
} catch (URISyntaxException e) {
e.printStackTrace();
}
} else {
LogManager.getLogger().warn("No CodeSource, if this is not a development environment we might run into problems!");
LogManager.getLogger().warn(getClass().getProtectionDomain());
}
}
@Override
public String[] getASMTransformerClass() {
return new String[]{
};
}
@Override
public String getModContainerClass() {
return null;
}
@Override
public String getSetupClass() {
return null;
}
@Override
public void injectData(Map<String, Object> data) {
}
@Override
public String getAccessTransformerClass() {
return null;
}
}

View File

@@ -0,0 +1,14 @@
//#if FABRIC>=1
package com.replaymod.core;
import net.fabricmc.loader.api.entrypoint.PreLaunchEntrypoint;
public class MixinExtrasInit implements PreLaunchEntrypoint {
@Override
public void onPreLaunch() {
//#if MC>=11604
com.llamalad7.mixinextras.MixinExtrasBootstrap.init();
//#endif
}
}
//#endif

View File

@@ -0,0 +1,10 @@
package com.replaymod.core;
public interface Module {
// FMLCommonSetupEvent for 1.13+, FMLInitializationEvent below
default void initCommon() {}
// FMLClientSetupEvent for 1.13+, FMLInitializationEvent (if client) below
default void initClient() {}
// FMLClientSetupEvent for 1.13+, FMLInitializationEvent below
default void registerKeyBindings(KeyBindingRegistry registry) {}
}

399
src/main/java/com/replaymod/core/ReplayMod.java Executable file → Normal file
View File

@@ -1,78 +1,116 @@
package com.replaymod.core; package com.replaymod.core;
import com.google.common.io.Files; import com.replaymod.compat.ReplayModCompat;
import com.google.common.util.concurrent.ListenableFutureTask; import com.replaymod.core.files.ReplayFilesService;
import com.replaymod.core.files.ReplayFoldersService;
import com.replaymod.core.gui.GuiBackgroundProcesses;
import com.replaymod.core.gui.GuiReplaySettings; import com.replaymod.core.gui.GuiReplaySettings;
import com.replaymod.core.gui.RestoreReplayGui; import com.replaymod.core.versions.MCVer;
import com.replaymod.core.handler.MainMenuHandler; import com.replaymod.core.versions.scheduler.Scheduler;
import com.replaymod.core.utils.OpenGLUtils; import com.replaymod.core.versions.scheduler.SchedulerImpl;
import com.replaymod.editor.ReplayModEditor;
import com.replaymod.extras.ReplayModExtras;
import com.replaymod.recording.ReplayModRecording;
import com.replaymod.render.ReplayModRender;
import com.replaymod.replay.ReplayModReplay;
import com.replaymod.replaystudio.lib.viaversion.api.protocol.version.ProtocolVersion;
import com.replaymod.replaystudio.studio.ReplayStudio;
import com.replaymod.replaystudio.util.I18n; import com.replaymod.replaystudio.util.I18n;
import de.johni0702.minecraft.gui.container.GuiScreen; import com.replaymod.simplepathing.ReplayModSimplePathing;
import lombok.Getter; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.Minecraft; import net.minecraft.resource.DirectoryResourcePack;
import net.minecraft.client.settings.GameSettings; import net.minecraft.text.LiteralText;
import net.minecraft.crash.CrashReport; import net.minecraft.text.Style;
import net.minecraft.crash.CrashReportCategory; import net.minecraft.text.Text;
import net.minecraft.util.ResourceLocation; import net.minecraft.text.TranslatableText;
import net.minecraft.util.text.*; import net.minecraft.util.Formatting;
import net.minecraftforge.common.MinecraftForge; import net.minecraft.util.Identifier;
import net.minecraftforge.common.config.Configuration;
import net.minecraftforge.fml.client.FMLClientHandler;
import net.minecraftforge.fml.common.Loader;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventHandler;
import net.minecraftforge.fml.common.Mod.Instance;
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 org.apache.commons.io.FileUtils;
import java.io.ByteArrayInputStream;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
@Mod(modid = ReplayMod.MOD_ID, import static de.johni0702.minecraft.gui.versions.MCVer.identifier;
useMetadata = true,
updateJSON = "https://raw.githubusercontent.com/ReplayMod/ReplayMod/master/versions.json",
guiFactory = "com.replaymod.core.gui.GuiFactory")
public class ReplayMod {
public static ModContainer getContainer() { //#if MC>=12006
return Loader.instance().getIndexedModList().get(MOD_ID); //$$ import net.minecraft.resource.ResourcePackInfo;
} //$$ import net.minecraft.resource.ResourcePackSource;
//$$ import net.minecraft.text.Text;
//$$ import java.util.Optional;
//#endif
@Getter(lazy = true) //#if MC>=11900
private static final String minecraftVersion = parseMinecraftVersion(); //#else
private static String parseMinecraftVersion() { import net.minecraft.client.options.Option;
CrashReport crashReport = new CrashReport("", new Throwable()); //#endif
@SuppressWarnings("unchecked")
List<CrashReportCategory.Entry> list = crashReport.getCategory().children; public class ReplayMod implements Module, Scheduler {
for (CrashReportCategory.Entry entry : list) {
if ("Minecraft Version".equals(entry.getKey())) {
return entry.getValue();
}
}
return "Unknown";
}
public static final String MOD_ID = "replaymod"; public static final String MOD_ID = "replaymod";
public static final ResourceLocation TEXTURE = new ResourceLocation("replaymod", "replay_gui.png"); public static final Identifier TEXTURE = identifier("replaymod", "replay_gui.png");
public static final int TEXTURE_SIZE = 256; public static final int TEXTURE_SIZE = 256;
public static final Identifier LOGO_FAVICON = identifier("replaymod", "favicon_logo.png");
private static final Minecraft mc = Minecraft.getMinecraft(); private static final MinecraftClient mc = MCVer.getMinecraft();
@Deprecated
public static Configuration config;
private final ReplayModBackend backend;
private final SchedulerImpl scheduler = new SchedulerImpl();
private final KeyBindingRegistry keyBindingRegistry = new KeyBindingRegistry(); private final KeyBindingRegistry keyBindingRegistry = new KeyBindingRegistry();
private final SettingsRegistry settingsRegistry = new SettingsRegistry(); private final SettingsRegistry settingsRegistry = new SettingsRegistry();
{
settingsRegistry.register(Setting.class);
}
// The instance of your mod that Forge uses. { instance = this; }
@Instance(MOD_ID)
public static ReplayMod instance; public static ReplayMod instance;
private final List<Module> modules = new ArrayList<>();
private final GuiBackgroundProcesses backgroundProcesses = new GuiBackgroundProcesses();
public final ReplayFoldersService folders = new ReplayFoldersService(settingsRegistry);
public final ReplayFilesService files = new ReplayFilesService(folders);
/**
* Whether the current MC version is supported by the embedded ReplayStudio version.
* If this is not the case (i.e. if this is variable true), any feature of the RM which depends on the ReplayStudio
* lib will be disabled.
*
* Only supported on Fabric builds, i.e. will always be false / crash the game with Forge/pre-1.14 builds.
* (specifically the code below and MCVer#getProtocolVersion make this assumption)
*/
private boolean minimalMode;
public ReplayMod(ReplayModBackend backend) {
this.backend = backend;
I18n.setI18n(net.minecraft.client.resource.language.I18n::translate);
// Check Minecraft protocol version for compatibility
if (!ProtocolVersion.isRegistered(MCVer.getProtocolVersion()) && !Boolean.parseBoolean(System.getProperty("replaymod.skipversioncheck", "false"))) {
minimalMode = true;
}
// Register all RM modules
modules.add(this);
modules.add(new ReplayModRecording(this));
ReplayModReplay replayModule = new ReplayModReplay(this);
modules.add(replayModule);
modules.add(new ReplayModRender(this));
modules.add(new ReplayModSimplePathing(this));
modules.add(new ReplayModEditor(this));
modules.add(new ReplayModExtras(this));
modules.add(new ReplayModCompat());
settingsRegistry.register();
}
public KeyBindingRegistry getKeyBindingRegistry() { public KeyBindingRegistry getKeyBindingRegistry() {
return keyBindingRegistry; return keyBindingRegistry;
} }
@@ -81,99 +119,133 @@ public class ReplayMod {
return settingsRegistry; return settingsRegistry;
} }
public File getReplayFolder() throws IOException { public static final DirectoryResourcePack jGuiResourcePack = createJGuiResourcePack();
String path = getSettingsRegistry().get(Setting.RECORDING_PATH); public static final String JGUI_RESOURCE_PACK_NAME = "replaymod_jgui";
File folder = new File(path.startsWith("./") ? getMinecraft().mcDataDir : null, path); private static DirectoryResourcePack createJGuiResourcePack() {
FileUtils.forceMkdir(folder); File folder = new File("../jGui/src/main/resources");
return folder; if (!folder.exists()) {
} folder = new File("../../../jGui/src/main/resources");
if (!folder.exists()) {
@EventHandler return null;
public void preInit(FMLPreInitializationEvent event) {
// Initialize the static OpenGL info field from the minecraft main thread
// Unfortunately lwjgl uses static methods so we have to make use of magic init calls as well
OpenGLUtils.init();
I18n.setI18n(net.minecraft.client.resources.I18n::format);
config = new Configuration(event.getSuggestedConfigurationFile());
config.load();
settingsRegistry.setConfiguration(config);
}
@EventHandler
public void init(FMLInitializationEvent event) {
getSettingsRegistry().register(Setting.class);
new MainMenuHandler().register();
MinecraftForge.EVENT_BUS.register(keyBindingRegistry);
getKeyBindingRegistry().registerKeyBinding("replaymod.input.settings", 0, () -> {
new GuiReplaySettings(null, settingsRegistry).display();
});
}
@EventHandler
public void postInit(FMLPostInitializationEvent event) throws IOException {
settingsRegistry.save(); // Save default values to disk
if(!FMLClientHandler.instance().hasOptifine())
GameSettings.Options.RENDER_DISTANCE.setValueMax(64f);
testIfMoeshAndExitMinecraft();
runLater(() -> {
// Cleanup deleted corrupted replays
try {
File[] files = getReplayFolder().listFiles();
if (files != null) {
for (File file : files) {
if (file.isDirectory() && file.getName().endsWith(".mcpr.del")) {
if (file.lastModified() + 2 * 24 * 60 * 60 * 1000 < System.currentTimeMillis()) {
FileUtils.deleteDirectory(file);
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
} }
// Restore corrupted replays
try {
File[] files = getReplayFolder().listFiles();
if (files != null) {
for (File file : files) {
if (file.isDirectory() && file.getName().endsWith(".mcpr.tmp")) {
File origFile = new File(file.getParentFile(), Files.getNameWithoutExtension(file.getName()));
new RestoreReplayGui(GuiScreen.wrap(mc.currentScreen), origFile).display();
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
});
}
public void runLater(Runnable runnable) {
synchronized (mc.scheduledTasks) {
mc.scheduledTasks.add(ListenableFutureTask.create(runnable, null));
} }
//#if MC>=12006
//$$ return new DirectoryResourcePack(new ResourcePackInfo(JGUI_RESOURCE_PACK_NAME, Text.literal("jGui"), ResourcePackSource.NONE, Optional.empty()), folder.toPath()) {
//#elseif MC>=11903
//$$ return new DirectoryResourcePack(JGUI_RESOURCE_PACK_NAME, folder.toPath(), true) {
//#else
return new DirectoryResourcePack(folder) {
//#endif
@Override
//#if MC>=11400
public String getName() {
//#else
//$$ public String getPackName() {
//#endif
return JGUI_RESOURCE_PACK_NAME;
}
//#if MC>=11903
//$$ @Override
//$$ public net.minecraft.resource.InputSupplier<InputStream> openRoot(String... segments) {
//$$ if (segments.length == 1 && segments[0].equals("pack.mcmeta")) {
//$$ return () -> new ByteArrayInputStream(generatePackMeta());
//$$ }
//$$ return super.openRoot(segments);
//$$ }
//#else
@Override
protected InputStream openFile(String resourceName) throws IOException {
try {
return super.openFile(resourceName);
} catch (IOException e) {
if ("pack.mcmeta".equals(resourceName)) {
return new ByteArrayInputStream(generatePackMeta());
}
throw e;
}
}
//#endif
private byte[] generatePackMeta() {
//#if MC>=11400
int version = 4;
//#else
//$$ int version = 1;
//#endif
return ("{\"pack\": {\"description\": \"dummy pack for jGui resources in dev-env\", \"pack_format\": "
+ version + "}}").getBytes(StandardCharsets.UTF_8);
}
};
}
void initModules() {
modules.forEach(Module::initCommon);
modules.forEach(Module::initClient);
modules.forEach(m -> m.registerKeyBindings(keyBindingRegistry));
}
@Override
public void registerKeyBindings(KeyBindingRegistry registry) {
registry.registerKeyBinding("replaymod.input.settings", 0, () -> {
new GuiReplaySettings(null, settingsRegistry).display();
}, false);
}
@Override
public void initClient() {
backgroundProcesses.register();
keyBindingRegistry.register();
// 1.7.10 crashes when render distance > 16
// Post 1.19 this has become non-trivial to do, install Sodium+Bobby or OptiFine if you need it
//#if MC>=10800 && MC<11900
if (!MCVer.hasOptifine()) {
Option.RENDER_DISTANCE.setMax(64f);
}
//#endif
runPostStartup(() -> files.initialScan(this));
}
@Override
public void runSync(Runnable runnable) throws InterruptedException, ExecutionException, TimeoutException {
scheduler.runSync(runnable);
}
@Override
public void runPostStartup(Runnable runnable) {
scheduler.runPostStartup(runnable);
}
@Override
public void runLaterWithoutLock(Runnable runnable) {
scheduler.runLaterWithoutLock(runnable);
}
@Override
public void runLater(Runnable runnable) {
scheduler.runLater(runnable);
}
@Override
public void runTasks() {
scheduler.runTasks();
} }
public String getVersion() { public String getVersion() {
return getContainer().getVersion(); return backend.getVersion();
} }
private void testIfMoeshAndExitMinecraft() { public String getMinecraftVersion() {
if("currentPlayer".equals("Moesh")) { return backend.getMinecraftVersion();
System.exit(-1);
}
} }
public Minecraft getMinecraft() { public boolean isModLoaded(String id) {
return backend.isModLoaded(id);
}
public MinecraftClient getMinecraft() {
return mc; return mc;
} }
@@ -186,18 +258,55 @@ public class ReplayMod {
} }
private void printToChat(boolean warning, String message, Object... args) { private void printToChat(boolean warning, String message, Object... args) {
if (!mc.isOnThread()) {
runLater(() -> printToChat(warning, message, args));
return;
}
if (getSettingsRegistry().get(Setting.NOTIFICATIONS)) { if (getSettingsRegistry().get(Setting.NOTIFICATIONS)) {
// Some nostalgia: "§8[§6Replay Mod§8]§r Your message goes here" // Some nostalgia: "§8[§6Replay Mod§8]§r Your message goes here"
Style coloredDarkGray = new Style().setColor(TextFormatting.DARK_GRAY); //#if MC>=10904
Style coloredGold = new Style().setColor(TextFormatting.GOLD); //#if MC>=11600
ITextComponent text = new TextComponentString("[").setStyle(coloredDarkGray) Style coloredDarkGray = Style.EMPTY.withColor(Formatting.DARK_GRAY);
.appendSibling(new TextComponentTranslation("replaymod.title").setStyle(coloredGold)) Style coloredGold = Style.EMPTY.withColor(Formatting.GOLD);
.appendSibling(new TextComponentString("] ")) Style alert = Style.EMPTY.withColor(warning ? Formatting.RED : Formatting.DARK_GREEN);
.appendSibling(new TextComponentTranslation(message, args).setStyle(new Style() //#else
.setColor(warning ? TextFormatting.RED : TextFormatting.DARK_GREEN))); //$$ Style coloredDarkGray = new Style().setColor(Formatting.DARK_GRAY);
//$$ Style coloredGold = new Style().setColor(Formatting.GOLD);
//$$ Style alert = new Style().setColor(warning ? Formatting.RED : Formatting.DARK_GREEN);
//#endif
Text text = new LiteralText("[").setStyle(coloredDarkGray)
.append(new TranslatableText("replaymod.title").setStyle(coloredGold))
.append(new LiteralText("] "))
.append(new TranslatableText(message, args).setStyle(alert));
//#else
//$$ ChatStyle coloredDarkGray = new ChatStyle().setColor(EnumChatFormatting.DARK_GRAY);
//$$ ChatStyle coloredGold = new ChatStyle().setColor(EnumChatFormatting.GOLD);
//$$ IChatComponent text = new ChatComponentText("[").setChatStyle(coloredDarkGray)
//$$ .appendSibling(new ChatComponentTranslation("replaymod.title").setChatStyle(coloredGold))
//$$ .appendSibling(new ChatComponentText("] "))
//$$ .appendSibling(new ChatComponentTranslation(message, args).setChatStyle(new ChatStyle()
//$$ .setColor(warning ? EnumChatFormatting.RED : EnumChatFormatting.DARK_GREEN)));
//#endif
// Send message to chat GUI // Send message to chat GUI
// The ingame GUI is initialized at startup, therefore this is possible before the client is connected // The ingame GUI is initialized at startup, therefore this is possible before the client is connected
mc.ingameGUI.getChatGUI().printChatMessage(text); mc.inGameHud.getChatHud().addMessage(text);
}
}
public GuiBackgroundProcesses getBackgroundProcesses() {
return backgroundProcesses;
}
// This method is static because it depends solely on the environment, not on the actual RM instance.
public static boolean isMinimalMode() {
return ReplayMod.instance.minimalMode;
}
public static boolean isCompatible(int fileFormatVersion, int protocolVersion) {
if (isMinimalMode()) {
return protocolVersion == MCVer.getProtocolVersion();
} else {
return new ReplayStudio().isCompatible(fileFormatVersion, protocolVersion, MCVer.getProtocolVersion());
} }
} }
} }

View File

@@ -0,0 +1,34 @@
package com.replaymod.core;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.SharedConstants;
import static com.replaymod.core.ReplayMod.MOD_ID;
public class ReplayModBackend implements ClientModInitializer {
private final ReplayMod mod = new ReplayMod(this);
@Override
public void onInitializeClient() {
mod.initModules();
}
public String getVersion() {
return FabricLoader.getInstance().getModContainer(MOD_ID)
.orElseThrow(IllegalStateException::new)
.getMetadata().getVersion().toString();
}
public String getMinecraftVersion() {
//#if MC>=12106
//$$ return SharedConstants.getGameVersion().comp_4025();
//#else
return SharedConstants.getGameVersion().getName();
//#endif
}
public boolean isModLoaded(String id) {
return FabricLoader.getInstance().isModLoaded(id.toLowerCase());
}
}

View File

@@ -0,0 +1,31 @@
//#if FABRIC>=1
package com.replaymod.core;
import org.spongepowered.asm.mixin.Mixins;
// We need to wait for MM to call us, otherwise we might initialize our mixins before it calls optifabric which would
// result in OF classes not existing while our mixins get resolved.
public class ReplayModMMLauncher implements Runnable {
private static boolean ran;
@Override
public void run() {
// If this is MM2, then we're currently getting called because of our entrypoint declaration.
// For backwards compatibility with MM1, we also declare our early_riser via custom metadata and MM2 supports
// that as well and will therefore call us twice.
if (ran) {
return;
}
ran = true;
Mixins.addConfiguration("mixins.compat.mapwriter.replaymod.json");
Mixins.addConfiguration("mixins.compat.shaders.replaymod.json");
Mixins.addConfiguration("mixins.core.replaymod.json");
Mixins.addConfiguration("mixins.extras.playeroverview.replaymod.json");
Mixins.addConfiguration("mixins.recording.replaymod.json");
Mixins.addConfiguration("mixins.render.blend.replaymod.json");
Mixins.addConfiguration("mixins.render.replaymod.json");
Mixins.addConfiguration("mixins.replay.replaymod.json");
}
}
//#endif

View File

@@ -0,0 +1,96 @@
package com.replaymod.core;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
import java.io.IOException;
import java.util.List;
import java.util.Set;
//#if FABRIC
import net.fabricmc.loader.api.FabricLoader;
//#endif
//#if MC>=11400
import java.io.InputStream;
//#else
//$$ import net.minecraft.launchwrapper.Launch;
//#endif
//#if MC>=11200
import org.objectweb.asm.tree.ClassNode;
//#else
//$$ import org.spongepowered.asm.lib.tree.ClassNode;
//#endif
public class ReplayModMixinConfigPlugin implements IMixinConfigPlugin {
static boolean hasClass(String name) throws IOException {
//#if MC>=11400
InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream(name.replace('.', '/') + ".class");
if (stream != null) stream.close();
return stream != null;
//#else
//$$ return Launch.classLoader.getClassBytes(name) != null;
//#endif
}
private final Logger logger = LogManager.getLogger("replaymod/mixin");
private final boolean hasOF = hasClass("optifine.OptiFineForgeTweaker") || hasClass("me.modmuss50.optifabric.mod.Optifabric");
//#if FABRIC
private final boolean hasIris = FabricLoader.getInstance().isModLoaded("iris");
//#endif
{
logger.debug("hasOF: " + hasOF);
}
@Override
public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
if (hasOF) {
//#if MC>=11500
// OF renames the lambda method name and I see no way we can target it now, so we give up on that patch
if (mixinClassName.endsWith("MixinTileEntityEndPortalRenderer")) return false;
//#endif
}
if (mixinClassName.endsWith("_OF")) return hasOF;
if (mixinClassName.endsWith("_NoOF")) return !hasOF;
//#if FABRIC
if (mixinClassName.endsWith("_Iris")) return hasIris;
//#endif
return true;
}
@Override
public void onLoad(String mixinPackage) {
}
@Override
public String getRefMapperConfig() {
return null;
}
@Override
public void acceptTargets(Set<String> myTargets, Set<String> otherTargets) {
}
@Override
public List<String> getMixins() {
return null;
}
@Override
public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
}
@Override
public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
}
public ReplayModMixinConfigPlugin() throws IOException {
}
}

View File

@@ -0,0 +1,62 @@
//#if FABRIC>=1
package com.replaymod.core;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.objectweb.asm.tree.ClassNode;
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
import java.io.IOException;
import java.util.List;
import java.util.Set;
// See ReplayModMMLauncher. This is the fallback if MM is not installed.
public class ReplayModNonMMLauncher implements IMixinConfigPlugin {
private final Logger logger = LogManager.getLogger("replaymod/nonmm");
@Override
public void onLoad(String mixinPackage) {
}
@Override
public String getRefMapperConfig() {
return null;
}
@Override
public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
return false;
}
@Override
public void acceptTargets(Set<String> myTargets, Set<String> otherTargets) {
}
@Override
public List<String> getMixins() {
try {
if (ReplayModMixinConfigPlugin.hasClass("com.chocohead.mm.Plugin")) {
logger.debug("Detected MM, they should call us...");
} else {
logger.debug("Did not detect MM, initializing ourselves...");
new ReplayModMMLauncher().run();
}
return null;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
}
@Override
public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
}
}
//#endif

View File

@@ -3,6 +3,7 @@ package com.replaymod.core;
public final class Setting<T> extends SettingsRegistry.SettingKeys<T> { public final class Setting<T> extends SettingsRegistry.SettingKeys<T> {
public static final Setting<Boolean> NOTIFICATIONS = make("notifications", "notifications", true); public static final Setting<Boolean> NOTIFICATIONS = make("notifications", "notifications", true);
public static final Setting<String> RECORDING_PATH = advanced("recordingPath", null, "./replay_recordings/"); public static final Setting<String> RECORDING_PATH = advanced("recordingPath", null, "./replay_recordings/");
public static final Setting<String> CACHE_PATH = advanced("cachePath", null, "./.replay_cache/");
private static <T> Setting<T> make(String key, String displayName, T defaultValue) { private static <T> Setting<T> make(String key, String displayName, T defaultValue) {
return new Setting<>("core", key, displayName, defaultValue); return new Setting<>("core", key, displayName, defaultValue);

View File

@@ -1,28 +1,17 @@
package com.replaymod.core; package com.replaymod.core;
import com.replaymod.core.events.SettingsChangedEvent; import com.replaymod.core.events.SettingsChangedCallback;
import net.minecraft.client.resources.I18n;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.config.Configuration;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.*; import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
public class SettingsRegistry { public class SettingsRegistry {
private static final Object NULL_OBJECT = new Object(); private final Map<SettingKey<?>, Object> settings = Collections.synchronizedMap(new LinkedHashMap<>());
private Map<SettingKey<?>, Object> settings = new ConcurrentHashMap<>(); final SettingsRegistryBackend backend = new SettingsRegistryBackend(settings);
private Configuration configuration;
public void setConfiguration(Configuration configuration) { public void register() {
this.configuration = configuration; backend.register();
List<SettingKey<?>> keys = new ArrayList<>(settings.keySet());
settings.clear();
for (SettingKey key : keys) {
register(key);
}
} }
public void register(Class<?> settingsClass) { public void register(Class<?> settingsClass) {
@@ -39,23 +28,8 @@ public class SettingsRegistry {
} }
public void register(SettingKey<?> key) { public void register(SettingKey<?> key) {
Object value; settings.put(key, key.getDefault());
if (configuration != null) { backend.register(key);
if (key.getDefault() instanceof Boolean) {
value = configuration.get(key.getCategory(), key.getKey(), (Boolean) key.getDefault()).getBoolean();
} else if (key.getDefault() instanceof Integer) {
value = configuration.get(key.getCategory(), key.getKey(), (Integer) key.getDefault()).getInt();
} else if (key.getDefault() instanceof Double) {
value = configuration.get(key.getCategory(), key.getKey(), (Double) key.getDefault()).getDouble();
} else if (key.getDefault() instanceof String) {
value = configuration.get(key.getCategory(), key.getKey(), (String) key.getDefault()).getString();
} else {
throw new IllegalArgumentException("Default type " + key.getDefault().getClass() + " not supported.");
}
} else {
value = NULL_OBJECT;
}
settings.put(key, value);
} }
public Set<SettingKey<?>> getSettings() { public Set<SettingKey<?>> getSettings() {
@@ -71,23 +45,13 @@ public class SettingsRegistry {
} }
public <T> void set(SettingKey<T> key, T value) { public <T> void set(SettingKey<T> key, T value) {
if (key.getDefault() instanceof Boolean) { backend.update(key, value);
configuration.get(key.getCategory(), key.getKey(), (Boolean) key.getDefault()).set((Boolean) value);
} else if (key.getDefault() instanceof Integer) {
configuration.get(key.getCategory(), key.getKey(), (Integer) key.getDefault()).set((Integer) value);
} else if (key.getDefault() instanceof Double) {
configuration.get(key.getCategory(), key.getKey(), (Double) key.getDefault()).set((Double) value);
} else if (key.getDefault() instanceof String) {
configuration.get(key.getCategory(), key.getKey(), (String) key.getDefault()).set((String) value);
} else {
throw new IllegalArgumentException("Default type " + key.getDefault().getClass() + " not supported.");
}
settings.put(key, value); settings.put(key, value);
MinecraftForge.EVENT_BUS.post(new SettingsChangedEvent(this, key)); SettingsChangedCallback.EVENT.invoker().onSettingsChanged(this, key);
} }
public void save() { public void save() {
configuration.save(); backend.save();
} }
public interface SettingKey<T> { public interface SettingKey<T> {
@@ -126,7 +90,7 @@ public class SettingsRegistry {
@Override @Override
public String getDisplayString() { public String getDisplayString() {
return displayString == null ? null : I18n.format(displayString); return displayString;
} }
@Override @Override

View File

@@ -0,0 +1,189 @@
package com.replaymod.core;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.replaymod.core.events.SettingsChangedCallback;
import net.minecraft.client.MinecraftClient;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.util.List;
import java.util.Map;
import static com.replaymod.core.utils.Utils.ensureDirectoryExists;
import static com.replaymod.core.versions.MCVer.getMinecraft;
class SettingsRegistryBackend {
private static final Logger LOGGER = LogManager.getLogger();
private final Map<SettingsRegistry.SettingKey<?>, Object> settings;
private final Path configFile = getMinecraft().runDirectory.toPath().resolve("config/replaymod.json");
SettingsRegistryBackend(Map<SettingsRegistry.SettingKey<?>, Object> settings) {
this.settings = settings;
}
public void register() {
load(true);
try {
registerWatcher();
} catch (IOException e) {
LOGGER.warn("Failed to setup file watcher for {}, live-reloading is disabled. Cause: {}", configFile, e);
}
}
private void load(boolean createIfMissingOrBroken) {
String config;
if (Files.exists(configFile)) {
try {
config = new String(Files.readAllBytes(configFile), StandardCharsets.UTF_8);
} catch (IOException e) {
e.printStackTrace();
return;
}
} else {
if (createIfMissingOrBroken) {
save();
}
return;
}
Gson gson = new Gson();
JsonObject root = gson.fromJson(config, JsonObject.class);
if (root == null) {
LOGGER.error("Config file {} appears corrupted: {}", configFile, config);
if (createIfMissingOrBroken) {
save();
}
return;
}
for (Map.Entry<SettingsRegistry.SettingKey<?>, Object> entry : settings.entrySet()) {
SettingsRegistry.SettingKey<?> key = entry.getKey();
JsonElement category = root.get(key.getCategory());
if (category != null && category.isJsonObject()) {
JsonElement valueElem = category.getAsJsonObject().get(key.getKey());
if (valueElem == null || !valueElem.isJsonPrimitive()) continue;
JsonPrimitive value = valueElem.getAsJsonPrimitive();
if (key.getDefault() instanceof Boolean && value.isBoolean()) {
entry.setValue(value.getAsBoolean());
}
if (key.getDefault() instanceof Integer && value.isNumber()) {
entry.setValue(value.getAsNumber().intValue());
}
if (key.getDefault() instanceof Double && value.isNumber()) {
entry.setValue(value.getAsNumber().doubleValue());
}
if (key.getDefault() instanceof String && value.isString()) {
String valueStr = value.getAsString();
if (entry instanceof SettingsRegistry.MultipleChoiceSettingKey) {
@SuppressWarnings("unchecked")
List<String> choices = ((SettingsRegistry.MultipleChoiceSettingKey<String>) entry).getChoices();
if (choices.stream().noneMatch(valueStr::equals)) {
continue;
}
}
entry.setValue(valueStr);
}
}
}
}
private void registerWatcher() throws IOException {
WatchService watchService = configFile.getFileSystem().newWatchService();
configFile.getParent().register(watchService, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_MODIFY);
Thread thread = new Thread(() -> {
while (true) {
WatchKey nextKey;
try {
nextKey = watchService.take();
} catch (InterruptedException e) {
return;
}
for (WatchEvent<?> event : nextKey.pollEvents()) {
WatchEvent.Kind<?> kind = event.kind();
if (kind == StandardWatchEventKinds.OVERFLOW) {
continue;
}
Path fileName = ((Path) event.context());
if (fileName.equals(configFile.getFileName())) {
MinecraftClient.getInstance().send(this::reload);
}
}
if (!nextKey.reset()) {
return;
}
}
});
thread.setName("replaymod-config-watcher");
thread.setDaemon(true);
thread.start();
}
private void reload() {
load(false);
SettingsRegistry settingsRegistry = ReplayMod.instance.getSettingsRegistry();
for (SettingsRegistry.SettingKey<?> key : settings.keySet()) {
SettingsChangedCallback.EVENT.invoker().onSettingsChanged(settingsRegistry, key);
}
}
@SuppressWarnings("unused")
public void register(SettingsRegistry.SettingKey<?> key) {
}
@SuppressWarnings("unused")
public <T> void update(SettingsRegistry.SettingKey<T> key, T value) {
}
public void save() {
JsonObject root = new JsonObject();
for (Map.Entry<SettingsRegistry.SettingKey<?>, Object> entry : settings.entrySet()) {
SettingsRegistry.SettingKey<?> key = entry.getKey();
JsonObject category = root.getAsJsonObject(key.getCategory());
if (category == null) {
category = new JsonObject();
root.add(key.getCategory(), category);
}
Object value = entry.getValue();
if (value instanceof Boolean) {
category.addProperty(key.getKey(), (Boolean) value);
}
if (value instanceof Number) {
category.addProperty(key.getKey(), (Number) value);
}
if (value instanceof String) {
category.addProperty(key.getKey(), (String) value);
if (key instanceof SettingsRegistry.MultipleChoiceSettingKey) {
@SuppressWarnings("unchecked")
List<String> choices = ((SettingsRegistry.MultipleChoiceSettingKey<String>) key).getChoices();
JsonArray array = new JsonArray();
for (String choice : choices) {
array.add(choice);
}
category.add(key.getKey() + "_valid_values", array);
}
}
}
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String config = gson.toJson(root);
try {
ensureDirectoryExists(configFile.getParent());
Files.write(configFile, config.getBytes(StandardCharsets.UTF_8));
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1 @@
// 1.7.10 and below

View File

@@ -0,0 +1 @@
// 1.7.10 and below

View File

@@ -0,0 +1,15 @@
package com.replaymod.core.events;
import de.johni0702.minecraft.gui.utils.Event;
public interface KeyBindingEventCallback {
Event<KeyBindingEventCallback> EVENT = Event.create((listeners) ->
() -> {
for (KeyBindingEventCallback listener : listeners) {
listener.onKeybindingEvent();
}
}
);
void onKeybindingEvent();
}

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