mirror of
https://github.com/FalsePattern/FalsePatternLib.git
synced 2026-11-15 12:34: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
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user