summaryrefslogtreecommitdiff
path: root/src/main/java/cuchaz/enigma/translation/mapping/serde/SrgMappingsWriter.java
blob: f67f8fcdd1393d41de18a21af3d909dd4f89e04a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package cuchaz.enigma.translation.mapping.serde;

import com.google.common.collect.Lists;
import cuchaz.enigma.ProgressListener;
import cuchaz.enigma.translation.MappingTranslator;
import cuchaz.enigma.translation.Translator;
import cuchaz.enigma.translation.mapping.EntryMapping;
import cuchaz.enigma.translation.mapping.MappingDelta;
import cuchaz.enigma.translation.mapping.MappingSaveParameters;
import cuchaz.enigma.translation.mapping.VoidEntryResolver;
import cuchaz.enigma.translation.mapping.tree.EntryTree;
import cuchaz.enigma.translation.mapping.tree.EntryTreeNode;
import cuchaz.enigma.translation.representation.entry.ClassEntry;
import cuchaz.enigma.translation.representation.entry.Entry;
import cuchaz.enigma.translation.representation.entry.FieldEntry;
import cuchaz.enigma.translation.representation.entry.MethodEntry;
import cuchaz.enigma.utils.I18n;
import cuchaz.enigma.utils.LFPrintWriter;

import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

public enum SrgMappingsWriter implements MappingsWriter {
	INSTANCE;

	@Override
	public void write(EntryTree<EntryMapping> mappings, MappingDelta<EntryMapping> delta, Path path, ProgressListener progress, MappingSaveParameters saveParameters) {
		try {
			Files.deleteIfExists(path);
			Files.createFile(path);
		} catch (IOException e) {
			e.printStackTrace();
		}

		List<String> classLines = new ArrayList<>();
		List<String> fieldLines = new ArrayList<>();
		List<String> methodLines = new ArrayList<>();

		Collection<Entry<?>> rootEntries = Lists.newArrayList(mappings).stream()
				.map(EntryTreeNode::getEntry)
				.collect(Collectors.toList());
		progress.init(rootEntries.size(), I18n.translate("progress.mappings.srg_file.generating"));

		int steps = 0;
		for (Entry<?> entry : sorted(rootEntries)) {
			progress.step(steps++, entry.getName());
			writeEntry(classLines, fieldLines, methodLines, mappings, entry);
		}

		progress.init(3, I18n.translate("progress.mappings.srg_file.writing"));
		try (PrintWriter writer = new LFPrintWriter(Files.newBufferedWriter(path))) {
			progress.step(0, I18n.translate("type.classes"));
			classLines.forEach(writer::println);
			progress.step(1, I18n.translate("type.fields"));
			fieldLines.forEach(writer::println);
			progress.step(2, I18n.translate("type.methods"));
			methodLines.forEach(writer::println);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private void writeEntry(List<String> classes, List<String> fields, List<String> methods, EntryTree<EntryMapping> mappings, Entry<?> entry) {
		EntryTreeNode<EntryMapping> node = mappings.findNode(entry);
		if (node == null) {
			return;
		}

		Translator translator = new MappingTranslator(mappings, VoidEntryResolver.INSTANCE);
		if (entry instanceof ClassEntry) {
			classes.add(generateClassLine((ClassEntry) entry, translator));
		} else if (entry instanceof FieldEntry) {
			fields.add(generateFieldLine((FieldEntry) entry, translator));
		} else if (entry instanceof MethodEntry) {
			methods.add(generateMethodLine((MethodEntry) entry, translator));
		}

		for (Entry<?> child : sorted(node.getChildren())) {
			writeEntry(classes, fields, methods, mappings, child);
		}
	}

	private String generateClassLine(ClassEntry sourceEntry, Translator translator) {
		ClassEntry targetEntry = translator.translate(sourceEntry);
		return "CL: " + sourceEntry.getFullName() + " " + targetEntry.getFullName();
	}

	private String generateMethodLine(MethodEntry sourceEntry, Translator translator) {
		MethodEntry targetEntry = translator.translate(sourceEntry);
		return "MD: " + describeMethod(sourceEntry) + " " + describeMethod(targetEntry);
	}

	private String describeMethod(MethodEntry entry) {
		return entry.getParent().getFullName() + "/" + entry.getName() + " " + entry.getDesc();
	}

	private String generateFieldLine(FieldEntry sourceEntry, Translator translator) {
		FieldEntry targetEntry = translator.translate(sourceEntry);
		return "FD: " + describeField(sourceEntry) + " " + describeField(targetEntry);
	}

	private String describeField(FieldEntry entry) {
		return entry.getParent().getFullName() + "/" + entry.getName();
	}

	private Collection<Entry<?>> sorted(Iterable<Entry<?>> iterable) {
		ArrayList<Entry<?>> sorted = Lists.newArrayList(iterable);
		sorted.sort(Comparator.comparing(Entry::getName));
		return sorted;
	}
}