Add updated brazilian portuguese translation by @almircanella! #64

Refactor NETCommunications. Not it's readable :D
A lot of small changes, code refactoring, updates and fixes.
master
Dmitry Isaenko 2020-07-10 16:57:29 +03:00
parent 96e85056dd
commit 267ffcf5d2
22 changed files with 553 additions and 522 deletions

View File

@ -18,7 +18,6 @@
*/
package nsusbloader.COM.NET;
import nsusbloader.COM.INSTask;
import nsusbloader.ModelControllers.ILogPrinter;
import nsusbloader.NSLDataTypes.EFileStatus;
import nsusbloader.ModelControllers.Log;
@ -32,305 +31,124 @@ import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.*;
public class NETCommunications implements INSTask { // todo: rewrite
public class NETCommunications implements Runnable {
private ILogPrinter logPrinter;
private final ILogPrinter logPrinter;
private String hostIP;
private int hostPort;
private String extras;
private final String switchIP;
private final static int SWITCH_PORT = 2000;
private final String hostIP;
private final int hostPort;
private final String extras;
private final boolean doNotServe;
private String switchIP;
private final HashMap<String, UniFile> files;
private HashMap<String, File> nspMap;
private HashMap<String, Long> nspFileSizes;
private final ServerSocket serverSocket;
private Socket clientSocket;
private ServerSocket serverSocket;
private boolean isValid;
private boolean doNotServeRequests;
private final boolean isValid;
private OutputStream currSockOS;
private PrintWriter currSockPW;
private volatile boolean cancel;
/**
* Simple constructor that everybody uses
* */
public NETCommunications(List<File> filesList,
String switchIP,
boolean doNotServeRequests,
String hostIPaddr,
boolean doNotServe,
String hostIP,
String hostPortNum,
String extras) {
this.doNotServeRequests = doNotServeRequests;
if (doNotServeRequests)
String extras)
{
this.doNotServe = doNotServe;
if (doNotServe)
this.extras = extras;
else
this.extras = "";
this.switchIP = switchIP;
this.logPrinter = Log.getPrinter(EModule.USB_NET_TRANSFERS);
this.nspMap = new HashMap<>();
this.nspFileSizes = new HashMap<>();
// Filter and remove empty/incorrect split-files
filesList.removeIf(f -> {
if (f.isDirectory()){
File[] subFiles = f.listFiles((file, name) -> name.matches("[0-9]{2}"));
if (subFiles == null || subFiles.length == 0) {
logPrinter.print("NET: Removing empty folder: " + f.getName(), EMsgType.WARNING);
return true;
}
else {
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: Removing strange 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;
});
// Collect and encode NSP files list
try {
for (File nspFile : filesList)
nspMap.put(URLEncoder.encode(nspFile.getName(), "UTF-8").replaceAll("\\+", "%20"), nspFile); // replace + to %20
}
catch (UnsupportedEncodingException uee){
isValid = false;
logPrinter.print("NET: Unsupported encoding for 'URLEncoder'. Internal issue you can't fix. Please report. Returned:\n\t"+uee.getMessage(), EMsgType.FAIL);
//for (File nspFile : filesList)
// nspMap.put(nspFile.getName(), nspFile);
NetworkSetupValidator validator =
new NetworkSetupValidator(filesList, doNotServe, hostIP, hostPortNum, logPrinter);
this.hostIP = validator.getHostIP();
this.hostPort = validator.getHostPort();
this.files = validator.getFiles();
this.serverSocket = validator.getServerSocket();
this.isValid = validator.isValid();
if (! isValid)
close(EFileStatus.FAILED);
return;
}
// Collect sizes since now we can have split-files support
for (Map.Entry<String, File> entry : nspMap.entrySet()){
File inFile = entry.getValue();
long fSize = 0;
if (inFile.isDirectory()){
File[] subFiles = inFile.listFiles((file, name) -> name.matches("[0-9]{2}"));
for (File subFile : subFiles)
fSize += subFile.length();
nspFileSizes.put(entry.getKey(), fSize);
}
else
nspFileSizes.put(entry.getKey(), inFile.length());
}
// Resolve IP
if (hostIPaddr.isEmpty()) {
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();
socket.close();
}
catch (SocketException | UnknownHostException e) {
logPrinter.print("NET: Can't get your computer IP using Google DNS server. Returned:\n\t"+e.getMessage(), 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. Returned:\n\t"+e1.getMessage(), 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. Returned:\n\t"+e2.getMessage(), EMsgType.FAIL);
logPrinter.print("Try using 'Expert mode' and set IP manually.", EMsgType.INFO);
this.showAvalIpExamples();
isValid = false;
close(EFileStatus.FAILED);
return;
}
}
}
// Say hello to MacOS Catalina
// Also this part could be used instead of what we have above. One day it has to be tested on all platforms and fixed (replace code above).
if (hostIP.equals("0.0.0.0")) {
Socket scoketK;
try {
scoketK = new Socket();
scoketK.connect(new InetSocketAddress("google.com", 80));
hostIP = scoketK.getLocalAddress().getHostAddress();
scoketK.close();
} catch (Exception scoketKex) {
scoketKex.printStackTrace();
logPrinter.print("NET: Can't get your computer IP using Google server (InetSocketAddress). Returned:\n\t"+scoketKex.getMessage(), EMsgType.INFO);
try {
scoketK = new Socket();
scoketK.connect(new InetSocketAddress("people.com.cn", 80));
hostIP = scoketK.getLocalAddress().getHostAddress();
scoketK.close();
} catch (Exception scoketKexx) {
scoketKex.printStackTrace();
logPrinter.print("NET: Can't get your computer IP using Renmin Ribao server (InetSocketAddress). Returned:\n\t"+scoketKexx.getMessage(), EMsgType.FAIL);
logPrinter.print("Try using 'Expert mode' and set IP manually.", EMsgType.INFO);
this.showAvalIpExamples();
isValid = false;
close(EFileStatus.FAILED);
return;
}
}
}
logPrinter.print("NET: Your IP detected as: " + hostIP, EMsgType.PASS);
}
else {
this.hostIP = hostIPaddr;
logPrinter.print("NET: Your IP defined as: " + hostIP, EMsgType.PASS);
}
// Get port
if (! doNotServeRequests) {
if (hostPortNum.isEmpty()) {
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);
}
}
} else {
try {
this.hostPort = Integer.parseInt(hostPortNum);
serverSocket = new ServerSocket(hostPort);
logPrinter.print("NET: Using defined port number: " + hostPort, EMsgType.PASS);
}
catch (NumberFormatException nfe) { // Literally never happens.
logPrinter.print("NET: Can't use port defined in settings: " + hostPortNum + "\nIt's not a valid number!", EMsgType.FAIL);
isValid = false;
close(EFileStatus.FAILED);
return;
}
catch (IOException ioex){
logPrinter.print("NET: Can't use port defined in settings: " + hostPortNum + "\n\t"+ioex.getMessage(), EMsgType.FAIL);
isValid = false;
close(EFileStatus.FAILED);
return;
}
}
}
else {
if (hostPortNum.isEmpty()){
logPrinter.print("NET: Port must be defined if 'Don't serve requests' option selected!", EMsgType.FAIL);
isValid = false;
close(EFileStatus.FAILED);
return;
}
try {
this.hostPort = Integer.parseInt(hostPortNum);
}
catch (NumberFormatException fex){
logPrinter.print("NET: Can't use port defined in settings: " + hostPortNum + "\nIt's not a valid number!", EMsgType.WARNING);
isValid = false;
close(EFileStatus.FAILED);
return;
}
}
isValid = true;
}
/**
* Show possible variants to log area
* */
private void showAvalIpExamples(){
try {
Enumeration<NetworkInterface> enumeration = NetworkInterface.getNetworkInterfaces();
while (enumeration.hasMoreElements()) {
NetworkInterface n = enumeration.nextElement();
Enumeration<InetAddress> enumeration1 = n.getInetAddresses();
while (enumeration1.hasMoreElements())
logPrinter.print("Check for: " + enumeration1.nextElement().getHostAddress(), EMsgType.INFO);
}
}
catch (SocketException socketException) { // Good block.
logPrinter.print("Can't determine possible variants. Returned:\n\t"+socketException.getMessage(), EMsgType.FAIL);
}
}
@Override
public boolean isCancelled(){
return cancel;
}
@Override
public void cancel() {
cancel = true;
}
@Override
public void run() {
if (!isValid | isCancelled())
if (! isValid || Thread.interrupted() )
return;
logPrinter.print("\tStart chain", EMsgType.INFO);
// Create string that we'll send to TF and which initiates chain
StringBuilder myStrBuilder;
myStrBuilder = new StringBuilder();
for (String fileNameEncoded : nspMap.keySet()) {
myStrBuilder.append(hostIP);
myStrBuilder.append(':');
myStrBuilder.append(hostPort);
myStrBuilder.append('/');
myStrBuilder.append(extras);
myStrBuilder.append(fileNameEncoded);
myStrBuilder.append('\n');
}
final String handshakeContent = buildHandshakeContent();
byte[] nspListNames = myStrBuilder.toString().getBytes(StandardCharsets.UTF_8); // Follow the
byte[] nspListSize = ByteBuffer.allocate(Integer.BYTES).putInt(nspListNames.length).array(); // defining order
byte[] handshakeCommand = handshakeContent.getBytes(StandardCharsets.UTF_8);
byte[] handshakeCommandSize = ByteBuffer.allocate(Integer.BYTES).putInt(handshakeCommand.length).array();
try {
Socket handShakeSocket = new Socket(InetAddress.getByName(switchIP), 2000);
OutputStream os = handShakeSocket.getOutputStream();
os.write(nspListSize);
os.write(nspListNames);
os.flush();
handShakeSocket.close();
}
catch (IOException uhe){
logPrinter.print("NET: Unable to connect to NS and send files list. Returned:\n\t"+uhe.getMessage(), EMsgType.FAIL);
close(EFileStatus.UNKNOWN);
if (sendHandshake(handshakeCommandSize, handshakeCommand))
return;
}
// Check if we should serve requests
if (this.doNotServeRequests){
logPrinter.print("NET: List of files transferred. Replies won't be served.", EMsgType.PASS);
if (this.doNotServe){
logPrinter.print("List of files transferred. Replies won't be served.", EMsgType.PASS);
close(EFileStatus.UNKNOWN);
return;
}
logPrinter.print("NET: Initiation files list has been sent to NS.", EMsgType.PASS);
logPrinter.print("Initiation files list has been sent to NS.", EMsgType.PASS);
// Go transfer
Socket clientSocket;
work_routine:
while (true){
try {
serveRequestsLoop();
}
/**
* Create string that we'll send to TF/AW and which initiates chain
* */
private String buildHandshakeContent(){
StringBuilder builder = new StringBuilder();
for (String fileNameEncoded : files.keySet()) {
builder.append(hostIP);
builder.append(':');
builder.append(hostPort);
builder.append('/');
builder.append(extras);
builder.append(fileNameEncoded);
builder.append('\n');
}
return builder.toString();
}
private boolean sendHandshake(byte[] handshakeCommandSize, byte[] handshakeCommand){
try {
Socket handshakeSocket = new Socket(InetAddress.getByName(switchIP), SWITCH_PORT);
OutputStream os = handshakeSocket.getOutputStream();
os.write(handshakeCommandSize);
os.write(handshakeCommand);
os.flush();
handshakeSocket.close();
}
catch (IOException uhe){
logPrinter.print("Unable to connect to NS and send files list:\n "
+ uhe.getMessage(), EMsgType.FAIL);
close(EFileStatus.UNKNOWN);
return true;
}
return false;
}
private void serveRequestsLoop(){
try {
while (true){
clientSocket = serverSocket.accept();
BufferedReader br = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream())
@ -345,8 +163,7 @@ public class NETCommunications implements INSTask { // todo: rewrite
while ((line = br.readLine()) != null) {
//System.out.println(line); // Debug
if (line.trim().isEmpty()) { // If TCP packet is ended
if (handleRequest(tcpPacket)) // Proceed required things
break work_routine;
handleRequest(tcpPacket); // Proceed required things
tcpPacket.clear(); // Clear data and wait for next TCP packet
}
else
@ -356,206 +173,219 @@ public class NETCommunications implements INSTask { // todo: rewrite
// and reopen client sock
clientSocket.close();
}
catch (IOException ioe){ // If server socket closed, then client socket also closed.
break;
}
}
if ( ! isCancelled() )
catch (Exception e){
if (Thread.interrupted())
logPrinter.print("Interrupted by user.", EMsgType.INFO);
else
logPrinter.print(e.getMessage(), EMsgType.INFO);
close(EFileStatus.UNKNOWN);
return;
}
}
// 200 206 400 (inv range) 404 416 (Range Not Satisfiable )
/**
* Handle requests
* @return true if failed
* */
private boolean handleRequest(LinkedList<String> packet){
//private boolean handleRequest(LinkedList<String> packet, OutputStreamWriter pw){
private void handleRequest(LinkedList<String> packet) throws Exception{
File requestedFile;
String reqFileName = packet.get(0).replaceAll("(^[A-z\\s]+/)|(\\s+?.*$)", "");
if (! nspFileSizes.containsKey(reqFileName)){
currSockPW.write(NETPacket.getCode404());
currSockPW.flush();
logPrinter.print("NET: File "+reqFileName+" doesn't exists or have 0 size. Returning 404", EMsgType.FAIL);
return true;
if (! files.containsKey(reqFileName)){
writeToSocket(NETPacket.getCode404());
logPrinter.print("File "+reqFileName+" doesn't exists or have 0 size. Returning 404", EMsgType.FAIL);
return;
}
long reqFileSize = nspFileSizes.get(reqFileName);
requestedFile = nspMap.get(reqFileName);
long reqFileSize = files.get(reqFileName).getSize();
requestedFile = files.get(reqFileName).getFile();
if (! requestedFile.exists() || reqFileSize == 0){ // well.. tell 404 if file exists with 0 length is against standard, but saves time
currSockPW.write(NETPacket.getCode404());
currSockPW.flush();
logPrinter.print("NET: File "+requestedFile.getName()+" doesn't exists or have 0 size. Returning 404", EMsgType.FAIL);
writeToSocket(NETPacket.getCode404());
logPrinter.print("File "+requestedFile.getName()+" doesn't exists or have 0 size. Returning 404", EMsgType.FAIL);
logPrinter.update(requestedFile, EFileStatus.FAILED);
return true;
return;
}
if (packet.get(0).startsWith("HEAD")){
currSockPW.write(NETPacket.getCode200(reqFileSize));
currSockPW.flush();
logPrinter.print("NET: Replying for requested file: "+requestedFile.getName(), EMsgType.INFO);
return false;
writeToSocket(NETPacket.getCode200(reqFileSize));
logPrinter.print("Replying for requested file: "+requestedFile.getName(), EMsgType.INFO);
return;
}
if (packet.get(0).startsWith("GET")) {
for (String line: packet) {
if (line.toLowerCase().startsWith("range")) { //todo: fix
try {
String[] rangeStr = line.toLowerCase().replaceAll("^range:\\s+?bytes=", "").split("-", 2);
if (!rangeStr[0].isEmpty() && !rangeStr[1].isEmpty()) { // If both ranges defined: Read requested
if (Long.parseLong(rangeStr[0]) > Long.parseLong(rangeStr[1])){ // If start bytes greater then end bytes
currSockPW.write(NETPacket.getCode400());
currSockPW.flush();
logPrinter.print("NET: Requested range for "+requestedFile.getName()+" is incorrect. Returning 400", EMsgType.FAIL);
logPrinter.update(requestedFile, EFileStatus.FAILED);
return true;
}
if (writeToSocket(reqFileName, Long.parseLong(rangeStr[0]), Long.parseLong(rangeStr[1]))) // DO WRITE
return true;
if (! line.toLowerCase().startsWith("range")) //todo: fix
continue;
}
else if (!rangeStr[0].isEmpty()) { // If only START defined: Read all
if (writeToSocket(reqFileName, Long.parseLong(rangeStr[0]), reqFileSize)) // DO WRITE
return true;
}
else if (!rangeStr[1].isEmpty()) { // If only END defined: Try to read last 500 bytes
if (reqFileSize > 500){
if (writeToSocket(reqFileName, reqFileSize-500, reqFileSize)) // DO WRITE
return true;
}
else { // If file smaller than 500 bytes
currSockPW.write(NETPacket.getCode416());
currSockPW.flush();
logPrinter.print("NET: File size requested for "+requestedFile.getName()+" while actual size of it: "+reqFileSize+". Returning 416", EMsgType.FAIL);
logPrinter.update(requestedFile, EFileStatus.FAILED);
return true;
}
}
else {
currSockPW.write(NETPacket.getCode400()); // If Range not defined: like "Range: bytes=-"
currSockPW.flush();
logPrinter.print("NET: Requested range for "+requestedFile.getName()+" is incorrect (empty start & end). Returning 400", EMsgType.FAIL);
logPrinter.update(requestedFile, EFileStatus.FAILED);
return true;
}
break;
}
catch (NumberFormatException nfe){
currSockPW.write(NETPacket.getCode400());
currSockPW.flush();
logPrinter.print("NET: Requested range for "+requestedFile.getName()+" has incorrect format. Returning 400\n\t"+nfe.getMessage(), EMsgType.FAIL);
logPrinter.update(requestedFile, EFileStatus.FAILED);
return true;
}
}
parseGETrange(requestedFile, reqFileName, reqFileSize, line);
return;
}
}
return false;
}
private void parseGETrange(File file, String fileName, long fileSize, String rangeDirective) throws Exception{
try {
String[] rangeStr = rangeDirective.toLowerCase().replaceAll("^range:\\s+?bytes=", "").split("-", 2);
if (! rangeStr[0].isEmpty() && ! rangeStr[1].isEmpty()) { // If both ranges defined: Read requested
long fromRange = Long.parseLong(rangeStr[0]);
long toRange = Long.parseLong(rangeStr[1]);
if (fromRange > toRange){ // If start bytes greater then end bytes
writeToSocket(NETPacket.getCode400());
logPrinter.print("Requested range for "
+ file.getName()
+ " is incorrect. Returning 400", EMsgType.FAIL);
logPrinter.update(file, EFileStatus.FAILED);
return;
}
writeToSocket(fileName, fromRange, toRange);
return;
}
if (! rangeStr[0].isEmpty()) { // If only START defined: Read all
writeToSocket(fileName, Long.parseLong(rangeStr[0]), fileSize);
return;
}
if (rangeStr[1].isEmpty()) { // If Range not defined: like "Range: bytes=-"
writeToSocket(NETPacket.getCode400());
logPrinter.print("Requested range for "
+ file.getName()
+ " is incorrect (empty start & end). Returning 400", EMsgType.FAIL);
logPrinter.update(file, EFileStatus.FAILED);
return;
}
if (fileSize > 500){
writeToSocket(fileName, fileSize - 500, fileSize);
return;
}
// If file smaller than 500 bytes
writeToSocket(NETPacket.getCode416());
logPrinter.print("File size requested for "
+ file.getName()
+ " while actual size of it: "
+ fileSize+". Returning 416", EMsgType.FAIL);
logPrinter.update(file, EFileStatus.FAILED);
}
catch (NumberFormatException nfe){
writeToSocket(NETPacket.getCode400());
logPrinter.print("Requested range for "
+ file.getName()
+ " has incorrect format. Returning 400\n\t"
+ nfe.getMessage(), EMsgType.FAIL);
logPrinter.update(file, EFileStatus.FAILED);
}
}
private void writeToSocket(String string) {
currSockPW.write(string);
currSockPW.flush();
}
/**
* Send files.
* */
private boolean writeToSocket(String fileName, long start, long end){
File reqFile = nspMap.get(fileName);
// Inform
logPrinter.print("NET: Responding to requested range: "+start+"-"+end, EMsgType.INFO);
// Reply
currSockPW.write(NETPacket.getCode206(nspFileSizes.get(fileName), start, end));
currSockPW.flush();
// Prepare transfer
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);
writeToSocket(NETPacket.getCode206(files.get(fileName).getSize(), start, end));
try{
if (file.isDirectory())
handleSplitFile(file, start, end);
else
handleRegularFile(file, start, end);
logPrinter.updateProgress(1.0);
}
catch (Exception e){
logPrinter.update(file, EFileStatus.FAILED);
throw new Exception("File transmission failed:\n "+e.getMessage());
}
}
private void handleSplitFile(File file, long start, long end) throws Exception{
long count = end - start + 1;
int readPice = 8388608; // = 8Mb
int readPice = 8388608;
byte[] byteBuf;
long currentOffset = 0;
try{
//================================= SPLIT FILE ====================================
if (reqFile.isDirectory()){
NSSplitReader nsr = new NSSplitReader(reqFile, start);
NSSplitReader nsr = new NSSplitReader(file, start);
while (currentOffset < count){
if (isCancelled())
return true;
if ((currentOffset + readPice) >= count){
readPice = Math.toIntExact(count - currentOffset);
}
byteBuf = new byte[readPice];
if (nsr.read(byteBuf) != readPice){
logPrinter.print("NET: Reading of file stream suddenly ended.", EMsgType.FAIL);
return true;
}
currSockOS.write(byteBuf);
//-------/
logPrinter.updateProgress((currentOffset+readPice)/(count/100.0) / 100.0);
//-------/
currentOffset += readPice;
}
currSockOS.flush(); // TODO: check if this really needed.
nsr.close();
while (currentOffset < count){
if ((currentOffset + readPice) >= count){
readPice = Math.toIntExact(count - currentOffset);
}
//================================= REGULAR FILE ====================================
else {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(reqFile));
byteBuf = new byte[readPice];
if (bis.skip(start) != start){
logPrinter.print("NET: Unable to skip requested range.", EMsgType.FAIL);
logPrinter.update(reqFile, EFileStatus.FAILED);
return true;
}
if (nsr.read(byteBuf) != readPice)
throw new IOException("File stream suddenly ended.");
while (currentOffset < count){
if (isCancelled())
return true;
if ((currentOffset + readPice) >= count){
readPice = Math.toIntExact(count - currentOffset);
}
byteBuf = new byte[readPice];
currSockOS.write(byteBuf);
logPrinter.updateProgress((currentOffset+readPice)/(count/100.0) / 100.0);
if (bis.read(byteBuf) != readPice){
logPrinter.print("NET: Reading of file stream suddenly ended.", EMsgType.FAIL);
return true;
}
currSockOS.write(byteBuf);
//-------/
logPrinter.updateProgress((currentOffset+readPice)/(count/100.0) / 100.0);
//-------/
currentOffset += readPice;
}
currSockOS.flush(); // TODO: check if this really needed.
bis.close();
currentOffset += readPice;
}
currSockOS.flush(); // TODO: check if this really needed.
nsr.close();
}
private void handleRegularFile(File file, long start, long end) throws Exception{
long count = end - start + 1;
int readPice = 8388608;
byte[] byteBuf;
long currentOffset = 0;
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
if (bis.skip(start) != start)
throw new IOException("Unable to skip requested range.");
while (currentOffset < count){
if ((currentOffset + readPice) >= count){
readPice = Math.toIntExact(count - currentOffset);
}
//-------/
logPrinter.updateProgress(1.0);
//-------/
byteBuf = new byte[readPice];
if (bis.read(byteBuf) != readPice){
throw new IOException("File stream suddenly ended.");
}
currSockOS.write(byteBuf);
logPrinter.updateProgress((currentOffset+readPice)/(count/100.0) / 100.0);
currentOffset += readPice;
}
catch (IOException | NullPointerException e){
logPrinter.print("NET: File transmission failed. Returned:\n\t"+e.getMessage(), EMsgType.FAIL);
logPrinter.update(reqFile, EFileStatus.FAILED);
return true;
}
return false;
currSockOS.flush(); // TODO: check if this really needed.
bis.close();
}
public ServerSocket getServerSocket(){
return serverSocket;
}
public Socket getClientSocket(){
return clientSocket;
}
/**
* Close when done
* */
private void close(EFileStatus status){
if (isCancelled())
logPrinter.print("NET: Interrupted by user.", EMsgType.INFO);
try {
if (serverSocket != null) {
if (serverSocket != null && ! serverSocket.isClosed()) {
serverSocket.close();
logPrinter.print("NET: Closing server socket.", EMsgType.PASS);
logPrinter.print("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("Closing server socket failed. Sometimes it's not an issue.", EMsgType.WARNING);
}
HashMap<String, File> tempMap = new HashMap<>();
for (UniFile sf : files.values())
tempMap.put(sf.getFile().getName(), sf.getFile());
logPrinter.update(tempMap, status);
logPrinter.print("\tEnd chain", EMsgType.INFO);
logPrinter.close();
}

View File

@ -0,0 +1,205 @@
/*
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 <https://www.gnu.org/licenses/>.
*/
package nsusbloader.COM.NET;
import nsusbloader.ModelControllers.ILogPrinter;
import nsusbloader.NSLDataTypes.EMsgType;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.*;
import java.util.*;
public class NetworkSetupValidator {
private String hostIP;
private int hostPort;
private final HashMap<String, UniFile> files;
private ServerSocket serverSocket;
private final boolean valid;
private final ILogPrinter logPrinter;
private final boolean doNotServe;
NetworkSetupValidator(List<File> filesList,
boolean doNotServe,
String hostIP,
String hostPortNum,
ILogPrinter logPrinter) {
this.files = new HashMap<>();
this.logPrinter = logPrinter;
this.doNotServe = doNotServe;
try {
validateFiles(filesList);
encodeAndAddFilesToMap(filesList);
resolveIp(hostIP);
resolvePort(hostPortNum);
}
catch (Exception e){
logPrinter.print(e.getMessage(), EMsgType.FAIL);
valid = false;
return;
}
valid = true;
}
private void validateFiles(List<File> filesList) {
filesList.removeIf(f -> {
if (f.isFile())
return false;
File[] subFiles = f.listFiles((file, name) -> name.matches("[0-9]{2}"));
if (subFiles == null || subFiles.length == 0) {
logPrinter.print("NET: Exclude folder: " + f.getName(), EMsgType.WARNING);
return true;
}
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()+
"\n Chunk sizes of the split file are not the same, but has to be.", EMsgType.WARNING);
return true;
}
}
return false;
});
}
private void encodeAndAddFilesToMap(List<File> filesList) throws UnsupportedEncodingException, FileNotFoundException {
for (File file : filesList){
String encodedName = URLEncoder.encode(file.getName(), "UTF-8").replaceAll("\\+", "%20"); // replace '+' to '%20'
UniFile uniFile = new UniFile(file);
files.put(encodedName, uniFile);
}
if (files.size() == 0) {
throw new FileNotFoundException("NET: No files to send.");
}
}
private void resolveIp(String hostIPaddr) throws IOException{
if (! hostIPaddr.isEmpty()){
this.hostIP = hostIPaddr;
logPrinter.print("NET: Host IP defined as: " + hostIP, EMsgType.PASS);
return;
}
if (findIpUsingHost("google.com"))
return;
if (findIpUsingHost("people.com.cn"))
return;
throw new IOException("Try using 'Expert mode' and set IP manually. " + getAvaliableIpExamples());
}
private boolean findIpUsingHost(String host) {
try {
Socket scoketK;
scoketK = new Socket();
scoketK.connect(new InetSocketAddress(host, 80));
hostIP = scoketK.getLocalAddress().getHostAddress();
scoketK.close();
logPrinter.print("NET: Host IP detected as: " + hostIP, EMsgType.PASS);
return true;
}
catch (IOException e){
logPrinter.print("NET: Can't get your computer IP using "
+ host
+ " server (InetSocketAddress). Returned:\n\t"+e.getMessage(), EMsgType.INFO);
return false;
}
}
private String getAvaliableIpExamples(){
try {
StringBuilder builder = new StringBuilder("Check for:\n");
Enumeration<NetworkInterface> enumeration = NetworkInterface.getNetworkInterfaces();
while (enumeration.hasMoreElements()) {
NetworkInterface n = enumeration.nextElement();
Enumeration<InetAddress> enumeration1 = n.getInetAddresses();
while (enumeration1.hasMoreElements()){
builder.append("- ");
builder.append(enumeration1.nextElement().getHostAddress());
builder.append("\n");
}
}
return builder.toString();
}
catch (SocketException socketException) {
return "";
}
}
private void resolvePort(String hostPortNum) throws Exception{
if (! hostPortNum.isEmpty()) {
parsePort(hostPortNum);
return;
}
if (doNotServe)
throw new Exception("NET: Port must be defined if 'Don't serve requests' option selected!");
findPort();
}
private void findPort() throws Exception{
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) {
throw new Exception("NET: Can't find good port\n"
+ "Set port by in settings ('Expert mode').");
}
logPrinter.print("NET: Can't use port " + hostPort + "\nLooking for another one.", EMsgType.WARNING);
}
}
}
private void parsePort(String hostPortNum) throws Exception{
try {
this.hostPort = Integer.parseInt(hostPortNum);
serverSocket = new ServerSocket(hostPort);
logPrinter.print("NET: Using defined port number: " + hostPort, EMsgType.PASS);
}
catch (IllegalArgumentException | IOException eee){
throw new Exception("NET: Can't use port defined in settings: " + hostPortNum + "\n\t"+eee.getMessage());
}
}
String getHostIP() { return hostIP; }
int getHostPort() { return hostPort; }
HashMap<String, UniFile> getFiles() { return files; }
ServerSocket getServerSocket() { return serverSocket; }
boolean isValid() { return valid; }
}

View File

@ -16,9 +16,29 @@
You should have received a copy of the GNU General Public License
along with NS-USBloader. If not, see <https://www.gnu.org/licenses/>.
*/
package nsusbloader.COM;
package nsusbloader.COM.NET;
public interface INSTask extends Runnable {
void cancel();
boolean isCancelled();
import java.io.File;
class UniFile {
private final long size;
private final File file;
UniFile(File file) {
this.file = file;
if (file.isFile()) {
size = file.length();
}
else {
long fSize = 0;
File[] subFiles = file.listFiles((myFile, name) -> name.matches("[0-9]{2}"));
for (File subFile : subFiles)
fSize += subFile.length();
size = fSize;
}
}
public long getSize() { return size; }
public File getFile() { return file; }
}

View File

@ -18,7 +18,6 @@
*/
package nsusbloader.COM.USB;
import nsusbloader.COM.INSTask;
import nsusbloader.ModelControllers.ILogPrinter;
import nsusbloader.NSLDataTypes.EFileStatus;
import nsusbloader.NSLDataTypes.EMsgType;
@ -53,7 +52,7 @@ public class GoldLeaf_05 extends TransferModule {
private RandomAccessFile raf; // NSP File
private NSSplitReader nsr; // It'a also NSP File
GoldLeaf_05(DeviceHandle handler, LinkedHashMap<String, File> nspMap, INSTask task, ILogPrinter logPrinter){
GoldLeaf_05(DeviceHandle handler, LinkedHashMap<String, File> nspMap, Runnable task, ILogPrinter logPrinter){
super(handler, nspMap, task, logPrinter);
status = EFileStatus.FAILED;
@ -335,7 +334,7 @@ public class GoldLeaf_05 extends TransferModule {
IntBuffer writeBufTransferred = IntBuffer.allocate(1);
int result;
while (! task.isCancelled()) {
while (! Thread.interrupted()) {
result = LibUsb.bulkTransfer(handlerNS, (byte) 0x01, writeBuffer, writeBufTransferred, 1000); // last one is TIMEOUT. 0 stands for unlimited. Endpoint OUT = 0x01
switch (result){
@ -368,7 +367,7 @@ public class GoldLeaf_05 extends TransferModule {
IntBuffer readBufTransferred = IntBuffer.allocate(1);
int result;
while (! task.isCancelled()) {
while (! Thread.interrupted()) {
result = LibUsb.bulkTransfer(handlerNS, (byte) 0x81, readBuffer, readBufTransferred, 1000); // last one is TIMEOUT. 0 stands for unlimited. Endpoint IN = 0x81
switch (result) {

View File

@ -21,7 +21,6 @@ package nsusbloader.COM.USB;
import javafx.application.Platform;
import javafx.stage.FileChooser;
import nsusbloader.COM.Helpers.NSSplitReader;
import nsusbloader.COM.INSTask;
import nsusbloader.MediatorControl;
import nsusbloader.ModelControllers.ILogPrinter;
import nsusbloader.NSLDataTypes.EMsgType;
@ -69,7 +68,7 @@ class GoldLeaf_07 extends TransferModule {
// For using in CMD_SelectFile with SPEC:/ prefix
private File selectedFile;
GoldLeaf_07(DeviceHandle handler, LinkedHashMap<String, File> nspMap, INSTask task, ILogPrinter logPrinter, boolean nspFilter){
GoldLeaf_07(DeviceHandle handler, LinkedHashMap<String, File> nspMap, Runnable task, ILogPrinter logPrinter, boolean nspFilter){
super(handler, nspMap, task, logPrinter);
final byte CMD_GetDriveCount = 0x00;
@ -993,7 +992,7 @@ class GoldLeaf_07 extends TransferModule {
int result;
while (! task.isCancelled()) {
while (! Thread.interrupted()) {
result = LibUsb.bulkTransfer(handlerNS, (byte) 0x81, readBuffer, readBufTransferred, 1000); // last one is TIMEOUT. 0 stands for unlimited. Endpoint IN = 0x81
switch (result) {
@ -1023,7 +1022,7 @@ class GoldLeaf_07 extends TransferModule {
int result;
while (! task.isCancelled()) {
while (! Thread.interrupted()) {
result = LibUsb.bulkTransfer(handlerNS, (byte) 0x81, readBuffer, readBufTransferred, 1000); // last one is TIMEOUT. 0 stands for unlimited. Endpoint IN = 0x81
switch (result) {
@ -1083,7 +1082,7 @@ class GoldLeaf_07 extends TransferModule {
IntBuffer writeBufTransferred = IntBuffer.allocate(1);
int result;
while (! task.isCancelled()) {
while (! Thread.interrupted()) {
result = LibUsb.bulkTransfer(handlerNS, (byte) 0x01, writeBuffer, writeBufTransferred, 1000); // last one is TIMEOUT. 0 stands for unlimited. Endpoint OUT = 0x01
switch (result){

View File

@ -20,7 +20,6 @@ package nsusbloader.COM.USB;
import javafx.application.Platform;
import javafx.stage.FileChooser;
import nsusbloader.COM.INSTask;
import nsusbloader.MediatorControl;
import nsusbloader.ModelControllers.ILogPrinter;
import nsusbloader.NSLDataTypes.EMsgType;
@ -69,7 +68,7 @@ class GoldLeaf_08 extends TransferModule {
// For using in CMD_SelectFile with SPEC:/ prefix
private File selectedFile;
GoldLeaf_08(DeviceHandle handler, LinkedHashMap<String, File> nspMap, INSTask task, ILogPrinter logPrinter, boolean nspFilter){
GoldLeaf_08(DeviceHandle handler, LinkedHashMap<String, File> nspMap, Runnable task, ILogPrinter logPrinter, boolean nspFilter){
super(handler, nspMap, task, logPrinter);
final byte CMD_GetDriveCount = 1;
@ -1012,7 +1011,7 @@ class GoldLeaf_08 extends TransferModule {
int result;
while (! task.isCancelled()) {
while (! Thread.interrupted()) {
result = LibUsb.bulkTransfer(handlerNS, (byte) 0x81, readBuffer, readBufTransferred, 1000); // last one is TIMEOUT. 0 stands for unlimited. Endpoint IN = 0x81
switch (result) {
@ -1042,7 +1041,7 @@ class GoldLeaf_08 extends TransferModule {
int result;
while (! task.isCancelled()) {
while (! Thread.interrupted() ) {
result = LibUsb.bulkTransfer(handlerNS, (byte) 0x81, readBuffer, readBufTransferred, 1000); // last one is TIMEOUT. 0 stands for unlimited. Endpoint IN = 0x81
switch (result) {
@ -1102,7 +1101,7 @@ class GoldLeaf_08 extends TransferModule {
IntBuffer writeBufTransferred = IntBuffer.allocate(1);
int result;
while (! task.isCancelled()) {
while (! Thread.interrupted()) {
result = LibUsb.bulkTransfer(handlerNS, (byte) 0x01, writeBuffer, writeBufTransferred, 1000); // last one is TIMEOUT. 0 stands for unlimited. Endpoint OUT = 0x01
switch (result){

View File

@ -18,7 +18,6 @@
*/
package nsusbloader.COM.USB;
import nsusbloader.COM.INSTask;
import nsusbloader.ModelControllers.ILogPrinter;
import nsusbloader.NSLDataTypes.EFileStatus;
import nsusbloader.NSLDataTypes.EMsgType;
@ -48,7 +47,7 @@ class TinFoil extends TransferModule {
/* byte[] magic = new byte[4];
ByteBuffer bb = StandardCharsets.UTF_8.encode("TUC0").rewind().get(magic); // Let's rephrase this 'string' */
TinFoil(DeviceHandle handler, LinkedHashMap<String, File> nspMap, INSTask task, ILogPrinter logPrinter){
TinFoil(DeviceHandle handler, LinkedHashMap<String, File> nspMap, Runnable task, ILogPrinter logPrinter){
super(handler, nspMap, task, logPrinter);
logPrinter.print("============= Tinfoil =============", EMsgType.INFO);
@ -305,7 +304,7 @@ class TinFoil extends TransferModule {
IntBuffer writeBufTransferred = IntBuffer.allocate(1);
int result;
//int varVar = 0; //todo:remove
while (! task.isCancelled()) {
while (! Thread.interrupted() ) {
/*
if (varVar != 0)
logPrinter.print("writeUsb() retry cnt: "+varVar, EMsgType.INFO); //NOTE: DEBUG
@ -345,7 +344,7 @@ class TinFoil extends TransferModule {
// We can limit it to 32 bytes, but there is a non-zero chance to got OVERFLOW from libusb.
IntBuffer readBufTransferred = IntBuffer.allocate(1);
int result;
while (! task.isCancelled()) {
while (! Thread.interrupted()) {
result = LibUsb.bulkTransfer(handlerNS, (byte) 0x81, readBuffer, readBufTransferred, 1000); // last one is TIMEOUT. 0 stands for unlimited. Endpoint IN = 0x81
switch (result) {

View File

@ -18,7 +18,6 @@
*/
package nsusbloader.COM.USB;
import nsusbloader.COM.INSTask;
import nsusbloader.ModelControllers.ILogPrinter;
import nsusbloader.NSLDataTypes.EFileStatus;
import nsusbloader.NSLDataTypes.EMsgType;
@ -33,9 +32,9 @@ public abstract class TransferModule {
LinkedHashMap<String, File> nspMap;
ILogPrinter logPrinter;
DeviceHandle handlerNS;
INSTask task;
Runnable task;
TransferModule(DeviceHandle handler, LinkedHashMap<String, File> nspMap, INSTask task, ILogPrinter printer){
TransferModule(DeviceHandle handler, LinkedHashMap<String, File> nspMap, Runnable task, ILogPrinter printer){
this.handlerNS = handler;
this.nspMap = nspMap;
this.task = task;

View File

@ -18,7 +18,6 @@
*/
package nsusbloader.COM.USB;
import nsusbloader.COM.INSTask;
import nsusbloader.ModelControllers.ILogPrinter;
import nsusbloader.ModelControllers.Log;
import nsusbloader.NSLDataTypes.EFileStatus;
@ -31,14 +30,12 @@ import java.io.*;
import java.util.*;
// TODO: add filter option to show only NSP files
public class UsbCommunications implements INSTask {
public class UsbCommunications implements Runnable {
private ILogPrinter logPrinter;
private LinkedHashMap<String, File> nspMap;
private String protocol;
private boolean nspFilterForGl;
private volatile boolean cancel;
private final ILogPrinter logPrinter;
private final LinkedHashMap<String, File> nspMap;
private final String protocol;
private final boolean nspFilterForGl;
public UsbCommunications(List<File> nspList, String protocol, boolean filterNspFilesOnlyForGl){
this.protocol = protocol;
@ -82,8 +79,6 @@ public class UsbCommunications implements INSTask {
usbConnect.close();
close(module.getStatus());
return;
}
/**
@ -94,14 +89,4 @@ public class UsbCommunications implements INSTask {
logPrinter.print("\tEnd", EMsgType.INFO);
logPrinter.close();
}
@Override
public boolean isCancelled() {
return cancel;
}
@Override
public void cancel() {
cancel = true;
}
}

View File

@ -30,7 +30,6 @@ import javafx.scene.layout.Region;
import javafx.stage.DirectoryChooser;
import javafx.stage.FileChooser;
import nsusbloader.AppPreferences;
import nsusbloader.COM.INSTask;
import nsusbloader.COM.NET.NETCommunications;
import nsusbloader.COM.USB.UsbCommunications;
import nsusbloader.MediatorControl;
@ -63,7 +62,7 @@ public class FrontController implements Initializable {
private String previouslyOpenedPath;
private Region btnUpStopImage;
private ResourceBundle resourceBundle;
private INSTask usbNetCommunications;
private Runnable usbNetCommunications;
private Thread workThread;
@Override
@ -265,8 +264,11 @@ public class FrontController implements Initializable {
SettingsController settings = MediatorControl.getInstance().getContoller().getSettingsCtrlr();
// If USB selected
if (getSelectedProtocol().equals("GoldLeaf") || ( getSelectedProtocol().equals("TinFoil") && getSelectedNetUsb().equals("USB") ) ){
usbNetCommunications = new UsbCommunications(nspToUpload, getSelectedProtocol() + settings.getGlVer(), settings.getNSPFileFilterForGL());
if (getSelectedProtocol().equals("GoldLeaf") ){
usbNetCommunications = new UsbCommunications(nspToUpload, "GoldLeaf" + settings.getGlVer(), settings.getNSPFileFilterForGL());
}
else if (( getSelectedProtocol().equals("TinFoil") && getSelectedNetUsb().equals("USB") )){
usbNetCommunications = new UsbCommunications(nspToUpload, "TinFoil", settings.getNSPFileFilterForGL());
}
else { // NET INSTALL OVER TINFOIL
final String ipValidationPattern = "^([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])$";
@ -300,7 +302,15 @@ public class FrontController implements Initializable {
* */
private void stopBtnAction(){
if (workThread != null && workThread.isAlive()){
usbNetCommunications.cancel();
workThread.interrupt();
if (usbNetCommunications instanceof NETCommunications){
try{
((NETCommunications) usbNetCommunications).getServerSocket().close();
((NETCommunications) usbNetCommunications).getClientSocket().close();
}
catch (Exception ignore){ }
}
}
}
/**

View File

@ -25,7 +25,6 @@ import javafx.scene.control.Label;
import javafx.scene.layout.Region;
import javafx.stage.DirectoryChooser;
import nsusbloader.AppPreferences;
import nsusbloader.COM.INSTask;
import nsusbloader.MediatorControl;
import nsusbloader.NSLDataTypes.EModule;
import nsusbloader.Utilities.nxdumptool.NxdtTask;
@ -45,7 +44,6 @@ public class NxdtController implements Initializable {
private Region btnDumpStopImage;
private INSTask NxdtTask;
private Thread workThread;
@Override
@ -83,7 +81,7 @@ public class NxdtController implements Initializable {
if ((workThread == null || ! workThread.isAlive())){
MediatorControl.getInstance().getContoller().logArea.clear();
NxdtTask = new NxdtTask(saveToLocationLbl.getText());
Runnable NxdtTask = new NxdtTask(saveToLocationLbl.getText());
workThread = new Thread(NxdtTask);
workThread.setDaemon(true);
workThread.start();
@ -95,7 +93,7 @@ public class NxdtController implements Initializable {
* */
private void stopBtnAction(){
if (workThread != null && workThread.isAlive()){
NxdtTask.cancel();
workThread.interrupt();
}
}

View File

@ -194,7 +194,8 @@ public class RcmController implements Initializable {
private void smash(){
statusLbl.setText("");
if (MediatorControl.getInstance().getTransferActive()) {
ServiceWindow.getErrorNotification(rb.getString("windowTitleError"), rb.getString("windowBodyPleaseFinishTransfersFirst"));
ServiceWindow.getErrorNotification(rb.getString("windowTitleError"),
rb.getString("windowBodyPleaseStopOtherProcessFirst"));
return;
}

View File

@ -21,7 +21,7 @@ package nsusbloader.ModelControllers;
import nsusbloader.NSLDataTypes.EModule;
import nsusbloader.NSLMain;
public class Log {
public abstract class Log {
private Log(){}

View File

@ -35,7 +35,7 @@ public class LogPrinterGui implements ILogPrinter {
private final HashMap<String, EFileStatus> statusMap; // BlockingQueue for literally one object. TODO: read more books ; replace to hashMap
private final AtomicBoolean oneLinerStatus;
public LogPrinterGui(EModule whoIsAsking){
LogPrinterGui(EModule whoIsAsking){
this.msgQueue = new LinkedBlockingQueue<>();
this.progressQueue = new LinkedBlockingQueue<>();
this.statusMap = new HashMap<>();

View File

@ -18,7 +18,6 @@
*/
package nsusbloader.Utilities.nxdumptool;
import nsusbloader.COM.INSTask;
import nsusbloader.COM.USB.UsbConnect;
import nsusbloader.ModelControllers.ILogPrinter;
import nsusbloader.ModelControllers.Log;
@ -26,12 +25,10 @@ import nsusbloader.NSLDataTypes.EModule;
import nsusbloader.NSLDataTypes.EMsgType;
import org.usb4java.DeviceHandle;
public class NxdtTask implements INSTask {
public class NxdtTask implements Runnable {
private ILogPrinter logPrinter;
private String saveToLocation;
private volatile boolean cancel;
private final ILogPrinter logPrinter;
private final String saveToLocation;
public NxdtTask(String saveToLocation){
this.logPrinter = Log.getPrinter(EModule.NXDT);
@ -52,23 +49,12 @@ public class NxdtTask implements INSTask {
DeviceHandle handler = usbConnect.getNsHandler();
new NxdtUsbAbi1(handler, this, logPrinter, saveToLocation);
new NxdtUsbAbi1(handler, logPrinter, saveToLocation);
logPrinter.print(".:: Complete ::.", EMsgType.PASS);
usbConnect.close();
logPrinter.updateOneLinerStatus(true);
logPrinter.close();
return;
}
@Override
public void cancel() {
cancel = true;
}
@Override
public boolean isCancelled() {
return cancel;
}
}

View File

@ -18,7 +18,6 @@
*/
package nsusbloader.Utilities.nxdumptool;
import nsusbloader.COM.INSTask;
import nsusbloader.COM.USB.UsbErrorCodes;
import nsusbloader.ModelControllers.ILogPrinter;
import nsusbloader.NSLDataTypes.EMsgType;
@ -35,7 +34,6 @@ import java.util.Arrays;
class NxdtUsbAbi1 {
private ILogPrinter logPrinter;
private DeviceHandle handlerNS;
private INSTask task;
private String saveToPath;
private boolean isWindows;
@ -79,12 +77,10 @@ class NxdtUsbAbi1 {
0x00, 0x00, 0x00, 0x00 };
public NxdtUsbAbi1(DeviceHandle handler,
INSTask task,
ILogPrinter logPrinter,
String saveToPath
){
this.handlerNS = handler;
this.task = task;
this.logPrinter = logPrinter;
this.isWindows = System.getProperty("os.name").toLowerCase().contains("windows");
@ -310,7 +306,7 @@ class NxdtUsbAbi1 {
writeBuffer.put(message);
IntBuffer writeBufTransferred = IntBuffer.allocate(1);
if ( task.isCancelled())
if ( Thread.interrupted() )
throw new InterruptedException("Execution interrupted");
int result = LibUsb.bulkTransfer(handlerNS, (byte) 0x01, writeBuffer, writeBufTransferred, 5050);
@ -339,7 +335,7 @@ class NxdtUsbAbi1 {
// We can limit it to 32 bytes, but there is a non-zero chance to got OVERFLOW from libusb.
IntBuffer readBufTransferred = IntBuffer.allocate(1);
int result;
while (! task.isCancelled()) {
while (! Thread.interrupted()) {
result = LibUsb.bulkTransfer(handlerNS, (byte) 0x81, readBuffer, readBufTransferred, 1000); // last one is TIMEOUT. 0 stands for unlimited. Endpoint IN = 0x81
switch (result) {
@ -368,7 +364,7 @@ class NxdtUsbAbi1 {
IntBuffer readBufTransferred = IntBuffer.allocate(1);
int result;
int countDown = 0;
while (! task.isCancelled() && countDown < 5) {
while (! Thread.interrupted() && countDown < 5) {
result = LibUsb.bulkTransfer(handlerNS, (byte) 0x81, readBuffer, readBufTransferred, 1000);
switch (result) {

View File

@ -18,7 +18,6 @@
*/
package nsusbloader.cli;
import nsusbloader.COM.INSTask;
import nsusbloader.COM.USB.UsbCommunications;
import nsusbloader.Controllers.SettingsController;
@ -125,7 +124,7 @@ public class GoldLeaf {
}
public void runGoldLeafBackend() throws InterruptedException {
INSTask task = new UsbCommunications(filesList,
Runnable task = new UsbCommunications(filesList,
"GoldLeaf"+goldLeafVersion,
filterForNsp);
Thread thread = new Thread(task);

View File

@ -18,7 +18,6 @@
*/
package nsusbloader.cli;
import nsusbloader.COM.INSTask;
import nsusbloader.COM.USB.UsbCommunications;
import java.io.File;
@ -61,7 +60,7 @@ public class TinfoilUsb {
}
private void runTinfoilBackend() throws InterruptedException{
INSTask task = new UsbCommunications(filesList, "TinFoil", false);
Runnable task = new UsbCommunications(filesList, "TinFoil", false);
Thread thread = new Thread(task);
thread.start();
thread.join();

View File

@ -67,4 +67,5 @@ windowBodyDownloadDrivers=Downloading drivers (libusbK v3.0.7.0)...
btn_Cancel=Cancel
btn_Close=Close
tab2_Cb_GlVersion=GoldLeaf version
tab2_Cb_GLshowNspOnly=Show only *.nsp in GoldLeaf.
tab2_Cb_GLshowNspOnly=Show only *.nsp in GoldLeaf.
windowBodyPleaseStopOtherProcessFirst=Please stop other active process before continuing.

View File

@ -1,13 +1,13 @@
btn_OpenFile=Selecionar arquivos
btn_Upload=Upar para o switch
tab3_Txt_EnteredAsMsg1=Voc\u00EA logou como:
tab3_Txt_EnteredAsMsg2=Voc\u00EA precisa de permiss\u00F5es root ou ter configurado as regras 'udev' deste usu\u00E1rio para evitar poss\u00EDveis problemas.
tab3_Txt_EnteredAsMsg2=Voc\u00EA precisa de permiss\u00F5es root ou ter configurado as regras 'udev' deste usu\u00E1rio para evitar poss\u00EDveis problemas
tab3_Txt_FilesToUploadTitle=Arquivos para upar:
tab3_Txt_GreetingsMessage=Bem vindo ao NS-USBloader
tab3_Txt_NoFolderOrFileSelected=Nenhum arquivo selecionado. Nada para upar.
tab3_Txt_NoFolderOrFileSelected=Nenhum arquivo selecionado. Nada para upar
windowBodyConfirmExit=Transfer\u00EAncia de dados em progresso: Fechar ir\u00E1 interromper.\nN\u00E3o \u00E9 aconselh\u00E1vel.\nInterromper processo e sair?
windowTitleConfirmExit=N\u00E3o, n\u00E3o fa\u00E7a isso!
btn_Stop=Imterromper!
btn_Stop=Interromper!
tab3_Txt_GreetingsMessage2=--\n\
Source: https://github.com/developersu/ns-usbloader/\n\
Site: https://developersu.blogspot.com/search/label/NS-USBloader\n\
@ -15,42 +15,43 @@ Dmitry Isaenko [developer.su]
tab1_table_Lbl_Status=Status
tab1_table_Lbl_FileName=Nome do arquivo
tab1_table_Lbl_Size=Tamanho
tab1_table_Lbl_Upload=Upar
tab1_table_Lbl_Upload=Upar?
tab1_table_contextMenu_Btn_BtnDelete=Remover
tab1_table_contextMenu_Btn_DeleteAll=Remover todos
tab2_Lbl_HostIP=Host IP
tab1_Lbl_NSIP=NS IP:
tab2_Cb_ValidateNSHostName=Sempre validar o IP do switch.
tab2_Cb_ValidateNSHostName=Sempre validar o IP do switch
windowBodyBadIp=Tem certeza que preencheu o endere\u00E7o IP corretamente?
windowTitleBadIp=Endere\u00E7o IP do switch provavelmente incorreto.
windowTitleBadIp=Endere\u00E7o IP do switch provavelmente incorreto
tab2_Cb_ExpertMode=Modo Expert (Configura\u00E7\u00E3o NET)
tab2_Lbl_HostPort=porta
tab2_Cb_AutoDetectIp=Auto-detectar IP
tab2_Cb_RandSelectPort=Usar porta aleat\u00F3ria
tab2_Cb_DontServeRequests=n\u00E3o aceitar solicita\u00E7\u00F5es
tab2_Lbl_DontServeRequestsDesc=Se selecionado, Este computador n\u00E3o ir\u00E1 aceitar solicita\u00E7\u00F5es de arquivos .nsp vindos, atrav\u00E9s da rede, do seu switch. Isso ir\u00E1 usar as defini\u00E7\u00F5es do host para informar ao tinfoil onde qual caminho procurar pelos arquivos.
tab2_Lbl_DontServeRequestsDesc=Se selecionado, Este computador n\u00E3o ir\u00E1 aceitar solicita\u00E7\u00F5es de arquivos .nsp vindos, atrav\u00E9s da rede, do seu switch. Isso ir\u00E1 usar as defini\u00E7\u00F5es do host para informar ao tinfoil onde qual caminho procurar pelos arquivos
tab2_Lbl_HostExtra=extra
windowTitleErrorPort=Porta configurada incorretamente!
windowBodyErrorPort=Porta n\u00E3o pode ser 0 or maior que 65535.
tab2_Cb_AutoCheckForUpdates=Auto checar por atualiza\u00E7\u00F5es.
windowTitleNewVersionAval=Nova vers\u00E3o dispon\u00EDvel.
windowTitleNewVersionNOTAval=Nao h\u00E1 novas vers\u00F5es.
windowTitleNewVersionUnknown=Nao conseguimos checar por novas atualiza\u00E7\u00F5es.
windowBodyErrorPort=Porta n\u00E3o pode ser 0 or maior que 65535
tab2_Cb_AutoCheckForUpdates=Auto checar por atualiza\u00E7\u00F5es
windowTitleNewVersionAval=Nova vers\u00E3o dispon\u00EDvel
windowTitleNewVersionNOTAval=Nao h\u00E1 novas vers\u00F5es
windowTitleNewVersionUnknown=Nao conseguimos checar por novas atualiza\u00E7\u00F5es
windowBodyNewVersionUnknown=Algo deu errado...\nProblemas de conex\u00E3o ou com a p\u00E1gina do github, talvez?
windowBodyNewVersionNOTAval=Voc\u00EA est\u00E1 na \u00FAltima vers\u00E3o!
tab2_Cb_AllowXciNszXcz=permitir arquivos XCI / NSZ / XCZ para o tinfoil
tab2_Lbl_AllowXciNszXczDesc=Usado por aplica\u00E7\u00F5es que suportam XCI/NSZ/XCZ e utiliza protocolos de transfer\u00EAncia do Tinfoil. N\u00E3o mude o que n\u00E3o tem certeza. Ative para uso com o Awoo-Installer.
tab2_Lbl_AllowXciNszXczDesc=Usado por aplica\u00E7\u00F5es que suportam XCI/NSZ/XCZ e utiliza protocolos de transfer\u00EAncia do Tinfoil. N\u00E3o mude o que n\u00E3o tem certeza. Ative para uso com o Awoo-Installer
tab2_Lbl_Language=Idioma
windowBodyRestartToApplyLang=Por favor, reinicie para aplicar as modifica\u00E7\u00F5es.
tab2_Cb_GLshowNspOnly=Mostrar apenas arquivos .nsp no GoldLeaf.
windowBodyRestartToApplyLang=Por favor, reinicie para aplicar as modifica\u00E7\u00F5es
tab2_Cb_GLshowNspOnly=Mostrar apenas arquivos .nsp no GoldLeaf
tab2_Cb_GlVersion=Vers\u00E3o do GoldLeaf.
btn_OpenSplitFile=Selecionar arquivos .nsp fragmentados(splitted)
tab2_Lbl_ApplicationSettings=Configura\u00E7\u00F5es principais
tabSplMrg_Lbl_SplitNMergeTitle=Ferramentas para fragmentar e juntar(merge) arquivos.
tabSplMrg_Lbl_SplitNMergeTitle=Ferramentas para fragmentar e mesclar(merge) arquivos
tabSplMrg_RadioBtn_Split=Fragmentar(split)
tabSplMrg_RadioBtn_Merge=Juntar(merge)
tabSplMrg_RadioBtn_Merge=Mesclar(merge)
tabSplMrg_Txt_File=File:
tabSplMrg_Txt_Folder=Arquivo fragmentado (pasta):
tabSplMrg_Btn_SelectFile=Selecionar arquivo.
tabSplMrg_Btn_SelectFile=Selecionar arquivo
tabSplMrg_Btn_SelectFolder=Selecionar pasta
tabSplMrg_Lbl_SaveToLocation=Salvar em:
tabSplMrg_Btn_ChangeSaveToLocation=Trocar
@ -61,6 +62,9 @@ done_txt=Feito!
failure_txt=Falhou
btn_Select=Selecionar
btn_InjectPayloader=Injetar payload
tabNXDT_Btn_Start=Iniciar!
tab2_Btn_InstallDrivers=Baixar e instalar drivers
windowTitleDownloadDrivers=Baixar e Instalar Drivers
windowBodyDownloadDrivers=Baixando drivers (libusbK v3.0.7.0)...
btn_Cancel=Cancelar
tab2_Cb_GlVersion=Vers\u00E3o do GoldLeaf.
btn_Close=Fechar

View File

@ -68,4 +68,5 @@ windowBodyDownloadDrivers=\u0421\u043A\u0430\u0447\u0438\u0432\u0430\u0435\u043C
btn_Cancel=\u041E\u0442\u043C\u0435\u043D\u0438\u0442\u044C
btn_Close=\u0417\u0430\u043A\u0440\u044B\u0442\u044C
tab2_Cb_GlVersion=\u0412\u0435\u0440\u0441\u0438\u044F GoldLeaf
windowBodyPleaseStopOtherProcessFirst=\u041F\u043E\u0436\u0430\u043B\u0443\u0439\u0441\u0442\u0430, \u043E\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u0435 \u0434\u0440\u0443\u0433\u043E\u0439 \u0430\u043A\u0442\u0438\u0432\u043D\u044B\u0439 \u043F\u0440\u043E\u0446\u0435\u0441\u0441 \u043F\u0435\u0440\u0435\u0434 \u0442\u0435\u043C, \u043A\u0430\u043A \u043F\u0440\u043E\u0434\u043E\u043B\u0436\u0438\u0442\u044C.

View File

@ -68,3 +68,4 @@ windowBodyDownloadDrivers=\u0417\u0430\u0432\u0430\u043D\u0442\u0430\u0436\u0443
btn_Cancel=\u0412\u0456\u0434\u043C\u0456\u043D\u0438\u0442\u0438
btn_Close=\u0417\u0430\u043A\u0440\u0438\u0442\u0438
tab2_Cb_GlVersion=\u0412\u0435\u0440\u0441\u0456\u044F GoldLeaf
windowBodyPleaseStopOtherProcessFirst=\u0411\u0443\u0434\u044C \u043B\u0430\u0441\u043A\u0430, \u0437\u0443\u043F\u0438\u043D\u0456\u0442\u044C \u0456\u043D\u0448\u0438\u0439 \u0430\u043A\u0442\u0438\u0432\u043D\u0438\u0439 \u043F\u0440\u043E\u0446\u0435\u0441 \u043F\u0435\u0440\u0448 \u043D\u0456\u0436 \u043F\u0440\u043E\u0434\u043E\u0432\u0436\u0438\u0442\u0438.