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.
This commit is contained in:
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; package nsusbloader.COM.NET;
import nsusbloader.COM.INSTask;
import nsusbloader.ModelControllers.ILogPrinter; import nsusbloader.ModelControllers.ILogPrinter;
import nsusbloader.NSLDataTypes.EFileStatus; import nsusbloader.NSLDataTypes.EFileStatus;
import nsusbloader.ModelControllers.Log; import nsusbloader.ModelControllers.Log;
@ -32,305 +31,124 @@ import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.*; 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 final String switchIP;
private int hostPort; private final static int SWITCH_PORT = 2000;
private String extras; 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 final ServerSocket serverSocket;
private HashMap<String, Long> nspFileSizes; private Socket clientSocket;
private ServerSocket serverSocket; private final boolean isValid;
private boolean isValid;
private boolean doNotServeRequests;
private OutputStream currSockOS; private OutputStream currSockOS;
private PrintWriter currSockPW; private PrintWriter currSockPW;
private volatile boolean cancel;
/** /**
* Simple constructor that everybody uses * Simple constructor that everybody uses
* */ * */
public NETCommunications(List<File> filesList, public NETCommunications(List<File> filesList,
String switchIP, String switchIP,
boolean doNotServeRequests, boolean doNotServe,
String hostIPaddr, String hostIP,
String hostPortNum, String hostPortNum,
String extras) { String extras)
this.doNotServeRequests = doNotServeRequests; {
if (doNotServeRequests) this.doNotServe = doNotServe;
if (doNotServe)
this.extras = extras; this.extras = extras;
else else
this.extras = ""; this.extras = "";
this.switchIP = switchIP; this.switchIP = switchIP;
this.logPrinter = Log.getPrinter(EModule.USB_NET_TRANSFERS); 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--){ NetworkSetupValidator validator =
if (subFiles[i].length() < subFiles[i-1].length()) { new NetworkSetupValidator(filesList, doNotServe, hostIP, hostPortNum, logPrinter);
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);
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());
}
this.hostIP = validator.getHostIP();
this.hostPort = validator.getHostPort();
this.files = validator.getFiles();
this.serverSocket = validator.getServerSocket();
this.isValid = validator.isValid();
// Resolve IP if (! isValid)
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); 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 @Override
public void run() { public void run() {
if (! isValid || Thread.interrupted() )
if (!isValid | isCancelled())
return; return;
logPrinter.print("\tStart chain", EMsgType.INFO); logPrinter.print("\tStart chain", EMsgType.INFO);
// Create string that we'll send to TF and which initiates chain
StringBuilder myStrBuilder;
myStrBuilder = new StringBuilder(); final String handshakeContent = buildHandshakeContent();
for (String fileNameEncoded : nspMap.keySet()) {
myStrBuilder.append(hostIP);
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[] handshakeCommand = handshakeContent.getBytes(StandardCharsets.UTF_8);
byte[] nspListSize = ByteBuffer.allocate(Integer.BYTES).putInt(nspListNames.length).array(); // defining order byte[] handshakeCommandSize = ByteBuffer.allocate(Integer.BYTES).putInt(handshakeCommand.length).array();
try { if (sendHandshake(handshakeCommandSize, handshakeCommand))
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);
return; return;
}
// Check if we should serve requests // Check if we should serve requests
if (this.doNotServeRequests){ if (this.doNotServe){
logPrinter.print("NET: List of files transferred. Replies won't be served.", EMsgType.PASS); logPrinter.print("List of files transferred. Replies won't be served.", EMsgType.PASS);
close(EFileStatus.UNKNOWN); close(EFileStatus.UNKNOWN);
return; 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 // Go transfer
Socket clientSocket; serveRequestsLoop();
work_routine: }
while (true){ /**
* 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 { 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(); clientSocket = serverSocket.accept();
BufferedReader br = new BufferedReader( BufferedReader br = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()) new InputStreamReader(clientSocket.getInputStream())
@ -345,8 +163,7 @@ public class NETCommunications implements INSTask { // todo: rewrite
while ((line = br.readLine()) != null) { while ((line = br.readLine()) != null) {
//System.out.println(line); // Debug //System.out.println(line); // Debug
if (line.trim().isEmpty()) { // If TCP packet is ended if (line.trim().isEmpty()) { // If TCP packet is ended
if (handleRequest(tcpPacket)) // Proceed required things handleRequest(tcpPacket); // Proceed required things
break work_routine;
tcpPacket.clear(); // Clear data and wait for next TCP packet tcpPacket.clear(); // Clear data and wait for next TCP packet
} }
else else
@ -356,206 +173,219 @@ public class NETCommunications implements INSTask { // todo: rewrite
// and reopen client sock // and reopen client sock
clientSocket.close(); clientSocket.close();
} }
catch (IOException ioe){ // If server socket closed, then client socket also closed.
break;
} }
} catch (Exception e){
if ( ! isCancelled() ) if (Thread.interrupted())
logPrinter.print("Interrupted by user.", EMsgType.INFO);
else
logPrinter.print(e.getMessage(), EMsgType.INFO);
close(EFileStatus.UNKNOWN); close(EFileStatus.UNKNOWN);
return;
} }
}
// 200 206 400 (inv range) 404 416 (Range Not Satisfiable )
/** /**
* Handle requests * Handle requests
* @return true if failed * @return true if failed
* */ * */
private boolean handleRequest(LinkedList<String> packet){ private void handleRequest(LinkedList<String> packet) throws Exception{
//private boolean handleRequest(LinkedList<String> packet, OutputStreamWriter pw){
File requestedFile; File requestedFile;
String reqFileName = packet.get(0).replaceAll("(^[A-z\\s]+/)|(\\s+?.*$)", ""); String reqFileName = packet.get(0).replaceAll("(^[A-z\\s]+/)|(\\s+?.*$)", "");
if (! nspFileSizes.containsKey(reqFileName)){ if (! files.containsKey(reqFileName)){
currSockPW.write(NETPacket.getCode404()); writeToSocket(NETPacket.getCode404());
currSockPW.flush(); logPrinter.print("File "+reqFileName+" doesn't exists or have 0 size. Returning 404", EMsgType.FAIL);
logPrinter.print("NET: File "+reqFileName+" doesn't exists or have 0 size. Returning 404", EMsgType.FAIL); return;
return true;
} }
long reqFileSize = nspFileSizes.get(reqFileName); long reqFileSize = files.get(reqFileName).getSize();
requestedFile = nspMap.get(reqFileName); 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 if (! requestedFile.exists() || reqFileSize == 0){ // well.. tell 404 if file exists with 0 length is against standard, but saves time
currSockPW.write(NETPacket.getCode404()); writeToSocket(NETPacket.getCode404());
currSockPW.flush(); logPrinter.print("File "+requestedFile.getName()+" doesn't exists or have 0 size. Returning 404", EMsgType.FAIL);
logPrinter.print("NET: File "+requestedFile.getName()+" doesn't exists or have 0 size. Returning 404", EMsgType.FAIL);
logPrinter.update(requestedFile, EFileStatus.FAILED); logPrinter.update(requestedFile, EFileStatus.FAILED);
return true; return;
} }
if (packet.get(0).startsWith("HEAD")){ if (packet.get(0).startsWith("HEAD")){
currSockPW.write(NETPacket.getCode200(reqFileSize)); writeToSocket(NETPacket.getCode200(reqFileSize));
currSockPW.flush(); logPrinter.print("Replying for requested file: "+requestedFile.getName(), EMsgType.INFO);
logPrinter.print("NET: Replying for requested file: "+requestedFile.getName(), EMsgType.INFO); return;
return false;
} }
if (packet.get(0).startsWith("GET")) { if (packet.get(0).startsWith("GET")) {
for (String line: packet) { for (String line: packet) {
if (line.toLowerCase().startsWith("range")) { //todo: fix if (! line.toLowerCase().startsWith("range")) //todo: fix
try { continue;
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;
} parseGETrange(requestedFile, reqFileName, reqFileSize, line);
else if (!rangeStr[0].isEmpty()) { // If only START defined: Read all return;
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;
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){ catch (NumberFormatException nfe){
currSockPW.write(NETPacket.getCode400()); 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(); 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;
}
}
}
}
return false;
} }
/** /**
* Send files. * Send files.
* */ * */
private boolean writeToSocket(String fileName, long start, long end){ private void writeToSocket(String fileName, long start, long end) throws Exception{
File reqFile = nspMap.get(fileName); File file = files.get(fileName).getFile();
// Inform
logPrinter.print("NET: Responding to requested range: "+start+"-"+end, EMsgType.INFO); logPrinter.print("Reply to range: "+start+"-"+end, EMsgType.INFO);
// Reply
currSockPW.write(NETPacket.getCode206(nspFileSizes.get(fileName), start, end)); writeToSocket(NETPacket.getCode206(files.get(fileName).getSize(), start, end));
currSockPW.flush(); try{
// Prepare transfer 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; long count = end - start + 1;
int readPice = 8388608; // = 8Mb int readPice = 8388608;
byte[] byteBuf; byte[] byteBuf;
long currentOffset = 0; long currentOffset = 0;
try{ NSSplitReader nsr = new NSSplitReader(file, start);
//================================= SPLIT FILE ====================================
if (reqFile.isDirectory()){
NSSplitReader nsr = new NSSplitReader(reqFile, start);
while (currentOffset < count){ while (currentOffset < count){
if (isCancelled())
return true;
if ((currentOffset + readPice) >= count){ if ((currentOffset + readPice) >= count){
readPice = Math.toIntExact(count - currentOffset); readPice = Math.toIntExact(count - currentOffset);
} }
byteBuf = new byte[readPice]; byteBuf = new byte[readPice];
if (nsr.read(byteBuf) != readPice){ if (nsr.read(byteBuf) != readPice)
logPrinter.print("NET: Reading of file stream suddenly ended.", EMsgType.FAIL); throw new IOException("File stream suddenly ended.");
return true;
}
currSockOS.write(byteBuf); currSockOS.write(byteBuf);
//-------/
logPrinter.updateProgress((currentOffset+readPice)/(count/100.0) / 100.0); logPrinter.updateProgress((currentOffset+readPice)/(count/100.0) / 100.0);
//-------/
currentOffset += readPice; currentOffset += readPice;
} }
currSockOS.flush(); // TODO: check if this really needed. currSockOS.flush(); // TODO: check if this really needed.
nsr.close(); nsr.close();
} }
//================================= REGULAR FILE ==================================== private void handleRegularFile(File file, long start, long end) throws Exception{
else { long count = end - start + 1;
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(reqFile));
if (bis.skip(start) != start){ int readPice = 8388608;
logPrinter.print("NET: Unable to skip requested range.", EMsgType.FAIL); byte[] byteBuf;
logPrinter.update(reqFile, EFileStatus.FAILED); long currentOffset = 0;
return true;
} BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
if (bis.skip(start) != start)
throw new IOException("Unable to skip requested range.");
while (currentOffset < count){ while (currentOffset < count){
if (isCancelled())
return true;
if ((currentOffset + readPice) >= count){ if ((currentOffset + readPice) >= count){
readPice = Math.toIntExact(count - currentOffset); readPice = Math.toIntExact(count - currentOffset);
} }
byteBuf = new byte[readPice]; byteBuf = new byte[readPice];
if (bis.read(byteBuf) != readPice){ if (bis.read(byteBuf) != readPice){
logPrinter.print("NET: Reading of file stream suddenly ended.", EMsgType.FAIL); throw new IOException("File stream suddenly ended.");
return true;
} }
currSockOS.write(byteBuf); currSockOS.write(byteBuf);
//-------/
logPrinter.updateProgress((currentOffset+readPice)/(count/100.0) / 100.0); logPrinter.updateProgress((currentOffset+readPice)/(count/100.0) / 100.0);
//-------/
currentOffset += readPice; currentOffset += readPice;
} }
currSockOS.flush(); // TODO: check if this really needed. currSockOS.flush(); // TODO: check if this really needed.
bis.close(); bis.close();
} }
//-------/
logPrinter.updateProgress(1.0); public ServerSocket getServerSocket(){
//-------/ return serverSocket;
} }
catch (IOException | NullPointerException e){ public Socket getClientSocket(){
logPrinter.print("NET: File transmission failed. Returned:\n\t"+e.getMessage(), EMsgType.FAIL); return clientSocket;
logPrinter.update(reqFile, EFileStatus.FAILED);
return true;
}
return false;
} }
/** /**
* Close when done * Close when done
* */ * */
private void close(EFileStatus status){ private void close(EFileStatus status){
if (isCancelled())
logPrinter.print("NET: Interrupted by user.", EMsgType.INFO);
try { try {
if (serverSocket != null) { if (serverSocket != null && ! serverSocket.isClosed()) {
serverSocket.close(); serverSocket.close();
logPrinter.print("NET: Closing server socket.", EMsgType.PASS); logPrinter.print("Closing server socket.", EMsgType.PASS);
} }
} }
catch (IOException ioe){ catch (IOException ioe){
logPrinter.print("NET: Closing server socket failed. Sometimes it's not an issue.", EMsgType.WARNING); logPrinter.print("Closing server socket failed. Sometimes it's not an issue.", EMsgType.WARNING);
}
if (status != null) {
logPrinter.update(nspMap, status);
} }
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.print("\tEnd chain", EMsgType.INFO);
logPrinter.close(); 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 You should have received a copy of the GNU General Public License
along with NS-USBloader. If not, see <https://www.gnu.org/licenses/>. along with NS-USBloader. If not, see <https://www.gnu.org/licenses/>.
*/ */
package nsusbloader.COM; package nsusbloader.COM.NET;
public interface INSTask extends Runnable { import java.io.File;
void cancel();
boolean isCancelled(); 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; package nsusbloader.COM.USB;
import nsusbloader.COM.INSTask;
import nsusbloader.ModelControllers.ILogPrinter; import nsusbloader.ModelControllers.ILogPrinter;
import nsusbloader.NSLDataTypes.EFileStatus; import nsusbloader.NSLDataTypes.EFileStatus;
import nsusbloader.NSLDataTypes.EMsgType; import nsusbloader.NSLDataTypes.EMsgType;
@ -53,7 +52,7 @@ public class GoldLeaf_05 extends TransferModule {
private RandomAccessFile raf; // NSP File private RandomAccessFile raf; // NSP File
private NSSplitReader nsr; // It'a also 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); super(handler, nspMap, task, logPrinter);
status = EFileStatus.FAILED; status = EFileStatus.FAILED;
@ -335,7 +334,7 @@ public class GoldLeaf_05 extends TransferModule {
IntBuffer writeBufTransferred = IntBuffer.allocate(1); IntBuffer writeBufTransferred = IntBuffer.allocate(1);
int result; 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 result = LibUsb.bulkTransfer(handlerNS, (byte) 0x01, writeBuffer, writeBufTransferred, 1000); // last one is TIMEOUT. 0 stands for unlimited. Endpoint OUT = 0x01
switch (result){ switch (result){
@ -368,7 +367,7 @@ public class GoldLeaf_05 extends TransferModule {
IntBuffer readBufTransferred = IntBuffer.allocate(1); IntBuffer readBufTransferred = IntBuffer.allocate(1);
int result; 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 result = LibUsb.bulkTransfer(handlerNS, (byte) 0x81, readBuffer, readBufTransferred, 1000); // last one is TIMEOUT. 0 stands for unlimited. Endpoint IN = 0x81
switch (result) { switch (result) {

View file

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

View file

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

View file

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

View file

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

View file

@ -18,7 +18,6 @@
*/ */
package nsusbloader.COM.USB; package nsusbloader.COM.USB;
import nsusbloader.COM.INSTask;
import nsusbloader.ModelControllers.ILogPrinter; import nsusbloader.ModelControllers.ILogPrinter;
import nsusbloader.ModelControllers.Log; import nsusbloader.ModelControllers.Log;
import nsusbloader.NSLDataTypes.EFileStatus; import nsusbloader.NSLDataTypes.EFileStatus;
@ -31,14 +30,12 @@ import java.io.*;
import java.util.*; import java.util.*;
// TODO: add filter option to show only NSP files // TODO: add filter option to show only NSP files
public class UsbCommunications implements INSTask { public class UsbCommunications implements Runnable {
private ILogPrinter logPrinter; private final ILogPrinter logPrinter;
private LinkedHashMap<String, File> nspMap; private final LinkedHashMap<String, File> nspMap;
private String protocol; private final String protocol;
private boolean nspFilterForGl; private final boolean nspFilterForGl;
private volatile boolean cancel;
public UsbCommunications(List<File> nspList, String protocol, boolean filterNspFilesOnlyForGl){ public UsbCommunications(List<File> nspList, String protocol, boolean filterNspFilesOnlyForGl){
this.protocol = protocol; this.protocol = protocol;
@ -82,8 +79,6 @@ public class UsbCommunications implements INSTask {
usbConnect.close(); usbConnect.close();
close(module.getStatus()); close(module.getStatus());
return;
} }
/** /**
@ -94,14 +89,4 @@ public class UsbCommunications implements INSTask {
logPrinter.print("\tEnd", EMsgType.INFO); logPrinter.print("\tEnd", EMsgType.INFO);
logPrinter.close(); 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.DirectoryChooser;
import javafx.stage.FileChooser; import javafx.stage.FileChooser;
import nsusbloader.AppPreferences; import nsusbloader.AppPreferences;
import nsusbloader.COM.INSTask;
import nsusbloader.COM.NET.NETCommunications; import nsusbloader.COM.NET.NETCommunications;
import nsusbloader.COM.USB.UsbCommunications; import nsusbloader.COM.USB.UsbCommunications;
import nsusbloader.MediatorControl; import nsusbloader.MediatorControl;
@ -63,7 +62,7 @@ public class FrontController implements Initializable {
private String previouslyOpenedPath; private String previouslyOpenedPath;
private Region btnUpStopImage; private Region btnUpStopImage;
private ResourceBundle resourceBundle; private ResourceBundle resourceBundle;
private INSTask usbNetCommunications; private Runnable usbNetCommunications;
private Thread workThread; private Thread workThread;
@Override @Override
@ -265,8 +264,11 @@ public class FrontController implements Initializable {
SettingsController settings = MediatorControl.getInstance().getContoller().getSettingsCtrlr(); SettingsController settings = MediatorControl.getInstance().getContoller().getSettingsCtrlr();
// If USB selected // If USB selected
if (getSelectedProtocol().equals("GoldLeaf") || ( getSelectedProtocol().equals("TinFoil") && getSelectedNetUsb().equals("USB") ) ){ if (getSelectedProtocol().equals("GoldLeaf") ){
usbNetCommunications = new UsbCommunications(nspToUpload, getSelectedProtocol() + settings.getGlVer(), settings.getNSPFileFilterForGL()); 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 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])$"; 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(){ private void stopBtnAction(){
if (workThread != null && workThread.isAlive()){ 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.scene.layout.Region;
import javafx.stage.DirectoryChooser; import javafx.stage.DirectoryChooser;
import nsusbloader.AppPreferences; import nsusbloader.AppPreferences;
import nsusbloader.COM.INSTask;
import nsusbloader.MediatorControl; import nsusbloader.MediatorControl;
import nsusbloader.NSLDataTypes.EModule; import nsusbloader.NSLDataTypes.EModule;
import nsusbloader.Utilities.nxdumptool.NxdtTask; import nsusbloader.Utilities.nxdumptool.NxdtTask;
@ -45,7 +44,6 @@ public class NxdtController implements Initializable {
private Region btnDumpStopImage; private Region btnDumpStopImage;
private INSTask NxdtTask;
private Thread workThread; private Thread workThread;
@Override @Override
@ -83,7 +81,7 @@ public class NxdtController implements Initializable {
if ((workThread == null || ! workThread.isAlive())){ if ((workThread == null || ! workThread.isAlive())){
MediatorControl.getInstance().getContoller().logArea.clear(); MediatorControl.getInstance().getContoller().logArea.clear();
NxdtTask = new NxdtTask(saveToLocationLbl.getText()); Runnable NxdtTask = new NxdtTask(saveToLocationLbl.getText());
workThread = new Thread(NxdtTask); workThread = new Thread(NxdtTask);
workThread.setDaemon(true); workThread.setDaemon(true);
workThread.start(); workThread.start();
@ -95,7 +93,7 @@ public class NxdtController implements Initializable {
* */ * */
private void stopBtnAction(){ private void stopBtnAction(){
if (workThread != null && workThread.isAlive()){ if (workThread != null && workThread.isAlive()){
NxdtTask.cancel(); workThread.interrupt();
} }
} }

View file

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

View file

@ -21,7 +21,7 @@ package nsusbloader.ModelControllers;
import nsusbloader.NSLDataTypes.EModule; import nsusbloader.NSLDataTypes.EModule;
import nsusbloader.NSLMain; import nsusbloader.NSLMain;
public class Log { public abstract class Log {
private 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 HashMap<String, EFileStatus> statusMap; // BlockingQueue for literally one object. TODO: read more books ; replace to hashMap
private final AtomicBoolean oneLinerStatus; private final AtomicBoolean oneLinerStatus;
public LogPrinterGui(EModule whoIsAsking){ LogPrinterGui(EModule whoIsAsking){
this.msgQueue = new LinkedBlockingQueue<>(); this.msgQueue = new LinkedBlockingQueue<>();
this.progressQueue = new LinkedBlockingQueue<>(); this.progressQueue = new LinkedBlockingQueue<>();
this.statusMap = new HashMap<>(); this.statusMap = new HashMap<>();

View file

@ -18,7 +18,6 @@
*/ */
package nsusbloader.Utilities.nxdumptool; package nsusbloader.Utilities.nxdumptool;
import nsusbloader.COM.INSTask;
import nsusbloader.COM.USB.UsbConnect; import nsusbloader.COM.USB.UsbConnect;
import nsusbloader.ModelControllers.ILogPrinter; import nsusbloader.ModelControllers.ILogPrinter;
import nsusbloader.ModelControllers.Log; import nsusbloader.ModelControllers.Log;
@ -26,12 +25,10 @@ import nsusbloader.NSLDataTypes.EModule;
import nsusbloader.NSLDataTypes.EMsgType; import nsusbloader.NSLDataTypes.EMsgType;
import org.usb4java.DeviceHandle; import org.usb4java.DeviceHandle;
public class NxdtTask implements INSTask { public class NxdtTask implements Runnable {
private ILogPrinter logPrinter; private final ILogPrinter logPrinter;
private String saveToLocation; private final String saveToLocation;
private volatile boolean cancel;
public NxdtTask(String saveToLocation){ public NxdtTask(String saveToLocation){
this.logPrinter = Log.getPrinter(EModule.NXDT); this.logPrinter = Log.getPrinter(EModule.NXDT);
@ -52,23 +49,12 @@ public class NxdtTask implements INSTask {
DeviceHandle handler = usbConnect.getNsHandler(); DeviceHandle handler = usbConnect.getNsHandler();
new NxdtUsbAbi1(handler, this, logPrinter, saveToLocation); new NxdtUsbAbi1(handler, logPrinter, saveToLocation);
logPrinter.print(".:: Complete ::.", EMsgType.PASS); logPrinter.print(".:: Complete ::.", EMsgType.PASS);
usbConnect.close(); usbConnect.close();
logPrinter.updateOneLinerStatus(true); logPrinter.updateOneLinerStatus(true);
logPrinter.close(); 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; package nsusbloader.Utilities.nxdumptool;
import nsusbloader.COM.INSTask;
import nsusbloader.COM.USB.UsbErrorCodes; import nsusbloader.COM.USB.UsbErrorCodes;
import nsusbloader.ModelControllers.ILogPrinter; import nsusbloader.ModelControllers.ILogPrinter;
import nsusbloader.NSLDataTypes.EMsgType; import nsusbloader.NSLDataTypes.EMsgType;
@ -35,7 +34,6 @@ import java.util.Arrays;
class NxdtUsbAbi1 { class NxdtUsbAbi1 {
private ILogPrinter logPrinter; private ILogPrinter logPrinter;
private DeviceHandle handlerNS; private DeviceHandle handlerNS;
private INSTask task;
private String saveToPath; private String saveToPath;
private boolean isWindows; private boolean isWindows;
@ -79,12 +77,10 @@ class NxdtUsbAbi1 {
0x00, 0x00, 0x00, 0x00 }; 0x00, 0x00, 0x00, 0x00 };
public NxdtUsbAbi1(DeviceHandle handler, public NxdtUsbAbi1(DeviceHandle handler,
INSTask task,
ILogPrinter logPrinter, ILogPrinter logPrinter,
String saveToPath String saveToPath
){ ){
this.handlerNS = handler; this.handlerNS = handler;
this.task = task;
this.logPrinter = logPrinter; this.logPrinter = logPrinter;
this.isWindows = System.getProperty("os.name").toLowerCase().contains("windows"); this.isWindows = System.getProperty("os.name").toLowerCase().contains("windows");
@ -310,7 +306,7 @@ class NxdtUsbAbi1 {
writeBuffer.put(message); writeBuffer.put(message);
IntBuffer writeBufTransferred = IntBuffer.allocate(1); IntBuffer writeBufTransferred = IntBuffer.allocate(1);
if ( task.isCancelled()) if ( Thread.interrupted() )
throw new InterruptedException("Execution interrupted"); throw new InterruptedException("Execution interrupted");
int result = LibUsb.bulkTransfer(handlerNS, (byte) 0x01, writeBuffer, writeBufTransferred, 5050); 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. // We can limit it to 32 bytes, but there is a non-zero chance to got OVERFLOW from libusb.
IntBuffer readBufTransferred = IntBuffer.allocate(1); IntBuffer readBufTransferred = IntBuffer.allocate(1);
int result; 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 result = LibUsb.bulkTransfer(handlerNS, (byte) 0x81, readBuffer, readBufTransferred, 1000); // last one is TIMEOUT. 0 stands for unlimited. Endpoint IN = 0x81
switch (result) { switch (result) {
@ -368,7 +364,7 @@ class NxdtUsbAbi1 {
IntBuffer readBufTransferred = IntBuffer.allocate(1); IntBuffer readBufTransferred = IntBuffer.allocate(1);
int result; int result;
int countDown = 0; int countDown = 0;
while (! task.isCancelled() && countDown < 5) { while (! Thread.interrupted() && countDown < 5) {
result = LibUsb.bulkTransfer(handlerNS, (byte) 0x81, readBuffer, readBufTransferred, 1000); result = LibUsb.bulkTransfer(handlerNS, (byte) 0x81, readBuffer, readBufTransferred, 1000);
switch (result) { switch (result) {

View file

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

View file

@ -18,7 +18,6 @@
*/ */
package nsusbloader.cli; package nsusbloader.cli;
import nsusbloader.COM.INSTask;
import nsusbloader.COM.USB.UsbCommunications; import nsusbloader.COM.USB.UsbCommunications;
import java.io.File; import java.io.File;
@ -61,7 +60,7 @@ public class TinfoilUsb {
} }
private void runTinfoilBackend() throws InterruptedException{ 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 thread = new Thread(task);
thread.start(); thread.start();
thread.join(); thread.join();

View file

@ -68,3 +68,4 @@ btn_Cancel=Cancel
btn_Close=Close btn_Close=Close
tab2_Cb_GlVersion=GoldLeaf version 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_OpenFile=Selecionar arquivos
btn_Upload=Upar para o switch btn_Upload=Upar para o switch
tab3_Txt_EnteredAsMsg1=Voc\u00EA logou como: 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_FilesToUploadTitle=Arquivos para upar:
tab3_Txt_GreetingsMessage=Bem vindo ao NS-USBloader 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? 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! windowTitleConfirmExit=N\u00E3o, n\u00E3o fa\u00E7a isso!
btn_Stop=Imterromper! btn_Stop=Interromper!
tab3_Txt_GreetingsMessage2=--\n\ tab3_Txt_GreetingsMessage2=--\n\
Source: https://github.com/developersu/ns-usbloader/\n\ Source: https://github.com/developersu/ns-usbloader/\n\
Site: https://developersu.blogspot.com/search/label/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_Status=Status
tab1_table_Lbl_FileName=Nome do arquivo tab1_table_Lbl_FileName=Nome do arquivo
tab1_table_Lbl_Size=Tamanho 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_BtnDelete=Remover
tab1_table_contextMenu_Btn_DeleteAll=Remover todos tab1_table_contextMenu_Btn_DeleteAll=Remover todos
tab2_Lbl_HostIP=Host IP tab2_Lbl_HostIP=Host IP
tab1_Lbl_NSIP=NS 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? 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_Cb_ExpertMode=Modo Expert (Configura\u00E7\u00E3o NET)
tab2_Lbl_HostPort=porta tab2_Lbl_HostPort=porta
tab2_Cb_AutoDetectIp=Auto-detectar IP tab2_Cb_AutoDetectIp=Auto-detectar IP
tab2_Cb_RandSelectPort=Usar porta aleat\u00F3ria tab2_Cb_RandSelectPort=Usar porta aleat\u00F3ria
tab2_Cb_DontServeRequests=n\u00E3o aceitar solicita\u00E7\u00F5es 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 tab2_Lbl_HostExtra=extra
windowTitleErrorPort=Porta configurada incorretamente! windowTitleErrorPort=Porta configurada incorretamente!
windowBodyErrorPort=Porta n\u00E3o pode ser 0 or maior que 65535. windowBodyErrorPort=Porta n\u00E3o pode ser 0 or maior que 65535
tab2_Cb_AutoCheckForUpdates=Auto checar por atualiza\u00E7\u00F5es. tab2_Cb_AutoCheckForUpdates=Auto checar por atualiza\u00E7\u00F5es
windowTitleNewVersionAval=Nova vers\u00E3o dispon\u00EDvel. windowTitleNewVersionAval=Nova vers\u00E3o dispon\u00EDvel
windowTitleNewVersionNOTAval=Nao h\u00E1 novas vers\u00F5es. windowTitleNewVersionNOTAval=Nao h\u00E1 novas vers\u00F5es
windowTitleNewVersionUnknown=Nao conseguimos checar por novas atualiza\u00E7\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? 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! windowBodyNewVersionNOTAval=Voc\u00EA est\u00E1 na \u00FAltima vers\u00E3o!
tab2_Cb_AllowXciNszXcz=permitir arquivos XCI / NSZ / XCZ para o tinfoil 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 tab2_Lbl_Language=Idioma
windowBodyRestartToApplyLang=Por favor, reinicie para aplicar as modifica\u00E7\u00F5es. windowBodyRestartToApplyLang=Por favor, reinicie para aplicar as modifica\u00E7\u00F5es
tab2_Cb_GLshowNspOnly=Mostrar apenas arquivos .nsp no GoldLeaf. tab2_Cb_GLshowNspOnly=Mostrar apenas arquivos .nsp no GoldLeaf
tab2_Cb_GlVersion=Vers\u00E3o do GoldLeaf.
btn_OpenSplitFile=Selecionar arquivos .nsp fragmentados(splitted) btn_OpenSplitFile=Selecionar arquivos .nsp fragmentados(splitted)
tab2_Lbl_ApplicationSettings=Configura\u00E7\u00F5es principais 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_Split=Fragmentar(split)
tabSplMrg_RadioBtn_Merge=Juntar(merge) tabSplMrg_RadioBtn_Merge=Mesclar(merge)
tabSplMrg_Txt_File=File: tabSplMrg_Txt_File=File:
tabSplMrg_Txt_Folder=Arquivo fragmentado (pasta): tabSplMrg_Txt_Folder=Arquivo fragmentado (pasta):
tabSplMrg_Btn_SelectFile=Selecionar arquivo. tabSplMrg_Btn_SelectFile=Selecionar arquivo
tabSplMrg_Btn_SelectFolder=Selecionar pasta tabSplMrg_Btn_SelectFolder=Selecionar pasta
tabSplMrg_Lbl_SaveToLocation=Salvar em: tabSplMrg_Lbl_SaveToLocation=Salvar em:
tabSplMrg_Btn_ChangeSaveToLocation=Trocar tabSplMrg_Btn_ChangeSaveToLocation=Trocar
@ -61,6 +62,9 @@ done_txt=Feito!
failure_txt=Falhou failure_txt=Falhou
btn_Select=Selecionar btn_Select=Selecionar
btn_InjectPayloader=Injetar payload 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 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_Cancel=\u041E\u0442\u043C\u0435\u043D\u0438\u0442\u044C
btn_Close=\u0417\u0430\u043A\u0440\u044B\u0442\u044C btn_Close=\u0417\u0430\u043A\u0440\u044B\u0442\u044C
tab2_Cb_GlVersion=\u0412\u0435\u0440\u0441\u0438\u044F GoldLeaf 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_Cancel=\u0412\u0456\u0434\u043C\u0456\u043D\u0438\u0442\u0438
btn_Close=\u0417\u0430\u043A\u0440\u0438\u0442\u0438 btn_Close=\u0417\u0430\u043A\u0440\u0438\u0442\u0438
tab2_Cb_GlVersion=\u0412\u0435\u0440\u0441\u0456\u044F GoldLeaf 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.