format
This commit is contained in:
parent
9e61b40f81
commit
ac09413c61
|
@ -1,6 +1,9 @@
|
|||
package org.ecorous.esnesnon.nonsense.loader.impl;
|
||||
|
||||
import java.io.*;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
|
@ -11,29 +14,26 @@ import java.util.*;
|
|||
import java.util.stream.Collectors;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import lombok.Getter;
|
||||
import org.ecorous.esnesnon.nonsense.loader.api.Loader;
|
||||
import org.ecorous.esnesnon.nonsense.loader.api.env.Env;
|
||||
import org.ecorous.esnesnon.nonsense.loader.api.mod.ModProperties;
|
||||
import org.ecorous.esnesnon.nonsense.loader.impl.launch.MixinClassLoader;
|
||||
import org.ecorous.esnesnon.nonsense.loader.impl.mod.ModUtil;
|
||||
import org.ecorous.esnesnon.nonsense.loader.impl.plugin.NonsensePlugin;
|
||||
import lombok.Getter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.spongepowered.asm.mixin.MixinEnvironment;
|
||||
|
||||
public class LoaderImpl implements Loader {
|
||||
public static final String MOD_FILE_EXTENSION = ".frogmod";
|
||||
@Getter
|
||||
private static LoaderImpl instance;
|
||||
private final boolean DEV_ENV = Boolean.getBoolean("nonsense.development");
|
||||
|
||||
@Getter
|
||||
private final String[] args;
|
||||
@Getter
|
||||
private final Env env;
|
||||
|
||||
@Getter
|
||||
private static LoaderImpl instance;
|
||||
|
||||
private final Logger LOGGER = LoggerFactory.getLogger("Frogloader");
|
||||
|
||||
@Getter
|
||||
|
@ -79,6 +79,15 @@ public class LoaderImpl implements Loader {
|
|||
plugins.forEach(NonsensePlugin::run);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static void run(String[] args, Env env) {
|
||||
if (instance != null) {
|
||||
throw new IllegalStateException("Loader was started multiple times!");
|
||||
}
|
||||
|
||||
new LoaderImpl(args, env);
|
||||
}
|
||||
|
||||
private void advanceMixinState() {
|
||||
try {
|
||||
MethodHandle m = MethodHandles.privateLookupIn(MixinEnvironment.class, MethodHandles.lookup()).findStatic(MixinEnvironment.class, "gotoPhase", MethodType.methodType(void.class, MixinEnvironment.Phase.class));
|
||||
|
@ -89,15 +98,6 @@ public class LoaderImpl implements Loader {
|
|||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static void run(String[] args, Env env) {
|
||||
if (instance != null) {
|
||||
throw new IllegalStateException("Loader was started multiple times!");
|
||||
}
|
||||
|
||||
new LoaderImpl(args, env);
|
||||
}
|
||||
|
||||
private void discoverPlugins() {
|
||||
List<String> classes = new ArrayList<>();
|
||||
this.getClass().getClassLoader().resources("META-INF/services/" + NonsensePlugin.class.getName()).distinct().forEach(url -> {
|
||||
|
|
|
@ -6,30 +6,24 @@ import java.lang.invoke.MethodType;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.ecorous.esnesnon.nonsense.loader.api.env.Env;
|
||||
import org.ecorous.esnesnon.nonsense.loader.impl.mixin.NonsenseMixinService;
|
||||
import lombok.Getter;
|
||||
import org.spongepowered.asm.launch.MixinBootstrap;
|
||||
import org.spongepowered.asm.service.IPropertyKey;
|
||||
|
||||
public class Launcher {
|
||||
|
||||
@Getter
|
||||
private final MixinClassLoader targetClassLoader;
|
||||
|
||||
@Getter
|
||||
private static Launcher instance;
|
||||
|
||||
@Getter
|
||||
private final MixinClassLoader targetClassLoader;
|
||||
@Getter
|
||||
private final Map<IPropertyKey, Object> globalProperties = new HashMap<>();
|
||||
|
||||
@Getter
|
||||
private final Env env;
|
||||
|
||||
public static void run(String[] args, Env env) {
|
||||
new Launcher(args, env);
|
||||
}
|
||||
|
||||
public Launcher(String[] args, Env env) {
|
||||
if (instance != null) {
|
||||
throw new IllegalStateException();
|
||||
|
@ -57,4 +51,8 @@ public class Launcher {
|
|||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void run(String[] args, Env env) {
|
||||
new Launcher(args, env);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
package org.ecorous.esnesnon.nonsense.loader.impl.launch;
|
||||
|
||||
import org.ecorous.esnesnon.nonsense.loader.impl.mixin.NonsenseMixinService;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.MixinEnvironment;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
|
@ -13,15 +9,20 @@ import java.util.Collections;
|
|||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
|
||||
import org.ecorous.esnesnon.nonsense.loader.impl.mixin.NonsenseMixinService;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.MixinEnvironment;
|
||||
|
||||
public class MixinClassLoader extends URLClassLoader {
|
||||
|
||||
private static final ClassLoader SYSTEM = ClassLoader.getSystemClassLoader();
|
||||
private final List<String> exclusions = new ArrayList<>();
|
||||
|
||||
static {
|
||||
registerAsParallelCapable();
|
||||
}
|
||||
|
||||
private final List<String> exclusions = new ArrayList<>();
|
||||
|
||||
public MixinClassLoader() {
|
||||
super(new URL[0], null);
|
||||
excludePackage("java");
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package org.ecorous.esnesnon.nonsense.loader.impl.launch.client;
|
||||
|
||||
import org.ecorous.esnesnon.nonsense.loader.impl.launch.Launcher;
|
||||
import org.ecorous.esnesnon.nonsense.loader.api.env.Env;
|
||||
import org.ecorous.esnesnon.nonsense.loader.impl.launch.Launcher;
|
||||
|
||||
public class NonsenseClient {
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package org.ecorous.esnesnon.nonsense.loader.impl.launch.server;
|
||||
|
||||
import org.ecorous.esnesnon.nonsense.loader.impl.launch.Launcher;
|
||||
import org.ecorous.esnesnon.nonsense.loader.api.env.Env;
|
||||
import org.ecorous.esnesnon.nonsense.loader.impl.launch.Launcher;
|
||||
|
||||
public class NonsenseServer {
|
||||
|
||||
|
|
|
@ -12,11 +12,6 @@ import org.spongepowered.asm.logging.LoggerAdapterAbstract;
|
|||
|
||||
public class NonsenseMixinLogger extends LoggerAdapterAbstract {
|
||||
private static final Map<String, NonsenseMixinLogger> LOGGERS = new ConcurrentHashMap<>();
|
||||
|
||||
public static ILogger get(String name){
|
||||
return LOGGERS.computeIfAbsent(name, NonsenseMixinLogger::new);
|
||||
}
|
||||
|
||||
private final Logger log;
|
||||
|
||||
public NonsenseMixinLogger(String name) {
|
||||
|
@ -24,6 +19,10 @@ public class NonsenseMixinLogger extends LoggerAdapterAbstract {
|
|||
log = LoggerFactory.getLogger("Nonsense Loader/" + name.substring(0, 1).toUpperCase(Locale.ROOT) + name.substring(1));
|
||||
}
|
||||
|
||||
public static ILogger get(String name) {
|
||||
return LOGGERS.computeIfAbsent(name, NonsenseMixinLogger::new);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return "Nonsense Loader/Mixin Logger";
|
||||
|
@ -33,6 +32,7 @@ public class NonsenseMixinLogger extends LoggerAdapterAbstract {
|
|||
public void catching(Level level, Throwable t) {
|
||||
log.atLevel(org.slf4j.event.Level.valueOf(level.name())).setCause(t).log();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log(Level level, String message, Object... params) {
|
||||
log.atLevel(org.slf4j.event.Level.valueOf(level.name())).log(message, params);
|
||||
|
|
|
@ -19,16 +19,14 @@ import org.slf4j.LoggerFactory;
|
|||
public class ModDependencyResolver {
|
||||
|
||||
private final static Logger LOGGER = LoggerFactory.getLogger(ModDependencyResolver.class);
|
||||
|
||||
private static final Pattern COMPARATOR = Pattern.compile("(=|>=|<=|>|<)?(\\d.*)");
|
||||
private final Collection<ModProperties> original;
|
||||
|
||||
private final Map<String, DependencyEntry> dependencies = new HashMap<>();
|
||||
private final Map<String, DependencyEntry> breakings = new HashMap<>();
|
||||
private final Map<String, DependencyEntry> suggests = new HashMap<>();
|
||||
private final Map<String, SemVer> provides = new HashMap<>();
|
||||
private final Map<String, ModProperties> presentMods = new HashMap<>();
|
||||
|
||||
|
||||
public ModDependencyResolver(Collection<ModProperties> mods) throws ResolverException {
|
||||
this.original = Collections.unmodifiableCollection(mods);
|
||||
load();
|
||||
|
@ -116,35 +114,6 @@ public class ModDependencyResolver {
|
|||
return result;
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public static class BreakingModException extends Exception {
|
||||
private final ModProperties source, broken;
|
||||
private final VersionRange range;
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public static class UnfulfilledDependencyException extends Exception {
|
||||
private final ModProperties source;
|
||||
private final String dependency;
|
||||
private final VersionRange range;
|
||||
}
|
||||
|
||||
public static class ResolverException extends Exception {
|
||||
public ResolverException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private record DependencyEntry(VersionRange range, ModProperties origin) {
|
||||
|
||||
public DependencyEntry(String range, ModProperties origin) throws ResolverException {
|
||||
this(VersionRange.parse(range), origin);
|
||||
}
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
private enum DependencyType {
|
||||
EQ("=", Object::equals),
|
||||
|
@ -166,7 +135,33 @@ public class ModDependencyResolver {
|
|||
}
|
||||
}
|
||||
|
||||
private static final Pattern COMPARATOR = Pattern.compile("(=|>=|<=|>|<)?(\\d.*)");
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public static class BreakingModException extends Exception {
|
||||
private final ModProperties source, broken;
|
||||
private final VersionRange range;
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public static class UnfulfilledDependencyException extends Exception {
|
||||
private final ModProperties source;
|
||||
private final String dependency;
|
||||
private final VersionRange range;
|
||||
}
|
||||
|
||||
public static class ResolverException extends Exception {
|
||||
public ResolverException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
||||
private record DependencyEntry(VersionRange range, ModProperties origin) {
|
||||
|
||||
public DependencyEntry(String range, ModProperties origin) throws ResolverException {
|
||||
this(VersionRange.parse(range), origin);
|
||||
}
|
||||
}
|
||||
|
||||
private record Comparator(DependencyType type, SemVer version) {
|
||||
|
||||
|
@ -222,6 +217,8 @@ public class ModDependencyResolver {
|
|||
|
||||
private record VersionRange(Collection<ComparatorSet> sets) {
|
||||
|
||||
private static final Pattern NUMBER_EXTRACTOR = Pattern.compile("[^~]?(\\d+)(?:\\.(?:([\\dxX*]+)(?:\\.([\\dxX*]+)?)?)?)?(.*)");
|
||||
|
||||
public static VersionRange parse(String range) throws ResolverException {
|
||||
|
||||
String[] sets = resolveAdvanced(range).split("\\|\\|");
|
||||
|
@ -229,8 +226,6 @@ public class ModDependencyResolver {
|
|||
return new VersionRange(Arrays.stream(sets).map(ComparatorSet::parse).toList());
|
||||
}
|
||||
|
||||
private static final Pattern NUMBER_EXTRACTOR = Pattern.compile("[^~]?(\\d+)(?:\\.(?:([\\dxX*]+)(?:\\.([\\dxX*]+)?)?)?)?(.*)");
|
||||
|
||||
private static String resolveAdvanced(String range) throws ResolverException {
|
||||
if (range.isEmpty() || range.equals("*")) {
|
||||
return ">=0.0.0";
|
||||
|
|
|
@ -14,14 +14,15 @@ import com.electronwill.nightconfig.core.UnmodifiableConfig;
|
|||
import com.electronwill.nightconfig.core.file.FileNotFoundAction;
|
||||
import com.electronwill.nightconfig.toml.TomlParser;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.ecorous.esnesnon.nonsense.loader.api.mod.*;
|
||||
import org.ecorous.esnesnon.nonsense.loader.api.mod.ModDependencies;
|
||||
import org.ecorous.esnesnon.nonsense.loader.api.mod.ModExtensions;
|
||||
import org.ecorous.esnesnon.nonsense.loader.api.mod.ModProperties;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class ModPropertiesReader {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ModPropertiesReader.class);
|
||||
public static final String PROPERTIES_FILE_NAME = "frog.mod.toml";
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ModPropertiesReader.class);
|
||||
private static final TomlParser PARSER = new TomlParser();
|
||||
|
||||
public static Optional<ModProperties> read(Path mod) {
|
||||
|
@ -104,11 +105,10 @@ public class ModPropertiesReader {
|
|||
return new ModPropertiesImpl(id, name, SemVerImpl.parse(version), license, Collections.unmodifiableMap(credits), new ModDependencies(depends, breaks, suggests, provides), ModExtensions.of(extensions));
|
||||
});
|
||||
|
||||
private static final Map<String, Parser> versions = Arrays.stream(values()).collect(Collectors.toMap(v -> v.version, v -> v.parser));
|
||||
private final String version;
|
||||
private final Parser parser;
|
||||
|
||||
private static final Map<String, Parser> versions = Arrays.stream(values()).collect(Collectors.toMap(v -> v.version, v -> v.parser));
|
||||
|
||||
public static Parser get(String version) {
|
||||
return versions.get(version);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,210 @@
|
|||
package org.ecorous.esnesnon.nonsense.loader.impl.plugin.game.minecraft;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentSkipListSet;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.ecorous.esnesnon.nonsense.loader.api.mod.ModProperties;
|
||||
import org.ecorous.esnesnon.nonsense.loader.impl.mod.BuiltinExtensions;
|
||||
import org.objectweb.asm.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Minimal implementation of accesswideners.
|
||||
*/
|
||||
|
||||
class AWProcessor {
|
||||
|
||||
private static final String AW_EXTENSION_NAME = BuiltinExtensions.ACCESSWIDENER;
|
||||
private static final Predicate<String> HEADER = Pattern.compile("accessWidener\\s+v[12]\\s+.*").asMatchPredicate();
|
||||
private static final String SEPARATOR = "[\\t ]+";
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger("AccessWidener");
|
||||
|
||||
static void apply(Collection<ModProperties> mods, Path input, Path output) throws IOException {
|
||||
long startTime = System.currentTimeMillis();
|
||||
Map<String, Entry> classMap = new ConcurrentHashMap<>();
|
||||
Map<String, Map<String, Entry>> methods = new ConcurrentHashMap<>();
|
||||
Map<String, Map<String, Entry>> fields = new ConcurrentHashMap<>();
|
||||
Map<String, Map<String, Entry>> mutations = new ConcurrentHashMap<>();
|
||||
Set<String> classNames = new ConcurrentSkipListSet<>();
|
||||
|
||||
mods.stream().map(ModProperties::extensions).map(e -> (String) e.get(AW_EXTENSION_NAME))
|
||||
.filter(Objects::nonNull).map(s -> "/" + s).map(AWProcessor.class::getResourceAsStream).filter(Objects::nonNull)
|
||||
.map(InputStreamReader::new).map(BufferedReader::new).flatMap(BufferedReader::lines)
|
||||
.map(l -> l.contains("#") ? l.split("#")[0] : l).filter(l -> !l.isBlank())
|
||||
.filter(l -> !HEADER.test(l)).distinct()
|
||||
.map(l -> l.replace("transitive-", "")) // ignore all transitive declarations (just make them normal) as they're only relevant for dev envs
|
||||
.map(l -> l.split(SEPARATOR)).filter(l -> l.length > 0).map(Entry::new).forEach(e -> {
|
||||
classNames.add(e.className);
|
||||
if ("class".equals(e.targetType)) {
|
||||
if (e.type == AccessType.MUTABLE) {
|
||||
throw new IllegalArgumentException("aw format error: classes can not have a 'mutable' modifier (at: " + e + ")");
|
||||
}
|
||||
if (!classMap.containsKey(e.className)) {
|
||||
classMap.put(e.className, e);
|
||||
} else {
|
||||
var other = classMap.get(e.className);
|
||||
if (e.isAccessGreaterThan(other)) {
|
||||
classMap.put(e.className, e);
|
||||
}
|
||||
}
|
||||
} else if ("method".equals(e.targetType)) {
|
||||
if (e.type == AccessType.MUTABLE) {
|
||||
throw new IllegalArgumentException("aw format error: methods can not have a 'mutable' modifier (at: " + e + ")");
|
||||
}
|
||||
var map = methods.computeIfAbsent(e.className, s -> new ConcurrentHashMap<>());
|
||||
var id = e.name + e.descriptor;
|
||||
if (!map.containsKey(id)) {
|
||||
map.put(id, e);
|
||||
} else {
|
||||
var other = map.get(id);
|
||||
if (e.isAccessGreaterThan(other)) {
|
||||
classMap.put(id, e);
|
||||
}
|
||||
}
|
||||
} else if ("field".equals(e.targetType)) {
|
||||
if (e.type == AccessType.EXTENDABLE) {
|
||||
throw new IllegalArgumentException("aw format error: fields can not have a 'extendable' modifier (at: " + e + ")");
|
||||
}
|
||||
var map = fields.computeIfAbsent(e.className, s -> new ConcurrentHashMap<>());
|
||||
var id = e.name + e.descriptor;
|
||||
if (e.type == AccessType.MUTABLE) {
|
||||
mutations.computeIfAbsent(e.className, s -> new ConcurrentHashMap<>()).putIfAbsent(id, e);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!map.containsKey(id)) {
|
||||
map.put(id, e);
|
||||
} else {
|
||||
var other = map.get(id);
|
||||
if (e.isAccessGreaterThan(other)) {
|
||||
classMap.put(id, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Files.deleteIfExists(output);
|
||||
Files.copy(input, output);
|
||||
|
||||
if (!classNames.isEmpty()) {
|
||||
try (FileSystem out = FileSystems.newFileSystem(output)) {
|
||||
|
||||
for (String name : classNames) {
|
||||
processFile(name, out.getPath("/" + name + ".class"), classMap, fields, methods, mutations);
|
||||
}
|
||||
}
|
||||
}
|
||||
LOGGER.info(String.format("Applied AccessWideners in %.2fs", (System.currentTimeMillis() - startTime) / 1000f));
|
||||
}
|
||||
|
||||
private static void processFile(String className, Path file, Map<String, Entry> classMap, Map<String, Map<String, Entry>> fields, Map<String, Map<String, Entry>> methods, Map<String, Map<String, Entry>> mutations) throws IOException {
|
||||
ClassReader reader = new ClassReader(Files.newInputStream(file));
|
||||
ClassWriter writer = new ClassWriter(0);
|
||||
ClassVisitor mapper = new ClassVisitor(Opcodes.ASM9, writer) {
|
||||
@Override
|
||||
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
|
||||
Entry e = classMap.get(className);
|
||||
if (e != null) {
|
||||
access &= ~(Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED | Opcodes.ACC_PUBLIC);
|
||||
access |= e.type.access;
|
||||
}
|
||||
if (fields.containsKey(className) || methods.containsKey(className) || mutations.containsKey(className)) { // make all classes with modifications public as well
|
||||
access &= ~(Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED | Opcodes.ACC_PUBLIC);
|
||||
access |= Opcodes.ACC_PUBLIC;
|
||||
}
|
||||
super.visit(version, access, name, signature, superName, interfaces);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FieldVisitor visitField(int access, String name, String descriptor, String signature, Object value) {
|
||||
Map<String, Entry> map = fields.get(className);
|
||||
if (map != null) {
|
||||
Entry e = map.get(name + descriptor);
|
||||
if (e != null) {
|
||||
access &= ~(Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED | Opcodes.ACC_PUBLIC); // remove all access modifiers
|
||||
access |= e.type.access; // re-add the new one
|
||||
}
|
||||
}
|
||||
if ((map = mutations.get(className)) != null) {
|
||||
var e = map.get(name + descriptor);
|
||||
if (e != null) {
|
||||
access &= ~Opcodes.ACC_FINAL; // always AccessType.MUTABLE
|
||||
}
|
||||
}
|
||||
return super.visitField(access, name, descriptor, signature, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
|
||||
Map<String, Entry> map = methods.get(className);
|
||||
if (map != null) {
|
||||
Entry e = map.get(name + descriptor);
|
||||
if (e != null) {
|
||||
access &= ~(Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED | Opcodes.ACC_PUBLIC);
|
||||
access |= e.type.access;
|
||||
}
|
||||
}
|
||||
return super.visitMethod(access, name, descriptor, signature, exceptions);
|
||||
}
|
||||
};
|
||||
|
||||
reader.accept(mapper, 0);
|
||||
|
||||
Files.write(file, writer.toByteArray());
|
||||
}
|
||||
|
||||
private record Entry(AccessType type, String targetType, String className, String name, String descriptor) {
|
||||
|
||||
public Entry(String[] line) {
|
||||
this(AccessType.of(line[0]), line[1], line[2], line[3], line[4]);
|
||||
}
|
||||
|
||||
public boolean isAccessGreaterThan(Entry other) {
|
||||
return Access.of(type().access).index < Access.of(other.type.access).index;
|
||||
}
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
private enum AccessType {
|
||||
ACCESSIBLE("accessible", Opcodes.ACC_PUBLIC),
|
||||
EXTENDABLE("extendable", Opcodes.ACC_PROTECTED),
|
||||
MUTABLE("mutable", ~Opcodes.ACC_FINAL);
|
||||
private final String id;
|
||||
private final int access;
|
||||
|
||||
public static AccessType of(String name) {
|
||||
return Arrays.stream(values()).filter(a -> a.id.equals(name)).findFirst().orElseThrow(() -> new IllegalStateException("Unknown access type: " + name));
|
||||
}
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
private enum Access {
|
||||
PUBLIC(1), PROTECTED(2), PACKAGE_PRIVATE(3), PRIVATE(4);
|
||||
private final int index;
|
||||
|
||||
public static Access of(int access) {
|
||||
if ((access & Opcodes.ACC_PUBLIC) != 0) {
|
||||
return PUBLIC;
|
||||
}
|
||||
if ((access & Opcodes.ACC_PROTECTED) != 0) {
|
||||
return PROTECTED;
|
||||
}
|
||||
if ((access & Opcodes.ACC_PRIVATE) != 0) {
|
||||
return PRIVATE;
|
||||
}
|
||||
return PACKAGE_PRIVATE;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,7 +12,9 @@ import java.util.*;
|
|||
|
||||
import com.google.gson.JsonObject;
|
||||
import org.ecorous.esnesnon.nonsense.loader.api.extensions.PreLaunchExtension;
|
||||
import org.ecorous.esnesnon.nonsense.loader.api.mod.*;
|
||||
import org.ecorous.esnesnon.nonsense.loader.api.mod.ModDependencies;
|
||||
import org.ecorous.esnesnon.nonsense.loader.api.mod.ModExtensions;
|
||||
import org.ecorous.esnesnon.nonsense.loader.api.mod.ModProperties;
|
||||
import org.ecorous.esnesnon.nonsense.loader.impl.Discovery;
|
||||
import org.ecorous.esnesnon.nonsense.loader.impl.LoaderImpl;
|
||||
import org.ecorous.esnesnon.nonsense.loader.impl.mod.BuiltinExtensions;
|
||||
|
@ -27,17 +29,16 @@ import org.spongepowered.asm.mixin.Mixins;
|
|||
|
||||
public class Minecraft implements NonsensePlugin {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger("Plugin/Minecraft");
|
||||
protected static final String[] MINECRAFT_CLASSES = new String[]{
|
||||
"net/minecraft/client/main/Main.class",
|
||||
"net/minecraft/client/MinecraftApplet.class",
|
||||
"net/minecraft/server/Main.class"
|
||||
};
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger("Plugin/Minecraft");
|
||||
protected final Collection<ModProperties> modProperties = new ArrayList<>();
|
||||
private String version;
|
||||
protected Path gamePath;
|
||||
protected String foundMainClass;
|
||||
private String version;
|
||||
|
||||
@Override
|
||||
public boolean isApplicable() {
|
||||
|
|
|
@ -8,6 +8,7 @@ import org.jetbrains.annotations.NotNull;
|
|||
public class MinecraftSemVerImpl implements SemVer {
|
||||
|
||||
private final String version;
|
||||
|
||||
private MinecraftSemVerImpl(String version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue