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

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

View File

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

View File

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