mirror of
https://github.com/FalsePattern/FalsePatternLib.git
synced 2026-11-15 21:54:45 +00:00
initial "implementation" of the reflection tools. Only a mapping explorer for now.
This commit is contained in:
12 files changed
+22383
No files matched your search
@@ -0,0 +1,117 @@
|
||||
package com.falsepattern.lib.internal;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
@Getter
|
||||
class SRGGen {
|
||||
private static class StringPair {
|
||||
public final String name;
|
||||
public final String desc;
|
||||
|
||||
private StringPair(String name, String desc) {
|
||||
this.name = name;
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
StringPair that = (StringPair) o;
|
||||
return name.equals(that.name) && desc.equals(that.desc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(name, desc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name + "," + desc;
|
||||
}
|
||||
}
|
||||
private static Map<String, String> class_notch_srg = new HashMap<>();
|
||||
private static Map<String, String> class_notch_mcp = new HashMap<>();
|
||||
private static Map<String, String> class_srg_mcp = new HashMap<>();
|
||||
private static Map<String, String> class_mcp_srg = new HashMap<>();
|
||||
private static Map<String, String> class_mcp_notch = new HashMap<>();
|
||||
private static Map<String, String> field_notch_srg = new HashMap<>();
|
||||
private static Map<String, String> field_notch_mcp = new HashMap<>();
|
||||
private static Map<String, String> field_srg_mcp = new HashMap<>();
|
||||
private static Map<String, String> field_mcp_srg = new HashMap<>();
|
||||
private static Map<String, String> field_mcp_notch = new HashMap<>();
|
||||
private static Map<StringPair, StringPair> method_notch_srg = new HashMap<>();
|
||||
private static Map<StringPair, StringPair> method_notch_mcp = new HashMap<>();
|
||||
private static Map<StringPair, StringPair> method_srg_mcp = new HashMap<>();
|
||||
private static Map<StringPair, StringPair> method_mcp_srg = new HashMap<>();
|
||||
private static Map<StringPair, StringPair> method_mcp_notch = new HashMap<>();
|
||||
public static void main(String[] args) throws IOException {
|
||||
Path dir = Paths.get(args[0]);
|
||||
parseLines(Files.readAllLines(dir.resolve("notch-srg.srg")), class_notch_srg, field_notch_srg, method_notch_srg);
|
||||
parseLines(Files.readAllLines(dir.resolve("notch-mcp.srg")), class_notch_mcp, field_notch_mcp, method_notch_mcp);
|
||||
parseLines(Files.readAllLines(dir.resolve("srg-mcp.srg")), class_srg_mcp, field_srg_mcp, method_srg_mcp);
|
||||
parseLines(Files.readAllLines(dir.resolve("mcp-srg.srg")), class_mcp_srg, field_mcp_srg, method_mcp_srg);
|
||||
parseLines(Files.readAllLines(dir.resolve("mcp-notch.srg")), class_mcp_notch, field_mcp_notch, method_mcp_notch);
|
||||
try (OutputStream output = Files.newOutputStream(dir.resolve("classes.csv"))) {
|
||||
output.write("notch,srg,mcp\n".getBytes(StandardCharsets.UTF_8));
|
||||
crossValidate(class_notch_srg, class_notch_mcp, class_srg_mcp, class_mcp_srg, class_mcp_notch, output);
|
||||
}
|
||||
try (OutputStream output = Files.newOutputStream(dir.resolve("fields.csv"))) {
|
||||
output.write("notch,srg,mcp\n".getBytes(StandardCharsets.UTF_8));
|
||||
crossValidate(field_notch_srg, field_notch_mcp, field_srg_mcp, field_mcp_srg, field_mcp_notch, output);
|
||||
}
|
||||
|
||||
try (OutputStream output = Files.newOutputStream(dir.resolve("methods.csv"))) {
|
||||
output.write("notch,notchdesc,srg,srgdesc,mcp,mcpdesc\n".getBytes(StandardCharsets.UTF_8));
|
||||
crossValidate(method_notch_srg, method_notch_mcp, method_srg_mcp, method_mcp_srg, method_mcp_notch, output);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean crossValidate(Map<?, ?> notch_srg, Map<?, ?> notch_mcp, Map<?, ?> srg_mcp, Map<?, ?> mcp_srg, Map<?, ?> mcp_notch, OutputStream output)
|
||||
throws IOException {
|
||||
for (Map.Entry<?, ?> notch_srg_entry: notch_srg.entrySet()) {
|
||||
Object notch = notch_srg_entry.getKey();
|
||||
Object srg = notch_srg_entry.getValue();
|
||||
Object mcp = notch_mcp.get(notch);
|
||||
if (!srg_mcp.get(srg).equals(mcp) ||
|
||||
!mcp_srg.get(mcp).equals(srg) ||
|
||||
!mcp_notch.get(mcp).equals(notch)) {
|
||||
throw new RuntimeException(notch + " - " + srg + " - " + mcp);
|
||||
}
|
||||
output.write((notch + "," + srg + "," + mcp + "\n").getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void parseLines(List<String> lines, Map<String, String> classes, Map<String, String> fields, Map<StringPair, StringPair> methods) {
|
||||
for (String line: lines) {
|
||||
String[] parts = line.split(" ");
|
||||
switch (parts[0]) {
|
||||
case "CL:":
|
||||
classes.put(parts[1], parts[2]);
|
||||
break;
|
||||
case "FD:":
|
||||
fields.put(parts[1], parts[2]);
|
||||
break;
|
||||
case "MD:":
|
||||
methods.put(new StringPair(parts[1], parts[2]), new StringPair(parts[3], parts[4]));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.falsepattern.lib.reflection;
|
||||
|
||||
import com.falsepattern.lib.reflection.types.MappingType;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import lombok.ToString;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
@Accessors(fluent = true)
|
||||
@ToString
|
||||
@EqualsAndHashCode
|
||||
@Getter
|
||||
public class MappedString {
|
||||
public final String notch;
|
||||
public final String srg;
|
||||
public final String mcp;
|
||||
public MappedString(String[] source, int offset, int stride, Function<String, String> remapper, Map<String, String> stringPool) {
|
||||
notch = stringPool.computeIfAbsent(remapper.apply(source[offset ]), (str) -> str);
|
||||
srg = stringPool.computeIfAbsent(remapper.apply(source[offset + stride ]), (str) -> str);
|
||||
mcp = stringPool.computeIfAbsent(remapper.apply(source[offset + stride * 2]), (str) -> str);
|
||||
}
|
||||
|
||||
public String get(@NonNull MappingType type) {
|
||||
switch (type) {
|
||||
case Notch:
|
||||
return notch;
|
||||
case SRG:
|
||||
return srg;
|
||||
case MCP:
|
||||
return mcp;
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid enum value " + type);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package com.falsepattern.lib.reflection;
|
||||
|
||||
import com.falsepattern.lib.internal.FalsePatternLib;
|
||||
import com.falsepattern.lib.reflection.storage.Lookup;
|
||||
import com.falsepattern.lib.reflection.types.MappingType;
|
||||
import com.falsepattern.lib.reflection.types.NameType;
|
||||
import com.falsepattern.lib.util.ResourceUtil;
|
||||
import lombok.NonNull;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.val;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class MappingManager {
|
||||
private static boolean initialized = false;
|
||||
|
||||
private static final Lookup<UniversalClass> internalLookup = new Lookup<>();
|
||||
private static final Lookup<UniversalClass> regularLookup = new Lookup<>();
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
private static synchronized void initialize() {
|
||||
if (initialized) return;
|
||||
initialized = true;
|
||||
val stringPool = new HashMap<String, String>();
|
||||
{
|
||||
val classMappings = ResourceUtil.getResourceStringFromJar("/classes.csv", FalsePatternLib.class).split("\n");
|
||||
for (int i = 1; i < classMappings.length; i++) {
|
||||
val line = classMappings[i].split(",");
|
||||
val clazz = new UniversalClass(line, stringPool);
|
||||
internalLookup.unwrap(clazz.internalName, clazz);
|
||||
regularLookup.unwrap(clazz.regularName, clazz);
|
||||
}
|
||||
}
|
||||
{
|
||||
val fieldMappings = ResourceUtil.getResourceStringFromJar("/fields.csv", FalsePatternLib.class).split("\n");
|
||||
for (int i = 1; i < fieldMappings.length; i++) {
|
||||
val line = fieldMappings[i].split(",");
|
||||
val field = new UniversalField(line, stringPool);
|
||||
val clazz = internalLookup.get(MappingType.Notch, line[0].substring(0, line[0].lastIndexOf('/')));
|
||||
clazz.addField(field);
|
||||
}
|
||||
}
|
||||
{
|
||||
val methodMappings = ResourceUtil.getResourceStringFromJar("/methods.csv", FalsePatternLib.class).split("\n");
|
||||
for (int i = 1; i < methodMappings.length; i++) {
|
||||
val line = methodMappings[i].split(",");
|
||||
val field = new UniversalMethod(line, stringPool);
|
||||
val clazz = internalLookup.get(MappingType.Notch, line[0].substring(0, line[0].lastIndexOf('/')));
|
||||
clazz.addMethod(field);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static UniversalClass classForName(@NonNull NameType nameType, @NonNull MappingType mappingType, String className) {
|
||||
initialize();
|
||||
switch (nameType) {
|
||||
case Internal:
|
||||
return internalLookup.get(mappingType, className);
|
||||
case Regular:
|
||||
return regularLookup.get(mappingType, className);
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid enum value " + nameType);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.falsepattern.lib.reflection;
|
||||
|
||||
import com.falsepattern.lib.reflection.storage.Lookup;
|
||||
import com.falsepattern.lib.reflection.types.MappingType;
|
||||
import com.falsepattern.lib.reflection.types.NameType;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import lombok.ToString;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Accessors(fluent = true)
|
||||
@ToString
|
||||
@EqualsAndHashCode
|
||||
public class UniversalClass {
|
||||
@Getter
|
||||
public final MappedString internalName;
|
||||
@Getter
|
||||
public final MappedString regularName;
|
||||
|
||||
private final Lookup<UniversalField> fields = new Lookup<>();
|
||||
private final Lookup<UniversalMethod> methods = new Lookup<>();
|
||||
|
||||
public UniversalClass(String[] names, Map<String, String> stringPool) {
|
||||
internalName = new MappedString(names, 0, 1, (str) -> str, stringPool);
|
||||
regularName = new MappedString(names, 0, 1, (str) -> str.replace('/', '.'), stringPool);
|
||||
}
|
||||
|
||||
public void addField(UniversalField field) {
|
||||
fields.unwrap(field.name, field);
|
||||
}
|
||||
|
||||
public void addMethod(UniversalMethod method) {
|
||||
methods.unwrap(method.name, method);
|
||||
}
|
||||
|
||||
public String getName(@NonNull NameType nameType, @NonNull MappingType mappingType) {
|
||||
switch (nameType) {
|
||||
case Internal:
|
||||
return internalName.get(mappingType);
|
||||
case Regular:
|
||||
return regularName.get(mappingType);
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid enum value " + nameType);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.falsepattern.lib.reflection;
|
||||
|
||||
import com.falsepattern.lib.reflection.types.MappingType;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import lombok.ToString;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Accessors(fluent = true)
|
||||
@ToString
|
||||
@EqualsAndHashCode
|
||||
public class UniversalField {
|
||||
@Getter
|
||||
public final MappedString name;
|
||||
|
||||
public UniversalField(String[] names, Map<String, String> stringPool) {
|
||||
name = new MappedString(names, 0, 1, (str) -> str.substring(str.lastIndexOf('/') + 1), stringPool);
|
||||
}
|
||||
|
||||
public String getName(@NonNull MappingType mappingType) {
|
||||
return name.get(mappingType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.falsepattern.lib.reflection;
|
||||
|
||||
import com.falsepattern.lib.reflection.types.MappingType;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import lombok.ToString;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Accessors(fluent = true)
|
||||
@ToString
|
||||
@EqualsAndHashCode
|
||||
public class UniversalMethod {
|
||||
@Getter
|
||||
public final MappedString name;
|
||||
@Getter
|
||||
public final MappedString descriptor;
|
||||
|
||||
public UniversalMethod(String[] names, Map<String, String> stringPool) {
|
||||
name = new MappedString(names, 0, 2, (str) -> str.substring(str.lastIndexOf('/') + 1), stringPool);
|
||||
descriptor = new MappedString(names, 1, 2, (str) -> str, stringPool);
|
||||
}
|
||||
|
||||
public String getName(@NonNull MappingType mappingType) {
|
||||
return name.get(mappingType);
|
||||
}
|
||||
|
||||
public String getDescriptor(@NonNull MappingType mappingType) {
|
||||
return descriptor.get(mappingType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.falsepattern.lib.reflection.storage;
|
||||
|
||||
import com.falsepattern.lib.reflection.MappedString;
|
||||
import com.falsepattern.lib.reflection.types.MappingType;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NonNull;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Accessors(fluent = true)
|
||||
@EqualsAndHashCode
|
||||
public class Lookup<T> {
|
||||
private final Map<String, T> notch = new HashMap<>();
|
||||
private final Map<String, T> srg = new HashMap<>();
|
||||
private final Map<String, T> mcp = new HashMap<>();
|
||||
|
||||
public void unwrap(MappedString mappedString, T value) {
|
||||
notch.put(mappedString.notch, value);
|
||||
srg.put(mappedString.srg, value);
|
||||
mcp.put(mappedString.mcp, value);
|
||||
}
|
||||
|
||||
public T get(@NonNull MappingType mappingType, @NonNull String key) {
|
||||
switch (mappingType) {
|
||||
case Notch:
|
||||
return notch.get(key);
|
||||
case SRG:
|
||||
return srg.get(key);
|
||||
case MCP:
|
||||
return mcp.get(key);
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid enum value " + mappingType);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.falsepattern.lib.reflection.types;
|
||||
|
||||
public enum MappingType {
|
||||
Notch,
|
||||
SRG,
|
||||
MCP
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.falsepattern.lib.reflection.types;
|
||||
|
||||
public enum NameType {
|
||||
Internal,
|
||||
Regular
|
||||
}
|
||||
Reference in new issue
Block a user