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:
parent
96e85056dd
commit
267ffcf5d2
22 changed files with 553 additions and 522 deletions
|
@ -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);
|
||||
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());
|
||||
}
|
||||
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();
|
||||
|
||||
// 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;
|
||||
if (! isValid)
|
||||
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){
|
||||
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;
|
||||
parseGETrange(requestedFile, reqFileName, reqFileSize, line);
|
||||
return;
|
||||
}
|
||||
}
|
||||
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){
|
||||
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();
|
||||
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.
|
||||
* */
|
||||
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;
|
||||
}
|
||||
if (nsr.read(byteBuf) != readPice)
|
||||
throw new IOException("File stream suddenly ended.");
|
||||
|
||||
currSockOS.write(byteBuf);
|
||||
//-------/
|
||||
logPrinter.updateProgress((currentOffset+readPice)/(count/100.0) / 100.0);
|
||||
//-------/
|
||||
|
||||
currentOffset += readPice;
|
||||
}
|
||||
currSockOS.flush(); // TODO: check if this really needed.
|
||||
nsr.close();
|
||||
}
|
||||
//================================= REGULAR FILE ====================================
|
||||
else {
|
||||
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(reqFile));
|
||||
private void handleRegularFile(File file, long start, long end) throws Exception{
|
||||
long count = end - start + 1;
|
||||
|
||||
if (bis.skip(start) != start){
|
||||
logPrinter.print("NET: Unable to skip requested range.", EMsgType.FAIL);
|
||||
logPrinter.update(reqFile, EFileStatus.FAILED);
|
||||
return true;
|
||||
}
|
||||
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 (isCancelled())
|
||||
return true;
|
||||
|
||||
if ((currentOffset + readPice) >= count){
|
||||
readPice = Math.toIntExact(count - currentOffset);
|
||||
}
|
||||
byteBuf = new byte[readPice];
|
||||
|
||||
if (bis.read(byteBuf) != readPice){
|
||||
logPrinter.print("NET: Reading of file stream suddenly ended.", EMsgType.FAIL);
|
||||
return true;
|
||||
throw new IOException("File stream suddenly ended.");
|
||||
}
|
||||
currSockOS.write(byteBuf);
|
||||
//-------/
|
||||
logPrinter.updateProgress((currentOffset+readPice)/(count/100.0) / 100.0);
|
||||
//-------/
|
||||
currentOffset += readPice;
|
||||
}
|
||||
currSockOS.flush(); // TODO: check if this really needed.
|
||||
bis.close();
|
||||
}
|
||||
//-------/
|
||||
logPrinter.updateProgress(1.0);
|
||||
//-------/
|
||||
|
||||
public ServerSocket getServerSocket(){
|
||||
return serverSocket;
|
||||
}
|
||||
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;
|
||||
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();
|
||||
}
|
||||
|
|
205
src/main/java/nsusbloader/COM/NET/NetworkSetupValidator.java
Normal file
205
src/main/java/nsusbloader/COM/NET/NetworkSetupValidator.java
Normal 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; }
|
||||
}
|
|
@ -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; }
|
||||
}
|
|
@ -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) {
|
||||
|
|
|
@ -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){
|
||||
|
|
|
@ -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){
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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){ }
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ package nsusbloader.ModelControllers;
|
|||
import nsusbloader.NSLDataTypes.EModule;
|
||||
import nsusbloader.NSLMain;
|
||||
|
||||
public class Log {
|
||||
public abstract class Log {
|
||||
|
||||
private Log(){}
|
||||
|
||||
|
|
|
@ -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<>();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -68,3 +68,4 @@ btn_Cancel=Cancel
|
|||
btn_Close=Close
|
||||
tab2_Cb_GlVersion=GoldLeaf version
|
||||
tab2_Cb_GLshowNspOnly=Show only *.nsp in GoldLeaf.
|
||||
windowBodyPleaseStopOtherProcessFirst=Please stop other active process before continuing.
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in a new issue