Merge remote-tracking branch 'origin/1.18' into 1.19.2

This commit is contained in:
embeddedt 2023-05-27 10:28:35 -04:00
commit f4b2db89ec
No known key found for this signature in database
GPG Key ID: A69433EC199B5613
7 changed files with 80 additions and 29 deletions

View File

@ -11,6 +11,7 @@ import org.embeddedt.modernfix.core.ModernFixMixinPlugin;
import org.embeddedt.modernfix.platform.ModernFixPlatformHooks; import org.embeddedt.modernfix.platform.ModernFixPlatformHooks;
import org.embeddedt.modernfix.resources.ReloadExecutor; import org.embeddedt.modernfix.resources.ReloadExecutor;
import org.embeddedt.modernfix.util.ClassInfoManager; import org.embeddedt.modernfix.util.ClassInfoManager;
import org.embeddedt.modernfix.world.IntegratedWatchdog;
import java.lang.management.ManagementFactory; import java.lang.management.ManagementFactory;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
@ -46,6 +47,19 @@ public class ModernFix {
public ModernFix() { public ModernFix() {
INSTANCE = this; INSTANCE = this;
ModernFixPlatformHooks.onServerCommandRegister(ModernFixCommands::register); ModernFixPlatformHooks.onServerCommandRegister(ModernFixCommands::register);
if(ModernFixMixinPlugin.instance.isOptionEnabled("feature.spam_thread_dump.ThreadDumper")) {
Thread t = new Thread() {
public void run() {
while(true) {
LOGGER.error("------ DEBUG THREAD DUMP (occurs every 60 seconds) ------");
LOGGER.error(IntegratedWatchdog.obtainThreadDump());
try { Thread.sleep(60000); } catch(InterruptedException e) {}
}
}
};
t.setDaemon(true);
t.start();
}
} }
public void onServerStarted() { public void onServerStarted() {

View File

@ -34,6 +34,19 @@ public interface ModernFixClientIntegration {
return originalModel; return originalModel;
} }
/**
* Called to allow mods to observe the use of an unbaked model at bake time and either make changes to it or wrap it with their
* own instance.
* @param location the ResourceLocation of the model (this may be a ModelResourceLocation)
* @param originalModel the original model
* @param bakery the model bakery - do not touch internal fields as they probably don't behave the way you expect
* with dynamic resources on
* @return the model which should actually be loaded for this resource location
*/
default UnbakedModel onUnbakedModelPreBake(ResourceLocation location, UnbakedModel originalModel, ModelBakery bakery) {
return originalModel;
}
/** /**
* Called to allow mods to observe the loading of a baked model and either make changes to it or wrap it with their * Called to allow mods to observe the loading of a baked model and either make changes to it or wrap it with their
* own instance. * own instance.

View File

@ -6,27 +6,24 @@ import org.embeddedt.modernfix.util.CanonizingStringMap;
import org.spongepowered.asm.mixin.*; import org.spongepowered.asm.mixin.*;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.ModifyArg;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.Map; import java.util.Map;
@Mixin(CompoundTag.class) @Mixin(CompoundTag.class)
public class CompoundTagMixin { public class CompoundTagMixin {
@Shadow @Final @Mutable @Shadow @Final
private Map<String, Tag> tags; private Map<String, Tag> tags;
/** /**
* Ensure that the backing map is always a CanonizingStringMap. * Ensure that the default backing map is a CanonizingStringMap.
*/ */
@Redirect(method = "<init>(Ljava/util/Map;)V", at = @At(value = "FIELD", target = "Lnet/minecraft/nbt/CompoundTag;tags:Ljava/util/Map;", ordinal = 0)) @ModifyArg(method = "<init>()V", at = @At(value = "INVOKE", target = "Lnet/minecraft/nbt/CompoundTag;<init>(Ljava/util/Map;)V"), index = 0)
private void replaceTagMap(CompoundTag tag, Map<String, Tag> incomingMap) { private static Map<String, Tag> useCanonizingStringMap(Map<String, Tag> incoming) {
if(incomingMap instanceof CanonizingStringMap) CanonizingStringMap<Tag> newMap = new CanonizingStringMap<>();
this.tags = incomingMap; newMap.putAll(incoming);
else { return newMap;
this.tags = new CanonizingStringMap<>();
this.tags.putAll(incomingMap);
}
} }
/** /**

View File

@ -143,6 +143,7 @@ public class ModernFixEarlyConfig {
.put("mixin.perf.dynamic_entity_renderers", false) .put("mixin.perf.dynamic_entity_renderers", false)
.put("mixin.feature.integrated_server_watchdog", true) .put("mixin.feature.integrated_server_watchdog", true)
.put("mixin.perf.faster_item_rendering", false) .put("mixin.perf.faster_item_rendering", false)
.put("mixin.feature.spam_thread_dump", false)
.put("mixin.devenv", isDevEnv) .put("mixin.devenv", isDevEnv)
.put("mixin.perf.remove_spawn_chunks", isDevEnv) .put("mixin.perf.remove_spawn_chunks", isDevEnv)
.build(); .build();

View File

@ -25,6 +25,27 @@ public class IntegratedWatchdog extends Thread {
this.setName("ModernFix integrated server watchdog"); this.setName("ModernFix integrated server watchdog");
} }
public static String obtainThreadDump() {
ThreadMXBean threadmxbean = ManagementFactory.getThreadMXBean();
ThreadInfo[] athreadinfo = threadmxbean.dumpAllThreads(true, true);
StringBuilder sb = new StringBuilder();
sb.append("Thread Dump:\n");
for(ThreadInfo threadinfo : athreadinfo) {
sb.append(threadinfo);
StackTraceElement[] elements = threadinfo.getStackTrace();
if(elements.length > 8) {
sb.append("extended trace:\n");
for(int i = 8; i < elements.length; i++) {
sb.append("\tat ");
sb.append(elements[i]);
sb.append('\n');
}
}
sb.append('\n');
}
return sb.toString();
}
public void run() { public void run() {
while(true) { while(true) {
MinecraftServer server = this.server.get(); MinecraftServer server = this.server.get();
@ -35,24 +56,7 @@ public class IntegratedWatchdog extends Thread {
long delta = curTime - nextTick; long delta = curTime - nextTick;
if(delta > MAX_TICK_DELTA) { if(delta > MAX_TICK_DELTA) {
LOGGER.error("A single server tick has taken {}, more than {} milliseconds", delta, MAX_TICK_DELTA); LOGGER.error("A single server tick has taken {}, more than {} milliseconds", delta, MAX_TICK_DELTA);
ThreadMXBean threadmxbean = ManagementFactory.getThreadMXBean(); LOGGER.error(obtainThreadDump());
ThreadInfo[] athreadinfo = threadmxbean.dumpAllThreads(true, true);
StringBuilder sb = new StringBuilder();
sb.append("Thread Dump:\n");
for(ThreadInfo threadinfo : athreadinfo) {
sb.append(threadinfo);
StackTraceElement[] elements = threadinfo.getStackTrace();
if(elements.length > 8) {
sb.append("extended trace:\n");
for(int i = 8; i < elements.length; i++) {
sb.append("\tat ");
sb.append(elements[i]);
sb.append('\n');
}
}
sb.append('\n');
}
LOGGER.error(sb.toString());
nextTick = 0; nextTick = 0;
curTime = 0; curTime = 0;
} }

View File

@ -453,6 +453,17 @@ public abstract class ModelBakeryMixin implements IExtendedModelBakery {
if(iunbakedmodel == missingModel && debugDynamicModelLoading) if(iunbakedmodel == missingModel && debugDynamicModelLoading)
LOGGER.warn("Model {} not present", arg); LOGGER.warn("Model {} not present", arg);
if(iunbakedmodel != missingModel) {
for(ModernFixClientIntegration integration : ModernFixClient.CLIENT_INTEGRATIONS) {
try {
iunbakedmodel = integration.onUnbakedModelPreBake(arg, iunbakedmodel, (ModelBakery)(Object)this);
} catch(RuntimeException e) {
ModernFix.LOGGER.error("Exception firing model pre-bake event for {}", arg, e);
}
}
}
BakedModel ibakedmodel = null; BakedModel ibakedmodel = null;
if (iunbakedmodel instanceof BlockModel) { if (iunbakedmodel instanceof BlockModel) {
BlockModel blockmodel = (BlockModel)iunbakedmodel; BlockModel blockmodel = (BlockModel)iunbakedmodel;

View File

@ -330,6 +330,17 @@ public abstract class ModelBakeryMixin implements IExtendedModelBakery {
iunbakedmodel.getMaterials(this::getModel, new HashSet<>()); iunbakedmodel.getMaterials(this::getModel, new HashSet<>());
if(iunbakedmodel == missingModel && debugDynamicModelLoading) if(iunbakedmodel == missingModel && debugDynamicModelLoading)
LOGGER.warn("Model {} not present", arg); LOGGER.warn("Model {} not present", arg);
if(iunbakedmodel != missingModel) {
for(ModernFixClientIntegration integration : ModernFixClient.CLIENT_INTEGRATIONS) {
try {
iunbakedmodel = integration.onUnbakedModelPreBake(arg, iunbakedmodel, (ModelBakery)(Object)this);
} catch(RuntimeException e) {
ModernFix.LOGGER.error("Exception encountered firing bake event for {}", arg, e);
}
}
}
BakedModel ibakedmodel = null; BakedModel ibakedmodel = null;
if (iunbakedmodel instanceof BlockModel) { if (iunbakedmodel instanceof BlockModel) {
BlockModel blockmodel = (BlockModel)iunbakedmodel; BlockModel blockmodel = (BlockModel)iunbakedmodel;