Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor reading/writing into plugins #197

Merged
merged 48 commits into from
Jun 3, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
2969043
https://github.com/FabricMC/Enigma/pull/532 - rai version
ix0rai Apr 16, 2024
dd1ed5c
fix ExtensionFileFilter for leading dot change
ix0rai Apr 16, 2024
e8c1d95
checkstyle
ix0rai Apr 16, 2024
67ff574
oro review + filter "open" dialogue
ix0rai Apr 17, 2024
9dc672c
start moving to plugin
ix0rai Apr 18, 2024
b969aa7
migration to read write service: begin!
ix0rai Apr 21, 2024
fc1a744
Merge branch 'refs/heads/quiltmc-master' into juuxel-file-extensions
ix0rai Apr 21, 2024
caf0dc2
add namespace parameters to MappingSaveParameters, port most of command
ix0rai Apr 21, 2024
682972c
add non functional activeByDefault parameter to service types, move D…
ix0rai Apr 21, 2024
ce11f45
decompiler service active by default
ix0rai Apr 21, 2024
6f3519a
implement active by default
ix0rai Apr 21, 2024
01f4a30
cli tests passing!
ix0rai Apr 21, 2024
1fb7da5
core tests passing!
ix0rai Apr 21, 2024
068b6cd
GUI compiles (does not work)
ix0rai Apr 21, 2024
369afa4
default to enigma format for directories
ix0rai Apr 21, 2024
3771c99
checkstyle
ix0rai Apr 21, 2024
31159b5
fix test checkstyle, remove bad API methods
ix0rai Apr 22, 2024
0a30236
add "tiny" extension for tiny format
ix0rai Apr 22, 2024
1b6e1c9
more docs
ix0rai Apr 22, 2024
d342120
add validation for plugin registration
ix0rai Apr 22, 2024
eea654d
update gradle
ix0rai Apr 23, 2024
b09b191
checkstyle
ix0rai Apr 23, 2024
d0a4f40
address gradle deprecation
ix0rai Apr 23, 2024
a921600
update gradle again, update proguard
ix0rai Apr 23, 2024
6a4074d
fix gradle deprecations
ix0rai Apr 23, 2024
6098587
actions should pass again
ix0rai Apr 23, 2024
c15b6a7
test plugin id validation
ix0rai Apr 24, 2024
872769b
test all types of plugin validation
ix0rai Apr 24, 2024
53c181d
refactor test names
ix0rai Apr 24, 2024
f6ac5f9
IN MY DOCUMENTATION ERA
ix0rai Apr 24, 2024
3c5ed9c
fix some issues
ix0rai Apr 27, 2024
3874707
reintroduce EnigmaServiceType.create
ix0rai May 1, 2024
85d3a19
private tinyWriter constructor
ix0rai May 1, 2024
17dda83
improve MappingFileNameFormat docs
ix0rai May 1, 2024
70320be
Update enigma/src/main/java/org/quiltmc/enigma/api/service/NamePropos…
ix0rai May 1, 2024
9857315
Update enigma-cli/src/main/java/org/quiltmc/enigma/command/InvertMapp…
ix0rai May 1, 2024
e3040aa
Update enigma-cli/src/test/java/org/quiltmc/enigma/command/FillClassM…
ix0rai May 1, 2024
0c079ac
only create enigma instances once in commands
ix0rai May 1, 2024
31a0df7
Merge remote-tracking branch 'origin/juuxel-file-extensions' into juu…
ix0rai May 1, 2024
430b66f
Update enigma-cli/src/test/java/org/quiltmc/enigma/command/MapSpecial…
ix0rai May 1, 2024
eb381ed
use WalkFileTree
ix0rai May 1, 2024
f4c0bae
Merge remote-tracking branch 'origin/juuxel-file-extensions' into juu…
ix0rai May 1, 2024
d0f1eda
superfluous variable in build.gradle
ix0rai May 2, 2024
629f5aa
new default namespaces
ix0rai May 2, 2024
e14101a
reimplement format detection test (no longer automatic :( )
ix0rai May 2, 2024
1c2b78d
checkstyle and NPE fix
ix0rai May 2, 2024
08fefc6
test format not found
ix0rai May 2, 2024
eedbc6d
remove pointless method
ix0rai Jun 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 8 additions & 11 deletions enigma-swing/src/main/java/org/quiltmc/enigma/gui/Gui.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.quiltmc.enigma.gui.panel.EditorPanel;
import org.quiltmc.enigma.gui.panel.IdentifierPanel;
import org.quiltmc.enigma.gui.renderer.MessageListCellRenderer;
import org.quiltmc.enigma.gui.util.ExtensionFileFilter;
import org.quiltmc.enigma.gui.util.GuiUtil;
import org.quiltmc.enigma.gui.util.LanguageUtil;
import org.quiltmc.enigma.gui.util.ScaleUtil;
Expand Down Expand Up @@ -95,8 +96,7 @@ public class Gui {
private final NotificationManager notificationManager;

public final JFileChooser jarFileChooser;
public final JFileChooser tinyMappingsFileChooser;
public final JFileChooser enigmaMappingsFileChooser;
public final JFileChooser mappingsFileChooser;
public final JFileChooser exportSourceFileChooser;
public final JFileChooser exportJarFileChooser;
public final SearchDialog searchDialog;
Expand All @@ -118,8 +118,7 @@ public Gui(EnigmaProfile profile, Set<EditableType> editableTypes, boolean visib
this.splitRight = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, this.centerPanel, this.dockerManager.getRightDock());
this.splitLeft = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, this.dockerManager.getLeftDock(), this.splitRight);
this.jarFileChooser = new JFileChooser();
this.tinyMappingsFileChooser = new JFileChooser();
this.enigmaMappingsFileChooser = new JFileChooser();
this.mappingsFileChooser = new JFileChooser();
this.exportSourceFileChooser = new JFileChooser();
this.exportJarFileChooser = new JFileChooser();
this.connectionStatusLabel = new JLabel();
Expand Down Expand Up @@ -165,10 +164,6 @@ private void setupUi() {
this.setupDockers();

this.jarFileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
this.tinyMappingsFileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);

this.enigmaMappingsFileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
this.enigmaMappingsFileChooser.setAcceptAllFileFilterUsed(false);

this.exportSourceFileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
this.exportSourceFileChooser.setAcceptAllFileFilterUsed(false);
Expand Down Expand Up @@ -367,7 +362,7 @@ public void updateAllClasses() {
}

public void setMappingsFile(Path path) {
this.enigmaMappingsFileChooser.setSelectedFile(path != null ? path.toFile() : null);
this.mappingsFileChooser.setSelectedFile(path != null ? path.toFile() : null);
this.updateUiState();
}

Expand Down Expand Up @@ -491,8 +486,10 @@ public void showDiscardDiag(IntFunction<Void> callback, String... options) {
}

public CompletableFuture<Void> saveMapping() {
if (this.enigmaMappingsFileChooser.getSelectedFile() != null || this.enigmaMappingsFileChooser.showSaveDialog(this.mainWindow.getFrame()) == JFileChooser.APPROVE_OPTION) {
return this.controller.saveMappings(this.enigmaMappingsFileChooser.getSelectedFile().toPath());
ExtensionFileFilter.setupFileChooser(this.mappingsFileChooser, this.controller.getLoadedMappingFormat());

if (this.mappingsFileChooser.getSelectedFile() != null || this.mappingsFileChooser.showSaveDialog(this.mainWindow.getFrame()) == JFileChooser.APPROVE_OPTION) {
return this.controller.saveMappings(ExtensionFileFilter.getSavePath(this.mappingsFileChooser));
}

return CompletableFuture.completedFuture(null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
import org.quiltmc.enigma.util.validation.ValidationContext;
import org.tinylog.Logger;

import javax.annotation.Nullable;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import java.awt.Desktop;
Expand Down Expand Up @@ -611,10 +612,16 @@ public Enigma getEnigma() {
return this.enigma;
}

@Nullable
public StatsGenerator getStatsGenerator() {
return this.statsGenerator;
}

@Nullable
public MappingFormat getLoadedMappingFormat() {
return loadedMappingFormat;
}

public void createClient(String username, String ip, int port, char[] password) throws IOException {
this.client = new IntegratedEnigmaClient(this, ip, port);
this.client.connect();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.quiltmc.enigma.gui.dialog.StatsDialog;
import org.quiltmc.enigma.gui.dialog.decompiler.DecompilerSettingsDialog;
import org.quiltmc.enigma.gui.dialog.keybind.ConfigureKeyBindsDialog;
import org.quiltmc.enigma.gui.util.ExtensionFileFilter;
import org.quiltmc.enigma.gui.util.GuiUtil;
import org.quiltmc.enigma.gui.util.LanguageUtil;
import org.quiltmc.enigma.gui.util.ScaleUtil;
Expand Down Expand Up @@ -222,8 +223,7 @@ public void updateUiState() {

this.jarCloseItem.setEnabled(jarOpen);
this.openMappingsItem.setEnabled(jarOpen);
this.saveMappingsItem.setEnabled(jarOpen && this.gui.enigmaMappingsFileChooser.getSelectedFile() != null && connectionState != ConnectionState.CONNECTED);
this.saveMappingsAsMenu.setEnabled(jarOpen);
this.saveMappingsItem.setEnabled(jarOpen && this.gui.mappingsFileChooser.getSelectedFile() != null && connectionState != ConnectionState.CONNECTED); this.saveMappingsAsMenu.setEnabled(jarOpen);
this.closeMappingsItem.setEnabled(jarOpen);
this.reloadMappingsItem.setEnabled(jarOpen);
this.reloadAllItem.setEnabled(jarOpen);
Expand Down Expand Up @@ -324,7 +324,7 @@ private void onMaxRecentFilesClicked() {
}

private void onSaveMappingsClicked() {
this.gui.getController().saveMappings(this.gui.enigmaMappingsFileChooser.getSelectedFile().toPath());
this.gui.getController().saveMappings(this.gui.mappingsFileChooser.getSelectedFile().toPath());
}

private void openMappingsDiscardPrompt(Runnable then) {
Expand Down Expand Up @@ -469,10 +469,10 @@ private void onGithubClicked() {
}

private void onOpenMappingsClicked() {
this.gui.enigmaMappingsFileChooser.setCurrentDirectory(new File(Config.main().stats.lastSelectedDir.value()));
if (this.gui.enigmaMappingsFileChooser.showOpenDialog(this.gui.getFrame()) == JFileChooser.APPROVE_OPTION) {
File selectedFile = this.gui.enigmaMappingsFileChooser.getSelectedFile();
Config.main().stats.lastSelectedDir.setValue(this.gui.enigmaMappingsFileChooser.getCurrentDirectory().toString(), true);
this.gui.mappingsFileChooser.setCurrentDirectory(new File(Config.main().stats.lastSelectedDir.value()));
if (this.gui.mappingsFileChooser.showOpenDialog(this.gui.getFrame()) == JFileChooser.APPROVE_OPTION) {
File selectedFile = this.gui.mappingsFileChooser.getSelectedFile();
Config.main().stats.lastSelectedDir.setValue(this.gui.mappingsFileChooser.getCurrentDirectory().toString(), true);

MappingFormat format = MappingFormat.parseFromFile(selectedFile.toPath());
if (format.getReader() != null) {
Expand Down Expand Up @@ -549,15 +549,18 @@ private static void prepareSaveMappingsAsMenu(JMenu saveMappingsAsMenu, JMenuIte
if (format.getWriter() != null) {
JMenuItem item = new JMenuItem(I18n.translate("mapping_format." + format.name().toLowerCase(Locale.ROOT)));
item.addActionListener(event -> {
// TODO: Use a specific file chooser for it
if (gui.enigmaMappingsFileChooser.getCurrentDirectory() == null) {
gui.enigmaMappingsFileChooser.setCurrentDirectory(new File(Config.main().stats.lastSelectedDir.value()));
JFileChooser fileChooser = gui.mappingsFileChooser;
ExtensionFileFilter.setupFileChooser(fileChooser, format);

if (fileChooser.getCurrentDirectory() == null) {
fileChooser.setCurrentDirectory(new File(Config.main().stats.lastSelectedDir.value()));
}

if (gui.enigmaMappingsFileChooser.showSaveDialog(gui.getFrame()) == JFileChooser.APPROVE_OPTION) {
gui.getController().saveMappings(gui.enigmaMappingsFileChooser.getSelectedFile().toPath(), format);
if (fileChooser.showSaveDialog(gui.getFrame()) == JFileChooser.APPROVE_OPTION) {
Path savePath = ExtensionFileFilter.getSavePath(fileChooser);
gui.getController().saveMappings(savePath, format);
saveMappingsItem.setEnabled(true);
Config.main().stats.lastSelectedDir.setValue(gui.enigmaMappingsFileChooser.getCurrentDirectory().toString(), true);
Config.main().stats.lastSelectedDir.setValue(fileChooser.getCurrentDirectory().toString());
}
});
saveMappingsAsMenu.add(item);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
package org.quiltmc.enigma.gui.util;

import org.quiltmc.enigma.api.translation.mapping.serde.MappingFormat;
import org.quiltmc.enigma.util.I18n;

import javax.annotation.Nullable;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileFilter;
import java.io.File;
import java.nio.file.Path;
import java.util.List;
import java.util.StringJoiner;

public final class ExtensionFileFilter extends FileFilter {
private final String formatName;
private final List<String> extensions;

/**
* Constructs an {@code ExtensionFileFilter}.
*
* @param formatName the human-readable name of the file format
* @param extensions the file extensions with no leading dots
ix0rai marked this conversation as resolved.
Show resolved Hide resolved
*/
public ExtensionFileFilter(String formatName, List<String> extensions) {
this.formatName = formatName;
this.extensions = extensions.stream().map(s -> "." + s).toList();
}

public List<String> getExtensions() {
return extensions;
}

@Override
public boolean accept(File f) {
// Always accept directories so the user can see them.
if (f.isDirectory()) {
return true;
}

for (String extension : extensions) {
if (f.getName().endsWith(extension)) {
return true;
}
}

return false;
}

@Override
public String getDescription() {
var joiner = new StringJoiner(", ");

for (String extension : extensions) {
joiner.add("*" + extension);
}

return I18n.translateFormatted("menu.file.mappings.file_filter", formatName, joiner.toString());
}

/**
* Sets up a file chooser with a mapping format. This method resets the choosable filters,
* and adds and selects a new filter based on the provided mapping format.
*
* @param fileChooser the file chooser to set up
* @param format the mapping format to use. if {@code null}, the file chooser will accept only directories
*/
public static void setupFileChooser(JFileChooser fileChooser, @Nullable MappingFormat format) {
if (format == null) {
format = MappingFormat.ENIGMA_DIRECTORY;
}

// Remove previous custom filters.
fileChooser.resetChoosableFileFilters();

if (format.getFileType().isDirectory()) {
fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
} else {
fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
String formatName = I18n.translate("mapping_format." + format.name().toLowerCase());
var filter = new ExtensionFileFilter(formatName, format.getFileType().getExtensions());
// Add our new filter to the list...
fileChooser.addChoosableFileFilter(filter);
// ...and choose it as the default.
fileChooser.setFileFilter(filter);
}
}

/**
* Fixes a missing file extension in a save file path when the selected filter
* is an {@code ExtensionFileFilter}.
*
* @param fileChooser the file chooser to check
* @return the fixed path
*/
public static Path getSavePath(JFileChooser fileChooser) {
Path savePath = fileChooser.getSelectedFile().toPath();

if (fileChooser.getFileFilter() instanceof ExtensionFileFilter extensionFilter) {
// Check that the file name ends with the extension.
String fileName = savePath.getFileName().toString();
boolean hasExtension = false;

for (String extension : extensionFilter.getExtensions()) {
if (fileName.endsWith(extension)) {
hasExtension = true;
break;
}
}

if (!hasExtension) {
String defaultExtension = extensionFilter.getExtensions().get(0);
// If not, add the extension.
savePath = savePath.resolveSibling(fileName + defaultExtension);
// Store the adjusted file, so that it shows up properly
// the next time this dialog is used.
fileChooser.setSelectedFile(savePath.toFile());
}
}

return savePath;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,32 @@
import org.quiltmc.enigma.api.translation.mapping.serde.tinyv2.TinyV2Reader;
import org.quiltmc.enigma.api.translation.mapping.serde.tinyv2.TinyV2Writer;
import org.quiltmc.enigma.api.translation.mapping.tree.EntryTree;
import org.quiltmc.enigma.impl.translation.FileType;

import javax.annotation.Nullable;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.Objects;

public enum MappingFormat {
ENIGMA_FILE(EnigmaMappingsWriter.FILE, EnigmaMappingsReader.FILE),
ENIGMA_DIRECTORY(EnigmaMappingsWriter.DIRECTORY, EnigmaMappingsReader.DIRECTORY),
ENIGMA_ZIP(EnigmaMappingsWriter.ZIP, EnigmaMappingsReader.ZIP),
TINY_V2(new TinyV2Writer("intermediary", "named"), new TinyV2Reader()),
SRG_FILE(SrgMappingsWriter.INSTANCE, null),
PROGUARD(null, ProguardMappingsReader.INSTANCE);
ENIGMA_FILE(EnigmaMappingsWriter.FILE, EnigmaMappingsReader.FILE, FileType.ENIGMA_MAPPING),
ENIGMA_DIRECTORY(EnigmaMappingsWriter.DIRECTORY, EnigmaMappingsReader.DIRECTORY, FileType.ENIGMA_DIRECTORY),
ENIGMA_ZIP(EnigmaMappingsWriter.ZIP, EnigmaMappingsReader.ZIP, FileType.ENIGMA_ZIP),
TINY_V2(new TinyV2Writer("intermediary", "named"), new TinyV2Reader(), FileType.TINY_V2),
SRG_FILE(SrgMappingsWriter.INSTANCE, null, FileType.SRG),
PROGUARD(null, ProguardMappingsReader.INSTANCE, FileType.PROGUARD);

private final MappingsWriter writer;
private final MappingsReader reader;
private final FileType fileType;

MappingFormat(MappingsWriter writer, MappingsReader reader) {
MappingFormat(MappingsWriter writer, MappingsReader reader, FileType fileType) {
this.writer = writer;
this.reader = reader;
this.fileType = fileType;
}

public void write(EntryTree<EntryMapping> mappings, Path path, MappingSaveParameters saveParameters) {
Expand Down Expand Up @@ -90,34 +96,47 @@ public MappingsReader getReader() {
return this.reader;
}

public FileType getFileType() {
return this.fileType;
}

/**
* Determines the mapping format of the provided file. Checks all formats, and returns {@link #PROGUARD} if none match.
* Determines the mapping format of the provided file. Checks all formats according to their {@link #getFileType()} file extensions.
* If the file is a directory, it will check the first file in the directory.
* Will return {@link #PROGUARD} if no format is found for single files, and {@link #ENIGMA_DIRECTORY} if no format is found for directories.
* @param file the file to analyse
* @apiNote Any directory is considered to be the {@link #ENIGMA_DIRECTORY} format.
* Proguard does not have an explicit file extension, so it is the fallback.
* @return the mapping format of the file.
*/
public static MappingFormat parseFromFile(Path file) {
if (Files.isDirectory(file)) {
return ENIGMA_DIRECTORY;
} else {
switch (MoreFiles.getFileExtension(file).toLowerCase()) {
case "zip" -> {
return ENIGMA_ZIP;
}
case "mapping", "mappings" -> {
return ENIGMA_FILE;
}
case "tiny" -> {
return TINY_V2;
}
case "tsrg" -> {
return SRG_FILE;
try {
File firstFile = Arrays.stream(Objects.requireNonNull(file.toFile().listFiles())).findFirst().orElseThrow();

for (MappingFormat format : values()) {
if (!format.getFileType().isDirectory()) {
continue;
}

String extension = MoreFiles.getFileExtension(firstFile.toPath()).toLowerCase();
if (format.fileType.getExtensions().contains(extension)) {
return format;
}
}
default -> {
return PROGUARD;

return ENIGMA_DIRECTORY;
} catch (Exception e) {
return ENIGMA_DIRECTORY;
}
} else {
String extension = MoreFiles.getFileExtension(file).toLowerCase();

for (MappingFormat format : values()) {
if (format.fileType.getExtensions().contains(extension)) {
return format;
}
}
}

return PROGUARD;
ix0rai marked this conversation as resolved.
Show resolved Hide resolved
}
}
Loading
Loading