flashback compat

This commit is contained in:
mcrcortex
2025-09-07 19:12:25 +10:00
parent 8615f29132
commit effabf95fd
9 changed files with 158 additions and 7 deletions

View File

@@ -134,6 +134,8 @@ dependencies {
//modImplementation('io.github.douira:glsl-transformer:2.0.1') //modImplementation('io.github.douira:glsl-transformer:2.0.1')
modCompileOnly("maven.modrinth:vivecraft:1.21.1-1.1.14-b2-fabric") modCompileOnly("maven.modrinth:vivecraft:1.21.1-1.1.14-b2-fabric")
modCompileOnly("maven.modrinth:flashback:rNCr1Rbs")
} }

View File

@@ -1,5 +1,6 @@
package me.cortex.voxy.client; package me.cortex.voxy.client;
import me.cortex.voxy.client.compat.FlashbackCompat;
import me.cortex.voxy.client.config.VoxyConfig; import me.cortex.voxy.client.config.VoxyConfig;
import me.cortex.voxy.common.Logger; import me.cortex.voxy.common.Logger;
import me.cortex.voxy.common.config.ConfigBuildCtx; import me.cortex.voxy.common.config.ConfigBuildCtx;
@@ -23,15 +24,17 @@ public class VoxyClientInstance extends VoxyInstance {
public static boolean isInGame = false; public static boolean isInGame = false;
private final SectionStorageConfig storageConfig; private final SectionStorageConfig storageConfig;
private final Path basePath = getBasePath(); private final Path basePath;
private final boolean noIngestOverride;
public VoxyClientInstance() { public VoxyClientInstance() {
super(VoxyConfig.CONFIG.serviceThreads); super(VoxyConfig.CONFIG.serviceThreads);
try { var path = FlashbackCompat.getReplayStoragePath();
Files.createDirectories(this.basePath); this.noIngestOverride = path != null;
} catch (Exception e) { if (path == null) {
throw new RuntimeException(e); path = getBasePath();
} }
this.storageConfig = getCreateStorageConfig(this.basePath); this.basePath = path;
this.storageConfig = getCreateStorageConfig(path);
} }
@Override @Override
@@ -48,7 +51,12 @@ public class VoxyClientInstance extends VoxyInstance {
return this.storageConfig.build(ctx); return this.storageConfig.build(ctx);
} }
private static SectionStorageConfig getCreateStorageConfig(Path path) { public static SectionStorageConfig getCreateStorageConfig(Path path) {
try {
Files.createDirectories(path);
} catch (Exception e) {
throw new RuntimeException(e);
}
var json = path.resolve("config.json"); var json = path.resolve("config.json");
Config config = null; Config config = null;
if (Files.exists(json)) { if (Files.exists(json)) {
@@ -81,6 +89,15 @@ public class VoxyClientInstance extends VoxyInstance {
return config.sectionStorageConfig; return config.sectionStorageConfig;
} }
public Path getStorageBasePath() {
return this.basePath;
}
@Override
public boolean isIngestEnabled(WorldIdentifier worldId) {
return !this.noIngestOverride;
}
private static class Config { private static class Config {
public int version = 1; public int version = 1;
public SectionStorageConfig sectionStorageConfig; public SectionStorageConfig sectionStorageConfig;

View File

@@ -0,0 +1,42 @@
package me.cortex.voxy.client.compat;
import com.moulberry.flashback.Flashback;
import com.moulberry.flashback.playback.ReplayServer;
import com.moulberry.flashback.record.FlashbackMeta;
import me.cortex.voxy.common.Logger;
import me.cortex.voxy.common.config.section.SectionStorageConfig;
import net.fabricmc.loader.api.FabricLoader;
import org.apache.commons.logging.Log;
import java.nio.file.Path;
public class FlashbackCompat {
public static final boolean FLASHBACK_INSTALLED = FabricLoader.getInstance().isModLoaded("flashback");
public static Path getReplayStoragePath() {
if (!FLASHBACK_INSTALLED) {
return null;
}
return getReplayStoragePath0();
}
private static Path getReplayStoragePath0() {
ReplayServer replayServer = Flashback.getReplayServer();
if (replayServer != null) {
FlashbackMeta meta = replayServer.getMetadata();
if (meta != null) {
var path = ((IFlashbackMeta)meta).getVoxyPath();
if (path != null) {
Logger.info("Flashback replay server exists and meta exists");
if (path.exists()) {
Logger.info("Flashback voxy path exists in filesystem, using this as lod data source");
return path.toPath();
} else {
Logger.warn("Flashback meta had voxy path saved but path doesnt exist");
}
}
}
}
return null;
}
}

View File

@@ -0,0 +1,8 @@
package me.cortex.voxy.client.compat;
import java.io.File;
public interface IFlashbackMeta {
void setVoxyPath(File path);
File getVoxyPath();
}

View File

@@ -0,0 +1,45 @@
package me.cortex.voxy.client.mixin.flashback;
import com.google.gson.JsonObject;
import com.moulberry.flashback.record.FlashbackMeta;
import me.cortex.voxy.client.compat.IFlashbackMeta;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.io.File;
@Mixin(value = FlashbackMeta.class, remap = false)
public class MixinFlashbackMeta implements IFlashbackMeta {
@Unique private File voxyPath;
@Override
public void setVoxyPath(File path) {
this.voxyPath = path;
}
@Override
public File getVoxyPath() {
return this.voxyPath;
}
@Inject(method = "toJson", at = @At("RETURN"))
private void voxy$injectSaveVoxyPath(CallbackInfoReturnable<JsonObject> cir) {
var val = cir.getReturnValue();
if (val != null && this.voxyPath != null) {
val.addProperty("voxy_storage_path", this.voxyPath.getAbsoluteFile().getPath());
}
}
@Inject(method = "fromJson", at = @At("RETURN"))
private static void voxy$injectGetVoxyPath(JsonObject meta, CallbackInfoReturnable<FlashbackMeta> cir) {
var val = cir.getReturnValue();
if (val != null && meta != null) {
if (meta.has("voxy_storage_path")) {
((IFlashbackMeta)val).setVoxyPath(new File(meta.get("voxy_storage_path").getAsString()));
}
}
}
}

View File

@@ -0,0 +1,29 @@
package me.cortex.voxy.client.mixin.flashback;
import com.moulberry.flashback.record.FlashbackMeta;
import com.moulberry.flashback.record.Recorder;
import me.cortex.voxy.client.VoxyClientInstance;
import me.cortex.voxy.client.compat.IFlashbackMeta;
import me.cortex.voxy.commonImpl.VoxyCommon;
import net.minecraft.registry.DynamicRegistryManager;
import org.spongepowered.asm.mixin.Final;
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(value = Recorder.class, remap = false)
public class MixinFlashbackRecorder {
@Shadow @Final private FlashbackMeta metadata;
@Inject(method = "<init>", at = @At("TAIL"))
private void voxy$getStoragePath(DynamicRegistryManager registryAccess, CallbackInfo retInf) {
if (VoxyCommon.isAvailable()) {
var instance = VoxyCommon.getInstance();
if (instance instanceof VoxyClientInstance ci) {
((IFlashbackMeta)this.metadata).setVoxyPath(ci.getStorageBasePath().toFile());
}
}
}
}

View File

@@ -177,6 +177,7 @@ public class VoxelIngestService {
if (worldId == null) return false; if (worldId == null) return false;
var instance = VoxyCommon.getInstance(); var instance = VoxyCommon.getInstance();
if (instance == null) return false; if (instance == null) return false;
if (!instance.isIngestEnabled(worldId)) return false;
var engine = instance.getOrCreate(worldId); var engine = instance.getOrCreate(worldId);
if (engine == null) return false; if (engine == null) return false;
instance.getIngestService().enqueueIngest(engine, chunk); instance.getIngestService().enqueueIngest(engine, chunk);
@@ -202,6 +203,7 @@ public class VoxelIngestService {
public static boolean rawIngest(WorldEngine engine, ChunkSection section, int x, int y, int z, ChunkNibbleArray bl, ChunkNibbleArray sl) { public static boolean rawIngest(WorldEngine engine, ChunkSection section, int x, int y, int z, ChunkNibbleArray bl, ChunkNibbleArray sl) {
if (!shouldIngestSection(section, x, y, z)) return false; if (!shouldIngestSection(section, x, y, z)) return false;
if (engine.instanceIn == null) return false; if (engine.instanceIn == null) return false;
if (!engine.instanceIn.isIngestEnabled(null)) return false;//TODO: dont pass in null
return engine.instanceIn.getIngestService().rawIngest0(engine, section, x, y, z, bl, sl); return engine.instanceIn.getIngestService().rawIngest0(engine, section, x, y, z, bl, sl);
} }
} }

View File

@@ -243,4 +243,8 @@ public abstract class VoxyInstance {
Logger.info("Instance shutdown"); Logger.info("Instance shutdown");
this.activeWorldLock.unlockWrite(stamp); this.activeWorldLock.unlockWrite(stamp);
} }
public boolean isIngestEnabled(WorldIdentifier worldId) {
return true;
}
} }

View File

@@ -3,6 +3,8 @@
"package": "me.cortex.voxy.client.mixin", "package": "me.cortex.voxy.client.mixin",
"compatibilityLevel": "JAVA_17", "compatibilityLevel": "JAVA_17",
"client": [ "client": [
"flashback.MixinFlashbackMeta",
"flashback.MixinFlashbackRecorder",
"iris.MixinWorldRenderer", "iris.MixinWorldRenderer",
"iris.MixinPackRenderTargetDirectives", "iris.MixinPackRenderTargetDirectives",
"iris.CustomUniformsAccessor", "iris.CustomUniformsAccessor",