Skip to content

Commit

Permalink
Add chunk save CME debugger (#234)
Browse files Browse the repository at this point in the history
* add chunk save cme debugger

Signed-off-by: Glease <[email protected]>

* spotless

Signed-off-by: Glease <[email protected]>

* move away from too new API

Signed-off-by: Glease <[email protected]>

* dump full tag

Signed-off-by: Glease <[email protected]>

* fix build

Signed-off-by: Glease <[email protected]>

---------

Signed-off-by: Glease <[email protected]>
Co-authored-by: Glease <[email protected]>
  • Loading branch information
miozune and Glease authored Aug 17, 2023
1 parent 19e147d commit 7f39d59
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 1 deletion.
2 changes: 1 addition & 1 deletion dependencies.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ dependencies {
transformedMod("com.github.GTNewHorizons:Baubles:1.0.1.14:dev")
transformedMod("com.github.GTNewHorizons:Applied-Energistics-2-Unofficial:rv3-beta-195-GTNH")
transformedMod("com.github.GTNewHorizons:Galacticraft:3.0.63-GTNH:dev")
transformedMod("com.github.GTNewHorizons:GT5-Unofficial:5.09.42.36:dev")
transformedMod("com.github.GTNewHorizons:GT5-Unofficial:5.09.42.41:dev")
transformedMod("com.github.GTNewHorizons:HungerOverhaul:1.0.4-GTNH:dev")
transformedMod("com.github.GTNewHorizons:MrTJPCore:1.1.1:dev") // Do not update, fixed afterwards
transformedMod("com.github.GTNewHorizons:Railcraft:9.13.15:dev") { exclude group: "thaumcraft", module: "Thaumcraft" }
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/com/mitchej123/hodgepodge/LoadingConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ public class LoadingConfig {
public boolean bedMessageAboveHotbar;
public boolean validatePacketEncodingBeforeSending;
public boolean validatePacketEncodingBeforeSendingShouldCrash;
public boolean chunkSaveCMEDebug;

// render debug
public boolean renderDebug;
Expand Down Expand Up @@ -295,6 +296,7 @@ public LoadingConfig(File file) {
enableMacosCmdShortcuts = config.get(Category.TWEAKS.toString(), "enableMacosCmdShortcuts", true, "Use CMD key on MacOS to COPY / INSERT / SELECT in text fields (Chat, NEI, Server IP etc.)").getBoolean();
removeSpawningMinecartSound = config.get(Category.TWEAKS.toString(), "removeSpawningMinecartSound", true, "Stop playing a sound when spawning a minecart in the world").getBoolean();
removeUpdateChecks = config.get(Category.FIXES.toString(), "removeUpdateChecks", true, "Remove old/stale/outdated update checks.").getBoolean();
chunkSaveCMEDebug = config.get(Category.DEBUG.toString(), "chunkSaveCMEDebug", false, "Enable chunk save cme debugging code.").getBoolean();
renderDebug = config.get(Category.DEBUG.toString(), "renderDebug", true, "Enable GL state debug hooks. Will not do anything useful unless mode is changed to nonzero.").getBoolean();
renderDebugMode = config.get(Category.DEBUG.toString(), "renderDebugMode", 0, "Default GL state debug mode. 0 - off, 1 - reduced, 2 - full").setMinValue(0).setMaxValue(2).getInt();
speedupAnimations = config.get(Category.FIXES.toString(), "speedupAnimations", true, "Drastically speedup animated textures (Basically the same as with optifine animations off but animations are working)").getBoolean();
Expand Down
3 changes: 3 additions & 0 deletions src/main/java/com/mitchej123/hodgepodge/mixins/Mixins.java
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,9 @@ public enum Mixins {
OPTIMIZE_ASMDATATABLE_INDEX(
new Builder("Optimize ASM DataTable Index").setPhase(Phase.EARLY).addMixinClasses("forge.MixinASMDataTable")
.setApplyIf(() -> Common.config.optimizeASMDataTable).addTargetedMod(TargetedMod.VANILLA)),
CHUNK_SAVE_CME_DEBUG(new Builder("Add debugging code to Chunk Save CME").setPhase(Phase.EARLY)
.addMixinClasses("minecraft.MixinNBTTagCompound").setApplyIf(() -> Common.config.chunkSaveCMEDebug)
.addTargetedMod(TargetedMod.VANILLA)),
RENDER_DEBUG(new Builder("Render Debug").setPhase(Phase.EARLY).addMixinClasses("minecraft.MixinRenderGlobal")
.setSide(Side.CLIENT).setApplyIf(() -> Common.config.renderDebug).addTargetedMod(TargetedMod.VANILLA)),
STATIC_LAN_PORT(new Builder("Static Lan Port").setPhase(Phase.EARLY)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package com.mitchej123.hodgepodge.mixins.early.minecraft;

import java.io.DataOutput;
import java.io.IOException;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;

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.Redirect;

import com.mitchej123.hodgepodge.util.NBTTagCompoundConcurrentModificationException;

@Mixin(NBTTagCompound.class)
public abstract class MixinNBTTagCompound {

@Shadow
protected static void func_150298_a(String name, NBTBase data, DataOutput output) throws IOException {}

@Shadow
public abstract NBTBase getTag(String key);

@Redirect(method = "write", at = @At(value = "INVOKE", target = "Ljava/util/Iterator;next()Ljava/lang/Object;"))
private Object hodgepodge$checkCME(Iterator<?> instance) {
if ("File IO Thread".equals(Thread.currentThread().getName())) {
// only do this on chunk save thread
try {
return instance.next();
} catch (ConcurrentModificationException ex) {
throw new NBTTagCompoundConcurrentModificationException(ex, this);
}
} else {
return instance.next();
}
}

@Redirect(
method = "write",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/nbt/NBTTagCompound;func_150298_a(Ljava/lang/String;Lnet/minecraft/nbt/NBTBase;Ljava/io/DataOutput;)V"))
private void hodgepodge$appendKeyPath(String name, NBTBase data, DataOutput output) throws IOException {
if ("File IO Thread".equals(Thread.currentThread().getName())) {
// only do this on chunk save thread
try {
func_150298_a(name, data, output);
} catch (NBTTagCompoundConcurrentModificationException ex) {
String prefix = Stream.of("id", "mID", "x", "y", "z").map(s -> s + "=" + this.getTag(s))
.collect(Collectors.joining(",", "[", "]"));
if (prefix.length() > 2) { // len(prefix + suffix) == 2
ex.addKeyPath(String.format("[%s]%s", prefix, name));
} else {
ex.addKeyPath(name);
}
ex.setFullTag(this);
throw ex;
}
} else {
func_150298_a(name, data, output);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.mitchej123.hodgepodge.util;

import java.util.*;

import net.minecraft.nbt.NBTTagCompound;

import codechicken.nei.util.NBTJson;

public class NBTTagCompoundConcurrentModificationException extends ConcurrentModificationException {

private final Deque<String> keyChain = new ArrayDeque<>();
private final String source;
private Object fullTag;

public NBTTagCompoundConcurrentModificationException(ConcurrentModificationException cause, Object source) {
super(cause);
this.source = toString(source);
fullTag = source;
}

public void addKeyPath(String key) {
keyChain.addFirst(key);
}

public void setFullTag(Object fullTag) {
this.fullTag = fullTag;
}

@Override
public String getMessage() {
return String.format(
"Keys: %s. Source tag: %s. Full tag: %s",
String.join("...", keyChain),
source,
toString(fullTag));
}

private static String toString(Object source) {
if (source == null) return "null";
for (int i = 0; i < 10; i++) {
try {
return source instanceof NBTTagCompound ? NBTJson.toJson((NBTTagCompound) source) : source.toString();

} catch (ConcurrentModificationException ignored) {}
}
return "~~failed to serialize~~";
}
}

0 comments on commit 7f39d59

Please sign in to comment.