From 1176ad9e8382dd46d7cba0bb4c6a0668abf21af8 Mon Sep 17 00:00:00 2001 From: Dmitry Isaenko Date: Mon, 9 Aug 2021 22:47:52 +0300 Subject: [PATCH] Solve - #87. Break LogPrinterGui --- .../Controllers/BlockListViewController.java | 102 ++++++++++ .../Controllers/NSLMainController.java | 44 +++-- .../Controllers/SplitMergeController.java | 68 +++---- .../ModelControllers/ILogPrinter.java | 4 +- .../ModelControllers/LogPrinterGui.java | 48 ++--- .../ModelControllers/MessagesConsumer.java | 56 +++--- src/main/java/nsusbloader/Utilities/Rcm.java | 43 ++-- .../Utilities/nxdumptool/NxdtTask.java | 17 +- .../Utilities/nxdumptool/NxdtUsbAbi1.java | 4 +- .../Utilities/splitmerge/MergeSubTask.java | 178 +++++++++++++++++ .../Utilities/splitmerge/MergeTask.java | 169 ---------------- .../MultithreadingPrintAdapter.java | 44 +++++ .../splitmerge/SplitMergeTaskExecutor.java | 147 ++++++++++++++ .../Utilities/splitmerge/SplitSubTask.java | 186 ++++++++++++++++++ .../Utilities/splitmerge/SplitTask.java | 173 ---------------- src/main/java/nsusbloader/cli/MergeCli.java | 25 ++- src/main/java/nsusbloader/cli/SplitCli.java | 28 +-- .../com/net/NETCommunications.java | 44 +++-- .../com/net/NetworkSetupValidator.java | 33 ++-- .../java/nsusbloader/com/usb/GoldLeaf_05.java | 102 +++++----- .../java/nsusbloader/com/usb/GoldLeaf_07.java | 84 ++++---- .../java/nsusbloader/com/usb/GoldLeaf_08.java | 80 ++++---- .../java/nsusbloader/com/usb/TinFoil.java | 48 ++--- .../nsusbloader/com/usb/TransferModule.java | 15 +- .../com/usb/UsbCommunications.java | 12 +- .../java/nsusbloader/com/usb/UsbConnect.java | 25 ++- src/main/resources/BlockListView.fxml | 10 + src/main/resources/SplitMergeTab.fxml | 71 +++---- src/main/resources/res/app_dark.css | 33 +++- src/main/resources/res/app_light.css | 29 +++ .../java/nsusbloader/com/usb/MergeTest.java | 86 ++++++++ .../java/nsusbloader/com/usb/SplitTest.java | 78 ++++++++ 32 files changed, 1348 insertions(+), 738 deletions(-) create mode 100644 src/main/java/nsusbloader/Controllers/BlockListViewController.java create mode 100644 src/main/java/nsusbloader/Utilities/splitmerge/MergeSubTask.java delete mode 100644 src/main/java/nsusbloader/Utilities/splitmerge/MergeTask.java create mode 100644 src/main/java/nsusbloader/Utilities/splitmerge/MultithreadingPrintAdapter.java create mode 100644 src/main/java/nsusbloader/Utilities/splitmerge/SplitMergeTaskExecutor.java create mode 100644 src/main/java/nsusbloader/Utilities/splitmerge/SplitSubTask.java delete mode 100644 src/main/java/nsusbloader/Utilities/splitmerge/SplitTask.java create mode 100644 src/main/resources/BlockListView.fxml create mode 100644 src/test/java/nsusbloader/com/usb/MergeTest.java create mode 100644 src/test/java/nsusbloader/com/usb/SplitTest.java diff --git a/src/main/java/nsusbloader/Controllers/BlockListViewController.java b/src/main/java/nsusbloader/Controllers/BlockListViewController.java new file mode 100644 index 0000000..bba5d6b --- /dev/null +++ b/src/main/java/nsusbloader/Controllers/BlockListViewController.java @@ -0,0 +1,102 @@ +/* + Copyright 2019-2021 Dmitry Isaenko + + This file is part of NS-USBloader. + + NS-USBloader is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + NS-USBloader is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with NS-USBloader. If not, see . + */ +package nsusbloader.Controllers; + +import javafx.collections.ObservableList; +import javafx.fxml.FXML; +import javafx.fxml.Initializable; +import javafx.scene.control.ContextMenu; +import javafx.scene.control.ListCell; +import javafx.scene.control.ListView; +import javafx.scene.control.MenuItem; + +import java.io.File; +import java.net.URL; +import java.util.List; +import java.util.ResourceBundle; + +public class BlockListViewController implements Initializable { + + @FXML + private ListView splitMergeListView; + private ObservableList filesList; + + private ResourceBundle resourceBundle; + + private static class FileListCell extends ListCell{ + @Override + public void updateItem(File file, boolean isEmpty){ + super.updateItem(file, isEmpty); + + if (file == null || isEmpty){ + setText(null); + return; + } + String fileName = file.getName(); + setText(fileName); + } + } + + @Override + public void initialize(URL url, ResourceBundle resourceBundle) { + this.resourceBundle = resourceBundle; + setFilesListView(); + filesList = splitMergeListView.getItems(); + } + private void setFilesListView(){ + splitMergeListView.setCellFactory(fileListView -> { + ListCell item = new FileListCell(); + setContextMenuToItem(item); + return item; + }); + } + + private void setContextMenuToItem(ListCell item){ + ContextMenu contextMenu = new ContextMenu(); + MenuItem deleteMenuItem = new MenuItem(resourceBundle.getString("tab1_table_contextMenu_Btn_BtnDelete")); + deleteMenuItem.setOnAction(actionEvent -> { + filesList.remove(item.getItem()); + splitMergeListView.refresh(); + }); + MenuItem deleteAllMenuItem = new MenuItem(resourceBundle.getString("tab1_table_contextMenu_Btn_DeleteAll")); + deleteAllMenuItem.setOnAction(actionEvent -> { + filesList.clear(); + splitMergeListView.refresh(); + }); + contextMenu.getItems().addAll(deleteMenuItem, deleteAllMenuItem); + + item.setContextMenu(contextMenu); + } + + public void add(File file){ + if (filesList.contains(file)) + return; + filesList.add(file); + } + public void addAll(List files){ + for (File file : files) { + add(file); + } + } + public ObservableList getItems(){ return filesList; } + public void clear(){ + filesList.clear(); + splitMergeListView.refresh(); + } +} diff --git a/src/main/java/nsusbloader/Controllers/NSLMainController.java b/src/main/java/nsusbloader/Controllers/NSLMainController.java index 618cee9..99fa2d0 100644 --- a/src/main/java/nsusbloader/Controllers/NSLMainController.java +++ b/src/main/java/nsusbloader/Controllers/NSLMainController.java @@ -46,7 +46,7 @@ public class NSLMainController implements Initializable { private Tab GamesTabHolder, RCMTabHolder, SMTabHolder; @FXML - private GamesController GamesTabController; // Accessible from Mediator | todo: incapsulate + private GamesController GamesTabController; @FXML private SettingsController SettingsTabController; @FXML @@ -69,30 +69,32 @@ public class NSLMainController implements Initializable { MediatorControl.getInstance().setController(this); if (AppPreferences.getInstance().getAutoCheckUpdates()){ - Task> updTask = new UpdatesChecker(); - updTask.setOnSucceeded(event->{ - List result = updTask.getValue(); - if (result != null){ - if (!result.get(0).isEmpty()) { - SettingsTabController.getGenericSettings().setNewVersionLink(result.get(0)); - ServiceWindow.getInfoNotification( - resourceBundle.getString("windowTitleNewVersionAval"), - resourceBundle.getString("windowTitleNewVersionAval") + ": " + result.get(0) + "\n\n" + result.get(1)); - } - } - else - ServiceWindow.getInfoNotification( - resourceBundle.getString("windowTitleNewVersionUnknown"), - resourceBundle.getString("windowBodyNewVersionUnknown")); - }); - Thread updates = new Thread(updTask); - updates.setDaemon(true); - updates.start(); + checkForUpdates(); } openLastOpenedTab(); } - + private void checkForUpdates(){ + Task> updTask = new UpdatesChecker(); + updTask.setOnSucceeded(event->{ + List result = updTask.getValue(); + if (result != null){ + if (!result.get(0).isEmpty()) { + SettingsTabController.getGenericSettings().setNewVersionLink(result.get(0)); + ServiceWindow.getInfoNotification( + resourceBundle.getString("windowTitleNewVersionAval"), + resourceBundle.getString("windowTitleNewVersionAval") + ": " + result.get(0) + "\n\n" + result.get(1)); + } + } + else + ServiceWindow.getInfoNotification( + resourceBundle.getString("windowTitleNewVersionUnknown"), + resourceBundle.getString("windowBodyNewVersionUnknown")); + }); + Thread updates = new Thread(updTask); + updates.setDaemon(true); + updates.start(); + } /** * Get resources * TODO: Find better solution; used in UsbCommunications() -> GL -> SelectFile command diff --git a/src/main/java/nsusbloader/Controllers/SplitMergeController.java b/src/main/java/nsusbloader/Controllers/SplitMergeController.java index 59656ac..b7a6be9 100644 --- a/src/main/java/nsusbloader/Controllers/SplitMergeController.java +++ b/src/main/java/nsusbloader/Controllers/SplitMergeController.java @@ -18,6 +18,7 @@ */ package nsusbloader.Controllers; +import javafx.beans.binding.Bindings; import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.control.*; @@ -33,11 +34,11 @@ import nsusbloader.MediatorControl; import nsusbloader.ModelControllers.CancellableRunnable; import nsusbloader.NSLDataTypes.EModule; import nsusbloader.ServiceWindow; -import nsusbloader.Utilities.splitmerge.MergeTask; -import nsusbloader.Utilities.splitmerge.SplitTask; +import nsusbloader.Utilities.splitmerge.SplitMergeTaskExecutor; import java.io.File; import java.net.URL; +import java.util.List; import java.util.ResourceBundle; public class SplitMergeController implements Initializable { @@ -53,40 +54,39 @@ public class SplitMergeController implements Initializable { changeSaveToBtn, convertBtn; @FXML - private Label fileFolderLabelLbl, - fileFolderActualPathLbl, - saveToPathLbl, + private Label saveToPathLbl, statusLbl; + @FXML + private BlockListViewController BlockListViewController; + private ResourceBundle resourceBundle; private Region convertRegion; private Thread smThread; - private CancellableRunnable smTask; + private Runnable smTask; @Override public void initialize(URL url, ResourceBundle resourceBundle) { this.resourceBundle = resourceBundle; + convertRegion = new Region(); convertBtn.setGraphic(convertRegion); + convertBtn.disableProperty().bind(Bindings.isEmpty(BlockListViewController.getItems())); splitRad.setOnAction((actionEvent -> { statusLbl.setText(""); convertRegion.getStyleClass().clear(); convertRegion.getStyleClass().add("regionSplitToOne"); - fileFolderLabelLbl.setText(resourceBundle.getString("tabSplMrg_Txt_File")); selectFileFolderBtn.setText(resourceBundle.getString("tabSplMrg_Btn_SelectFile")); - fileFolderActualPathLbl.setText(""); - convertBtn.setDisable(true); + BlockListViewController.clear(); })); mergeRad.setOnAction((actionEvent -> { statusLbl.setText(""); convertRegion.getStyleClass().clear(); convertRegion.getStyleClass().add("regionOneToSplit"); - fileFolderLabelLbl.setText(resourceBundle.getString("tabSplMrg_Txt_Folder")); selectFileFolderBtn.setText(resourceBundle.getString("tabSplMrg_Btn_SelectFolder")); - fileFolderActualPathLbl.setText(""); - convertBtn.setDisable(true); + BlockListViewController.clear(); })); if (AppPreferences.getInstance().getSplitMergeType() == 0) @@ -110,32 +110,27 @@ public class SplitMergeController implements Initializable { selectFileFolderBtn.setOnAction(actionEvent -> { statusLbl.setText(""); + List alreadyAddedFiles = BlockListViewController.getItems(); if (splitRad.isSelected()) { FileChooser fc = new FileChooser(); fc.setTitle(resourceBundle.getString("tabSplMrg_Btn_SelectFile")); - if (! fileFolderActualPathLbl.getText().isEmpty()){ - File temporaryFile = new File(fileFolderActualPathLbl.getText()).getParentFile(); - if (temporaryFile != null && temporaryFile.exists()) - fc.setInitialDirectory(temporaryFile); - else - fc.setInitialDirectory(new File(System.getProperty("user.home"))); + if (! alreadyAddedFiles.isEmpty()){ + String recentLocation = FilesHelper.getRealFolder(alreadyAddedFiles.get(0).getParentFile().getAbsolutePath()); + fc.setInitialDirectory(new File(recentLocation)); } else fc.setInitialDirectory(new File(System.getProperty("user.home"))); - File fileFile = fc.showOpenDialog(changeSaveToBtn.getScene().getWindow()); - if (fileFile == null) + List files = fc.showOpenMultipleDialog(changeSaveToBtn.getScene().getWindow()); + if (files == null || files.isEmpty()) return; - fileFolderActualPathLbl.setText(fileFile.getAbsolutePath()); + this.BlockListViewController.addAll(files); } else{ DirectoryChooser dc = new DirectoryChooser(); dc.setTitle(resourceBundle.getString("tabSplMrg_Btn_SelectFolder")); - if (! fileFolderActualPathLbl.getText().isEmpty()){ - File temporaryFile = new File(fileFolderActualPathLbl.getText()); - if (temporaryFile.exists()) - dc.setInitialDirectory(temporaryFile); - else - dc.setInitialDirectory(new File(System.getProperty("user.home"))); + if (! alreadyAddedFiles.isEmpty()){ + String recentLocation = FilesHelper.getRealFolder(alreadyAddedFiles.get(0).getParentFile().getAbsolutePath()); + dc.setInitialDirectory(new File(recentLocation)); } else dc.setInitialDirectory(new File(System.getProperty("user.home"))); @@ -143,9 +138,8 @@ public class SplitMergeController implements Initializable { File folderFile = dc.showDialog(changeSaveToBtn.getScene().getWindow()); if (folderFile == null) return; - fileFolderActualPathLbl.setText(folderFile.getAbsolutePath()); + this.BlockListViewController.add(folderFile); } - convertBtn.setDisable(false); }); convertBtn.setOnAction(actionEvent -> setConvertBtnAction()); @@ -192,7 +186,7 @@ public class SplitMergeController implements Initializable { * */ private void stopBtnAction(){ if (smThread != null && smThread.isAlive()) { - smTask.cancel(); + smThread.interrupt(); } } /** @@ -209,9 +203,9 @@ public class SplitMergeController implements Initializable { } if (splitRad.isSelected()) - smTask = new SplitTask(fileFolderActualPathLbl.getText(), saveToPathLbl.getText()); + smTask = new SplitMergeTaskExecutor(true, BlockListViewController.getItems(), saveToPathLbl.getText()); else - smTask = new MergeTask(fileFolderActualPathLbl.getText(), saveToPathLbl.getText()); + smTask = new SplitMergeTaskExecutor(false, BlockListViewController.getItems(), saveToPathLbl.getText()); smThread = new Thread(smTask); smThread.setDaemon(true); smThread.start(); @@ -230,14 +224,16 @@ public class SplitMergeController implements Initializable { * */ @FXML private void handleDrop(DragEvent event) { - File fileDrpd = event.getDragboard().getFiles().get(0); + List files = event.getDragboard().getFiles(); + File firstFile = files.get(0); - if (fileDrpd.isDirectory()) + if (firstFile.isDirectory()) mergeRad.fire(); else splitRad.fire(); - fileFolderActualPathLbl.setText(fileDrpd.getAbsolutePath()); - convertBtn.setDisable(false); + + this.BlockListViewController.addAll(files); + event.setDropCompleted(true); event.consume(); } diff --git a/src/main/java/nsusbloader/ModelControllers/ILogPrinter.java b/src/main/java/nsusbloader/ModelControllers/ILogPrinter.java index 09b1e8e..7c96ac4 100644 --- a/src/main/java/nsusbloader/ModelControllers/ILogPrinter.java +++ b/src/main/java/nsusbloader/ModelControllers/ILogPrinter.java @@ -26,8 +26,8 @@ import java.io.File; import java.util.HashMap; public interface ILogPrinter { - void print(String message, EMsgType type); - void updateProgress(Double value); + void print(String message, EMsgType type) throws InterruptedException; + void updateProgress(Double value) throws InterruptedException; void update(HashMap nspMap, EFileStatus status); void update(File file, EFileStatus status); void updateOneLinerStatus(boolean status); diff --git a/src/main/java/nsusbloader/ModelControllers/LogPrinterGui.java b/src/main/java/nsusbloader/ModelControllers/LogPrinterGui.java index a18d544..d557964 100644 --- a/src/main/java/nsusbloader/ModelControllers/LogPrinterGui.java +++ b/src/main/java/nsusbloader/ModelControllers/LogPrinterGui.java @@ -32,9 +32,11 @@ public class LogPrinterGui implements ILogPrinter { private final MessagesConsumer msgConsumer; private final BlockingQueue msgQueue; private final BlockingQueue progressQueue; - private final HashMap statusMap; // BlockingQueue for literally one object. TODO: read more books ; replace to hashMap + private final HashMap statusMap; private final AtomicBoolean oneLinerStatus; + /* TODO: Rewrite 'print()' implementation everywhere */ + LogPrinterGui(EModule whoIsAsking){ this.msgQueue = new LinkedBlockingQueue<>(); this.progressQueue = new LinkedBlockingQueue<>(); @@ -47,38 +49,30 @@ public class LogPrinterGui implements ILogPrinter { * This is what will print to textArea of the application. * */ @Override - public void print(String message, EMsgType type){ - try { - switch (type){ - case PASS: - msgQueue.put("[ PASS ] "+message+"\n"); - break; - case FAIL: - msgQueue.put("[ FAIL ] "+message+"\n"); - break; - case INFO: - msgQueue.put("[ INFO ] "+message+"\n"); - break; - case WARNING: - msgQueue.put("[ WARN ] "+message+"\n"); - break; - default: - msgQueue.put(message); - } - } - catch (InterruptedException ie){ - ie.printStackTrace(); + public void print(String message, EMsgType type) throws InterruptedException{ + switch (type){ + case PASS: + msgQueue.put("[ PASS ] "+message+"\n"); + break; + case FAIL: + msgQueue.put("[ FAIL ] "+message+"\n"); + break; + case INFO: + msgQueue.put("[ INFO ] "+message+"\n"); + break; + case WARNING: + msgQueue.put("[ WARN ] "+message+"\n"); + break; + default: + msgQueue.put(message); } } /** * Update progress for progress bar * */ @Override - public void updateProgress(Double value) { - try { - progressQueue.put(value); - } - catch (InterruptedException ignored){} // TODO: Do something with this + public void updateProgress(Double value) throws InterruptedException { + progressQueue.put(value); } /** * When we're done - update status diff --git a/src/main/java/nsusbloader/ModelControllers/MessagesConsumer.java b/src/main/java/nsusbloader/ModelControllers/MessagesConsumer.java index 8baa5be..ba4b294 100644 --- a/src/main/java/nsusbloader/ModelControllers/MessagesConsumer.java +++ b/src/main/java/nsusbloader/ModelControllers/MessagesConsumer.java @@ -42,7 +42,7 @@ public class MessagesConsumer extends AnimationTimer { private final NSTableViewController tableViewController; private final EModule appModuleType; - private AtomicBoolean oneLinerStatus; + private final AtomicBoolean oneLinerStatus; private boolean isInterrupted; @@ -50,7 +50,7 @@ public class MessagesConsumer extends AnimationTimer { BlockingQueue msgQueue, BlockingQueue progressQueue, HashMap statusMap, - AtomicBoolean oneLinerStatus) { + AtomicBoolean oneLinerStatus){ this.appModuleType = appModuleType; this.isInterrupted = false; @@ -72,15 +72,15 @@ public class MessagesConsumer extends AnimationTimer { } @Override - public void handle(long l) { + public void handle(long l){ ArrayList messages = new ArrayList<>(); - int msgRecieved = msgQueue.drainTo(messages); - if (msgRecieved > 0) + int msgReceived = msgQueue.drainTo(messages); + if (msgReceived > 0) messages.forEach(logsArea::appendText); ArrayList progress = new ArrayList<>(); - int progressRecieved = progressQueue.drainTo(progress); - if (progressRecieved > 0) { + int progressReceived = progressQueue.drainTo(progress); + if (progressReceived > 0) { progress.forEach(prg -> { if (prg != 1.0) progressBar.setProgress(prg); @@ -89,29 +89,31 @@ public class MessagesConsumer extends AnimationTimer { }); } - if (isInterrupted) { // It's safe 'cuz it's could't be interrupted while HashMap populating - MediatorControl.getInstance().setBgThreadActive(false, appModuleType); - progressBar.setProgress(0.0); + if (isInterrupted) // It's safe 'cuz it's could't be interrupted while HashMap populating + updateElementsAndStop(); + } - if (statusMap.size() > 0){ - for (String key : statusMap.keySet()) - tableViewController.setFileStatus(key, statusMap.get(key)); - } + private void updateElementsAndStop(){ + MediatorControl.getInstance().setBgThreadActive(false, appModuleType); + progressBar.setProgress(0.0); - switch (appModuleType){ - case RCM: - MediatorControl.getInstance().getRcmController().setOneLineStatus(oneLinerStatus.get()); - break; - case NXDT: - MediatorControl.getInstance().getNxdtController().setOneLineStatus(oneLinerStatus.get()); - break; - case SPLIT_MERGE_TOOL: - MediatorControl.getInstance().getSplitMergeController().setOneLineStatus(oneLinerStatus.get()); - break; - } - - this.stop(); + if (statusMap.size() > 0){ + for (String key : statusMap.keySet()) + tableViewController.setFileStatus(key, statusMap.get(key)); } + + switch (appModuleType){ + case RCM: + MediatorControl.getInstance().getRcmController().setOneLineStatus(oneLinerStatus.get()); + break; + case NXDT: + MediatorControl.getInstance().getNxdtController().setOneLineStatus(oneLinerStatus.get()); + break; + case SPLIT_MERGE_TOOL: + MediatorControl.getInstance().getSplitMergeController().setOneLineStatus(oneLinerStatus.get()); + break; + } + this.stop(); } public void interrupt(){ diff --git a/src/main/java/nsusbloader/Utilities/Rcm.java b/src/main/java/nsusbloader/Utilities/Rcm.java index 3072944..33a9268 100644 --- a/src/main/java/nsusbloader/Utilities/Rcm.java +++ b/src/main/java/nsusbloader/Utilities/Rcm.java @@ -72,8 +72,8 @@ public class Rcm implements Runnable{ @Override public void run() { - logPrinter.print("Selected: "+filePath, EMsgType.INFO); - logPrinter.print("=============== RCM ===============", EMsgType.INFO); + print("Selected: "+filePath, EMsgType.INFO); + print("=============== RCM ===============", EMsgType.INFO); ECurrentOS ecurrentOS; String realOsName = System.getProperty("os.name").toLowerCase().replace(" ", ""); @@ -85,11 +85,11 @@ public class Rcm implements Runnable{ ecurrentOS = ECurrentOS.lin; else ecurrentOS = ECurrentOS.unsupported; - logPrinter.print("Found your OS: "+System.getProperty("os.name"), EMsgType.PASS); + print("Found your OS: "+System.getProperty("os.name"), EMsgType.PASS); if (! ecurrentOS.equals(ECurrentOS.mac)){ if (! RcmSmash.isSupported()){ - logPrinter.print("Unfortunately your platform '"+System.getProperty("os.name")+ + print("Unfortunately your platform '"+System.getProperty("os.name")+ "' of '"+System.getProperty("os.arch")+"' is not supported :("+ "\n But you could file a bug with request."+ "\n\n Nothing has been sent to NS. Execution stopped.", EMsgType.FAIL); @@ -124,14 +124,14 @@ public class Rcm implements Runnable{ // Send payload for (int i=0; i < fullPayload.length / 4096 ; i++){ if (writeUsb(Arrays.copyOfRange(fullPayload, i*4096, (i+1)*4096))){ - logPrinter.print("Failed to sent payload ["+i+"]"+ + print("Failed to sent payload ["+i+"]"+ "\n\n Execution stopped.", EMsgType.FAIL); usbConnect.close(); logPrinter.close(); return; } } - logPrinter.print("Information sent to NS.", EMsgType.PASS); + print("Information sent to NS.", EMsgType.PASS); if (ecurrentOS.equals(ECurrentOS.mac)){ if (smashMacOS()){ @@ -149,7 +149,7 @@ public class Rcm implements Runnable{ retval = RcmSmash.smashWindows(); else { // ( ?_?) - logPrinter.print("Failed to smash the stack since your OS is not supported. Please report this issue."+ + print("Failed to smash the stack since your OS is not supported. Please report this issue."+ "\n\n Execution stopped and failed. And it's strange.", EMsgType.FAIL); usbConnect.close(); logPrinter.close(); @@ -157,18 +157,27 @@ public class Rcm implements Runnable{ } if (retval != 0){ - logPrinter.print("Failed to smash the stack ("+retval+")"+ + print("Failed to smash the stack ("+retval+")"+ "\n\n Execution stopped and failed.", EMsgType.FAIL); usbConnect.close(); logPrinter.close(); return; } } - logPrinter.print(".:: Payload complete ::.", EMsgType.PASS); + print(".:: Payload complete ::.", EMsgType.PASS); usbConnect.close(); logPrinter.updateOneLinerStatus(true); logPrinter.close(); } + + private void print(String message, EMsgType type){ + try { + logPrinter.print(message, type); + } + catch (InterruptedException intr){ + intr.printStackTrace(); + } + } /** * Prepare the 'big' or full-size byte-buffer that is actually is a payload that we're about to use. * @return false for issues @@ -179,7 +188,7 @@ public class Rcm implements Runnable{ // 126296 b <- biggest size per CTCaer; 16384 selected randomly as minimum threshold. It's probably wrong. if (pldrFile.length() > 126296 || pldrFile.length() < 16384) { - logPrinter.print("File size of this payload looks wired. It's "+pldrFile.length()+" bytes."+ + print("File size of this payload looks wired. It's "+pldrFile.length()+" bytes."+ "\n 1. Double-check that you're using the right payload." + "\n 2. Please report this issue in case you're sure that you're doing everything right." + "\n\n Nothing has been sent to NS. Execution stopped.", EMsgType.FAIL); @@ -194,7 +203,7 @@ public class Rcm implements Runnable{ totalSize += 4096; // Double-check if (totalSize > 0x30298){ - logPrinter.print("File size of the payload is too big. Comparing to maximum size, it's greater to "+(totalSize - 0x30298)+" bytes!"+ + print("File size of the payload is too big. Comparing to maximum size, it's greater to "+(totalSize - 0x30298)+" bytes!"+ "\n 1. Double-check that you're using the right payload." + "\n 2. Please report this issue in case you're sure that you're doing everything right." + "\n\n Nothing has been sent to NS. Execution stopped.", EMsgType.FAIL); // Occurs: never. I'm too lazy to check. @@ -209,7 +218,7 @@ public class Rcm implements Runnable{ BufferedInputStream bis = new BufferedInputStream(new FileInputStream(pldrFile)); int readSize; if ((readSize = bis.read(dataPldFile)) != pldFileSize){ - logPrinter.print("Failed to retrieve data from payload file." + + print("Failed to retrieve data from payload file." + "\n Got only "+readSize+" bytes while "+pldFileSize+" expected." + "\n\n Nothing has been sent to NS. Execution stopped.", EMsgType.FAIL); bis.close(); @@ -218,7 +227,7 @@ public class Rcm implements Runnable{ bis.close(); } catch (Exception e){ - logPrinter.print("Failed to retrieve data from payload file: " +e.getMessage()+ + print("Failed to retrieve data from payload file: " +e.getMessage()+ "\n\n Nothing has been sent to NS. Execution stopped.", EMsgType.FAIL); return true; } @@ -241,7 +250,7 @@ public class Rcm implements Runnable{ IntBuffer readBufTransferred = IntBuffer.allocate(1); int result = LibUsb.bulkTransfer(handler, (byte) 0x81, readBuffer, readBufTransferred, 1000); if (result != LibUsb.SUCCESS) { - logPrinter.print("Unable to get device ID" + + print("Unable to get device ID" + "\n\n Nothing has been sent to NS. Execution stopped.", EMsgType.FAIL); return true; } @@ -251,7 +260,7 @@ public class Rcm implements Runnable{ StringBuilder idStrBld = new StringBuilder("Found device with ID: "); for (byte b: receivedBytes) idStrBld.append(String.format("%02x ", b)); - logPrinter.print(idStrBld.toString(), EMsgType.PASS); + print(idStrBld.toString(), EMsgType.PASS); return false; } /** @@ -269,13 +278,13 @@ public class Rcm implements Runnable{ if (writeBufTransferred.get() == 4096) return false; - logPrinter.print("RCM Data transfer issue [write]" + + print("RCM Data transfer issue [write]" + "\n Requested: " + message.length + "\n Transferred: " + writeBufTransferred.get()+ "\n\n Execution stopped.", EMsgType.FAIL); return true; } - logPrinter.print("RCM Data transfer issue [write]" + + print("RCM Data transfer issue [write]" + "\n Returned: " + UsbErrorCodes.getErrCode(result) + "\n\n Execution stopped.", EMsgType.FAIL); return true; diff --git a/src/main/java/nsusbloader/Utilities/nxdumptool/NxdtTask.java b/src/main/java/nsusbloader/Utilities/nxdumptool/NxdtTask.java index b5cb872..4ea63b3 100644 --- a/src/main/java/nsusbloader/Utilities/nxdumptool/NxdtTask.java +++ b/src/main/java/nsusbloader/Utilities/nxdumptool/NxdtTask.java @@ -38,8 +38,8 @@ public class NxdtTask extends CancellableRunnable { @Override public void run() { - logPrinter.print("Save to location: "+ saveToLocation, EMsgType.INFO); - logPrinter.print("=============== nxdumptool ===============", EMsgType.INFO); + print("Save to location: "+ saveToLocation, EMsgType.INFO); + print("=============== nxdumptool ===============", EMsgType.INFO); UsbConnect usbConnect = UsbConnect.connectHomebrewMode(logPrinter); @@ -54,13 +54,22 @@ public class NxdtTask extends CancellableRunnable { new NxdtUsbAbi1(handler, logPrinter, saveToLocation, this); } catch (Exception e){ - logPrinter.print(e.getMessage(), EMsgType.FAIL); + print(e.getMessage(), EMsgType.FAIL); } - logPrinter.print(".:: Complete ::.", EMsgType.PASS); + print(".:: Complete ::.", EMsgType.PASS); usbConnect.close(); logPrinter.updateOneLinerStatus(true); logPrinter.close(); } + + private void print(String message, EMsgType type){ + try { + logPrinter.print(message, type); + } + catch (InterruptedException ie){ + ie.printStackTrace(); + } + } } \ No newline at end of file diff --git a/src/main/java/nsusbloader/Utilities/nxdumptool/NxdtUsbAbi1.java b/src/main/java/nsusbloader/Utilities/nxdumptool/NxdtUsbAbi1.java index 613597d..b01a571 100644 --- a/src/main/java/nsusbloader/Utilities/nxdumptool/NxdtUsbAbi1.java +++ b/src/main/java/nsusbloader/Utilities/nxdumptool/NxdtUsbAbi1.java @@ -119,7 +119,7 @@ class NxdtUsbAbi1 { USBSTATUS_SUCCESS[9] = (byte)((endpointMaxPacketSize >> 8) & 0xFF); } - private void readLoop(){ + private void readLoop() throws InterruptedException{ logPrinter.print("Awaiting for handshake", EMsgType.INFO); try { byte[] directive; @@ -292,7 +292,7 @@ class NxdtUsbAbi1 { return nspFile != null; } - private String getAbsoluteFilePath(String filename) throws Exception{ + private String getAbsoluteFilePath(String filename) { if (isRomFs(filename) && isWindows) // Since RomFS entry starts from '/' it should be replaced to '\'. return saveToPath + filename.replaceAll("/", "\\\\"); return saveToPath + filename; diff --git a/src/main/java/nsusbloader/Utilities/splitmerge/MergeSubTask.java b/src/main/java/nsusbloader/Utilities/splitmerge/MergeSubTask.java new file mode 100644 index 0000000..2d1a27e --- /dev/null +++ b/src/main/java/nsusbloader/Utilities/splitmerge/MergeSubTask.java @@ -0,0 +1,178 @@ +/* + Copyright 2019-2021 Dmitry Isaenko + + This file is part of NS-USBloader. + + NS-USBloader is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + NS-USBloader is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with NS-USBloader. If not, see . +*/ +package nsusbloader.Utilities.splitmerge; + +import nsusbloader.NSLDataTypes.EMsgType; + +import java.io.*; +import java.util.Arrays; +import java.util.concurrent.Callable; + +public class MergeSubTask implements Callable { + private final int id; + private final String saveToPath; + private final MultithreadingPrintAdapter printAdapter; + private final File splitFile; + + private File[] chunkFiles; + private long chunksTotalSize; + private File resultFile; + + public MergeSubTask(int id, File splitFile, String saveToPath, MultithreadingPrintAdapter printAdapter){ + this.id = id; + this.splitFile = splitFile; + this.saveToPath = saveToPath; + this.printAdapter = printAdapter; + } + + @Override + public Boolean call(){ + try{ + collectChunks(); + validateChunks(); + sortChunks(); + calculateChunksSizeSum(); + + createFile(); + mergeChunksToFile(); + validateFile(); + return true; + } + catch (InterruptedException ie){ + cleanup(); + return false; + } + catch (Exception e){ + e.printStackTrace(); + try { + printAdapter.print("["+id+"] "+e.getMessage(), EMsgType.FAIL); + } + catch (InterruptedException ignore) {} + return false; + } + } + + private void collectChunks(){ + chunkFiles = splitFile.listFiles((file, s) -> s.matches("^[0-9][0-9]$")); + } + + private void validateChunks() throws Exception{ + if (chunkFiles == null || chunkFiles.length == 0){ + throw new Exception("Selected folder doesn't have any chunks. Nothing to do here."); + } + } + + private void sortChunks(){ + Arrays.sort(chunkFiles); + } + + private void calculateChunksSizeSum() throws InterruptedException{ + StringBuilder builder = new StringBuilder("["+id+"] Next files will be merged in following order: "); + + for (File cnk : chunkFiles){ + builder.append(cnk.getName()); + builder.append(" "); + chunksTotalSize += cnk.length(); + } + printAdapter.print(builder.toString(), EMsgType.INFO); + } + + private void createFile() throws Exception{ + final String splitFileName = splitFile.getName(); + + resultFile = new File(saveToPath+File.separator+"!_"+splitFileName); + + for (int i = 0; i < 50 ; i++){ + if (interrupted()) + throw new InterruptedException(); + + if (resultFile.exists()){ + printAdapter.print("["+id+"] Trying to create a good new file...", EMsgType.WARNING); + resultFile = new File(saveToPath+File.separator+"!_"+i+"_"+splitFileName); + continue; + } + + printAdapter.print("["+id+"] Save results to: "+resultFile.getAbsolutePath(), EMsgType.INFO); + return; + } + throw new Exception("Can't create new file."); + } + + private void mergeChunksToFile() throws Exception{ + if ( interrupted()) + throw new InterruptedException(); + + try(BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(resultFile))){ + BufferedInputStream bis; + byte[] chunk; + int readBytesCnt; + + printAdapter.reportFileSize(chunksTotalSize); + + for (File chunkFile : chunkFiles){ + bis = new BufferedInputStream(new FileInputStream(chunkFile)); + while (true){ + chunk = new byte[4194240]; + readBytesCnt = bis.read(chunk); + + if (readBytesCnt < 4194240){ + if (readBytesCnt > 0) + bos.write(chunk, 0, readBytesCnt); + break; + } + + if (interrupted()) + throw new InterruptedException(); + + bos.write(chunk); + + printAdapter.updateProgressBySize(readBytesCnt); + } + bis.close(); + } + } + } + + private void validateFile() throws Exception{ + if ( interrupted()) + throw new Exception("Merge task interrupted!"); + + long resultFileSize = resultFile.length(); + printAdapter.print("["+id+"] Total chunks size: " + chunksTotalSize + +"\n Merged file size: " + resultFileSize, EMsgType.INFO); + + if (chunksTotalSize != resultFileSize) + throw new Exception("Sizes are different! Do NOT use this file for installations!"); + + printAdapter.print("["+id+"] Sizes are the same! Resulting file should be good!", EMsgType.PASS); + } + + private void cleanup(){ + boolean isDeleted = resultFile.delete(); + try { + printAdapter.print( + "[" + id + "] Merge task interrupted and file " + + (isDeleted ? "deleted." : "is NOT deleted."), EMsgType.FAIL); + } + catch (InterruptedException ignore) {} + } + private boolean interrupted(){ + return Thread.interrupted(); // NOTE: it's not isInterrupted(); And it's handled properly for now. + } +} diff --git a/src/main/java/nsusbloader/Utilities/splitmerge/MergeTask.java b/src/main/java/nsusbloader/Utilities/splitmerge/MergeTask.java deleted file mode 100644 index 4119a0f..0000000 --- a/src/main/java/nsusbloader/Utilities/splitmerge/MergeTask.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - Copyright 2019-2020 Dmitry Isaenko - - This file is part of NS-USBloader. - - NS-USBloader is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - NS-USBloader is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with NS-USBloader. If not, see . -*/ -package nsusbloader.Utilities.splitmerge; - -import nsusbloader.ModelControllers.CancellableRunnable; -import nsusbloader.ModelControllers.ILogPrinter; -import nsusbloader.ModelControllers.Log; -import nsusbloader.NSLDataTypes.EModule; -import nsusbloader.NSLDataTypes.EMsgType; - -import java.io.*; -import java.util.Arrays; - -public class MergeTask extends CancellableRunnable { - - private final ILogPrinter logPrinter; - private final String saveToPath; - private final String filePath; - - private File splitFile; - - private File[] chunkFiles; - private long chunksTotalSize; - private File resultFile; - - public MergeTask(String filePath, String saveToPath) { - this.filePath = filePath; - this.saveToPath = saveToPath; - logPrinter = Log.getPrinter(EModule.SPLIT_MERGE_TOOL); - } - - @Override - public void run() { - try { - logPrinter.print("Merge file: " + filePath, EMsgType.INFO); - splitFile = new File(filePath); - - collectChunks(); - validateChunks(); - sortChunks(); - calculateChunksSizeSum(); - - createFile(); - mergeChunksToFile(); - validateFile(); - - logPrinter.print(".:: Merge complete ::.", EMsgType.INFO); - logPrinter.updateOneLinerStatus(true); - logPrinter.close(); - } - catch (Exception e){ - logPrinter.print(e.getMessage(), EMsgType.FAIL); - logPrinter.updateOneLinerStatus(false); - logPrinter.close(); - } - } - - private void collectChunks(){ - chunkFiles = splitFile.listFiles((file, s) -> s.matches("^[0-9][0-9]$")); - } - - private void validateChunks() throws Exception{ - if (chunkFiles == null || chunkFiles.length == 0){ - throw new Exception("Selected folder doesn't have any chunks. Nothing to do here."); - } - } - - private void sortChunks(){ - Arrays.sort(chunkFiles); - } - - private void calculateChunksSizeSum(){ - logPrinter.print("Next files will be merged in following order: ", EMsgType.INFO); - for (File cnk : chunkFiles){ - logPrinter.print(" "+cnk.getName(), EMsgType.INFO); - chunksTotalSize += cnk.length(); - } - } - - private void createFile() throws Exception{ - final String splitFileName = splitFile.getName(); - - resultFile = new File(saveToPath+File.separator+"!_"+splitFileName); - - for (int i = 0; i < 50 ; i++){ - if (isCancelled()){ - throw new InterruptedException("Split task interrupted!"); - } - - if (resultFile.exists()){ - logPrinter.print("Trying to create a good new file...", EMsgType.WARNING); - resultFile = new File(saveToPath+File.separator+"!_"+i+"_"+splitFileName); - continue; - } - - logPrinter.print("Save results to: "+resultFile.getAbsolutePath(), EMsgType.INFO); - return; - } - throw new Exception("Can't create new file."); - } - - private void mergeChunksToFile() throws Exception{ - double chunkPercent = (4194240.0 / (chunksTotalSize / 100.0) / 100.0); - long totalSizeCnt = 0; - - BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(resultFile)); - - BufferedInputStream bis; - byte[] chunk; - int readBytesCnt; - - for (File chunkFile : chunkFiles){ - bis = new BufferedInputStream(new FileInputStream(chunkFile)); - while (true){ - - if (isCancelled()){ - bos.close(); - bis.close(); - boolean isDeleted = resultFile.delete(); - throw new InterruptedException("Merge task interrupted and file " - + (isDeleted ? "deleted." : "is not deleted.")); - } - - chunk = new byte[4194240]; - readBytesCnt = bis.read(chunk); - - logPrinter.updateProgress(chunkPercent * totalSizeCnt); - totalSizeCnt++; - - if (readBytesCnt < 4194240){ - if (readBytesCnt > 0) - bos.write(chunk, 0, readBytesCnt); - break; - } - - bos.write(chunk); - } - bis.close(); - } - bos.close(); - } - - private void validateFile() throws Exception{ - long resultFileSize = resultFile.length(); - logPrinter.print("Total chunks size: " + chunksTotalSize, EMsgType.INFO); - logPrinter.print("Merged file size: " + resultFileSize, EMsgType.INFO); - - if (chunksTotalSize != resultFileSize) - throw new Exception("Sizes are different! Do NOT use this file for installations!"); - - logPrinter.print("Sizes are the same! Resulting file should be good!", EMsgType.PASS); - } -} diff --git a/src/main/java/nsusbloader/Utilities/splitmerge/MultithreadingPrintAdapter.java b/src/main/java/nsusbloader/Utilities/splitmerge/MultithreadingPrintAdapter.java new file mode 100644 index 0000000..b050498 --- /dev/null +++ b/src/main/java/nsusbloader/Utilities/splitmerge/MultithreadingPrintAdapter.java @@ -0,0 +1,44 @@ +/* + Copyright 2019-2021 Dmitry Isaenko + + This file is part of NS-USBloader. + + NS-USBloader is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + NS-USBloader is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with NS-USBloader. If not, see . + */ +package nsusbloader.Utilities.splitmerge; + +import nsusbloader.ModelControllers.ILogPrinter; +import nsusbloader.NSLDataTypes.EMsgType; + +public class MultithreadingPrintAdapter { + private final ILogPrinter printer; + private long totalFilesSize; + private long bytesComplete; + + public MultithreadingPrintAdapter(ILogPrinter printer){ + this.printer = printer; + } + + public void print(String message, EMsgType type) throws InterruptedException{ + printer.print(message, type); + } + + public void reportFileSize(long fileSize){ + totalFilesSize += fileSize; + } + public void updateProgressBySize(long chunkSize) throws InterruptedException{ + bytesComplete += chunkSize; + printer.updateProgress((double) bytesComplete / (double) totalFilesSize); + } +} diff --git a/src/main/java/nsusbloader/Utilities/splitmerge/SplitMergeTaskExecutor.java b/src/main/java/nsusbloader/Utilities/splitmerge/SplitMergeTaskExecutor.java new file mode 100644 index 0000000..6ac7110 --- /dev/null +++ b/src/main/java/nsusbloader/Utilities/splitmerge/SplitMergeTaskExecutor.java @@ -0,0 +1,147 @@ +/* + Copyright 2019-2020 Dmitry Isaenko + + This file is part of NS-USBloader. + + NS-USBloader is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + NS-USBloader is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with NS-USBloader. If not, see . +*/ +package nsusbloader.Utilities.splitmerge; + +import nsusbloader.ModelControllers.ILogPrinter; +import nsusbloader.ModelControllers.Log; +import nsusbloader.NSLDataTypes.EModule; +import nsusbloader.NSLDataTypes.EMsgType; + +import java.io.*; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.*; +/* +* TODO: Kill this on application exit (?) +*/ +public class SplitMergeTaskExecutor implements Runnable { + private final boolean isSplit; + private final List files; + private final String saveToPath; + private final ILogPrinter logPrinter; + private final ExecutorService executorService; + + private final MultithreadingPrintAdapter printAdapter; + + public SplitMergeTaskExecutor(boolean isSplit, List files, String saveToPath){ + this.isSplit = isSplit; + this.files = files; + this.saveToPath = saveToPath; + this.logPrinter = Log.getPrinter(EModule.SPLIT_MERGE_TOOL); + this.executorService = Executors.newFixedThreadPool( + files.size(), + runnable -> { + Thread thread = new Thread(runnable); + thread.setDaemon(true); + return thread; + }); + this.printAdapter = new MultithreadingPrintAdapter(logPrinter); + } + + public void run(){ + try { + List> futuresResults = executorService.invokeAll(getSubTasksCollection()); + boolean onelinerResult = true; + for (Future future : futuresResults){ + onelinerResult &= future.get(); + } + executorService.shutdown(); + logPrinter.updateOneLinerStatus(onelinerResult); + } + catch (InterruptedException ie){ + //ie.printStackTrace(); + executorService.shutdownNow(); + boolean interruptedSuccessfully = false; + try { + interruptedSuccessfully = executorService.awaitTermination(20, TimeUnit.SECONDS); + } + catch (InterruptedException awaitInterrupt){ + print("Force interrupting task...", EMsgType.WARNING); + } + logPrinter.updateOneLinerStatus(false); + print(( + isSplit? + "Split tasks interrupted ": + "Merge tasks interrupted ")+ + (interruptedSuccessfully? + "successfully": + "with some issues"), EMsgType.WARNING); + } + catch (Exception e){ + logPrinter.updateOneLinerStatus(false); + print( + isSplit? + "Split task failed: ": + "Merge task failed: "+e.getMessage(), EMsgType.FAIL); + e.printStackTrace(); + } + + print( + isSplit? + ".:: Split complete ::.": + ".:: Merge complete ::.", EMsgType.INFO); + logPrinter.close(); + } + private List> getSubTasksCollection() throws InterruptedException{ + List> subTasks = new ArrayList<>(); + StringBuilder stringBuilder = new StringBuilder(); + + // TODO: Optimize? + + if (isSplit){ + stringBuilder.append("Split files:\n"); + for (int i = 0; i < files.size(); i++){ + File file = files.get(i); + stringBuilder.append("["); + stringBuilder.append(i); + stringBuilder.append("] "); + stringBuilder.append(file.getName()); + stringBuilder.append("\n"); + Callable task = new SplitSubTask(i, file, saveToPath, printAdapter); + subTasks.add(task); + } + } + else { + stringBuilder.append("Merge files:\n"); + for (int i = 0; i < files.size(); i++){ + File file = files.get(i); + stringBuilder.append("["); + stringBuilder.append(i); + stringBuilder.append("] "); + stringBuilder.append(file.getName()); + stringBuilder.append("\n"); + Callable task = new MergeSubTask(i, file, saveToPath, printAdapter); + subTasks.add(task); + } + } + + logPrinter.print(stringBuilder.toString(), EMsgType.INFO); + + return subTasks; + } + + private void print(String message, EMsgType type){ + try { + logPrinter.print(message, type); + } + catch (InterruptedException ie){ + ie.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/src/main/java/nsusbloader/Utilities/splitmerge/SplitSubTask.java b/src/main/java/nsusbloader/Utilities/splitmerge/SplitSubTask.java new file mode 100644 index 0000000..6533a02 --- /dev/null +++ b/src/main/java/nsusbloader/Utilities/splitmerge/SplitSubTask.java @@ -0,0 +1,186 @@ +/* + Copyright 2019-2021 Dmitry Isaenko + + This file is part of NS-USBloader. + + NS-USBloader is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + NS-USBloader is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with NS-USBloader. If not, see . + */ +package nsusbloader.Utilities.splitmerge; + +import nsusbloader.NSLDataTypes.EMsgType; + +import java.io.*; +import java.util.Arrays; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; + +public class SplitSubTask implements Callable { + private final int id; + private final String saveToPath; + + private final File file; + private File splitFile; + private long originalFileLen; + private final MultithreadingPrintAdapter printAdapter; + + SplitSubTask(int id, File file, String saveToPath, MultithreadingPrintAdapter printAdapter){ + this.id = id; + this.file = file; + this.saveToPath = saveToPath; + this.printAdapter = printAdapter; + } + + @Override + public Boolean call(){ + try { + createSplitFile(); + splitFileToChunks(); + validateSplitFile(); + return true; + } + catch (InterruptedException | ExecutionException ie){ + ie.printStackTrace(); + cleanup(); + return false; + } + catch (Exception e){ + e.printStackTrace(); + try { + printAdapter.print("["+id+"] "+e.getMessage(), EMsgType.FAIL); + } + catch (InterruptedException ignore) {} + return false; + } + } + + private void createSplitFile() throws Exception{ + if ( interrupted()) + throw new Exception("Split task interrupted!"); + + splitFile = new File(saveToPath+File.separator+"!_"+file.getName()); + + for (int i = 0; i < 50; i++){ + if (splitFile.mkdirs()){ + printAdapter.print("["+id+"] Save results to: "+splitFile.getAbsolutePath(), EMsgType.INFO); + return; + } + + if (splitFile.exists()){ + printAdapter.print("["+id+"] Trying to create a good new folder...", EMsgType.WARNING); + splitFile = new File(saveToPath+File.separator+"!_"+i+"_"+file.getName()); + continue; + } + + throw new Exception("Folder " + splitFile.getAbsolutePath() + + " could not be created. Not enough rights or something like that?"); + } + throw new Exception("Can't create new file."); + } + + private void splitFileToChunks() throws Exception{ + try(BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file))){ + long counter; + + originalFileLen = file.length(); + printAdapter.reportFileSize(originalFileLen); + + byte[] chunk; + int readBytesCnt; + + main_loop: + for (int i = 0; ; i++){ + String pathname = splitFile.getAbsolutePath()+File.separator+String.format("%02d", i); + BufferedOutputStream fragmentBos = new BufferedOutputStream(new FileOutputStream(pathname)); + + counter = 0; + + while (counter < 1024){ // 0xffff0000 total + chunk = new byte[4194240]; + + if ((readBytesCnt = bis.read(chunk)) < 4194240){ + if (readBytesCnt > 0) + fragmentBos.write(chunk, 0, readBytesCnt); + fragmentBos.close(); + printAdapter.updateProgressBySize(readBytesCnt); + break main_loop; + } + if (interrupted()) + throw new InterruptedException(); + + fragmentBos.write(chunk); + counter++; + printAdapter.updateProgressBySize(readBytesCnt); + } + fragmentBos.close(); + } + } + } + + private void validateSplitFile() throws Exception{ + if (interrupted()) + throw new Exception("Split task interrupted!"); + + printAdapter.print("["+id+"] Original file: "+splitFile.getAbsolutePath()+" (size: "+originalFileLen+")", EMsgType.INFO); + + long totalChunksSize = 0; + File[] chunkFileArr = splitFile.listFiles(); + + if (chunkFileArr == null) + throw new Exception("Unable to check results. It means that something went wrong."); + + Arrays.sort(chunkFileArr); + + StringBuilder stringBuilder = new StringBuilder("["+id+"] Chunks"); + + for (File chunkFile : chunkFileArr) { + stringBuilder.append("\n"); + stringBuilder.append(" "); + stringBuilder.append(chunkFile.getName()); + stringBuilder.append(" size: "); + stringBuilder.append(chunkFile.length()); + totalChunksSize += chunkFile.length(); + } + stringBuilder.append("\n"); + stringBuilder.append("Total chunks size: "); + stringBuilder.append(totalChunksSize); + + printAdapter.print(stringBuilder.toString(), EMsgType.INFO); + + if (originalFileLen != totalChunksSize) + throw new Exception("Sizes are different! Do NOT use this file for installations!"); + + printAdapter.print("["+id+"] Sizes are the same! Split file should be good!", EMsgType.PASS); + } + + private void cleanup(){ + boolean isDeleted = splitFile.delete(); + File[] chunksToDelete = splitFile.listFiles(); + if (! isDeleted && chunksToDelete != null){ + isDeleted = true; + for (File chunkFile : chunksToDelete) + isDeleted &= chunkFile.delete(); + isDeleted &= splitFile.delete(); + } + try { + printAdapter.print( + "["+id+"] Split task interrupted and folder " + + (isDeleted?"deleted.":"is NOT deleted.") + , EMsgType.FAIL); + } + catch (InterruptedException ignore) {} + } + private boolean interrupted(){ + return Thread.interrupted(); // NOTE: it's not isInterrupted(); And it's handled properly for now. + } +} diff --git a/src/main/java/nsusbloader/Utilities/splitmerge/SplitTask.java b/src/main/java/nsusbloader/Utilities/splitmerge/SplitTask.java deleted file mode 100644 index 1c617b8..0000000 --- a/src/main/java/nsusbloader/Utilities/splitmerge/SplitTask.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - Copyright 2019-2020 Dmitry Isaenko - - This file is part of NS-USBloader. - - NS-USBloader is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - NS-USBloader is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with NS-USBloader. If not, see . -*/ -package nsusbloader.Utilities.splitmerge; - -import nsusbloader.ModelControllers.CancellableRunnable; -import nsusbloader.ModelControllers.ILogPrinter; -import nsusbloader.ModelControllers.Log; -import nsusbloader.NSLDataTypes.EModule; -import nsusbloader.NSLDataTypes.EMsgType; - -import java.io.*; -import java.util.Arrays; - -public class SplitTask extends CancellableRunnable { - - private final ILogPrinter logPrinter; - private final String saveToPath; - private final String filePath; - - private File file; - private File splitFile; - private long originalFileLen; - - public SplitTask(String filePath, String saveToPath){ - this.filePath = filePath; - this.saveToPath = saveToPath; - this.logPrinter = Log.getPrinter(EModule.SPLIT_MERGE_TOOL); - } - - @Override - public void run() { - try { - logPrinter.print("Split file: "+filePath, EMsgType.INFO); - this.file = new File(filePath); - - createSplitFile(); - splitFileToChunks(); - validateSplitFile(); - - logPrinter.print(".:: Split complete ::.", EMsgType.INFO); - logPrinter.updateOneLinerStatus(true); - logPrinter.close(); - } - catch (Exception e){ - logPrinter.print(e.getMessage(), EMsgType.FAIL); - logPrinter.updateOneLinerStatus(false); - logPrinter.close(); - } - } - - private void createSplitFile() throws Exception{ - splitFile = new File(saveToPath+File.separator+"!_"+file.getName()); - - for (int i = 0; i < 50 ; i++){ - if (isCancelled()){ - throw new InterruptedException("Split task interrupted!"); - } - - if (splitFile.mkdir()){ - logPrinter.print("Save results to: "+splitFile.getAbsolutePath(), EMsgType.INFO); - return; - } - - if (splitFile.exists()){ - logPrinter.print("Trying to create a good new folder...", EMsgType.WARNING); - splitFile = new File(saveToPath+File.separator+"!_"+i+"_"+file.getName()); - continue; - } - - throw new Exception("Folder " + splitFile.getAbsolutePath() - + " could not be created. Not enough rights or something like that?"); - } - throw new Exception("Can't create new file."); - } - - private void splitFileToChunks() throws Exception{ - BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file)); - - long counter; - - originalFileLen = file.length(); - - double chunkPercent = (4194240.0 / (originalFileLen / 100.0) / 100.0); - long totalSizeCnt = 0; - - byte[] chunk; - int readBytesCnt; - - main_loop: - for (int i = 0; ; i++){ - String pathname = splitFile.getAbsolutePath()+File.separator+String.format("%02d", i); - BufferedOutputStream fragmentBos = new BufferedOutputStream(new FileOutputStream(new File(pathname))); - - counter = 0; - - while (counter < 1024){ // 0xffff0000 total - - if (isCancelled()){ - fragmentBos.close(); - bis.close(); - boolean isDeleted = splitFile.delete(); - File[] chunksToDelete = splitFile.listFiles(); - if (! isDeleted && chunksToDelete != null){ - isDeleted = true; - for (File chunkFile : chunksToDelete) - isDeleted &= chunkFile.delete(); - isDeleted &= splitFile.delete(); - } - - throw new InterruptedException("Split task interrupted and folder " - + (isDeleted?"deleted.":"is not deleted.")); - } - - chunk = new byte[4194240]; - - if ((readBytesCnt = bis.read(chunk)) < 4194240){ - if (readBytesCnt > 0) - fragmentBos.write(chunk, 0, readBytesCnt); - fragmentBos.close(); - logPrinter.updateProgress(1.0); - break main_loop; - } - - fragmentBos.write(chunk); - - logPrinter.updateProgress(chunkPercent * totalSizeCnt); - counter++; // NOTE: here we have some redundancy of variables. It has to be fixed one day. - totalSizeCnt++; - } - fragmentBos.close(); - } - bis.close(); - } - - private void validateSplitFile() throws Exception{ - logPrinter.print("Original file size: "+originalFileLen, EMsgType.INFO); - long totalChunksSize = 0; - File[] chunkFileArr = splitFile.listFiles(); - - if (chunkFileArr == null) - throw new Exception("Unable to check results. It means that something went wrong."); - - Arrays.sort(chunkFileArr); - - for (File chunkFile : chunkFileArr) { - logPrinter.print("Chunk " + chunkFile.getName() + " size: " + chunkFile.length(), EMsgType.INFO); - totalChunksSize += chunkFile.length(); - } - - logPrinter.print("Total chunks size: " + totalChunksSize, EMsgType.INFO); - - if (originalFileLen != totalChunksSize) - throw new Exception("Sizes are different! Do NOT use this file for installations!"); - - logPrinter.print("Sizes are the same! Split file should be good!", EMsgType.PASS); - } -} \ No newline at end of file diff --git a/src/main/java/nsusbloader/cli/MergeCli.java b/src/main/java/nsusbloader/cli/MergeCli.java index ae28f5d..99fba28 100644 --- a/src/main/java/nsusbloader/cli/MergeCli.java +++ b/src/main/java/nsusbloader/cli/MergeCli.java @@ -18,8 +18,7 @@ */ package nsusbloader.cli; -import nsusbloader.Utilities.splitmerge.MergeTask; -import nsusbloader.Utilities.splitmerge.SplitTask; +import nsusbloader.Utilities.splitmerge.SplitMergeTaskExecutor; import java.io.File; import java.util.ArrayList; @@ -27,7 +26,7 @@ import java.util.List; public class MergeCli { - private String[] arguments; + private final String[] arguments; private String saveTo; private String[] splitFiles; @@ -97,12 +96,20 @@ public class MergeCli { } private void runBackend() throws InterruptedException{ - for (String filePath : splitFiles){ - Runnable mergeTask = new MergeTask(filePath, saveTo); - Thread thread = new Thread(mergeTask); - thread.setDaemon(true); - thread.start(); - thread.join(); + Runnable mergeTask = new SplitMergeTaskExecutor( + false, + getFilesFromStrings(), + saveTo); + Thread thread = new Thread(mergeTask); + thread.setDaemon(true); + thread.start(); + thread.join(); + } + private List getFilesFromStrings(){ + ArrayList realFiles = new ArrayList<>(); + for (String splitFileString : splitFiles){ + realFiles.add(new File(splitFileString)); } + return realFiles; } } diff --git a/src/main/java/nsusbloader/cli/SplitCli.java b/src/main/java/nsusbloader/cli/SplitCli.java index b9e6922..1f093cf 100644 --- a/src/main/java/nsusbloader/cli/SplitCli.java +++ b/src/main/java/nsusbloader/cli/SplitCli.java @@ -18,16 +18,14 @@ */ package nsusbloader.cli; -import nsusbloader.Utilities.splitmerge.SplitTask; +import nsusbloader.Utilities.splitmerge.SplitMergeTaskExecutor; import java.io.File; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.List; +import java.util.*; public class SplitCli { - private String[] arguments; + private final String[] arguments; private String saveTo; private String[] files; @@ -95,12 +93,20 @@ public class SplitCli { } private void runBackend() throws InterruptedException{ - for (String filePath : files){ - Runnable splitTaks = new SplitTask(filePath, saveTo); - Thread thread = new Thread(splitTaks); - thread.setDaemon(true); - thread.start(); - thread.join(); + Runnable splitTasks = new SplitMergeTaskExecutor( + true, + getFilesFromStrings(), + saveTo); + Thread thread = new Thread(splitTasks); + thread.setDaemon(true); + thread.start(); + thread.join(); + } + private List getFilesFromStrings(){ + ArrayList realFiles = new ArrayList<>(); + for (String fileString : files){ + realFiles.add(new File(fileString)); } + return realFiles; } } diff --git a/src/main/java/nsusbloader/com/net/NETCommunications.java b/src/main/java/nsusbloader/com/net/NETCommunications.java index ba03ff6..b26e8bd 100644 --- a/src/main/java/nsusbloader/com/net/NETCommunications.java +++ b/src/main/java/nsusbloader/com/net/NETCommunications.java @@ -90,7 +90,7 @@ public class NETCommunications extends CancellableRunnable { if (! isValid || isCancelled() ) return; - logPrinter.print("\tStart chain", EMsgType.INFO); + print("\tStart chain", EMsgType.INFO); final String handshakeContent = buildHandshakeContent(); @@ -102,11 +102,11 @@ public class NETCommunications extends CancellableRunnable { // Check if we should serve requests if (this.doNotServe){ - logPrinter.print("List of files transferred. Replies won't be served.", EMsgType.PASS); + print("List of files transferred. Replies won't be served.", EMsgType.PASS); close(EFileStatus.UNKNOWN); return; } - logPrinter.print("Initiation files list has been sent to NS.", EMsgType.PASS); + print("Initiation files list has been sent to NS.", EMsgType.PASS); // Go transfer serveRequestsLoop(); @@ -142,7 +142,7 @@ public class NETCommunications extends CancellableRunnable { handshakeSocket.close(); } catch (IOException uhe){ - logPrinter.print("Unable to connect to NS and send files list:\n " + print("Unable to connect to NS and send files list:\n " + uhe.getMessage(), EMsgType.FAIL); close(EFileStatus.UNKNOWN); return true; @@ -175,13 +175,13 @@ public class NETCommunications extends CancellableRunnable { } catch (Exception e){ if (isCancelled()) - logPrinter.print("Interrupted by user.", EMsgType.INFO); + print("Interrupted by user.", EMsgType.INFO); else - logPrinter.print(e.getMessage(), EMsgType.INFO); + print(e.getMessage(), EMsgType.INFO); close(EFileStatus.UNKNOWN); return; } - logPrinter.print("All transfers complete", EMsgType.PASS); + print("All transfers complete", EMsgType.PASS); close(EFileStatus.UPLOADED); } /** @@ -199,7 +199,7 @@ public class NETCommunications extends CancellableRunnable { if (! files.containsKey(reqFileName)){ writeToSocket(NETPacket.getCode404()); - logPrinter.print("File "+reqFileName+" doesn't exists or have 0 size. Returning 404", EMsgType.FAIL); + print("File "+reqFileName+" doesn't exists or have 0 size. Returning 404", EMsgType.FAIL); return; } @@ -208,13 +208,13 @@ public class NETCommunications extends CancellableRunnable { if (! requestedFile.exists() || reqFileSize == 0){ // well.. tell 404 if file exists with 0 length is against standard, but saves time writeToSocket(NETPacket.getCode404()); - logPrinter.print("File "+requestedFile.getName()+" doesn't exists or have 0 size. Returning 404", EMsgType.FAIL); + print("File "+requestedFile.getName()+" doesn't exists or have 0 size. Returning 404", EMsgType.FAIL); logPrinter.update(requestedFile, EFileStatus.FAILED); return; } if (packet.get(0).startsWith("HEAD")){ writeToSocket(NETPacket.getCode200(reqFileSize)); - logPrinter.print("Replying for requested file: "+requestedFile.getName(), EMsgType.INFO); + print("Replying for requested file: "+requestedFile.getName(), EMsgType.INFO); return; } if (packet.get(0).startsWith("GET")) { @@ -237,7 +237,7 @@ public class NETCommunications extends CancellableRunnable { if (fromRange > toRange){ // If start bytes greater then end bytes writeToSocket(NETPacket.getCode400()); - logPrinter.print("Requested range for " + print("Requested range for " + file.getName() + " is incorrect. Returning 400", EMsgType.FAIL); logPrinter.update(file, EFileStatus.FAILED); @@ -254,7 +254,7 @@ public class NETCommunications extends CancellableRunnable { if (rangeStr[1].isEmpty()) { // If Range not defined: like "Range: bytes=-" writeToSocket(NETPacket.getCode400()); - logPrinter.print("Requested range for " + print("Requested range for " + file.getName() + " is incorrect (empty start & end). Returning 400", EMsgType.FAIL); logPrinter.update(file, EFileStatus.FAILED); @@ -267,7 +267,7 @@ public class NETCommunications extends CancellableRunnable { } // If file smaller than 500 bytes writeToSocket(NETPacket.getCode416()); - logPrinter.print("File size requested for " + print("File size requested for " + file.getName() + " while actual size of it: " + fileSize+". Returning 416", EMsgType.FAIL); @@ -275,7 +275,7 @@ public class NETCommunications extends CancellableRunnable { } catch (NumberFormatException nfe){ writeToSocket(NETPacket.getCode400()); - logPrinter.print("Requested range for " + print("Requested range for " + file.getName() + " has incorrect format. Returning 400\n\t" + nfe.getMessage(), EMsgType.FAIL); @@ -293,7 +293,7 @@ public class NETCommunications extends CancellableRunnable { private void writeToSocket(String fileName, long start, long end) throws Exception{ File file = files.get(fileName).getFile(); - logPrinter.print("Reply to range: "+start+"-"+end, EMsgType.INFO); + print("Reply to range: "+start+"-"+end, EMsgType.INFO); writeToSocket(NETPacket.getCode206(files.get(fileName).getSize(), start, end)); try{ @@ -379,11 +379,11 @@ public class NETCommunications extends CancellableRunnable { try { if (serverSocket != null && ! serverSocket.isClosed()) { serverSocket.close(); - logPrinter.print("Closing server socket.", EMsgType.PASS); + print("Closing server socket.", EMsgType.PASS); } } catch (IOException ioe){ - logPrinter.print("Closing server socket failed. Sometimes it's not an issue.", EMsgType.WARNING); + print("Closing server socket failed. Sometimes it's not an issue.", EMsgType.WARNING); } HashMap tempMap = new HashMap<>(); @@ -392,7 +392,15 @@ public class NETCommunications extends CancellableRunnable { logPrinter.update(tempMap, status); - logPrinter.print("\tEnd chain", EMsgType.INFO); + print("\tEnd chain", EMsgType.INFO); logPrinter.close(); } + private void print(String message, EMsgType type){ + try { + logPrinter.print(message, type); + } + catch (InterruptedException ie){ + ie.printStackTrace(); + } + } } \ No newline at end of file diff --git a/src/main/java/nsusbloader/com/net/NetworkSetupValidator.java b/src/main/java/nsusbloader/com/net/NetworkSetupValidator.java index 706bd97..b4908db 100644 --- a/src/main/java/nsusbloader/com/net/NetworkSetupValidator.java +++ b/src/main/java/nsusbloader/com/net/NetworkSetupValidator.java @@ -55,15 +55,21 @@ public class NetworkSetupValidator { resolvePort(hostPortNum); } catch (Exception e){ - logPrinter.print(e.getMessage(), EMsgType.FAIL); + try { + logPrinter.print(e.getMessage(), EMsgType.FAIL); + } + catch (InterruptedException ignore){} valid = false; return; } valid = true; } - private void validateFiles(List filesList) { - filesList.removeIf(f -> { + private void validateFiles(List filesList){ + filesList.removeIf(this::validator); + } + private boolean validator(File f){ + try { if (f.isFile()) return false; @@ -76,24 +82,27 @@ public class NetworkSetupValidator { Arrays.sort(subFiles, Comparator.comparingInt(file -> Integer.parseInt(file.getName()))); - for (int i = subFiles.length - 2; i > 0 ; i--){ - if (subFiles[i].length() != subFiles[i-1].length()) { - logPrinter.print("NET: Exclude split file: "+f.getName()+ + for (int i = subFiles.length - 2; i > 0; i--) { + if (subFiles[i].length() != subFiles[i - 1].length()) { + logPrinter.print("NET: Exclude split file: " + f.getName() + "\n Chunk sizes of the split file are not the same, but has to be.", EMsgType.WARNING); return true; } } long firstFileLength = subFiles[0].length(); - long lastFileLength = subFiles[subFiles.length-1].length(); + long lastFileLength = subFiles[subFiles.length - 1].length(); - if (lastFileLength > firstFileLength){ - logPrinter.print("NET: Exclude split file: "+f.getName()+ + if (lastFileLength > firstFileLength) { + logPrinter.print("NET: Exclude split file: " + f.getName() + "\n Chunk sizes of the split file are not the same, but has to be.", EMsgType.WARNING); return true; } return false; - }); + } + catch (InterruptedException ie){ + return false; + } } private void encodeAndAddFilesToMap(List filesList) throws UnsupportedEncodingException, FileNotFoundException { @@ -108,7 +117,7 @@ public class NetworkSetupValidator { } } - private void resolveIp(String hostIPaddr) throws IOException{ + private void resolveIp(String hostIPaddr) throws IOException, InterruptedException{ if (! hostIPaddr.isEmpty()){ this.hostIP = hostIPaddr; logPrinter.print("NET: Host IP defined as: " + hostIP, EMsgType.PASS); @@ -124,7 +133,7 @@ public class NetworkSetupValidator { throw new IOException("Try using 'Expert mode' and set IP manually. " + getAvaliableIpExamples()); } - private boolean findIpUsingHost(String host) { + private boolean findIpUsingHost(String host) throws InterruptedException{ try { Socket scoketK; scoketK = new Socket(); diff --git a/src/main/java/nsusbloader/com/usb/GoldLeaf_05.java b/src/main/java/nsusbloader/com/usb/GoldLeaf_05.java index 53ebc4d..7a1d872 100644 --- a/src/main/java/nsusbloader/com/usb/GoldLeaf_05.java +++ b/src/main/java/nsusbloader/com/usb/GoldLeaf_05.java @@ -59,17 +59,17 @@ public class GoldLeaf_05 extends TransferModule { this.task = task; status = EFileStatus.FAILED; - logPrinter.print("============= GoldLeaf v0.5 =============\n" + + print("============= GoldLeaf v0.5 =============\n" + " Only one file per time could be sent. In case you selected more the first one would be picked.", EMsgType.INFO); if (nspMap.isEmpty()){ - logPrinter.print("For using this GoldLeaf version you have to add file to the table and select it for upload", EMsgType.INFO); + print("For using this GoldLeaf version you have to add file to the table and select it for upload", EMsgType.INFO); return; } File nspFile = (File) nspMap.values().toArray()[0]; - logPrinter.print("File for upload: "+nspFile.getAbsolutePath(), EMsgType.INFO); + print("File for upload: "+nspFile.getAbsolutePath(), EMsgType.INFO); if (!nspFile.getName().toLowerCase().endsWith(".nsp")) { - logPrinter.print("GL This file doesn't look like NSP", EMsgType.FAIL); + print("GL This file doesn't look like NSP", EMsgType.FAIL); return; } PFSProvider pfsElement; @@ -77,11 +77,11 @@ public class GoldLeaf_05 extends TransferModule { pfsElement = new PFSProvider(nspFile, logPrinter); } catch (Exception e){ - logPrinter.print("GL File provided has incorrect structure and won't be uploaded\n\t"+e.getMessage(), EMsgType.FAIL); + print("GL File provided has incorrect structure and won't be uploaded\n\t"+e.getMessage(), EMsgType.FAIL); status = EFileStatus.INCORRECT_FILE_FAILED; return; } - logPrinter.print("GL File structure validated and it will be uploaded", EMsgType.PASS); + print("GL File structure validated and it will be uploaded", EMsgType.PASS); try{ if (nspFile.isDirectory()) @@ -90,7 +90,7 @@ public class GoldLeaf_05 extends TransferModule { this.raf = new RandomAccessFile(nspFile, "r"); } catch (IOException ioe){ - logPrinter.print("GL File not found\n\t"+ioe.getMessage(), EMsgType.FAIL); + print("GL File not found\n\t"+ioe.getMessage(), EMsgType.FAIL); return; } @@ -99,15 +99,15 @@ public class GoldLeaf_05 extends TransferModule { // Go connect to GoldLeaf if (writeUsb(CMD_GLUC)) { - logPrinter.print("GL Initiating GoldLeaf connection [1/2]", EMsgType.FAIL); + print("GL Initiating GoldLeaf connection [1/2]", EMsgType.FAIL); return; } - logPrinter.print("GL Initiating GoldLeaf connection: [1/2]", EMsgType.PASS); + print("GL Initiating GoldLeaf connection: [1/2]", EMsgType.PASS); if (writeUsb(CMD_ConnectionRequest)){ - logPrinter.print("GL Initiating GoldLeaf connection: [2/2]", EMsgType.FAIL); + print("GL Initiating GoldLeaf connection: [2/2]", EMsgType.FAIL); return; } - logPrinter.print("GL Initiating GoldLeaf connection: [2/2]", EMsgType.PASS); + print("GL Initiating GoldLeaf connection: [2/2]", EMsgType.PASS); while (true) { readByte = readUsb(); @@ -143,7 +143,7 @@ public class GoldLeaf_05 extends TransferModule { continue; } if (Arrays.equals(readByte, CMD_Finish)) { - logPrinter.print("GL Closing GoldLeaf connection: Transfer successful.", EMsgType.PASS); + print("GL Closing GoldLeaf connection: Transfer successful.", EMsgType.PASS); status = EFileStatus.UPLOADED; break; } @@ -164,29 +164,29 @@ public class GoldLeaf_05 extends TransferModule { * false if no issues * */ private boolean handleConnectionResponse(PFSProvider pfsElement){ - logPrinter.print("GL 'ConnectionResponse' command:", EMsgType.INFO); + print("GL 'ConnectionResponse' command:", EMsgType.INFO); if (writeUsb(CMD_GLUC)) { - logPrinter.print(" [1/4]", EMsgType.FAIL); + print(" [1/4]", EMsgType.FAIL); return true; } - logPrinter.print(" [1/4]", EMsgType.PASS); + print(" [1/4]", EMsgType.PASS); if (writeUsb(CMD_NSPName)) { - logPrinter.print(" [2/4]", EMsgType.FAIL); + print(" [2/4]", EMsgType.FAIL); return true; } - logPrinter.print(" [2/4]", EMsgType.PASS); + print(" [2/4]", EMsgType.PASS); if (writeUsb(pfsElement.getBytesNspFileNameLength())) { - logPrinter.print(" [3/4]", EMsgType.FAIL); + print(" [3/4]", EMsgType.FAIL); return true; } - logPrinter.print(" [3/4]", EMsgType.PASS); + print(" [3/4]", EMsgType.PASS); if (writeUsb(pfsElement.getBytesNspFileName())) { - logPrinter.print(" [4/4]", EMsgType.FAIL); + print(" [4/4]", EMsgType.FAIL); return true; } - logPrinter.print(" [4/4]", EMsgType.PASS); + print(" [4/4]", EMsgType.PASS); return false; } @@ -196,50 +196,50 @@ public class GoldLeaf_05 extends TransferModule { * false if no issues * */ private boolean handleStart(PFSProvider pfsElement){ - logPrinter.print("GL Handle 'Start' command:", EMsgType.INFO); + print("GL Handle 'Start' command:", EMsgType.INFO); if (writeUsb(CMD_GLUC)) { - logPrinter.print(" [Prefix]", EMsgType.FAIL); + print(" [Prefix]", EMsgType.FAIL); return true; } - logPrinter.print(" [Prefix]", EMsgType.PASS); + print(" [Prefix]", EMsgType.PASS); if (writeUsb(CMD_NSPData)) { - logPrinter.print(" [Command]", EMsgType.FAIL); + print(" [Command]", EMsgType.FAIL); return true; } - logPrinter.print(" [Command]", EMsgType.PASS); + print(" [Command]", EMsgType.PASS); if (writeUsb(pfsElement.getBytesCountOfNca())) { - logPrinter.print(" [Sub-files count]", EMsgType.FAIL); + print(" [Sub-files count]", EMsgType.FAIL); return true; } - logPrinter.print(" [Sub-files count]", EMsgType.PASS); + print(" [Sub-files count]", EMsgType.PASS); int ncaCount = pfsElement.getIntCountOfNca(); - logPrinter.print(" [Information for "+ncaCount+" sub-files]", EMsgType.INFO); + print(" [Information for "+ncaCount+" sub-files]", EMsgType.INFO); for (int i = 0; i < ncaCount; i++){ - logPrinter.print("File #"+i, EMsgType.INFO); + print("File #"+i, EMsgType.INFO); if (writeUsb(pfsElement.getNca(i).getNcaFileNameLength())) { - logPrinter.print(" [1/4] Name length", EMsgType.FAIL); + print(" [1/4] Name length", EMsgType.FAIL); return true; } - logPrinter.print(" [1/4] Name length", EMsgType.PASS); + print(" [1/4] Name length", EMsgType.PASS); if (writeUsb(pfsElement.getNca(i).getNcaFileName())) { - logPrinter.print(" [2/4] Name", EMsgType.FAIL); + print(" [2/4] Name", EMsgType.FAIL); return true; } - logPrinter.print(" [2/4] Name", EMsgType.PASS); + print(" [2/4] Name", EMsgType.PASS); if (writeUsb(ByteBuffer.allocate(8).order(ByteOrder.LITTLE_ENDIAN).putLong(pfsElement.getBodySize()+pfsElement.getNca(i).getNcaOffset()).array())) { // offset. real. - logPrinter.print(" [3/4] Offset", EMsgType.FAIL); + print(" [3/4] Offset", EMsgType.FAIL); return true; } - logPrinter.print(" [3/4] Offset", EMsgType.PASS); + print(" [3/4] Offset", EMsgType.PASS); if (writeUsb(ByteBuffer.allocate(8).order(ByteOrder.LITTLE_ENDIAN).putLong(pfsElement.getNca(i).getNcaSize()).array())) { // size - logPrinter.print(" [4/4] Size", EMsgType.FAIL); + print(" [4/4] Size", EMsgType.FAIL); return true; } - logPrinter.print(" [4/4] Size", EMsgType.PASS); + print(" [4/4] Size", EMsgType.PASS); } return false; } @@ -254,18 +254,18 @@ public class GoldLeaf_05 extends TransferModule { int requestedNcaID; if (isItRawRequest) { - logPrinter.print("GL Handle 'Content' command", EMsgType.INFO); + print("GL Handle 'Content' command", EMsgType.INFO); byte[] readByte = readUsb(); if (readByte == null || readByte.length != 4) { - logPrinter.print(" [Read requested ID]", EMsgType.FAIL); + print(" [Read requested ID]", EMsgType.FAIL); return true; } requestedNcaID = ByteBuffer.wrap(readByte).order(ByteOrder.LITTLE_ENDIAN).getInt(); - logPrinter.print(" [Read requested ID = "+requestedNcaID+" ]", EMsgType.PASS); + print(" [Read requested ID = "+requestedNcaID+" ]", EMsgType.PASS); } else { requestedNcaID = pfsElement.getNcaTicketID(); - logPrinter.print("GL Handle 'Ticket' command (ID = "+requestedNcaID+" )", EMsgType.INFO); + print("GL Handle 'Ticket' command (ID = "+requestedNcaID+" )", EMsgType.INFO); } long realNcaOffset = pfsElement.getNca(requestedNcaID).getNcaOffset()+pfsElement.getBodySize(); @@ -317,8 +317,8 @@ public class GoldLeaf_05 extends TransferModule { logPrinter.updateProgress(1.0); //-----------------------------------------/ } - catch (IOException ioe){ - logPrinter.print("GL Failed to read NCA ID "+requestedNcaID+". IO Exception:\n "+ioe.getMessage(), EMsgType.FAIL); + catch (IOException | InterruptedException ioe){ + print("GL Failed to read NCA ID "+requestedNcaID+". Exception:\n "+ioe.getMessage(), EMsgType.FAIL); ioe.printStackTrace(); return true; } @@ -345,18 +345,18 @@ public class GoldLeaf_05 extends TransferModule { if (writeBufTransferred.get() == message.length) return false; else { - logPrinter.print("GL Data transfer issue [write]\n Requested: "+message.length+"\n Transferred: "+writeBufTransferred.get(), EMsgType.FAIL); + print("GL Data transfer issue [write]\n Requested: "+message.length+"\n Transferred: "+writeBufTransferred.get(), EMsgType.FAIL); return true; } case LibUsb.ERROR_TIMEOUT: continue; default: - logPrinter.print("GL Data transfer issue [write]\n Returned: "+ UsbErrorCodes.getErrCode(result), EMsgType.FAIL); - logPrinter.print("GL Execution stopped", EMsgType.FAIL); + print("GL Data transfer issue [write]\n Returned: "+ UsbErrorCodes.getErrCode(result), EMsgType.FAIL); + print("GL Execution stopped", EMsgType.FAIL); return true; } } - logPrinter.print("GL Execution interrupted", EMsgType.INFO); + print("GL Execution interrupted", EMsgType.INFO); return true; } /** @@ -382,12 +382,12 @@ public class GoldLeaf_05 extends TransferModule { case LibUsb.ERROR_TIMEOUT: continue; default: - logPrinter.print("GL Data transfer issue [read]\n Returned: " + UsbErrorCodes.getErrCode(result), EMsgType.FAIL); - logPrinter.print("GL Execution stopped", EMsgType.FAIL); + print("GL Data transfer issue [read]\n Returned: " + UsbErrorCodes.getErrCode(result), EMsgType.FAIL); + print("GL Execution stopped", EMsgType.FAIL); return null; } } - logPrinter.print("GL Execution interrupted", EMsgType.INFO); + print("GL Execution interrupted", EMsgType.INFO); return null; } } \ No newline at end of file diff --git a/src/main/java/nsusbloader/com/usb/GoldLeaf_07.java b/src/main/java/nsusbloader/com/usb/GoldLeaf_07.java index eb3eca3..38adb7e 100644 --- a/src/main/java/nsusbloader/com/usb/GoldLeaf_07.java +++ b/src/main/java/nsusbloader/com/usb/GoldLeaf_07.java @@ -69,7 +69,11 @@ class GoldLeaf_07 extends TransferModule { // For using in CMD_SelectFile with SPEC:/ prefix private File selectedFile; - GoldLeaf_07(DeviceHandle handler, LinkedHashMap nspMap, CancellableRunnable task, ILogPrinter logPrinter, boolean nspFilter){ + GoldLeaf_07(DeviceHandle handler, + LinkedHashMap nspMap, + CancellableRunnable task, + ILogPrinter logPrinter, + boolean nspFilter){ super(handler, nspMap, task, logPrinter); final byte CMD_GetDriveCount = 0x00; @@ -93,7 +97,7 @@ class GoldLeaf_07 extends TransferModule { this.nspFilterForGl = nspFilter; - logPrinter.print("============= GoldLeaf v0.7.x =============\n\t" + + print("============= GoldLeaf v0.7.x =============\n\t" + "VIRT:/ equals files added into the application\n\t" + "HOME:/ equals " +System.getProperty("user.home"), EMsgType.INFO); @@ -260,7 +264,7 @@ class GoldLeaf_07 extends TransferModule { byte[] drivesCnt = intToArrLE(2); //2 // Write count of drives if (writeGL_PASS(drivesCnt)) { - logPrinter.print("GL Handle 'ListDrives' command", EMsgType.FAIL); + print("GL Handle 'ListDrives' command", EMsgType.FAIL); return true; } return false; @@ -316,7 +320,7 @@ class GoldLeaf_07 extends TransferModule { command.add(totalSize); if (writeGL_PASS(command)) { - logPrinter.print("GL Handle 'GetDriveInfo' command", EMsgType.FAIL); + print("GL Handle 'GetDriveInfo' command", EMsgType.FAIL); return true; } @@ -332,7 +336,7 @@ class GoldLeaf_07 extends TransferModule { byte[] specialPathCnt = intToArrLE(0); // Write count of special paths if (writeGL_PASS(specialPathCnt)) { - logPrinter.print("GL Handle 'SpecialPathCount' command", EMsgType.FAIL); + print("GL Handle 'SpecialPathCount' command", EMsgType.FAIL); return true; } return false; @@ -354,13 +358,13 @@ class GoldLeaf_07 extends TransferModule { if (path.equals("VIRT:/")) { if (isGetDirectoryCount){ if (writeGL_PASS()) { - logPrinter.print("GL Handle 'GetDirectoryCount' command", EMsgType.FAIL); + print("GL Handle 'GetDirectoryCount' command", EMsgType.FAIL); return true; } } else { if (writeGL_PASS(intToArrLE(nspMap.size()))) { - logPrinter.print("GL Handle 'GetFileCount' command Count = "+nspMap.size(), EMsgType.FAIL); + print("GL Handle 'GetFileCount' command Count = "+nspMap.size(), EMsgType.FAIL); return true; } } @@ -401,7 +405,7 @@ class GoldLeaf_07 extends TransferModule { // If somehow there are no folders, let's say 0; if (filesOrDirs == null){ if (writeGL_PASS()) { - logPrinter.print("GL Handle 'GetDirectoryOrFileCount' command", EMsgType.FAIL); + print("GL Handle 'GetDirectoryOrFileCount' command", EMsgType.FAIL); return true; } return false; @@ -415,20 +419,20 @@ class GoldLeaf_07 extends TransferModule { this.recentFiles = filesOrDirs; // Otherwise, let's tell how may folders are in there if (writeGL_PASS(intToArrLE(filesOrDirs.length))) { - logPrinter.print("GL Handle 'GetDirectoryOrFileCount' command", EMsgType.FAIL); + print("GL Handle 'GetDirectoryOrFileCount' command", EMsgType.FAIL); return true; } } else if (path.startsWith("SPEC:/")){ if (isGetDirectoryCount){ // If dir request then 0 dirs if (writeGL_PASS()) { - logPrinter.print("GL Handle 'GetDirectoryCount' command", EMsgType.FAIL); + print("GL Handle 'GetDirectoryCount' command", EMsgType.FAIL); return true; } } else if (selectedFile != null){ // Else it's file request, if we have selected then we will report 1. if (writeGL_PASS(intToArrLE(1))) { - logPrinter.print("GL Handle 'GetFileCount' command Count = 1", EMsgType.FAIL); + print("GL Handle 'GetFileCount' command Count = 1", EMsgType.FAIL); return true; } } @@ -482,7 +486,7 @@ class GoldLeaf_07 extends TransferModule { // return proxyGetDirFile(true); if (writeGL_PASS(command)) { - logPrinter.print("GL Handle 'GetDirectory' command.", EMsgType.FAIL); + print("GL Handle 'GetDirectory' command.", EMsgType.FAIL); return true; } return false; @@ -539,7 +543,7 @@ class GoldLeaf_07 extends TransferModule { //if (proxyForGL) // TODO: NOTE: PROXY TAILS // return proxyGetDirFile(false); if (writeGL_PASS(command)) { - logPrinter.print("GL Handle 'GetFile' command.", EMsgType.FAIL); + print("GL Handle 'GetFile' command.", EMsgType.FAIL); return true; } return false; @@ -550,7 +554,7 @@ class GoldLeaf_07 extends TransferModule { command.add(intToArrLE(fileNameBytes.length / 2)); // since GL 0.7 command.add(fileNameBytes); if (writeGL_PASS(command)) { - logPrinter.print("GL Handle 'GetFile' command.", EMsgType.FAIL); + print("GL Handle 'GetFile' command.", EMsgType.FAIL); return true; } return false; @@ -562,7 +566,7 @@ class GoldLeaf_07 extends TransferModule { command.add(intToArrLE(fileNameBytes.length / 2)); // since GL 0.7 command.add(fileNameBytes); if (writeGL_PASS(command)) { - logPrinter.print("GL Handle 'GetFile' command.", EMsgType.FAIL); + print("GL Handle 'GetFile' command.", EMsgType.FAIL); return true; } return false; @@ -593,7 +597,7 @@ class GoldLeaf_07 extends TransferModule { command.add(longToArrLE(fileDirElement.length())); } if (writeGL_PASS(command)) { - logPrinter.print("GL Handle 'StatPath' command.", EMsgType.FAIL); + print("GL Handle 'StatPath' command.", EMsgType.FAIL); return true; } return false; @@ -610,7 +614,7 @@ class GoldLeaf_07 extends TransferModule { command.add(longToArrLE(nspMap.get(filePath).length())); // YES, THIS IS LONG! if (writeGL_PASS(command)) { - logPrinter.print("GL Handle 'StatPath' command.", EMsgType.FAIL); + print("GL Handle 'StatPath' command.", EMsgType.FAIL); return true; } return false; @@ -623,7 +627,7 @@ class GoldLeaf_07 extends TransferModule { command.add(GL_OBJ_TYPE_FILE); command.add(longToArrLE(selectedFile.length())); if (writeGL_PASS(command)) { - logPrinter.print("GL Handle 'StatPath' command.", EMsgType.FAIL); + print("GL Handle 'StatPath' command.", EMsgType.FAIL); return true; } return false; @@ -651,7 +655,7 @@ class GoldLeaf_07 extends TransferModule { try { if (currentFile.renameTo(newFile)){ if (writeGL_PASS()) { - logPrinter.print("GL Handle 'Rename' command.", EMsgType.FAIL); + print("GL Handle 'Rename' command.", EMsgType.FAIL); return true; } return false; @@ -676,7 +680,7 @@ class GoldLeaf_07 extends TransferModule { try { if (fileToDel.delete()){ if (writeGL_PASS()) { - logPrinter.print("GL Handle 'Rename' command.", EMsgType.FAIL); + print("GL Handle 'Rename' command.", EMsgType.FAIL); return true; } return false; @@ -714,10 +718,10 @@ class GoldLeaf_07 extends TransferModule { } if (result){ if (writeGL_PASS()) { - logPrinter.print("GL Handle 'Create' command.", EMsgType.FAIL); + print("GL Handle 'Create' command.", EMsgType.FAIL); return true; } - //logPrinter.print("GL Handle 'Create' command.", EMsgType.PASS); + //print("GL Handle 'Create' command.", EMsgType.PASS); return false; } } @@ -802,12 +806,12 @@ class GoldLeaf_07 extends TransferModule { "\n Received: " + bytesRead); // Let's tell as a command about our result. if (writeGL_PASS(longToArrLE(size))) { - logPrinter.print("GL Handle 'ReadFile' command [CMD]", EMsgType.FAIL); + print("GL Handle 'ReadFile' command [CMD]", EMsgType.FAIL); return true; } // Let's bypass bytes we read total if (writeToUsb(chunk)) { - logPrinter.print("GL Handle 'ReadFile' command", EMsgType.FAIL); + print("GL Handle 'ReadFile' command", EMsgType.FAIL); return true; } return false; @@ -822,12 +826,12 @@ class GoldLeaf_07 extends TransferModule { return writeGL_FAIL("GL Handle 'ReadFile' command [CMD] Requested = "+size+" Read from file = "+bytesRead); // Let's tell as a command about our result. if (writeGL_PASS(longToArrLE(size))) { - logPrinter.print("GL Handle 'ReadFile' command [CMD]", EMsgType.FAIL); + print("GL Handle 'ReadFile' command [CMD]", EMsgType.FAIL); return true; } // Let's bypass bytes we read total if (writeToUsb(chunk)) { - logPrinter.print("GL Handle 'ReadFile' command", EMsgType.FAIL); + print("GL Handle 'ReadFile' command", EMsgType.FAIL); return true; } return false; @@ -839,14 +843,14 @@ class GoldLeaf_07 extends TransferModule { } catch (NullPointerException ignored){} catch (IOException ioe_){ - logPrinter.print("GL Handle 'ReadFile' command: unable to close: "+openReadFileNameAndPath+"\n\t"+ioe_.getMessage(), EMsgType.WARNING); + print("GL Handle 'ReadFile' command: unable to close: "+openReadFileNameAndPath+"\n\t"+ioe_.getMessage(), EMsgType.WARNING); } try{ splitReader.close(); } catch (NullPointerException ignored){} catch (IOException ioe_){ - logPrinter.print("GL Handle 'ReadFile' command: unable to close: "+openReadFileNameAndPath+"\n\t"+ioe_.getMessage(), EMsgType.WARNING); + print("GL Handle 'ReadFile' command: unable to close: "+openReadFileNameAndPath+"\n\t"+ioe_.getMessage(), EMsgType.WARNING); } openReadFileNameAndPath = null; randAccessFile = null; @@ -888,7 +892,7 @@ class GoldLeaf_07 extends TransferModule { byte[] transferredData; if ((transferredData = readGL_file()) == null){ - logPrinter.print("GL Handle 'WriteFile' command [1/1]", EMsgType.FAIL); + print("GL Handle 'WriteFile' command [1/1]", EMsgType.FAIL); return true; } try{ @@ -899,7 +903,7 @@ class GoldLeaf_07 extends TransferModule { } // Report we're good if (writeGL_PASS()) { - logPrinter.print("GL Handle 'WriteFile' command", EMsgType.FAIL); + print("GL Handle 'WriteFile' command", EMsgType.FAIL); return true; } return false; @@ -926,7 +930,7 @@ class GoldLeaf_07 extends TransferModule { command.add(intToArrLE(selectedFileNameBytes.length / 2)); // since GL 0.7 command.add(selectedFileNameBytes); if (writeGL_PASS(command)) { - logPrinter.print("GL Handle 'SelectFile' command", EMsgType.FAIL); + print("GL Handle 'SelectFile' command", EMsgType.FAIL); this.selectedFile = null; return true; } @@ -1006,13 +1010,13 @@ class GoldLeaf_07 extends TransferModule { closeOpenedReadFilesGl(); // Could be a problem if GL glitches and slow down process. Or if user has extra-slow SD card. TODO: refactor continue; default: - logPrinter.print("GL Data transfer issue [read]\n Returned: " + + print("GL Data transfer issue [read]\n Returned: " + UsbErrorCodes.getErrCode(result) + "\n GL Execution stopped", EMsgType.FAIL); return null; } } - logPrinter.print("GL Execution interrupted", EMsgType.INFO); + print("GL Execution interrupted", EMsgType.INFO); return null; } private byte[] readGL_file(){ @@ -1035,13 +1039,13 @@ class GoldLeaf_07 extends TransferModule { case LibUsb.ERROR_TIMEOUT: continue; default: - logPrinter.print("GL Data transfer issue [read]\n Returned: " + + print("GL Data transfer issue [read]\n Returned: " + UsbErrorCodes.getErrCode(result) + "\n GL Execution stopped", EMsgType.FAIL); return null; } } - logPrinter.print("GL Execution interrupted", EMsgType.INFO); + print("GL Execution interrupted", EMsgType.INFO); return null; } /** @@ -1066,10 +1070,10 @@ class GoldLeaf_07 extends TransferModule { private boolean writeGL_FAIL(String reportToUImsg){ if (writeToUsb(Arrays.copyOf(CMD_GLCO_FAILURE, 4096))){ - logPrinter.print(reportToUImsg, EMsgType.WARNING); + print(reportToUImsg, EMsgType.WARNING); return true; } - logPrinter.print(reportToUImsg, EMsgType.FAIL); + print(reportToUImsg, EMsgType.FAIL); return false; } /** @@ -1091,7 +1095,7 @@ class GoldLeaf_07 extends TransferModule { if (writeBufTransferred.get() == message.length) return false; else { - logPrinter.print("GL Data transfer issue [write]\n Requested: " + + print("GL Data transfer issue [write]\n Requested: " + message.length + "\n Transferred: " + writeBufTransferred.get(), EMsgType.FAIL); @@ -1100,13 +1104,13 @@ class GoldLeaf_07 extends TransferModule { case LibUsb.ERROR_TIMEOUT: continue; default: - logPrinter.print("GL Data transfer issue [write]\n Returned: " + + print("GL Data transfer issue [write]\n Returned: " + UsbErrorCodes.getErrCode(result) + "\n GL Execution stopped", EMsgType.FAIL); return true; } } - logPrinter.print("GL Execution interrupted", EMsgType.INFO); + print("GL Execution interrupted", EMsgType.INFO); return true; } diff --git a/src/main/java/nsusbloader/com/usb/GoldLeaf_08.java b/src/main/java/nsusbloader/com/usb/GoldLeaf_08.java index 4e260cc..0a15656 100644 --- a/src/main/java/nsusbloader/com/usb/GoldLeaf_08.java +++ b/src/main/java/nsusbloader/com/usb/GoldLeaf_08.java @@ -103,7 +103,7 @@ class GoldLeaf_08 extends TransferModule { this.nspFilterForGl = nspFilter; - logPrinter.print("============= GoldLeaf v0.8 =============\n\t" + + print("============= GoldLeaf v0.8 =============\n\t" + "VIRT:/ equals files added into the application\n\t" + "HOME:/ equals " +System.getProperty("user.home"), EMsgType.INFO); @@ -273,7 +273,7 @@ class GoldLeaf_08 extends TransferModule { * */ private boolean startOrEndFile(){ if (writeGL_PASS()){ - logPrinter.print("GL Handle 'StartFile' command", EMsgType.FAIL); + print("GL Handle 'StartFile' command", EMsgType.FAIL); return true; } return false; @@ -288,7 +288,7 @@ class GoldLeaf_08 extends TransferModule { byte[] drivesCnt = intToArrLE(2); //2 // Write count of drives if (writeGL_PASS(drivesCnt)) { - logPrinter.print("GL Handle 'ListDrives' command", EMsgType.FAIL); + print("GL Handle 'ListDrives' command", EMsgType.FAIL); return true; } return false; @@ -344,7 +344,7 @@ class GoldLeaf_08 extends TransferModule { command.add(totalSize); if (writeGL_PASS(command)) { - logPrinter.print("GL Handle 'GetDriveInfo' command", EMsgType.FAIL); + print("GL Handle 'GetDriveInfo' command", EMsgType.FAIL); return true; } @@ -360,7 +360,7 @@ class GoldLeaf_08 extends TransferModule { byte[] specialPathCnt = intToArrLE(0); // Write count of special paths if (writeGL_PASS(specialPathCnt)) { - logPrinter.print("GL Handle 'SpecialPathCount' command", EMsgType.FAIL); + print("GL Handle 'SpecialPathCount' command", EMsgType.FAIL); return true; } return false; @@ -382,13 +382,13 @@ class GoldLeaf_08 extends TransferModule { if (path.equals("VIRT:/")) { if (isGetDirectoryCount){ if (writeGL_PASS()) { - logPrinter.print("GL Handle 'GetDirectoryCount' command", EMsgType.FAIL); + print("GL Handle 'GetDirectoryCount' command", EMsgType.FAIL); return true; } } else { if (writeGL_PASS(intToArrLE(nspMap.size()))) { - logPrinter.print("GL Handle 'GetFileCount' command Count = "+nspMap.size(), EMsgType.FAIL); + print("GL Handle 'GetFileCount' command Count = "+nspMap.size(), EMsgType.FAIL); return true; } } @@ -429,7 +429,7 @@ class GoldLeaf_08 extends TransferModule { // If somehow there are no folders, let's say 0; if (filesOrDirs == null){ if (writeGL_PASS()) { - logPrinter.print("GL Handle 'GetDirectoryOrFileCount' command", EMsgType.FAIL); + print("GL Handle 'GetDirectoryOrFileCount' command", EMsgType.FAIL); return true; } return false; @@ -443,20 +443,20 @@ class GoldLeaf_08 extends TransferModule { this.recentFiles = filesOrDirs; // Otherwise, let's tell how may folders are in there if (writeGL_PASS(intToArrLE(filesOrDirs.length))) { - logPrinter.print("GL Handle 'GetDirectoryOrFileCount' command", EMsgType.FAIL); + print("GL Handle 'GetDirectoryOrFileCount' command", EMsgType.FAIL); return true; } } else if (path.startsWith("SPEC:/")){ if (isGetDirectoryCount){ // If dir request then 0 dirs if (writeGL_PASS()) { - logPrinter.print("GL Handle 'GetDirectoryCount' command", EMsgType.FAIL); + print("GL Handle 'GetDirectoryCount' command", EMsgType.FAIL); return true; } } else if (selectedFile != null){ // Else it's file request, if we have selected then we will report 1. if (writeGL_PASS(intToArrLE(1))) { - logPrinter.print("GL Handle 'GetFileCount' command Count = 1", EMsgType.FAIL); + print("GL Handle 'GetFileCount' command Count = 1", EMsgType.FAIL); return true; } } @@ -510,7 +510,7 @@ class GoldLeaf_08 extends TransferModule { // return proxyGetDirFile(true); if (writeGL_PASS(command)) { - logPrinter.print("GL Handle 'GetDirectory' command.", EMsgType.FAIL); + print("GL Handle 'GetDirectory' command.", EMsgType.FAIL); return true; } return false; @@ -567,7 +567,7 @@ class GoldLeaf_08 extends TransferModule { //if (proxyForGL) // TODO: NOTE: PROXY TAILS // return proxyGetDirFile(false); if (writeGL_PASS(command)) { - logPrinter.print("GL Handle 'GetFile' command.", EMsgType.FAIL); + print("GL Handle 'GetFile' command.", EMsgType.FAIL); return true; } return false; @@ -578,7 +578,7 @@ class GoldLeaf_08 extends TransferModule { command.add(intToArrLE(fileNameBytes.length / 2)); // since GL 0.7 command.add(fileNameBytes); if (writeGL_PASS(command)) { - logPrinter.print("GL Handle 'GetFile' command.", EMsgType.FAIL); + print("GL Handle 'GetFile' command.", EMsgType.FAIL); return true; } return false; @@ -590,7 +590,7 @@ class GoldLeaf_08 extends TransferModule { command.add(intToArrLE(fileNameBytes.length / 2)); // since GL 0.7 command.add(fileNameBytes); if (writeGL_PASS(command)) { - logPrinter.print("GL Handle 'GetFile' command.", EMsgType.FAIL); + print("GL Handle 'GetFile' command.", EMsgType.FAIL); return true; } return false; @@ -621,7 +621,7 @@ class GoldLeaf_08 extends TransferModule { command.add(longToArrLE(fileDirElement.length())); } if (writeGL_PASS(command)) { - logPrinter.print("GL Handle 'StatPath' command.", EMsgType.FAIL); + print("GL Handle 'StatPath' command.", EMsgType.FAIL); return true; } return false; @@ -638,7 +638,7 @@ class GoldLeaf_08 extends TransferModule { command.add(longToArrLE(nspMap.get(filePath).length())); // YES, THIS IS LONG! if (writeGL_PASS(command)) { - logPrinter.print("GL Handle 'StatPath' command.", EMsgType.FAIL); + print("GL Handle 'StatPath' command.", EMsgType.FAIL); return true; } return false; @@ -651,7 +651,7 @@ class GoldLeaf_08 extends TransferModule { command.add(GL_OBJ_TYPE_FILE); command.add(longToArrLE(selectedFile.length())); if (writeGL_PASS(command)) { - logPrinter.print("GL Handle 'StatPath' command.", EMsgType.FAIL); + print("GL Handle 'StatPath' command.", EMsgType.FAIL); return true; } return false; @@ -679,7 +679,7 @@ class GoldLeaf_08 extends TransferModule { try { if (currentFile.renameTo(newFile)){ if (writeGL_PASS()) { - logPrinter.print("GL Handle 'Rename' command.", EMsgType.FAIL); + print("GL Handle 'Rename' command.", EMsgType.FAIL); return true; } return false; @@ -704,7 +704,7 @@ class GoldLeaf_08 extends TransferModule { try { if (fileToDel.delete()){ if (writeGL_PASS()) { - logPrinter.print("GL Handle 'Rename' command.", EMsgType.FAIL); + print("GL Handle 'Rename' command.", EMsgType.FAIL); return true; } return false; @@ -742,10 +742,10 @@ class GoldLeaf_08 extends TransferModule { } if (result){ if (writeGL_PASS()) { - logPrinter.print("GL Handle 'Create' command.", EMsgType.FAIL); + print("GL Handle 'Create' command.", EMsgType.FAIL); return true; } - //logPrinter.print("GL Handle 'Create' command.", EMsgType.PASS); + //print("GL Handle 'Create' command.", EMsgType.PASS); return false; } } @@ -830,12 +830,12 @@ class GoldLeaf_08 extends TransferModule { "\n Received: " + bytesRead); // Let's tell as a command about our result. if (writeGL_PASS(longToArrLE(size))) { - logPrinter.print("GL Handle 'ReadFile' command [CMD]", EMsgType.FAIL); + print("GL Handle 'ReadFile' command [CMD]", EMsgType.FAIL); return true; } // Let's bypass bytes we read total if (writeToUsb(chunk)) { - logPrinter.print("GL Handle 'ReadFile' command", EMsgType.FAIL); + print("GL Handle 'ReadFile' command", EMsgType.FAIL); return true; } return false; @@ -850,12 +850,12 @@ class GoldLeaf_08 extends TransferModule { return writeGL_FAIL("GL Handle 'ReadFile' command [CMD] Requested = "+size+" Read from file = "+bytesRead); // Let's tell as a command about our result. if (writeGL_PASS(longToArrLE(size))) { - logPrinter.print("GL Handle 'ReadFile' command [CMD]", EMsgType.FAIL); + print("GL Handle 'ReadFile' command [CMD]", EMsgType.FAIL); return true; } // Let's bypass bytes we read total if (writeToUsb(chunk)) { - logPrinter.print("GL Handle 'ReadFile' command", EMsgType.FAIL); + print("GL Handle 'ReadFile' command", EMsgType.FAIL); return true; } return false; @@ -867,14 +867,14 @@ class GoldLeaf_08 extends TransferModule { } catch (NullPointerException ignored){} catch (IOException ioe_){ - logPrinter.print("GL Handle 'ReadFile' command: unable to close: "+openReadFileNameAndPath+"\n\t"+ioe_.getMessage(), EMsgType.WARNING); + print("GL Handle 'ReadFile' command: unable to close: "+openReadFileNameAndPath+"\n\t"+ioe_.getMessage(), EMsgType.WARNING); } try{ splitReader.close(); } catch (NullPointerException ignored){} catch (IOException ioe_){ - logPrinter.print("GL Handle 'ReadFile' command: unable to close: "+openReadFileNameAndPath+"\n\t"+ioe_.getMessage(), EMsgType.WARNING); + print("GL Handle 'ReadFile' command: unable to close: "+openReadFileNameAndPath+"\n\t"+ioe_.getMessage(), EMsgType.WARNING); } openReadFileNameAndPath = null; randAccessFile = null; @@ -916,7 +916,7 @@ class GoldLeaf_08 extends TransferModule { byte[] transferredData; if ((transferredData = readGL_file()) == null){ - logPrinter.print("GL Handle 'WriteFile' command [1/1]", EMsgType.FAIL); + print("GL Handle 'WriteFile' command [1/1]", EMsgType.FAIL); return true; } try{ @@ -927,7 +927,7 @@ class GoldLeaf_08 extends TransferModule { } // Report we're good if (writeGL_PASS()) { - logPrinter.print("GL Handle 'WriteFile' command", EMsgType.FAIL); + print("GL Handle 'WriteFile' command", EMsgType.FAIL); return true; } return false; @@ -957,7 +957,7 @@ class GoldLeaf_08 extends TransferModule { command.add(intToArrLE(selectedFileNameBytes.length / 2)); // since GL 0.7 command.add(selectedFileNameBytes); if (writeGL_PASS(command)) { - logPrinter.print("GL Handle 'SelectFile' command", EMsgType.FAIL); + print("GL Handle 'SelectFile' command", EMsgType.FAIL); this.selectedFile = null; return true; } @@ -1033,13 +1033,13 @@ class GoldLeaf_08 extends TransferModule { closeOpenedReadFilesGl(); // Could be a problem if GL glitches and slow down process. Or if user has extra-slow SD card. TODO: refactor continue; default: - logPrinter.print("GL Data transfer issue [read]\n Returned: " + + print("GL Data transfer issue [read]\n Returned: " + UsbErrorCodes.getErrCode(result) + "\n GL Execution stopped", EMsgType.FAIL); return null; } } - logPrinter.print("GL Execution interrupted", EMsgType.INFO); + print("GL Execution interrupted", EMsgType.INFO); return null; } private byte[] readGL_file(){ @@ -1060,13 +1060,13 @@ class GoldLeaf_08 extends TransferModule { case LibUsb.ERROR_TIMEOUT: continue; default: - logPrinter.print("GL Data transfer issue [read]\n Returned: " + + print("GL Data transfer issue [read]\n Returned: " + UsbErrorCodes.getErrCode(result) + "\n GL Execution stopped", EMsgType.FAIL); return null; } } - logPrinter.print("GL Execution interrupted", EMsgType.INFO); + print("GL Execution interrupted", EMsgType.INFO); return null; } /** @@ -1091,10 +1091,10 @@ class GoldLeaf_08 extends TransferModule { private boolean writeGL_FAIL(String reportToUImsg){ if (writeToUsb(Arrays.copyOf(CMD_GLCO_FAILURE, 4096))){ - logPrinter.print(reportToUImsg, EMsgType.WARNING); + print(reportToUImsg, EMsgType.WARNING); return true; } - logPrinter.print(reportToUImsg, EMsgType.FAIL); + print(reportToUImsg, EMsgType.FAIL); return false; } /** @@ -1116,7 +1116,7 @@ class GoldLeaf_08 extends TransferModule { if (writeBufTransferred.get() == message.length) return false; else { - logPrinter.print("GL Data transfer issue [write]\n Requested: " + + print("GL Data transfer issue [write]\n Requested: " + message.length + "\n Transferred: "+writeBufTransferred.get(), EMsgType.FAIL); return true; @@ -1124,13 +1124,13 @@ class GoldLeaf_08 extends TransferModule { case LibUsb.ERROR_TIMEOUT: continue; default: - logPrinter.print("GL Data transfer issue [write]\n Returned: " + + print("GL Data transfer issue [write]\n Returned: " + UsbErrorCodes.getErrCode(result) + "\n GL Execution stopped", EMsgType.FAIL); return true; } } - logPrinter.print("GL Execution interrupted", EMsgType.INFO); + print("GL Execution interrupted", EMsgType.INFO); return true; } } diff --git a/src/main/java/nsusbloader/com/usb/TinFoil.java b/src/main/java/nsusbloader/com/usb/TinFoil.java index d033f08..33114bf 100644 --- a/src/main/java/nsusbloader/com/usb/TinFoil.java +++ b/src/main/java/nsusbloader/com/usb/TinFoil.java @@ -50,7 +50,7 @@ class TinFoil extends TransferModule { TinFoil(DeviceHandle handler, LinkedHashMap nspMap, CancellableRunnable task, ILogPrinter logPrinter){ super(handler, nspMap, task, logPrinter); - logPrinter.print("============= Tinfoil =============", EMsgType.INFO); + print("============= Tinfoil =============", EMsgType.INFO); if (! sendListOfFiles()) return; @@ -69,25 +69,25 @@ class TinFoil extends TransferModule { byte[] padding = new byte[8]; if (writeUsb(TUL0)) { - logPrinter.print("TF Send list of files: handshake [1/4]", EMsgType.FAIL); + print("TF Send list of files: handshake [1/4]", EMsgType.FAIL); return false; } if (writeUsb(nspListNamesSize)) { // size of the list we can transfer - logPrinter.print("TF Send list of files: list length [2/4]", EMsgType.FAIL); + print("TF Send list of files: list length [2/4]", EMsgType.FAIL); return false; } if (writeUsb(padding)) { - logPrinter.print("TF Send list of files: padding [3/4]", EMsgType.FAIL); + print("TF Send list of files: padding [3/4]", EMsgType.FAIL); return false; } if (writeUsb(nspListNames)) { - logPrinter.print("TF Send list of files: list itself [4/4]", EMsgType.FAIL); + print("TF Send list of files: list itself [4/4]", EMsgType.FAIL); return false; } - logPrinter.print("TF Send list of files complete.", EMsgType.PASS); + print("TF Send list of files complete.", EMsgType.PASS); return true; } @@ -114,7 +114,7 @@ class TinFoil extends TransferModule { * After we sent commands to NS, this chain starts * */ private boolean proceedCommands(){ - logPrinter.print("TF Awaiting for NS commands.", EMsgType.INFO); + print("TF Awaiting for NS commands.", EMsgType.INFO); try{ byte[] deviceReply; byte command; @@ -127,18 +127,18 @@ class TinFoil extends TransferModule { switch (command){ case CMD_EXIT: - logPrinter.print("TF Transfer complete.", EMsgType.PASS); + print("TF Transfer complete.", EMsgType.PASS); return true; case CMD_FILE_RANGE_DEFAULT: case CMD_FILE_RANGE_ALTERNATIVE: - //logPrinter.print("TF Received 'FILE RANGE' command [0x0"+command+"].", EMsgType.PASS); + //print("TF Received 'FILE RANGE' command [0x0"+command+"].", EMsgType.PASS); if (fileRangeCmd()) return false; // catches exception } } } catch (Exception e){ - logPrinter.print(e.getMessage(), EMsgType.INFO); + print(e.getMessage(), EMsgType.INFO); return false; } } @@ -169,7 +169,7 @@ class TinFoil extends TransferModule { String nspFileName = new String(receivedArray, StandardCharsets.UTF_8); - logPrinter.print(String.format("TF Reply to: %s" + + print(String.format("TF Reply to: %s" + "\n Offset: %-20d 0x%x" + "\n Size: %-20d 0x%x", nspFileName, @@ -188,28 +188,28 @@ class TinFoil extends TransferModule { else sendNormalFile(nspFile, size, offset); } catch (IOException ioe){ - logPrinter.print("TF IOException:\n "+ioe.getMessage(), EMsgType.FAIL); + print("TF IOException:\n "+ioe.getMessage(), EMsgType.FAIL); ioe.printStackTrace(); return true; } catch (ArithmeticException ae){ - logPrinter.print("TF ArithmeticException (can't cast 'offset end' - 'offsets current' to 'integer'):" + + print("TF ArithmeticException (can't cast 'offset end' - 'offsets current' to 'integer'):" + "\n "+ae.getMessage(), EMsgType.FAIL); ae.printStackTrace(); return true; } catch (NullPointerException npe){ - logPrinter.print("TF NullPointerException (in some moment application didn't find something. Something important.):" + + print("TF NullPointerException (in some moment application didn't find something. Something important.):" + "\n "+npe.getMessage(), EMsgType.FAIL); npe.printStackTrace(); return true; } catch (Exception defe){ - logPrinter.print(defe.getMessage(), EMsgType.FAIL); + print(defe.getMessage(), EMsgType.FAIL); return true; } return false; } - void sendSplitFile(File nspFile, long size, long offset) throws IOException, NullPointerException, ArithmeticException { + void sendSplitFile(File nspFile, long size, long offset) throws Exception { byte[] readBuffer; long currentOffset = 0; int chunk = 8388608; // = 8Mb; @@ -237,7 +237,7 @@ class TinFoil extends TransferModule { logPrinter.updateProgress(1.0); } - void sendNormalFile(File nspFile, long size, long offset) throws IOException, NullPointerException, ArithmeticException { + void sendNormalFile(File nspFile, long size, long offset) throws Exception { byte[] readBuffer; long currentOffset = 0; int chunk = 8388608; @@ -278,17 +278,17 @@ class TinFoil extends TransferModule { final byte[] twelveZeroBytes = new byte[12]; if (writeUsb(standardReplyBytes)){ // Send integer value of '1' in Little-endian format. - logPrinter.print("TF Sending response failed [1/3]", EMsgType.FAIL); + print("TF Sending response failed [1/3]", EMsgType.FAIL); return true; } if(writeUsb(sizeAsBytes)) { // Send EXACTLY what has been received - logPrinter.print("TF Sending response failed [2/3]", EMsgType.FAIL); + print("TF Sending response failed [2/3]", EMsgType.FAIL); return true; } if(writeUsb(twelveZeroBytes)) { // kinda another one padding - logPrinter.print("TF Sending response failed [3/3]", EMsgType.FAIL); + print("TF Sending response failed [3/3]", EMsgType.FAIL); return true; } return false; @@ -308,7 +308,7 @@ class TinFoil extends TransferModule { while (! task.isCancelled() ) { /* if (varVar != 0) - logPrinter.print("writeUsb() retry cnt: "+varVar, EMsgType.INFO); //NOTE: DEBUG + print("writeUsb() retry cnt: "+varVar, EMsgType.INFO); //NOTE: DEBUG varVar++; */ result = LibUsb.bulkTransfer(handlerNS, (byte) 0x01, writeBuffer, writeBufTransferred, 5050); // last one is TIMEOUT. 0 stands for unlimited. Endpoint OUT = 0x01 @@ -317,7 +317,7 @@ class TinFoil extends TransferModule { case LibUsb.SUCCESS: if (writeBufTransferred.get() == message.length) return false; - logPrinter.print("TF Data transfer issue [write]" + + print("TF Data transfer issue [write]" + "\n Requested: "+message.length+ "\n Transferred: "+writeBufTransferred.get(), EMsgType.FAIL); return true; @@ -326,13 +326,13 @@ class TinFoil extends TransferModule { //writeBufTransferred.clear(); // MUST BE HERE IF WE 'GET()' IT continue; default: - logPrinter.print("TF Data transfer issue [write]" + + print("TF Data transfer issue [write]" + "\n Returned: "+ UsbErrorCodes.getErrCode(result) + "\n (execution stopped)", EMsgType.FAIL); return true; } } - logPrinter.print("TF Execution interrupted", EMsgType.INFO); + print("TF Execution interrupted", EMsgType.INFO); return true; } /** diff --git a/src/main/java/nsusbloader/com/usb/TransferModule.java b/src/main/java/nsusbloader/com/usb/TransferModule.java index 4eebca6..e99a4a8 100644 --- a/src/main/java/nsusbloader/com/usb/TransferModule.java +++ b/src/main/java/nsusbloader/com/usb/TransferModule.java @@ -51,7 +51,7 @@ public abstract class TransferModule { File[] subFiles = f.listFiles((file, name) -> name.matches("[0-9]{2}")); if (subFiles == null || subFiles.length == 0) { - logPrinter.print("TransferModule: Exclude folder: " + f.getName(), EMsgType.WARNING); + print("TransferModule: Exclude folder: " + f.getName(), EMsgType.WARNING); return true; } @@ -59,7 +59,7 @@ public abstract class TransferModule { for (int i = subFiles.length - 2; i > 0 ; i--){ if (subFiles[i].length() != subFiles[i-1].length()) { - logPrinter.print("TransferModule: Exclude split file: "+f.getName()+ + print("TransferModule: Exclude split file: "+f.getName()+ "\n Chunk sizes of the split file are not the same, but has to be.", EMsgType.WARNING); return true; } @@ -69,7 +69,7 @@ public abstract class TransferModule { long lastFileLength = subFiles[subFiles.length-1].length(); if (lastFileLength > firstFileLength){ - logPrinter.print("TransferModule: Exclude split file: "+f.getName()+ + print("TransferModule: Exclude split file: "+f.getName()+ "\n Chunk sizes of the split file are not the same, but has to be.", EMsgType.WARNING); return true; } @@ -77,4 +77,13 @@ public abstract class TransferModule { }); } public EFileStatus getStatus(){ return status; } + + void print(String message, EMsgType type){ + try { + logPrinter.print(message, type); + } + catch (InterruptedException ie){ + ie.printStackTrace(); + } + } } diff --git a/src/main/java/nsusbloader/com/usb/UsbCommunications.java b/src/main/java/nsusbloader/com/usb/UsbCommunications.java index cf31dfd..3601848 100644 --- a/src/main/java/nsusbloader/com/usb/UsbCommunications.java +++ b/src/main/java/nsusbloader/com/usb/UsbCommunications.java @@ -49,7 +49,7 @@ public class UsbCommunications extends CancellableRunnable { @Override public void run() { - logPrinter.print("\tStart", EMsgType.INFO); + print("\tStart", EMsgType.INFO); UsbConnect usbConnect = UsbConnect.connectHomebrewMode(logPrinter); @@ -87,7 +87,15 @@ public class UsbCommunications extends CancellableRunnable { */ private void close(EFileStatus status){ logPrinter.update(nspMap, status); - logPrinter.print("\tEnd", EMsgType.INFO); + print("\tEnd", EMsgType.INFO); logPrinter.close(); } + private void print(String message, EMsgType type){ + try { + logPrinter.print(message, type); + } + catch (InterruptedException ie){ + ie.printStackTrace(); + } + } } \ No newline at end of file diff --git a/src/main/java/nsusbloader/com/usb/UsbConnect.java b/src/main/java/nsusbloader/com/usb/UsbConnect.java index 91fe5d4..f4e5ad3 100644 --- a/src/main/java/nsusbloader/com/usb/UsbConnect.java +++ b/src/main/java/nsusbloader/com/usb/UsbConnect.java @@ -65,7 +65,10 @@ public class UsbConnect { usbConnect.connected = true; } catch (Exception e){ - logPrinter.print(e.getMessage(), EMsgType.FAIL); + try { + logPrinter.print(e.getMessage(), EMsgType.FAIL); + } + catch (InterruptedException ignore){} usbConnect.close(); } @@ -89,7 +92,10 @@ public class UsbConnect { } catch (Exception e){ e.printStackTrace(); - logPrinter.print(e.getMessage(), EMsgType.FAIL); + try { + logPrinter.print(e.getMessage(), EMsgType.FAIL); + } + catch (InterruptedException ignore){} usbConnect.close(); } return usbConnect; @@ -100,7 +106,7 @@ public class UsbConnect { private UsbConnect(ILogPrinter logPrinter){ this.logPrinter = logPrinter; this.connected = false; - }; + } private void createContextAndInitLibUSB() throws Exception{ // Creating Context required by libusb. Optional? Consider removing. @@ -178,7 +184,7 @@ public class UsbConnect { // Actually, there are no drivers in Linux kernel which uses this device. returningValue = LibUsb.setAutoDetachKernelDriver(handlerNS, true); if (returningValue != LibUsb.SUCCESS) - logPrinter.print("Skip kernel driver attach & detach ("+UsbErrorCodes.getErrCode(returningValue)+")", EMsgType.INFO); + print("Skip kernel driver attach & detach ("+UsbErrorCodes.getErrCode(returningValue)+")", EMsgType.INFO); } /* @@ -230,7 +236,7 @@ public class UsbConnect { returningValue = LibUsb.releaseInterface(handlerNS, DEFAULT_INTERFACE); if (returningValue != LibUsb.SUCCESS) { - logPrinter.print("Release interface failure: " + + print("Release interface failure: " + UsbErrorCodes.getErrCode(returningValue) + " (sometimes it's not an issue)", EMsgType.WARNING); } @@ -241,4 +247,13 @@ public class UsbConnect { if (contextNS != null) LibUsb.exit(contextNS); } + + private void print(String message, EMsgType type){ + try { + logPrinter.print(message, type); + } + catch (InterruptedException ie){ + ie.printStackTrace(); + } + } } diff --git a/src/main/resources/BlockListView.fxml b/src/main/resources/BlockListView.fxml new file mode 100644 index 0000000..00a70db --- /dev/null +++ b/src/main/resources/BlockListView.fxml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/main/resources/SplitMergeTab.fxml b/src/main/resources/SplitMergeTab.fxml index 0032e02..2cedbcc 100644 --- a/src/main/resources/SplitMergeTab.fxml +++ b/src/main/resources/SplitMergeTab.fxml @@ -42,47 +42,42 @@ - + - - - - - - - - - - - - - - - - - -