[unsafe] Abstract away safe logging in SafeLog

This commit is contained in:
Johannes Frohnmeyer 2022-04-03 20:06:49 +02:00
parent 9e52a0d1f6
commit de5b205caf
Signed by: Johannes
GPG Key ID: E76429612C2929F4
12 changed files with 70 additions and 60 deletions

View File

@ -1,8 +1,7 @@
package io.gitlab.jfronny.libjf.config.impl;
import io.gitlab.jfronny.libjf.unsafe.JfLanguageAdapter;
import io.gitlab.jfronny.libjf.unsafe.SafeLog;
import net.fabricmc.loader.api.metadata.CustomValue;
import net.fabricmc.loader.impl.util.log.Log;
import java.util.LinkedList;
import java.util.List;
@ -28,11 +27,11 @@ public class AuxiliaryMetadata {
for (CustomValue value : referencedConfigs.getAsArray()) {
if (value.getType() == CustomValue.CvType.STRING) {
meta.referencedConfigs.add(value.getAsString());
} else Log.error(JfLanguageAdapter.LOG_CATEGORY, "Could not load config metadata: referenced config is not a string");
} else SafeLog.error("Could not load config metadata: referenced config is not a string");
}
} else Log.error(JfLanguageAdapter.LOG_CATEGORY, "Could not load config metadata: referencedConfigs is not an array");
} else SafeLog.error("Could not load config metadata: referencedConfigs is not an array");
}
} else Log.error(JfLanguageAdapter.LOG_CATEGORY, "Could not load config metadata: root is not an object");
} else SafeLog.error("Could not load config metadata: root is not an object");
return meta;
}
}

View File

@ -7,11 +7,10 @@ import io.gitlab.jfronny.libjf.LibJf;
import io.gitlab.jfronny.libjf.config.api.ConfigHolder;
import io.gitlab.jfronny.libjf.config.api.ConfigInstance;
import io.gitlab.jfronny.libjf.gson.HiddenAnnotationExclusionStrategy;
import io.gitlab.jfronny.libjf.unsafe.JfLanguageAdapter;
import io.gitlab.jfronny.libjf.unsafe.SafeLog;
import net.fabricmc.loader.api.FabricLoader;
import net.fabricmc.loader.api.ModContainer;
import net.fabricmc.loader.api.metadata.CustomValue;
import net.fabricmc.loader.impl.util.log.Log;
import org.jetbrains.annotations.ApiStatus;
import java.lang.reflect.Modifier;
@ -39,13 +38,13 @@ public class ConfigHolderImpl implements ConfigHolder {
public void register(String modId, Class<?> config) {
if (isRegistered(modId)) {
if (get(modId).matchesConfigClass(config)) {
Log.warn(JfLanguageAdapter.LOG_CATEGORY, "Attempted to set config of " + modId + " twice, skipping");
SafeLog.warn("Attempted to set config of " + modId + " twice, skipping");
return;
}
Log.warn(JfLanguageAdapter.LOG_CATEGORY, "Overriding config class of " + modId + " to " + config);
SafeLog.warn("Overriding config class of " + modId + " to " + config);
}
if (isRegistered(config)) {
Log.warn(JfLanguageAdapter.LOG_CATEGORY, "Attempted to reuse config class " + config + ", this is unsupported");
SafeLog.warn("Attempted to reuse config class " + config + ", this is unsupported");
}
Optional<ModContainer> container = FabricLoader.getInstance().getModContainer(modId);
AuxiliaryMetadata meta = new AuxiliaryMetadata();
@ -54,7 +53,7 @@ public class ConfigHolderImpl implements ConfigHolder {
if (cv != null) meta = AuxiliaryMetadata.load(cv);
}
else {
Log.warn(JfLanguageAdapter.LOG_CATEGORY, "Attempted to register config for a mod that is not installed: " + modId);
SafeLog.warn("Attempted to register config for a mod that is not installed: " + modId);
}
ConfigInstanceRoot instance = new ConfigInstanceRoot(modId, config, meta.sanitize());
configs.put(modId, instance);

View File

@ -5,8 +5,7 @@ import io.gitlab.jfronny.gson.JsonObject;
import io.gitlab.jfronny.gson.stream.JsonWriter;
import io.gitlab.jfronny.libjf.config.api.*;
import io.gitlab.jfronny.libjf.config.impl.entrypoint.JfConfigSafe;
import io.gitlab.jfronny.libjf.unsafe.JfLanguageAdapter;
import net.fabricmc.loader.impl.util.log.Log;
import io.gitlab.jfronny.libjf.unsafe.SafeLog;
import java.io.IOException;
import java.lang.reflect.Field;
@ -46,7 +45,7 @@ public abstract class ConfigInstanceAbstract implements ConfigInstance {
try {
entry.field.set(null, entry.defaultValue);
} catch (IllegalAccessException e) {
Log.error(JfLanguageAdapter.LOG_CATEGORY, "Could not reload default values", e);
SafeLog.error("Could not reload default values", e);
}
}
});
@ -57,7 +56,7 @@ public abstract class ConfigInstanceAbstract implements ConfigInstance {
try {
method.invoke(null);
} catch (IllegalAccessException | InvocationTargetException e) {
Log.error(JfLanguageAdapter.LOG_CATEGORY, "Could not apply preset", e);
SafeLog.error("Could not apply preset", e);
}
});
}
@ -66,7 +65,7 @@ public abstract class ConfigInstanceAbstract implements ConfigInstance {
try {
method.invoke(null);
} catch (IllegalAccessException | InvocationTargetException e) {
Log.error(JfLanguageAdapter.LOG_CATEGORY, "Could not run verifier", e);
SafeLog.error("Could not run verifier", e);
}
});
}
@ -77,7 +76,7 @@ public abstract class ConfigInstanceAbstract implements ConfigInstance {
try {
value = entry.field.get(null);
} catch (IllegalAccessException e) {
Log.error(JfLanguageAdapter.LOG_CATEGORY, "Could not read value", e);
SafeLog.error("Could not read value", e);
continue;
}
final Object valueOriginal = value;
@ -95,7 +94,7 @@ public abstract class ConfigInstanceAbstract implements ConfigInstance {
try {
entry.field.set(null, value);
} catch (IllegalAccessException e) {
Log.error(JfLanguageAdapter.LOG_CATEGORY, "Could not write value", e);
SafeLog.error("Could not write value", e);
}
}
}
@ -122,14 +121,14 @@ public abstract class ConfigInstanceAbstract implements ConfigInstance {
if (source.has(entry.field.getName())) {
JsonElement el = source.get(entry.field.getName());
entry.value = ConfigHolderImpl.GSON.fromJson(el, entry.field.getGenericType());
} else Log.error(JfLanguageAdapter.LOG_CATEGORY, "Config does not contain entry for " + entry.field.getName());
} else SafeLog.error("Config does not contain entry for " + entry.field.getName());
}
for (Map.Entry<String, ConfigInstance> entry : subcategories.entrySet()) {
if (source.has(entry.getKey())) {
JsonElement el = source.get(entry.getKey());
if (el.isJsonObject()) entry.getValue().loadFrom(el.getAsJsonObject());
else Log.error(JfLanguageAdapter.LOG_CATEGORY, "Config category is not a JSON object, skipping");
} else Log.error(JfLanguageAdapter.LOG_CATEGORY, "Config does not contain entry for subcategory " + entry.getKey());
else SafeLog.error("Config category is not a JSON object, skipping");
} else SafeLog.error("Config does not contain entry for subcategory " + entry.getKey());
}
syncToClass();
}
@ -162,7 +161,7 @@ public abstract class ConfigInstanceAbstract implements ConfigInstance {
try {
info.field.set(null, info.value);
} catch (IllegalAccessException e) {
Log.error(JfLanguageAdapter.LOG_CATEGORY, "Could not write value", e);
SafeLog.error("Could not write value", e);
}
}
syncFromClass();
@ -179,7 +178,7 @@ public abstract class ConfigInstanceAbstract implements ConfigInstance {
if (info.value == null) info.value = info.defaultValue;
info.tempValue = info.value == null ? null : info.value.toString();
} catch (IllegalAccessException e) {
Log.error(JfLanguageAdapter.LOG_CATEGORY, "Could not read value", e);
SafeLog.error("Could not read value", e);
}
}
}

View File

@ -3,9 +3,8 @@ package io.gitlab.jfronny.libjf.config.impl;
import io.gitlab.jfronny.gson.JsonElement;
import io.gitlab.jfronny.gson.JsonParser;
import io.gitlab.jfronny.gson.stream.JsonWriter;
import io.gitlab.jfronny.libjf.unsafe.JfLanguageAdapter;
import io.gitlab.jfronny.libjf.unsafe.SafeLog;
import net.fabricmc.loader.api.FabricLoader;
import net.fabricmc.loader.impl.util.log.Log;
import java.io.BufferedReader;
import java.io.BufferedWriter;
@ -29,10 +28,10 @@ public class ConfigInstanceRoot extends ConfigInstanceAbstract {
try (BufferedReader br = Files.newBufferedReader(path)) {
JsonElement element = JsonParser.parseReader(br);
if (element.isJsonObject()) loadFrom(element.getAsJsonObject());
else Log.error(JfLanguageAdapter.LOG_CATEGORY, "Invalid config: Not a JSON object for " + modId);
else SafeLog.error("Invalid config: Not a JSON object for " + modId);
}
catch (Exception e) {
Log.error(JfLanguageAdapter.LOG_CATEGORY, "Could not read config for " + modId, e);
SafeLog.error("Could not read config for " + modId, e);
}
}
write();
@ -45,7 +44,7 @@ public class ConfigInstanceRoot extends ConfigInstanceAbstract {
JsonWriter jw = ConfigHolderImpl.GSON.newJsonWriter(bw)) {
writeTo(jw);
} catch (Exception e) {
Log.error(JfLanguageAdapter.LOG_CATEGORY, "Could not write config", e);
SafeLog.error("Could not write config", e);
}
});
}

View File

@ -4,11 +4,10 @@ import io.gitlab.jfronny.libjf.LibJf;
import io.gitlab.jfronny.libjf.config.api.ConfigHolder;
import io.gitlab.jfronny.libjf.config.api.JfConfig;
import io.gitlab.jfronny.libjf.config.impl.ConfigHolderImpl;
import io.gitlab.jfronny.libjf.unsafe.JfLanguageAdapter;
import io.gitlab.jfronny.libjf.unsafe.SafeLog;
import net.fabricmc.loader.api.FabricLoader;
import net.fabricmc.loader.api.entrypoint.EntrypointContainer;
import net.fabricmc.loader.api.entrypoint.PreLaunchEntrypoint;
import net.fabricmc.loader.impl.util.log.Log;
import net.minecraft.util.Language;
import java.util.function.Function;
@ -29,7 +28,7 @@ public class JfConfigSafe implements PreLaunchEntrypoint {
public static void registerIfMissing(String modId, Class<?> klazz) {
if (!ConfigHolder.getInstance().isRegistered(modId)) {
Log.info(JfLanguageAdapter.LOG_CATEGORY, "Registering config for " + modId);
SafeLog.info("Registering config for " + modId);
ConfigHolder.getInstance().register(modId, klazz);
}
}

View File

@ -3,9 +3,8 @@ package io.gitlab.jfronny.libjf.config.impl.entrypoint;
import io.gitlab.jfronny.libjf.config.api.JfConfig;
import io.gitlab.jfronny.libjf.config.impl.ConfigHolderImpl;
import io.gitlab.jfronny.libjf.unsafe.DynamicEntry;
import io.gitlab.jfronny.libjf.unsafe.JfLanguageAdapter;
import io.gitlab.jfronny.libjf.unsafe.SafeLog;
import io.gitlab.jfronny.libjf.unsafe.UltraEarlyInit;
import net.fabricmc.loader.impl.util.log.Log;
public class JfConfigUnsafe implements UltraEarlyInit {
@Override
@ -13,6 +12,6 @@ public class JfConfigUnsafe implements UltraEarlyInit {
DynamicEntry.execute(ConfigHolderImpl.MODULE_ID, JfConfig.class,
s -> JfConfigSafe.registerIfMissing(s.modId(), s.instance().getClass())
);
Log.info(JfLanguageAdapter.LOG_CATEGORY, "Finished LibJF config entrypoint");
SafeLog.info("Finished LibJF config entrypoint");
}
}

View File

@ -5,8 +5,6 @@ import io.gitlab.jfronny.libjf.unsafe.inject.FabricLauncherClassUnlocker;
import io.gitlab.jfronny.libjf.unsafe.inject.KnotClassLoaderInterfaceAccessor;
import net.fabricmc.loader.api.LanguageAdapter;
import net.fabricmc.loader.impl.FabricLoaderImpl;
import net.fabricmc.loader.impl.util.log.Log;
import net.fabricmc.loader.impl.util.log.LogCategory;
import java.util.Set;
import java.util.stream.Collectors;
@ -15,16 +13,14 @@ public class JfLanguageAdapter implements LanguageAdapter {
@Override
public native <T> T create(net.fabricmc.loader.api.ModContainer mod, String value, Class<T> type);
public static LogCategory LOG_CATEGORY = new LogCategory("libjf");
static {
Set<Flags.BooleanFlag> flags = Flags.getBoolFlags("unsafe.unlock");
if (flags.stream().map(Flags.BooleanFlag::value).reduce(false, (left, right) -> left || right)) {
Log.warn(LOG_CATEGORY, "Unlocking classpath due to: " + flags.stream().map(Flags.BooleanFlag::source).collect(Collectors.joining(", ")));
SafeLog.warn("Unlocking classpath due to: " + flags.stream().map(Flags.BooleanFlag::source).collect(Collectors.joining(", ")));
FabricLoaderImpl.INSTANCE.getGameProvider().unlockClassPath(new FabricLauncherClassUnlocker(new KnotClassLoaderInterfaceAccessor(Thread.currentThread().getContextClassLoader())));
}
DynamicEntry.execute("libjf:preEarly", UltraEarlyInit.class, s -> s.instance().init());
DynamicEntry.execute("libjf:early", UltraEarlyInit.class, s -> s.instance().init());
Log.info(LOG_CATEGORY, "LibJF unsafe init completed");
SafeLog.info("LibJF unsafe init completed");
}
}

View File

@ -3,7 +3,6 @@ package io.gitlab.jfronny.libjf.unsafe;
import io.gitlab.jfronny.libjf.unsafe.asm.AsmConfig;
import io.gitlab.jfronny.libjf.unsafe.asm.AsmTransformer;
import io.gitlab.jfronny.libjf.unsafe.asm.BakedAsmConfig;
import net.fabricmc.loader.impl.util.log.Log;
import org.objectweb.asm.tree.ClassNode;
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
@ -38,13 +37,13 @@ public class MixinPlugin implements IMixinConfigPlugin {
AsmTransformer.INSTANCE.delegate = (IMixinTransformer) mixinTransformerField.get(delegate);
AsmTransformer.INSTANCE.asmConfigs = new HashSet<>();
DynamicEntry.execute("libjf:asm", AsmConfig.class, s -> {
Log.info(JfLanguageAdapter.LOG_CATEGORY, "Discovered LibJF asm plugin in " + s.modId());
SafeLog.info("Discovered LibJF asm plugin in " + s.modId());
AsmTransformer.INSTANCE.asmConfigs.add(new BakedAsmConfig(s.instance(), s.modId()));
});
AsmTransformer.INSTANCE.init();
mixinTransformerField.set(delegate, AsmTransformer.INSTANCE);
} catch (NoSuchFieldException | IllegalAccessException | InstantiationException e) {
Log.error(JfLanguageAdapter.LOG_CATEGORY, "Could not initialize LibJF ASM", e);
SafeLog.error("Could not initialize LibJF ASM", e);
}
}

View File

@ -0,0 +1,24 @@
package io.gitlab.jfronny.libjf.unsafe;
import net.fabricmc.loader.impl.util.log.Log;
import net.fabricmc.loader.impl.util.log.LogCategory;
public class SafeLog {
private static final LogCategory LOG_CATEGORY = new LogCategory("libjf");
public static void info(String text) {
Log.info(LOG_CATEGORY, text);
}
public static void warn(String text) {
Log.warn(LOG_CATEGORY, text);
}
public static void error(String text) {
Log.error(LOG_CATEGORY, text);
}
public static void error(String text, Throwable e) {
Log.error(LOG_CATEGORY, text, e);
}
}

View File

@ -1,11 +1,10 @@
package io.gitlab.jfronny.libjf.unsafe.asm;
import io.gitlab.jfronny.libjf.Flags;
import io.gitlab.jfronny.libjf.unsafe.JfLanguageAdapter;
import io.gitlab.jfronny.libjf.unsafe.SafeLog;
import io.gitlab.jfronny.libjf.unsafe.asm.patch.Patch;
import net.fabricmc.loader.api.FabricLoader;
import net.fabricmc.loader.api.MappingResolver;
import net.fabricmc.loader.impl.util.log.Log;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.ClassNode;
@ -40,7 +39,7 @@ public class AsmTransformer implements IMixinTransformer {
for (Flags.BooleanFlag flag : flags) {
flagNames.add(flag.source());
}
Log.info(JfLanguageAdapter.LOG_CATEGORY, "Exporting ASM due to: " + String.join(", ", flagNames));
SafeLog.info("Exporting ASM due to: " + String.join(", ", flagNames));
}
flags = Flags.getBoolFlags("asm.log");
flags.removeIf(flag -> !flag.value());
@ -50,7 +49,7 @@ public class AsmTransformer implements IMixinTransformer {
for (Flags.BooleanFlag flag : flags) {
flagNames.add(flag.source());
}
Log.info(JfLanguageAdapter.LOG_CATEGORY, "Logging ASM logs due to: " + String.join(", ", flagNames));
SafeLog.info("Logging ASM logs due to: " + String.join(", ", flagNames));
}
}
@ -78,7 +77,7 @@ public class AsmTransformer implements IMixinTransformer {
classBytes = delegate.transformClassBytes(name, transformedName, classBytes);
if (classBytes == null || name == null) return classBytes;
if (isClassUnmoddable(name, null)) {
if (debugLogsEnabled()) Log.info(JfLanguageAdapter.LOG_CATEGORY, "Skipping " + name);
if (debugLogsEnabled()) SafeLog.info("Skipping " + name);
return classBytes;
}
@ -94,7 +93,7 @@ public class AsmTransformer implements IMixinTransformer {
patch.apply(klazz);
}
catch (Throwable t) {
Log.error(JfLanguageAdapter.LOG_CATEGORY, "Could not apply patch: " + patch.getClass() + " on " + name, t);
SafeLog.error("Could not apply patch: " + patch.getClass() + " on " + name, t);
}
}
}
@ -106,7 +105,7 @@ public class AsmTransformer implements IMixinTransformer {
klazz.accept(writer);
}
catch (NullPointerException t) {
Log.error(JfLanguageAdapter.LOG_CATEGORY, "Could not transform " + transformedName, t);
SafeLog.error("Could not transform " + transformedName, t);
return null;
}
classBytes = writer.toByteArray();
@ -116,7 +115,7 @@ public class AsmTransformer implements IMixinTransformer {
if (!Files.exists(path)) Files.createDirectories(path.getParent());
Files.write(path, classBytes);
} catch (IOException e) {
Log.error(JfLanguageAdapter.LOG_CATEGORY, "Could not export modified bytecode", e);
SafeLog.error("Could not export modified bytecode", e);
}
}
return classBytes;

View File

@ -1,10 +1,9 @@
package io.gitlab.jfronny.libjf.unsafe.asm.patch.modification;
import io.gitlab.jfronny.libjf.unsafe.JfLanguageAdapter;
import io.gitlab.jfronny.libjf.unsafe.SafeLog;
import io.gitlab.jfronny.libjf.unsafe.asm.AsmTransformer;
import io.gitlab.jfronny.libjf.unsafe.asm.patch.MethodPatch;
import io.gitlab.jfronny.libjf.unsafe.asm.patch.Patch;
import net.fabricmc.loader.impl.util.log.Log;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodNode;
@ -23,7 +22,7 @@ public class MethodModificationPatch implements Patch {
);
}
for (String s : this.patches.keySet()) {
if (AsmTransformer.INSTANCE.debugLogsEnabled()) Log.info(JfLanguageAdapter.LOG_CATEGORY, "Registered patch for " + s);
if (AsmTransformer.INSTANCE.debugLogsEnabled()) SafeLog.info("Registered patch for " + s);
}
}
@ -31,7 +30,7 @@ public class MethodModificationPatch implements Patch {
public void apply(ClassNode klazz) {
for (MethodNode method : klazz.methods) {
if (patches.containsKey(method.name)) {
if (AsmTransformer.INSTANCE.debugLogsEnabled()) Log.info(JfLanguageAdapter.LOG_CATEGORY, "Patching " + method.name);
if (AsmTransformer.INSTANCE.debugLogsEnabled()) SafeLog.info("Patching " + method.name);
patches.get(method.name).apply(method, klazz);
}
}

View File

@ -1,9 +1,8 @@
package io.gitlab.jfronny.libjf.unsafe.asm.patch.targeting;
import io.gitlab.jfronny.libjf.unsafe.JfLanguageAdapter;
import io.gitlab.jfronny.libjf.unsafe.SafeLog;
import io.gitlab.jfronny.libjf.unsafe.asm.AsmTransformer;
import io.gitlab.jfronny.libjf.unsafe.asm.patch.Patch;
import net.fabricmc.loader.impl.util.log.Log;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.ClassNode;
@ -23,7 +22,7 @@ public class InterfaceImplTargetPatch implements Patch {
public void apply(ClassNode klazz) {
scanInterfaces(klazz);
if (getUpper(klazz.name).contains(targetInterface)) {
if (AsmTransformer.INSTANCE.debugLogsEnabled()) Log.info(JfLanguageAdapter.LOG_CATEGORY, "Found " + klazz.name + " implementing " + targetInterface);
if (AsmTransformer.INSTANCE.debugLogsEnabled()) SafeLog.info("Found " + klazz.name + " implementing " + targetInterface);
methodPatch.apply(klazz);
}
}
@ -79,7 +78,7 @@ public class InterfaceImplTargetPatch implements Patch {
&& !className.startsWith("it/unimi/dsi/fastutil/")
&& !className.startsWith("com/google/")
) {
if (AsmTransformer.INSTANCE.debugLogsEnabled()) Log.info(JfLanguageAdapter.LOG_CATEGORY, "Non-default class not considered for interface scanning: " + className);
if (AsmTransformer.INSTANCE.debugLogsEnabled()) SafeLog.info("Non-default class not considered for interface scanning: " + className);
INTERFACES.put(className, Set.of());
return Set.of();
}
@ -87,7 +86,7 @@ public class InterfaceImplTargetPatch implements Patch {
scanInterfaces(Class.forName(className.replace('/', '.')));
s = INTERFACES.get(className);
} catch (ClassNotFoundException e) {
Log.error(JfLanguageAdapter.LOG_CATEGORY, "Could not get base for " + className, e);
SafeLog.error("Could not get base for " + className, e);
return Set.of();
}
}