├── .github └── workflows │ ├── devbuild.yml │ └── release-build.yml ├── .gitignore ├── README.md ├── README_zh.md ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── scripts └── check.js ├── settings.gradle └── src └── main ├── java └── com │ └── hadroncfy │ └── sreplay │ ├── Lang.java │ ├── SReplayMod.java │ ├── Util.java │ ├── asm │ ├── MixinConfigPlugin.java │ └── MultipleOrdinalFieldInjectionPoint.java │ ├── command │ ├── ConfirmationManager.java │ └── SReplayCommand.java │ ├── config │ ├── AbstractTextRenderer.java │ ├── Config.java │ ├── FileSerializer.java │ ├── Formats.java │ ├── InetAddressSerializer.java │ ├── PatternSerializer.java │ └── TextRenderer.java │ ├── interfaces │ ├── IChunkSender.java │ └── IServer.java │ ├── mixin │ ├── GameStateChangeS2CPacketAccessor.java │ ├── MixinCommandManager.java │ ├── MixinEntityTracker.java │ ├── MixinIntegratedServer.java │ ├── MixinMinecraftServer.java │ ├── MixinThreadedAnvilChunkStorage.java │ ├── PlayerManagerAccessor.java │ ├── PlayerSpawnS2CPacketAccessor.java │ ├── ThreadedAnvilChunkStorageAccessor.java │ └── WorldTimeUpdateS2CPacketAccessor.java │ ├── recording │ ├── ForcedWeather.java │ ├── HackyClientConnection.java │ ├── IGamePausedListener.java │ ├── IPacketListener.java │ ├── ISizeLimitExceededListener.java │ ├── Photographer.java │ ├── Recorder.java │ ├── RecordingOption.java │ ├── RecordingSaveProgressBar.java │ ├── SimpleCompletedFuture.java │ ├── WeatherView.java │ ├── mcpr │ │ ├── DigestOutputStream.java │ │ ├── IReplayFile.java │ │ ├── Marker.java │ │ ├── Metadata.java │ │ ├── ProgressBar.java │ │ ├── SReplayFile.java │ │ └── UUIDSerializer.java │ └── param │ │ ├── EnumArgumentType.java │ │ ├── InvalidEnumException.java │ │ ├── Option.java │ │ ├── OptionEntry.java │ │ ├── OptionManager.java │ │ └── Validator.java │ └── server │ ├── FileEntry.java │ ├── HttpHandler.java │ └── Server.java └── resources ├── fabric.mod.json ├── lang └── zh_cn.json └── sreplay.mixins.json /.github/workflows/devbuild.yml: -------------------------------------------------------------------------------- 1 | name: Development Builds 2 | 3 | on: [push, workflow_dispatch] 4 | 5 | jobs: 6 | Build: 7 | 8 | runs-on: ubuntu-latest 9 | 10 | steps: 11 | - uses: actions/checkout@v2 12 | - name: Set up JDK 16 13 | uses: actions/setup-java@v2 14 | with: 15 | distribution: 'adopt' 16 | java-version: 16 17 | - name: Cache Gradle packages 18 | uses: actions/cache@v2 19 | with: 20 | path: ~/.gradle/caches 21 | key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} 22 | restore-keys: ${{ runner.os }}-gradle 23 | - name: Grant execute permission to gradlew 24 | run: chmod +x gradlew 25 | - name: Build with Gradle 26 | run: ./gradlew build 27 | - uses: actions/upload-artifact@v2 28 | with: 29 | name: Compiled artifacts for ${{ github.sha }} 30 | path: build/libs -------------------------------------------------------------------------------- /.github/workflows/release-build.yml: -------------------------------------------------------------------------------- 1 | # Thanks to https://github.com/gnembon/fabric-carpet/blob/master/.github/workflows/publish-release.yml 2 | # which is much more complicated.. 3 | 4 | name: Release Builds 5 | 6 | on: 7 | push: 8 | tags: 9 | - 'v*' 10 | 11 | jobs: 12 | Build-And-Publish: 13 | 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - uses: actions/checkout@v2 18 | - name: Set up JDK 16 19 | uses: actions/setup-java@v2 20 | with: 21 | distribution: 'adopt' 22 | java-version: 16 23 | - name: Cache Gradle packages 24 | uses: actions/cache@v2 25 | with: 26 | path: ~/.gradle/caches 27 | key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} 28 | restore-keys: ${{ runner.os }}-gradle 29 | - name: Grant execute permission to gradlew 30 | run: chmod +x gradlew 31 | - name: Build with Gradle 32 | run: ./gradlew build 33 | - uses: actions/upload-artifact@v2 34 | with: 35 | name: Compiled artifacts for ${{ github.sha }} 36 | path: build/libs 37 | - name: Find correct JAR 38 | id: findjar 39 | run: | 40 | output="$(find build/libs/ ! -name "*-dev.jar" ! -name "*-sources.jar" -type f -printf "%f\n")" 41 | echo "::set-output name=jarname::$output" 42 | - name: Create Github release 43 | uses: softprops/action-gh-release@v1 44 | env: 45 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 46 | with: 47 | files: build/libs/${{ steps.findjar.outputs.jarname }} 48 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore Gradle project-specific cache directory 2 | .gradle 3 | .classpath 4 | .vscode 5 | .settings 6 | .project 7 | run 8 | bin 9 | # Ignore Gradle build output directory 10 | build 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SReplay 2 | 3 | [中文文档](README_zh.md) 4 | 5 | Server-side recording mod for [ReplayMod](https://github.com/ReplayMod/ReplayMod). It records the game using fake players so can be used on servers for 24/7 recording. It's also an alternative way to record single player world. 6 | 7 | * Display recorded time, recorded file size, etc. in tab list. 8 | * Can be set to pause automatically when no players are near by. 9 | * Allow players to download recording files via an embedded http server. 10 | * Variable view distance, but not chunk loading distance. 11 | * Lock day time or weather in recording. 12 | 13 | Tested in Minecraft 1.14.4, should also work in later versions with only trivial modifications on the code (minecraft version and yarn mapping version of fabric-loom). 14 | 15 | ## Use 16 | Use `/sreplay help` to get general usage, and `/sreplay help set