Skip to content

Commit

Permalink
Merge branch 'refs/heads/1.20.6' into 1.19.4
Browse files Browse the repository at this point in the history
# Conflicts:
#	README.md
#	libs.versions.toml
#	src/main/kotlin/me/senseiwells/replay/recorder/ReplayRecorder.kt
#	src/main/kotlin/me/senseiwells/replay/viewer/ReplayViewer.kt
  • Loading branch information
senseiwells committed Sep 25, 2024
2 parents 220e71d + 4e52ed5 commit c161806
Show file tree
Hide file tree
Showing 17 changed files with 107 additions and 338 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ After you boot the server a new file will be generated in the path
"pause_notify_players": true,
"notify_admins_of_status": true,
"fix_carpet_bot_view_distance": false,
"include_resource_packs": true,
"ignore_sound_packets": false,
"ignore_light_packets": true,
"ignore_chat_packets": false,
Expand Down Expand Up @@ -261,6 +262,7 @@ After you boot the server a new file will be generated in the path
| `"pause_notify_players"` | <p> If `pause_unloaded_chunks` is enabled and this is enabled then when the recording for the chunk area is paused or resumed all online players will be notified. </p> |
| `"notify_admins_of_status"` | <p> When enabled this will notify admins of when a replay starts, when a replay ends, and when a replay has finished saving, as well as any errors that occur. </p> |
| `"fix_carpet_bot_view_distance"` | <p> If you are recording carpet bots you want to enable this as it sets the view distance to the server view distance. Otherwise it will only record a distance of 2 chunks around the bot. </p> |
| `"include_resource_packs"` | <p> If enabled all server-side resource packs will be copied in the replay file to ensure correct playback. Disabling this will decrease file size but instead it'll try to download the pack from the original source whenever viewing the replay, there is no guarantee that this will work correctly. </p> |
| `"ignore_sound_packets"` | <p> If you are recording a large area for a timelapse it's unlikely you'll want to record any sounds, these can eat up significant storage space. </p> |
| `"ignore_light_packets"` | <p> Light is calculated on the client as well as on the server so light packets are mostly redundant. </p> |
| `"ignore_chat_packets"` | <p> Stops chat packets (from both the server and other players) from being recorded if they are not necessary for your replay. </p> |
Expand Down Expand Up @@ -450,7 +452,7 @@ repositories {
}

dependencies {
modImplementation("me.senseiwells:server-replay:1.1.4+1.19.4")
modImplementation("me.senseiwells:server-replay:1.1.5+1.19.4")
}
```

Expand Down
10 changes: 6 additions & 4 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ plugins {
val shade: Configuration by configurations.creating

repositories {
maven("https://maven.supersanta.me/snapshots")
maven("https://maven.parchmentmc.org/")
maven("https://masa.dy.fi/maven")
maven("https://jitpack.io")
Expand All @@ -25,7 +26,7 @@ repositories {
}


val modVersion = "1.1.4"
val modVersion = "1.1.5"
val releaseVersion = "${modVersion}+mc${libs.versions.minecraft.get()}"
version = releaseVersion
group = "me.senseiwells"
Expand All @@ -42,6 +43,8 @@ dependencies {
modImplementation(libs.fabric.api)
modImplementation(libs.fabric.kotlin)

include(modImplementation(libs.arcade.pack.host.get())!!)

modCompileOnly(libs.carpet)
modCompileOnly(libs.vmp)
modCompileOnly(libs.voicechat)
Expand Down Expand Up @@ -109,9 +112,8 @@ tasks {
file = remapJar.get().archiveFile
changelog.set(
"""
- Fixed an incompatibility with Servux
- Fixed an incompatibility with C2ME
- Fixed an issue that caused players to not be able to join when auto recording
- Added `"include_resource_packs"` config
- Optimized resource pack hosting
""".trimIndent()
)
type = STABLE
Expand Down
5 changes: 4 additions & 1 deletion libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ parchment = "1.19.4:2023.06.26"
fabric-api = "0.87.2+1.19.4"
fabric-kotlin = "1.9.2+kotlin.1.8.10"
permissions = "0.3.1"
arcade = "0.2.0-alpha.46+1.21.1"
carpet = "1.4.101"
voicechat = "fabric-1.19.4-2.5.7"
voicechat-api = "2.4.0"
Expand All @@ -21,11 +22,13 @@ fabric-loader = { module = "net.fabricmc:fabric-loader" , version.ref
fabric-api = { module = "net.fabricmc.fabric-api:fabric-api" , version.ref = "fabric-api" }
fabric-kotlin = { module = "net.fabricmc:fabric-language-kotlin" , version.ref = "fabric-kotlin" }
permissions = { module = "me.lucko:fabric-permissions-api" , version.ref = "permissions" }
replay-studio = { module = "com.github.ReplayMod:ReplayStudio" , version.ref = "replay-studio" }
arcade-pack-host = { module = "net.casual-championships:arcade-resource-pack-host", version.ref = "arcade" }

carpet = { module = "com.github.gnembon:fabric-carpet" , version.ref = "carpet" }
voicechat = { module = "maven.modrinth:simple-voice-chat" , version.ref = "voicechat" }
voicechat-api = { module = "de.maxhenkel.voicechat:voicechat-api" , version.ref = "voicechat-api" }
vmp = { module = "maven.modrinth:vmp-fabric" , version.ref = "vmp" }
replay-studio = { module = "com.github.ReplayMod:ReplayStudio" , version.ref = "replay-studio" }

[plugins]
fabric-loom = { id = "fabric-loom", version.ref = "fabric-loom" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,29 +15,29 @@

@Mixin(value = ChunkMap.TrackedEntity.class, priority = 1100)
public class TrackedEntityMixin {
@Shadow
@Final
Entity entity;
@Shadow
@Final
Entity entity;

@Dynamic(mixin = MixinThreadedAnvilChunkStorageEntityTracker.class)
@ModifyExpressionValue(
method = "tryTick",
at = @At(
value = "INVOKE",
target = "Ljava/util/Set;isEmpty()Z"
),
remap = false
)
private boolean shouldNotTick(boolean original) {
if (!original) {
return false;
}
if (!((ChunkRecordable) this).getRecorders().isEmpty()) {
return false;
}
if (this.entity instanceof ServerPlayer player) {
return !PlayerRecorders.has(player);
}
return true;
}
@Dynamic(mixin = MixinThreadedAnvilChunkStorageEntityTracker.class)
@ModifyExpressionValue(
method = "tryTick",
at = @At(
value = "INVOKE",
target = "Ljava/util/Set;isEmpty()Z"
),
remap = false
)
private boolean shouldNotTick(boolean original) {
if (!original) {
return false;
}
if (!((ChunkRecordable) this).getRecorders().isEmpty()) {
return false;
}
if (this.entity instanceof ServerPlayer player) {
return !PlayerRecorders.has(player);
}
return true;
}
}
36 changes: 30 additions & 6 deletions src/main/kotlin/me/senseiwells/replay/ServerReplay.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import me.senseiwells.replay.commands.PackCommand
import me.senseiwells.replay.commands.ReplayCommand
import me.senseiwells.replay.config.ReplayConfig
import me.senseiwells.replay.download.DownloadHost
import net.casual.arcade.host.PackHost
import net.casual.arcade.host.pack.ReadablePack
import net.fabricmc.api.ModInitializer
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents
Expand All @@ -17,9 +19,10 @@ object ServerReplay: ModInitializer {
const val MOD_ID = "server-replay"

private var downloads: DownloadHost? = null
private var packs: PackHost? = null

@JvmField
val logger: Logger = LoggerFactory.getLogger("ServerReplay")
val logger: Logger = LoggerFactory.getLogger(MOD_ID)

val replay: ModContainer = FabricLoader.getInstance().getModContainer(MOD_ID).get()
val version: String = this.replay.metadata.version.friendlyString
Expand All @@ -29,12 +32,17 @@ object ServerReplay: ModInitializer {
private set

override fun onInitialize() {
this.reload()
this.config = ReplayConfig.read()

ServerReplayPluginManager.loadPlugins()

ServerLifecycleEvents.SERVER_STARTING.register { this.downloads?.start() }
ServerLifecycleEvents.SERVER_STOPPING.register { this.downloads?.stop() }
ServerLifecycleEvents.SERVER_STARTING.register {
this.reloadHost()
}
ServerLifecycleEvents.SERVER_STOPPING.register {
this.downloads?.stop()
this.packs?.stop()
}

CommandRegistrationCallback.EVENT.register { dispatcher, _, _ ->
ReplayCommand.register(dispatcher)
Expand All @@ -52,12 +60,28 @@ object ServerReplay: ModInitializer {
fun reload() {
this.config = ReplayConfig.read()

this.reloadHost()
}

fun hostPack(pack: ReadablePack): PackHost.HostedPackRef? {
return this.packs?.addPack(pack)
}

fun removePack(pack: ReadablePack) {
this.packs?.removePack(pack.name)
}

private fun reloadHost() {
this.downloads?.stop()
this.packs?.stop()

if (this.config.allowDownloadingReplays) {
val downloads = DownloadHost(this.config.replayServerIp, this.config.replayDownloadPort)
downloads.start()
this.downloads = downloads
} else {
this.downloads?.stop()
}
val packs = PackHost(this.config.replayServerIp, this.config.replayViewerPackPort)
packs.start()
this.packs = packs
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import net.minecraft.commands.Commands
import net.minecraft.network.protocol.game.ClientboundResourcePackPacket

object PackCommand {
@JvmStatic
fun register(dispatcher: CommandDispatcher<CommandSourceStack>) {
dispatcher.register(
Commands.literal("resource-pack").then(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ import java.util.concurrent.TimeUnit
import kotlin.io.path.*

object ReplayCommand {
@JvmStatic
fun register(dispatcher: CommandDispatcher<CommandSourceStack>) {
dispatcher.register(
Commands.literal("replay").requires {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package me.senseiwells.replay.compat

import com.google.common.collect.HashMultimap
import me.senseiwells.replay.ServerReplay
import net.fabricmc.loader.api.FabricLoader
import org.objectweb.asm.tree.ClassNode
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin
Expand Down Expand Up @@ -30,15 +29,10 @@ class ReplayMixinConfig: IMixinConfigPlugin {
override fun shouldApplyMixin(targetClassName: String, mixinClassName: String): Boolean {
if (mixinClassName.startsWith(MIXIN_COMPAT)) {
val modId = mixinClassName.removePrefix(MIXIN_COMPAT).substringBefore('.')
val isModLoaded = FabricLoader.getInstance().isModLoaded(modId)
if (!isModLoaded) {
ServerReplay.logger.debug("Not applying compat mixin for mod $modId, mod was not loaded")
}
return isModLoaded
return FabricLoader.getInstance().isModLoaded(modId)
}
for (modId in incompatible.get(mixinClassName)) {
if (FabricLoader.getInstance().isModLoaded(modId)) {
ServerReplay.logger.debug("Not applying $mixinClassName, $modId is incompatible")
return false
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/main/kotlin/me/senseiwells/replay/config/ReplayConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ data class ReplayConfig(
var notifyAdminsOfStatus: Boolean = true,
@SerialName("fix_carpet_bot_view_distance")
var fixCarpetBotViewDistance: Boolean = false,
@SerialName("include_resource_packs")
var includeResourcePacks: Boolean = true,
@SerialName("ignore_sound_packets")
var ignoreSoundPackets: Boolean = false,
@SerialName("ignore_light_packets")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@ package me.senseiwells.replay.download
import com.sun.net.httpserver.HttpExchange
import com.sun.net.httpserver.HttpServer
import me.senseiwells.replay.ServerReplay
import me.senseiwells.replay.util.HttpHost
import net.casual.arcade.host.core.HttpHost
import java.io.IOException
import java.net.URLDecoder
import java.nio.charset.StandardCharsets
import java.nio.file.Path
import java.util.function.Consumer
import kotlin.io.path.*

class DownloadHost(ip: String?, port: Int): HttpHost(ip, port) {
class DownloadHost(ip: String?, port: Int): HttpHost(ip, port, 3) {
override fun getName(): String {
return "ReplayDownloadHost"
return "replay-download-host"
}

override fun onStart(server: HttpServer, async: Consumer<Runnable>) {
override fun onStart(server: HttpServer) {
server.createContext("/player", this::handlePlayerDownloadRequest)
server.createContext("/chunk", this::handleChunkDownloadRequest)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -804,7 +804,7 @@ abstract class ReplayRecorder(
}

private fun downloadAndRecordResourcePack(packet: ClientboundResourcePackPacket): Boolean {
if (packet.url.startsWith("replay://")) {
if (!ServerReplay.config.includeResourcePacks ||packet.url.startsWith("replay://")) {
return false
}
@Suppress("DEPRECATION")
Expand Down
95 changes: 0 additions & 95 deletions src/main/kotlin/me/senseiwells/replay/util/HttpHost.kt

This file was deleted.

Loading

0 comments on commit c161806

Please sign in to comment.