From 863c69affaaa76cd91c966d6233bed28c11ec70f Mon Sep 17 00:00:00 2001 From: Dmitry Isaenko Date: Tue, 19 Mar 2019 07:01:30 +0300 Subject: [PATCH] WIP. Frontend 95% ready. Network backend 80% ready. --- src/main/java/nsusbloader/AppPreferences.java | 4 +- .../Controllers/NSLMainController.java | 8 +- .../Controllers/SettingsController.java | 7 +- .../nsusbloader/NET/NETCommunications.java | 145 +++++++++++++++--- .../nsusbloader/USB/UsbCommunications.java | 2 +- src/main/resources/NSLMain.fxml | 2 +- 6 files changed, 134 insertions(+), 34 deletions(-) diff --git a/src/main/java/nsusbloader/AppPreferences.java b/src/main/java/nsusbloader/AppPreferences.java index d833114..83d03b1 100644 --- a/src/main/java/nsusbloader/AppPreferences.java +++ b/src/main/java/nsusbloader/AppPreferences.java @@ -80,7 +80,7 @@ public class AppPreferences { public boolean getNotServeRequests(){return preferences.getBoolean("DONTSERVEREQ", false);} public void setNotServeRequests(boolean mode){preferences.putBoolean("DONTSERVEREQ", mode);} - public String getHostIp(){ return preferences.get("HOSTIP", "0.0.0.0");} + public String getHostIp(){ return preferences.get("HOSTIP", "0.0.0.0").replaceAll("(\\s)|(\t)", "");} // who the hell said 'paranoid'? public void setHostIp(String ip){preferences.put("HOSTIP", ip);} public String getHostPort(){ @@ -93,6 +93,6 @@ public class AppPreferences { } public void setHostPort(String port){preferences.put("HOSTPORT", port);} - public String getHostExtra(){ return preferences.get("HOSTEXTRA", "");} + public String getHostExtra(){ return preferences.get("HOSTEXTRA", "").replaceAll("(\\s)|(\t)", "");} // oh just shut up... public void setHostExtra(String postfix){preferences.put("HOSTEXTRA", postfix);} } diff --git a/src/main/java/nsusbloader/Controllers/NSLMainController.java b/src/main/java/nsusbloader/Controllers/NSLMainController.java index 1d966aa..0054284 100644 --- a/src/main/java/nsusbloader/Controllers/NSLMainController.java +++ b/src/main/java/nsusbloader/Controllers/NSLMainController.java @@ -18,11 +18,11 @@ import nsusbloader.ServiceWindow; import nsusbloader.USB.UsbCommunications; import java.io.File; -import java.net.URL; +import java.net.*; import java.util.ArrayList; +import java.util.Enumeration; import java.util.List; import java.util.ResourceBundle; -import java.util.function.UnaryOperator; public class NSLMainController implements Initializable { @@ -206,10 +206,10 @@ public class NSLMainController implements Initializable { workThread.start(); } else { // NET INSTALL OVER TINFOIL - if (SettingsTabController.isNsIpValidate() && !nsIpTextField.getText().trim().matches("^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])$")) + if (SettingsTabController.isNsIpValidate() && !nsIpTextField.getText().matches("^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])$")) if (!ServiceWindow.getConfirmationWindow(resourceBundle.getString("windowTitleBadIp"),resourceBundle.getString("windowBodyBadIp"))) return; - String nsIP = nsIpTextField.getText().trim(); + String nsIP = nsIpTextField.getText(); List nspToUpload; if (!SettingsTabController.getExpertModeSelected()) { diff --git a/src/main/java/nsusbloader/Controllers/SettingsController.java b/src/main/java/nsusbloader/Controllers/SettingsController.java index 876498a..c319634 100644 --- a/src/main/java/nsusbloader/Controllers/SettingsController.java +++ b/src/main/java/nsusbloader/Controllers/SettingsController.java @@ -9,10 +9,8 @@ import javafx.scene.layout.VBox; import nsusbloader.AppPreferences; import nsusbloader.ServiceWindow; - import java.net.URL; import java.util.ResourceBundle; -import java.util.function.UnaryOperator; public class SettingsController implements Initializable { @@ -53,12 +51,16 @@ public class SettingsController implements Initializable { pcIpTextField.setDisable(AppPreferences.getInstance().getAutoDetectIp()); autoDetectIpCb.setOnAction(e->{ pcIpTextField.setDisable(autoDetectIpCb.isSelected()); + if (!autoDetectIpCb.isSelected()) + pcIpTextField.requestFocus(); }); randPortCb.setSelected(AppPreferences.getInstance().getRandPort()); pcPortTextField.setDisable(AppPreferences.getInstance().getRandPort()); randPortCb.setOnAction(e->{ pcPortTextField.setDisable(randPortCb.isSelected()); + if (!randPortCb.isSelected()) + pcPortTextField.requestFocus(); }); if (AppPreferences.getInstance().getNotServeRequests()){ @@ -85,6 +87,7 @@ public class SettingsController implements Initializable { pcPortTextField.setDisable(false); pcExtraTextField.setDisable(false); + pcIpTextField.requestFocus(); } else { autoDetectIpCb.setDisable(false); diff --git a/src/main/java/nsusbloader/NET/NETCommunications.java b/src/main/java/nsusbloader/NET/NETCommunications.java index e71745c..0fb571c 100644 --- a/src/main/java/nsusbloader/NET/NETCommunications.java +++ b/src/main/java/nsusbloader/NET/NETCommunications.java @@ -3,14 +3,13 @@ package nsusbloader.NET; import javafx.concurrent.Task; import nsusbloader.NSLDataTypes.EFileStatus; import nsusbloader.ModelControllers.LogPrinter; +import nsusbloader.NSLDataTypes.EMsgType; import java.io.*; import java.net.*; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; +import java.util.*; /* * Add option: don't serve replies * */ @@ -21,49 +20,121 @@ public class NETCommunications extends Task { // todo: thows IOException? private String hostIP; private int hostPort; + private String extras; + private String switchIP; private HashMap nspMap; - private ServerSocket serverSocket; + private boolean isValid; + private boolean doNotServeRequests; + /** + * Simple constructor that everybody uses + * */ public NETCommunications(List filesList, String switchIP){ + this.doNotServeRequests = false; + this.extras = ""; this.logPrinter = new LogPrinter(); this.switchIP = switchIP; this.nspMap = new HashMap<>(); + logPrinter.print("\tPrepare chain", EMsgType.INFO); + // Collect and encode NSP files list try { for (File nspFile : filesList) nspMap.put(URLEncoder.encode(nspFile.getName(), "UTF-8"), nspFile); } catch (UnsupportedEncodingException uee){ - uee.printStackTrace(); - return; // TODO: FIX + isValid = false; + logPrinter.print("NET: Unsupported encoding for 'URLEncoder'. Internal issue you can't fix. Please report.", EMsgType.FAIL); + for (File nspFile : filesList) + nspMap.put(nspFile.getName(), nspFile); + close(EFileStatus.FAILED); + return; } - - try{ // todo: check other method if internet unavaliable - DatagramSocket socket = new DatagramSocket(); - socket.connect(InetAddress.getByName("8.8.8.8"), 10002); //193.0.14.129 RIPE NCC + // Resolve IP + DatagramSocket socket; + try{ // todo: check other method if internet unavaliable + socket = new DatagramSocket(); + socket.connect(InetAddress.getByName("8.8.8.8"), 10002); // Google hostIP = socket.getLocalAddress().getHostAddress(); - //System.out.println(hostIP); socket.close(); } catch (SocketException | UnknownHostException e){ - e.printStackTrace(); + logPrinter.print("NET: Can't get your computer IP using Google DNS server", EMsgType.INFO); + try { + socket = new DatagramSocket(); + socket.connect(InetAddress.getByName("193.0.14.129"), 10002); // RIPE NCC + hostIP = socket.getLocalAddress().getHostAddress(); + socket.close(); + } + catch (SocketException | UnknownHostException e1){ + logPrinter.print("NET: Can't get your computer IP using RIPE NCC root server", EMsgType.INFO); + try { + socket = new DatagramSocket(); + socket.connect(InetAddress.getByName("people.com.cn"), 10002); // Renmin Ribao + hostIP = socket.getLocalAddress().getHostAddress(); + socket.close(); + } + catch (SocketException | UnknownHostException e2){ + logPrinter.print("NET: Can't get your computer IP using Renmin Ribao server", EMsgType.FAIL); + logPrinter.print("Try using 'Expert mode' and set IP by yourself", EMsgType.INFO); + try { + Enumeration enumeration = NetworkInterface.getNetworkInterfaces(); + while (enumeration.hasMoreElements()) { + NetworkInterface n = (NetworkInterface) enumeration.nextElement(); + Enumeration enumeration1 = n.getInetAddresses(); + while (enumeration1.hasMoreElements()) { + InetAddress i = (InetAddress) enumeration1.nextElement(); + logPrinter.print("Check for: "+i.getHostAddress(), EMsgType.INFO); + } + } + } catch (SocketException socketException) { + logPrinter.print("Can't determine possible variants.", EMsgType.FAIL); + } + isValid = false; + close(EFileStatus.FAILED); + return; + } + } } - this.hostPort = 6000; // TODO: fix - - try { - - serverSocket = new ServerSocket(hostPort); // TODO: randomize - //System.out.println(serverSocket.getInetAddress()); 0.0.0.0 + logPrinter.print("NET: Your IP detected as: "+hostIP, EMsgType.PASS); + // Detect port + Random portRandomizer = new Random(); + for (int i=0; i<5; i++){ + try { + this.hostPort = portRandomizer.nextInt(999)+6000; + serverSocket = new ServerSocket(hostPort); //System.out.println(serverSocket.getInetAddress()); 0.0.0.0 + logPrinter.print("NET: Your port detected as: "+hostPort, EMsgType.PASS); + break; + } + catch (IOException ioe){ + if (i==4){ + logPrinter.print("NET: Can't find good port", EMsgType.FAIL); + logPrinter.print("Try using 'Expert mode' and set port by yourself.", EMsgType.INFO); + isValid = false; + close(EFileStatus.FAILED); + return; + } + else + logPrinter.print("NET: Can't use port "+hostPort+"\nLooking for another one.", EMsgType.WARNING); + } } - catch (IOException ioe){ - ioe.printStackTrace(); - System.out.println("unable to use socket"); - } - + isValid = true; } + /** + * Do it hard way (expert mode selected) + * */ + public NETCommunications(List filesList, String switchIP, boolean doNotServeRequests, String hostIP, int hostPort, String extras){ + this.doNotServeRequests = doNotServeRequests; + if (doNotServeRequests) + this.extras = extras; + else + this.extras = ""; + this.switchIP = switchIP; + } + /* Replace everything to ASCII (WEB representation) calculate @@ -71,6 +142,15 @@ write in first 4 bytes * */ @Override protected Void call() { + if (!isValid) + return null; + if (isCancelled()){ + logPrinter.print("NET: interrupted by user", EMsgType.INFO); + close(EFileStatus.FAILED); + return null; + } + + logPrinter.print("\tStart chain", EMsgType.INFO); // Get files list length StringBuilder myStrBuilder; @@ -80,11 +160,11 @@ write in first 4 bytes myStrBuilder.append(':'); myStrBuilder.append(hostPort); myStrBuilder.append('/'); + myStrBuilder.append(extras); myStrBuilder.append(fileNameEncoded); myStrBuilder.append('\n'); } - byte[] nspListNames = myStrBuilder.toString().getBytes(StandardCharsets.UTF_8); // Follow the byte[] nspListSize = ByteBuffer.allocate(Integer.BYTES).putInt(nspListNames.length).array(); // defining order @@ -187,4 +267,21 @@ write in first 4 bytes } } } + /** + * Close when done + * */ + private void close(EFileStatus status){ + try { + serverSocket.close(); + logPrinter.print("NET: Closing server socket.", EMsgType.PASS); + } + catch (IOException ioe){ + logPrinter.print("NET: Closing server socket failed. Sometimes it's not an issue.", EMsgType.WARNING); + } + if (status != null) { + logPrinter.update(nspMap, status); + } + logPrinter.print("\tEnd chain", EMsgType.INFO); + logPrinter.close(); + } } diff --git a/src/main/java/nsusbloader/USB/UsbCommunications.java b/src/main/java/nsusbloader/USB/UsbCommunications.java index 1bc7761..8829ff1 100644 --- a/src/main/java/nsusbloader/USB/UsbCommunications.java +++ b/src/main/java/nsusbloader/USB/UsbCommunications.java @@ -216,7 +216,6 @@ public class UsbCommunications extends Task { } close(); - logPrinter.print("\tEnd chain", EMsgType.INFO); return null; } /** @@ -709,6 +708,7 @@ public class UsbCommunications extends Task { // Report status and close logPrinter.update(nspMap, status); + logPrinter.print("\tEnd chain", EMsgType.INFO); logPrinter.close(); } /** diff --git a/src/main/resources/NSLMain.fxml b/src/main/resources/NSLMain.fxml index 2b42726..910746a 100644 --- a/src/main/resources/NSLMain.fxml +++ b/src/main/resources/NSLMain.fxml @@ -34,7 +34,7 @@