Compare commits
13 commits
ea97bcd2eb
...
2e0d583963
Author | SHA1 | Date | |
---|---|---|---|
|
2e0d583963 | ||
|
8eb05bb1b5 | ||
|
6b6bf8320f | ||
|
aff6044cdb | ||
|
bbb71e2a53 | ||
|
fe673c0ace | ||
|
ec4362ebc7 | ||
|
010c33c593 | ||
|
3d3fb56f9e | ||
|
ca061cd1f2 | ||
|
98155bc1f8 | ||
|
d00b914214 | ||
|
4dc6d0ae0c |
43 changed files with 2633 additions and 358 deletions
45
BUILD.md
Normal file
45
BUILD.md
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
### How to build this app
|
||||||
|
|
||||||
|
Java application:
|
||||||
|
* Install Maven
|
||||||
|
* Execute
|
||||||
|
`# mvn -B -DskipTests clean package`
|
||||||
|
|
||||||
|
**Building JNI libraries section**
|
||||||
|
|
||||||
|
First of all install JDK, GCC, make, kernel headers and whatever else (or use Gentoo <3 ).
|
||||||
|
|
||||||
|
Generate header (Optional! Already generated.):
|
||||||
|
```
|
||||||
|
$ cp NS-USBloader/src/main/java/nsusbloader/Utilities/RcmSmash.java .
|
||||||
|
$ javac -h . RcmSmash.java
|
||||||
|
```
|
||||||
|
**Build for Linux (amd64 Linux host):**
|
||||||
|
```
|
||||||
|
$ cd 'NS-USBloader/JNI sources/linux'
|
||||||
|
$ make install clean
|
||||||
|
```
|
||||||
|
**Build for Windows (on x86_64 host):**
|
||||||
|
|
||||||
|
[ This part should be updated ]
|
||||||
|
|
||||||
|
Install MinGW, msys (?) MinGW-w64 and JDK. Set JAVA_HOME, set PATH to match MinGW, MSYS, JDK/bin (and other?) environment variables.
|
||||||
|
|
||||||
|
x86: Install MinGw to C:\MinGW\
|
||||||
|
|
||||||
|
Update sources: set (uncomment) line 'BUILD_FOR_X86'
|
||||||
|
|
||||||
|
Set environment variables for MinGw:
|
||||||
|
* C:\MinGW\bin
|
||||||
|
* C:\MinGW\msys\1.0\bin
|
||||||
|
```
|
||||||
|
$ cd 'NS-USBloader/JNI sources/windows'
|
||||||
|
$ make x86
|
||||||
|
```
|
||||||
|
|
||||||
|
amd64: Install MinGw-w64
|
||||||
|
|
||||||
|
Update sources: remove line 'BUILD_FOR_X86'
|
||||||
|
```
|
||||||
|
$ make amd64
|
||||||
|
```
|
33
JNI sources/linux/Makefile
Normal file
33
JNI sources/linux/Makefile
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
# Compiler
|
||||||
|
CC=gcc
|
||||||
|
# Flags
|
||||||
|
CFLAGS=-O2
|
||||||
|
MKDIR_P = mkdir -p
|
||||||
|
APP_NAME = smashlib.so
|
||||||
|
|
||||||
|
all: x86 amd64
|
||||||
|
|
||||||
|
x86:
|
||||||
|
$(MKDIR_P) ./x86
|
||||||
|
$(CC) ${CFLAGS} -m32 -c -fPIC -I"${JAVA_HOME}/include" -I"${JAVA_HOME}/include/linux" smashlib.c -o smashlib_x86.o
|
||||||
|
$(CC) ${CFLAGS} -m32 -shared -fPIC -o ./x86/${APP_NAME} smashlib_x86.o -lc
|
||||||
|
|
||||||
|
amd64:
|
||||||
|
$(MKDIR_P) ./amd64
|
||||||
|
$(CC) ${CFLAGS} -m64 -c -fPIC -I"${JAVA_HOME}/include" -I"${JAVA_HOME}/include/linux" smashlib.c -o smashlib_amd64.o
|
||||||
|
$(CC) ${CFLAGS} -m64 -shared -fPIC -o ./amd64/${APP_NAME} smashlib_amd64.o -lc
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf \
|
||||||
|
smashlib_amd64.o \
|
||||||
|
smashlib_x86.o \
|
||||||
|
./x86 \
|
||||||
|
./amd64
|
||||||
|
|
||||||
|
install: x86 amd64
|
||||||
|
install ./x86/${APP_NAME} ../../src/main/resources/native/linux/x86/
|
||||||
|
install ./amd64/${APP_NAME} ../../src/main/resources/native/linux/amd64/
|
||||||
|
|
||||||
|
uninstall:
|
||||||
|
rm ../../src/main/resources/native/linux/x86/${APP_NAME}
|
||||||
|
rm ../../src/main/resources/native/linux/amd64/${APP_NAME}
|
29
JNI sources/linux/nsusbloader_Utilities_RcmSmash.h
Normal file
29
JNI sources/linux/nsusbloader_Utilities_RcmSmash.h
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||||
|
#include <jni.h>
|
||||||
|
/* Header for class nsusbloader_Utilities_RcmSmash */
|
||||||
|
|
||||||
|
#ifndef _Included_nsusbloader_Utilities_RcmSmash
|
||||||
|
#define _Included_nsusbloader_Utilities_RcmSmash
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
* Class: nsusbloader_Utilities_RcmSmash
|
||||||
|
* Method: smashLinux
|
||||||
|
* Signature: (II)I
|
||||||
|
*/
|
||||||
|
JNIEXPORT jint JNICALL Java_nsusbloader_Utilities_RcmSmash_smashLinux
|
||||||
|
(JNIEnv *, jclass, jint, jint);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: nsusbloader_Utilities_RcmSmash
|
||||||
|
* Method: smashWindows
|
||||||
|
* Signature: ()I
|
||||||
|
*/
|
||||||
|
JNIEXPORT jint JNICALL Java_nsusbloader_Utilities_RcmSmash_smashWindows
|
||||||
|
(JNIEnv *, jclass);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
88
JNI sources/linux/smashlib.c
Executable file
88
JNI sources/linux/smashlib.c
Executable file
|
@ -0,0 +1,88 @@
|
||||||
|
/* NS-USBloader - native libraries for 'special purposes'
|
||||||
|
* Copyright (C) 2020 Dmitry Isaenko
|
||||||
|
*
|
||||||
|
* This program 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.
|
||||||
|
*
|
||||||
|
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <linux/usbdevice_fs.h>
|
||||||
|
#include <linux/usb/ch9.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "nsusbloader_Utilities_RcmSmash.h"
|
||||||
|
|
||||||
|
struct usbdevfs_urb urb;
|
||||||
|
|
||||||
|
JNIEXPORT jint JNICALL Java_nsusbloader_Utilities_RcmSmash_smashLinux
|
||||||
|
(JNIEnv * jni_env, jclass this_class, jint bus_id, jint device_addr){
|
||||||
|
int ret_value;
|
||||||
|
|
||||||
|
char *usb_path = (char*)malloc(24 * sizeof(char));
|
||||||
|
|
||||||
|
sprintf(usb_path, "/dev/bus/usb/%03d/%03d", bus_id, device_addr);
|
||||||
|
int fd = open(usb_path, O_RDWR);
|
||||||
|
if (fd == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
struct usb_ctrlrequest* ctrl_req;
|
||||||
|
|
||||||
|
__u8* buf[0x7000+sizeof(ctrl_req)];
|
||||||
|
|
||||||
|
ctrl_req = (struct usb_ctrlrequest *) buf;
|
||||||
|
ctrl_req->bRequestType = 0x82;
|
||||||
|
ctrl_req->bRequest = USB_REQ_GET_STATUS;
|
||||||
|
ctrl_req->wValue = 0;
|
||||||
|
ctrl_req->wIndex = 0;
|
||||||
|
ctrl_req->wLength = 0x7000;
|
||||||
|
|
||||||
|
memset(&urb, 0, sizeof(urb));
|
||||||
|
urb.type = USBDEVFS_URB_TYPE_CONTROL;
|
||||||
|
urb.endpoint = USB_DIR_IN | 0;
|
||||||
|
urb.buffer = buf;
|
||||||
|
urb.buffer_length = sizeof(buf);
|
||||||
|
//Submit request
|
||||||
|
ret_value = ioctl(fd, USBDEVFS_SUBMITURB, &urb);
|
||||||
|
// If we failed on this step, it's a VERY bad sign. Nothing to do, let's report failure.
|
||||||
|
if (ret_value != 0)
|
||||||
|
return ret_value;
|
||||||
|
// Wait 1/4 sec
|
||||||
|
usleep(250000);
|
||||||
|
struct usbdevfs_urb urb1;
|
||||||
|
// Let's pick reply (everybody does it, right? In non-blocking manner.)
|
||||||
|
ret_value = ioctl(fd, USBDEVFS_REAPURBNDELAY, &urb1);
|
||||||
|
if (ret_value < 0){
|
||||||
|
if (errno == EAGAIN){ // In case of resource temporarily unavailable
|
||||||
|
// Wired.. so much time left. Let's cancel it!
|
||||||
|
ret_value = ioctl(fd, USBDEVFS_DISCARDURB, &urb);
|
||||||
|
// And wait a bit more..
|
||||||
|
usleep(40000);
|
||||||
|
// And try to pick reply. Yes, it's still possible. See /usr/src/linux/drivers/usb/core/devio.c
|
||||||
|
ret_value = ioctl(fd, USBDEVFS_REAPURBNDELAY, &urb1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Leftovers.
|
||||||
|
free(usb_path);
|
||||||
|
// Let's try to close device, but even if we fail with this, nvm.
|
||||||
|
close(fd); // So we won't even write returned value somewhere.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jint JNICALL Java_nsusbloader_Utilities_RcmSmash_smashWindows
|
||||||
|
(JNIEnv * jni_env, jclass this_class){
|
||||||
|
return -1;
|
||||||
|
}
|
34
JNI sources/windows/Makefile
Normal file
34
JNI sources/windows/Makefile
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
# Compiler
|
||||||
|
CC32='C:/MinGW/bin/gcc'
|
||||||
|
CC64='C:/Program Files/mingw-w64/x86_64-8.1.0-win32-seh-rt_v6-rev0/mingw64/bin/gcc'
|
||||||
|
# Flags
|
||||||
|
CFLAGS=-O2
|
||||||
|
MKDIR_P=mkdir
|
||||||
|
APP_NAME=smashlib.dll
|
||||||
|
|
||||||
|
all: x86 amd64
|
||||||
|
|
||||||
|
#$(CC) ${CFLAGS} -m32 -c -fPIC -I "C:/MinGW/include/ddk" -I "${JAVA_HOME}/include" -I "${JAVA_HOME}/include/win32" smashlib.c -o ./x86/smashlib.o # MinGw-32 version
|
||||||
|
x86:
|
||||||
|
$(MKDIR_P) ./x86
|
||||||
|
export PATH="C/MinGW/bin/:${PATH}"
|
||||||
|
$(CC32) ${CFLAGS} -m32 -c -fPIC -I "C:/MinGW/include/ddk" -I "${JAVA_HOME}/include" -I "${JAVA_HOME}/include/win32" smashlib.c -o ./smashlib_x86.o
|
||||||
|
$(CC32) ${CFLAGS} -shared -o ./x86/${APP_NAME} ./smashlib_x86.o -lsetupapi -lhid -Wl,--add-stdcall-alias
|
||||||
|
|
||||||
|
#$(CC) ${CFLAGS} -m64 -c -fPIC -I "C:/MinGW/include/ddk" -I "${JAVA_HOME}/include" -I "${JAVA_HOME}/include/win32" smashlib.c -o ./amd64/smashlib.o # MinGw-32 version
|
||||||
|
amd64:
|
||||||
|
$(MKDIR_P) ./amd64
|
||||||
|
export PATH="C/Program Files/mingw-w64/x86_64-8.1.0-win32-seh-rt_v6-rev0/mingw64/bin/:${PATH}"
|
||||||
|
$(CC64) ${CFLAGS} -m64 -c -fPIC -I "${JAVA_HOME}/include" -I "${JAVA_HOME}/include/win32" smashlib.c -o ./smashlib_amd64.o
|
||||||
|
$(CC64) ${CFLAGS} -shared -o ./amd64/${APP_NAME} ./smashlib_amd64.o -lsetupapi -lhid -Wl,--add-stdcall-alias
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf ./smashlib_x86.o ./smashlib_amd64.o ./x86 ./amd64
|
||||||
|
|
||||||
|
install: x86 amd64
|
||||||
|
install ./x86/${APP_NAME} ../../src/main/resources/native/windows/x86/
|
||||||
|
install ./amd64/${APP_NAME} ../../src/main/resources/native/windows/amd64/
|
||||||
|
|
||||||
|
uninstall:
|
||||||
|
rm ../../src/main/resources/native/windows/x86/${APP_NAME}
|
||||||
|
rm ../../src/main/resources/native/windows/amd64/${APP_NAME}
|
29
JNI sources/windows/nsusbloader_Utilities_RcmSmash.h
Normal file
29
JNI sources/windows/nsusbloader_Utilities_RcmSmash.h
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||||
|
#include <jni.h>
|
||||||
|
/* Header for class nsusbloader_Utilities_RcmSmash */
|
||||||
|
|
||||||
|
#ifndef _Included_nsusbloader_Utilities_RcmSmash
|
||||||
|
#define _Included_nsusbloader_Utilities_RcmSmash
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
* Class: nsusbloader_Utilities_RcmSmash
|
||||||
|
* Method: smashLinux
|
||||||
|
* Signature: (II)I
|
||||||
|
*/
|
||||||
|
JNIEXPORT jint JNICALL Java_nsusbloader_Utilities_RcmSmash_smashLinux
|
||||||
|
(JNIEnv *, jclass, jint, jint);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: nsusbloader_Utilities_RcmSmash
|
||||||
|
* Method: smashWindows
|
||||||
|
* Signature: ()I
|
||||||
|
*/
|
||||||
|
JNIEXPORT jint JNICALL Java_nsusbloader_Utilities_RcmSmash_smashWindows
|
||||||
|
(JNIEnv *, jclass);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
168
JNI sources/windows/smashlib.c
Normal file
168
JNI sources/windows/smashlib.c
Normal file
|
@ -0,0 +1,168 @@
|
||||||
|
/*
|
||||||
|
* Derivative & modified code based on awesome example from here: https://www.velleman.eu/images/tmp/usbfind.c
|
||||||
|
* And MSDN documentation :)
|
||||||
|
*
|
||||||
|
* return
|
||||||
|
* -2 device not connected
|
||||||
|
* -1 Unable to open handler
|
||||||
|
* 0 maybe we're all set
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define _DEBUG
|
||||||
|
#define _BUILD_FOR_X86
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <tchar.h>
|
||||||
|
#include <setupapi.h>
|
||||||
|
#ifdef DEBUG
|
||||||
|
#include <stdio.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BUILD_FOR_X86
|
||||||
|
#include <ntddser.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "nsusbloader_Utilities_RcmSmash.h"
|
||||||
|
|
||||||
|
#define LIBUSB_IOCTL_GET_STATUS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x807, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||||
|
|
||||||
|
static GUID GUID_DEVINTERFACE_USB_DEVICE = {0xA5DCBF10L, 0x6530, 0x11D2, {0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED}};
|
||||||
|
// NOTE: CHANGE TO NV DEVICE!
|
||||||
|
//static TCHAR VID_PID_PAIR[] = _T("vid_1a86&pid_7523"); // UNCOMMENT FOR TESTS
|
||||||
|
static TCHAR VID_PID_PAIR[] = _T("vid_0955&pid_7321"); // UNCOMMENT ON RELEASE
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unsigned int timeout;
|
||||||
|
unsigned int recipient;
|
||||||
|
unsigned int index;
|
||||||
|
unsigned int status;
|
||||||
|
unsigned int ___zeroes_hold_0; // made it for better understanding. Literally useless.
|
||||||
|
unsigned int ___zeroes_hold_1; // Just consider each int as 4 bytes and calculate size =)
|
||||||
|
} simple_status_req;
|
||||||
|
|
||||||
|
int win32_magic(LPCSTR lpFileName){
|
||||||
|
unsigned char reqBuf[24] = {0};
|
||||||
|
|
||||||
|
simple_status_req* request;
|
||||||
|
request = (simple_status_req *) &reqBuf;
|
||||||
|
request->timeout = 1000;
|
||||||
|
request->recipient = 0x02;
|
||||||
|
request->index = 0;
|
||||||
|
request->status = 0;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("Device path: %s\nStatus: %x\nIn buffer size: %d\nIn buffer content: ",
|
||||||
|
lpFileName,
|
||||||
|
LIBUSB_IOCTL_GET_STATUS,
|
||||||
|
sizeof(reqBuf) ); // Path and what is our IOCTL request looks like
|
||||||
|
|
||||||
|
for (int i = 0; i < sizeof(reqBuf); i++)
|
||||||
|
printf("%x ", reqBuf[i]);
|
||||||
|
printf("\n");
|
||||||
|
#endif
|
||||||
|
unsigned char outBuffer[28672];
|
||||||
|
|
||||||
|
OVERLAPPED ovrlpd;
|
||||||
|
memset(&ovrlpd, 0, sizeof(ovrlpd));
|
||||||
|
// Fucking finally let's open this
|
||||||
|
HANDLE handler = CreateFile(
|
||||||
|
lpFileName,
|
||||||
|
GENERIC_READ | GENERIC_WRITE,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
|
NULL,
|
||||||
|
OPEN_EXISTING,
|
||||||
|
FILE_FLAG_OVERLAPPED,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( handler == INVALID_HANDLE_VALUE )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
BOOL ret_val = DeviceIoControl(
|
||||||
|
handler,
|
||||||
|
LIBUSB_IOCTL_GET_STATUS,
|
||||||
|
(LPVOID) &reqBuf,
|
||||||
|
24,
|
||||||
|
(LPVOID) &outBuffer,
|
||||||
|
28672,
|
||||||
|
NULL,
|
||||||
|
&ovrlpd
|
||||||
|
);
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("\nDeviceIoControl reports: %d\nLast Error Code: %d\n", ret_val, GetLastError());
|
||||||
|
#endif
|
||||||
|
Sleep(250);
|
||||||
|
DWORD bReceived = 0;
|
||||||
|
ret_val = GetOverlappedResult(handler, &ovrlpd, &bReceived, FALSE);
|
||||||
|
#ifdef DEBUG
|
||||||
|
if (! ret_val) {
|
||||||
|
// we won't report any issues since there is no workaround.
|
||||||
|
printf("\nLast Error Code: %d\n\n", GetLastError());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
CloseHandle(handler);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jint JNICALL Java_nsusbloader_Utilities_RcmSmash_smashWindows
|
||||||
|
(JNIEnv * jnie_enb, jclass this_class) {
|
||||||
|
int found = 0;
|
||||||
|
int ret_val = -2;
|
||||||
|
HDEVINFO hDevInfo;
|
||||||
|
SP_DEVICE_INTERFACE_DATA DevIntfData;
|
||||||
|
PSP_DEVICE_INTERFACE_DETAIL_DATA DevIntfDetailData;
|
||||||
|
SP_DEVINFO_DATA DevData;
|
||||||
|
|
||||||
|
DWORD dwSize, dwType, dwMemberIdx;
|
||||||
|
HKEY hKey;
|
||||||
|
BYTE lpData[1024];
|
||||||
|
|
||||||
|
hDevInfo = SetupDiGetClassDevs(&GUID_DEVINTERFACE_USB_DEVICE, NULL, 0, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
|
||||||
|
|
||||||
|
if (hDevInfo != INVALID_HANDLE_VALUE){
|
||||||
|
DevIntfData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
|
||||||
|
dwMemberIdx = 0;
|
||||||
|
|
||||||
|
SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &GUID_DEVINTERFACE_USB_DEVICE, dwMemberIdx, &DevIntfData);
|
||||||
|
|
||||||
|
while(GetLastError() != ERROR_NO_MORE_ITEMS) {
|
||||||
|
DevData.cbSize = sizeof(DevData);
|
||||||
|
|
||||||
|
SetupDiGetDeviceInterfaceDetail(hDevInfo, &DevIntfData, NULL, 0, &dwSize, NULL);
|
||||||
|
|
||||||
|
DevIntfDetailData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize);
|
||||||
|
DevIntfDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
|
||||||
|
|
||||||
|
if (SetupDiGetDeviceInterfaceDetail(hDevInfo, &DevIntfData, DevIntfDetailData, dwSize, &dwSize, &DevData)) {
|
||||||
|
if (NULL != _tcsstr((TCHAR*)DevIntfDetailData->DevicePath, VID_PID_PAIR)) {
|
||||||
|
found = 1;
|
||||||
|
ret_val = win32_magic(DevIntfDetailData->DevicePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HeapFree(GetProcessHeap(), 0, DevIntfDetailData);
|
||||||
|
if (found)
|
||||||
|
break;
|
||||||
|
// Continue looping
|
||||||
|
SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &GUID_DEVINTERFACE_USB_DEVICE, ++dwMemberIdx, &DevIntfData);
|
||||||
|
}
|
||||||
|
SetupDiDestroyDeviceInfoList(hDevInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("Returning value: %d\n", ret_val);
|
||||||
|
#endif
|
||||||
|
return ret_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jint JNICALL Java_nsusbloader_Utilities_RcmSmash_smashLinux
|
||||||
|
(JNIEnv * jnie_env, jclass this_class, jint bus_id, jint device_addr){
|
||||||
|
return -1;
|
||||||
|
}
|
18
README.md
18
README.md
|
@ -4,8 +4,12 @@
|
||||||
|
|
||||||
[Support author](#support-this-app)
|
[Support author](#support-this-app)
|
||||||
|
|
||||||
NS-USBloader is a PC-side installer for **[Adubbz/TinFoil (v0.2.1)](https://github.com/Adubbz/Tinfoil/)**, **[Huntereb/Awoo-Installer](https://github.com/Huntereb/Awoo-Installer)** (USB and Network supported) and **[XorTroll/GoldLeaf](https://github.com/XorTroll/Goldleaf)** (USB) NSP installer.
|
NS-USBloader is:
|
||||||
|
* A PC-side installer for **[Adubbz/TinFoil (v0.2.1)](https://github.com/Adubbz/Tinfoil/)**, **[Huntereb/Awoo-Installer](https://github.com/Huntereb/Awoo-Installer)** (USB and Network supported) and **[XorTroll/GoldLeaf](https://github.com/XorTroll/Goldleaf)** (USB) NSP installer.
|
||||||
Replacement for default **usb_install_pc.py**, **remote_install_pc.py**, **GoldTree**/**Quark**.
|
Replacement for default **usb_install_pc.py**, **remote_install_pc.py**, **GoldTree**/**Quark**.
|
||||||
|
* This application also could be used as RCM payload on Windows, MacOS and Linux (supported arch: x86, x86_64).
|
||||||
|
* And of course it's a tool for split files!
|
||||||
|
* And also for merging split-files into one :)
|
||||||
|
|
||||||
[Click here for Android version ;)](https://github.com/developersu/ns-usbloader-mobile)
|
[Click here for Android version ;)](https://github.com/developersu/ns-usbloader-mobile)
|
||||||
|
|
||||||
|
@ -13,7 +17,9 @@ With GUI and cookies. Works on Windows, macOS and Linux.
|
||||||
|
|
||||||
Sometimes I add new posts about this project [on my home page](https://developersu.blogspot.com/search/label/NS-USBloader).
|
Sometimes I add new posts about this project [on my home page](https://developersu.blogspot.com/search/label/NS-USBloader).
|
||||||
|
|
||||||
![Screenshot](https://live.staticflickr.com/65535/48962978677_4c3913e8a9_o.png)
|
![Application screenshot](https://live.staticflickr.com/65535/49513701961_2b41747a9f_o.png)
|
||||||
|
<img src="https://live.staticflickr.com/65535/49513701841_e09c86b944_o.png" alt="screenshot" width="250"/> <img src="https://live.staticflickr.com/65535/49513701896_c4d0a905c0_o.png" alt="screenshot" width="250"/>
|
||||||
|
<img src="https://live.staticflickr.com/65535/49513184138_688ee551f8_o.png" alt="screenshot" width="250"/> <img src="https://live.staticflickr.com/65535/49513924407_212988e0e9_o.png" alt="screenshot" width="250"/>
|
||||||
|
|
||||||
#### License
|
#### License
|
||||||
|
|
||||||
|
@ -23,6 +29,7 @@ Sometimes I add new posts about this project [on my home page](https://developer
|
||||||
* [OpenJFX](https://wiki.openjdk.java.net/display/OpenJFX/Main)
|
* [OpenJFX](https://wiki.openjdk.java.net/display/OpenJFX/Main)
|
||||||
* [usb4java](https://mvnrepository.com/artifact/org.usb4java/usb4java)
|
* [usb4java](https://mvnrepository.com/artifact/org.usb4java/usb4java)
|
||||||
* Few icons taken from: [materialdesignicons.com](http://materialdesignicons.com/)
|
* Few icons taken from: [materialdesignicons.com](http://materialdesignicons.com/)
|
||||||
|
* Information, ideas and data from ['fusee-launcher'](https://github.com/reswitched/fusee-launcher) application
|
||||||
|
|
||||||
#### List of awesome contributors!
|
#### List of awesome contributors!
|
||||||
|
|
||||||
|
@ -73,6 +80,12 @@ root # vim /etc/udev/rules.d/99-NS.rules
|
||||||
SUBSYSTEM=="usb", ATTRS{idVendor}=="057e", ATTRS{idProduct}=="3000", GROUP="plugdev"
|
SUBSYSTEM=="usb", ATTRS{idVendor}=="057e", ATTRS{idProduct}=="3000", GROUP="plugdev"
|
||||||
root # udevadm control --reload-rules && udevadm trigger
|
root # udevadm control --reload-rules && udevadm trigger
|
||||||
```
|
```
|
||||||
|
4. For RCM part
|
||||||
|
```
|
||||||
|
root # vim /etc/udev/rules.d/99-NS-RCM.rules
|
||||||
|
SUBSYSTEM=="usb", ATTRS{idVendor}=="0955", ATTRS{idProduct}=="7321", GROUP="plugdev"
|
||||||
|
root # udevadm control --reload-rules && udevadm trigger
|
||||||
|
```
|
||||||
|
|
||||||
Please note: you may have to change 'plugdev' group from example above to the different one. It's depends on you linux distro.
|
Please note: you may have to change 'plugdev' group from example above to the different one. It's depends on you linux distro.
|
||||||
|
|
||||||
|
@ -155,7 +168,6 @@ Upload somewhere (create PR, use pastebin/google drive/whatever else). [Create n
|
||||||
|
|
||||||
To convert files of any locale to readable format (and vise-versa) you can use this site [https://itpro.cz/juniconv/](https://itpro.cz/juniconv/)
|
To convert files of any locale to readable format (and vise-versa) you can use this site [https://itpro.cz/juniconv/](https://itpro.cz/juniconv/)
|
||||||
|
|
||||||
|
|
||||||
#### TODO (maybe):
|
#### TODO (maybe):
|
||||||
- [x] [Android support](https://github.com/developersu/ns-usbloader-mobile)
|
- [x] [Android support](https://github.com/developersu/ns-usbloader-mobile)
|
||||||
- [ ] File order sort (non-critical)
|
- [ ] File order sort (non-critical)
|
||||||
|
|
2
pom.xml
2
pom.xml
|
@ -8,7 +8,7 @@
|
||||||
<name>NS-USBloader</name>
|
<name>NS-USBloader</name>
|
||||||
|
|
||||||
<artifactId>ns-usbloader</artifactId>
|
<artifactId>ns-usbloader</artifactId>
|
||||||
<version>1.0.0-SNAPSHOT</version>
|
<version>2.0-SNAPSHOT</version>
|
||||||
|
|
||||||
<url>https://github.com/developersu/ns-usbloader/</url>
|
<url>https://github.com/developersu/ns-usbloader/</url>
|
||||||
<description>
|
<description>
|
||||||
|
|
|
@ -123,6 +123,15 @@ public class AppPreferences {
|
||||||
public double getSceneWidth(){ return preferences.getDouble("WIND_WIDTH", 850.0); }
|
public double getSceneWidth(){ return preferences.getDouble("WIND_WIDTH", 850.0); }
|
||||||
public void setSceneWidth(double value){ preferences.putDouble("WIND_WIDTH", value); }
|
public void setSceneWidth(double value){ preferences.putDouble("WIND_WIDTH", value); }
|
||||||
|
|
||||||
public double getSceneHeight(){ return preferences.getDouble("WIND_HEIGHT", 475.0); }
|
public double getSceneHeight(){ return preferences.getDouble("WIND_HEIGHT", 525.0); }
|
||||||
public void setSceneHeight(double value){ preferences.putDouble("WIND_HEIGHT", value); }
|
public void setSceneHeight(double value){ preferences.putDouble("WIND_HEIGHT", value); }
|
||||||
|
// Split and Merge //
|
||||||
|
public int getSplitMergeType(){ return preferences.getInt("SM_TYPE", 0); }
|
||||||
|
public void setSplitMergeType(int value){ preferences.putInt("SM_TYPE", value); }
|
||||||
|
|
||||||
|
public String getSplitMergeRecent(){ return preferences.get("SM_RECENT", System.getProperty("user.home")); }
|
||||||
|
public void setSplitMergeRecent(String value){ preferences.put("SM_RECENT", value); }
|
||||||
|
// RCM //
|
||||||
|
public String getRecentRcm(int num){ return preferences.get(String.format("RCM_%02d", num), ""); }
|
||||||
|
public void setRecentRcm(int num, String value){ preferences.put(String.format("RCM_%02d", num), value); }
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package nsusbloader.COM.NET;
|
||||||
import javafx.concurrent.Task;
|
import javafx.concurrent.Task;
|
||||||
import nsusbloader.NSLDataTypes.EFileStatus;
|
import nsusbloader.NSLDataTypes.EFileStatus;
|
||||||
import nsusbloader.ModelControllers.LogPrinter;
|
import nsusbloader.ModelControllers.LogPrinter;
|
||||||
|
import nsusbloader.NSLDataTypes.EModule;
|
||||||
import nsusbloader.NSLDataTypes.EMsgType;
|
import nsusbloader.NSLDataTypes.EMsgType;
|
||||||
import nsusbloader.COM.Helpers.NSSplitReader;
|
import nsusbloader.COM.Helpers.NSSplitReader;
|
||||||
|
|
||||||
|
@ -42,7 +43,7 @@ public class NETCommunications extends Task<Void> { // todo: thows IOException?
|
||||||
else
|
else
|
||||||
this.extras = "";
|
this.extras = "";
|
||||||
this.switchIP = switchIP;
|
this.switchIP = switchIP;
|
||||||
this.logPrinter = new LogPrinter();
|
this.logPrinter = new LogPrinter(EModule.USB_NET_TRANSFERS);
|
||||||
this.nspMap = new HashMap<>();
|
this.nspMap = new HashMap<>();
|
||||||
this.nspFileSizes = new HashMap<>();
|
this.nspFileSizes = new HashMap<>();
|
||||||
// Filter and remove empty/incorrect split-files
|
// Filter and remove empty/incorrect split-files
|
||||||
|
|
|
@ -3,6 +3,7 @@ package nsusbloader.COM.USB;
|
||||||
import javafx.concurrent.Task;
|
import javafx.concurrent.Task;
|
||||||
import nsusbloader.ModelControllers.LogPrinter;
|
import nsusbloader.ModelControllers.LogPrinter;
|
||||||
import nsusbloader.NSLDataTypes.EFileStatus;
|
import nsusbloader.NSLDataTypes.EFileStatus;
|
||||||
|
import nsusbloader.NSLDataTypes.EModule;
|
||||||
import nsusbloader.NSLDataTypes.EMsgType;
|
import nsusbloader.NSLDataTypes.EMsgType;
|
||||||
import org.usb4java.*;
|
import org.usb4java.*;
|
||||||
|
|
||||||
|
@ -34,21 +35,21 @@ public class UsbCommunications extends Task<Void> {
|
||||||
this.nspMap = new LinkedHashMap<>();
|
this.nspMap = new LinkedHashMap<>();
|
||||||
for (File f: nspList)
|
for (File f: nspList)
|
||||||
nspMap.put(f.getName(), f);
|
nspMap.put(f.getName(), f);
|
||||||
this.logPrinter = new LogPrinter();
|
this.logPrinter = new LogPrinter(EModule.USB_NET_TRANSFERS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Void call() {
|
protected Void call() {
|
||||||
logPrinter.print("\tStart chain", EMsgType.INFO);
|
logPrinter.print("\tStart chain", EMsgType.INFO);
|
||||||
|
|
||||||
UsbConnect usbConnect = new UsbConnect(logPrinter);
|
UsbConnect usbConnect = new UsbConnect(logPrinter, false);
|
||||||
|
|
||||||
if (! usbConnect.isConnected()){
|
if (! usbConnect.isConnected()){
|
||||||
close(EFileStatus.FAILED);
|
close(EFileStatus.FAILED);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceHandle handler = usbConnect.getHandlerNS();
|
DeviceHandle handler = usbConnect.getNsHandler();
|
||||||
|
|
||||||
TransferModule module;
|
TransferModule module;
|
||||||
|
|
||||||
|
|
|
@ -4,20 +4,38 @@ import nsusbloader.ModelControllers.LogPrinter;
|
||||||
import nsusbloader.NSLDataTypes.EMsgType;
|
import nsusbloader.NSLDataTypes.EMsgType;
|
||||||
import org.usb4java.*;
|
import org.usb4java.*;
|
||||||
|
|
||||||
class UsbConnect {
|
public class UsbConnect {
|
||||||
private final int DEFAULT_INTERFACE = 0;
|
private int DEFAULT_INTERFACE = 0;
|
||||||
|
|
||||||
private Context contextNS;
|
private Context contextNS;
|
||||||
private DeviceHandle handlerNS;
|
private DeviceHandle handlerNS;
|
||||||
|
private Device deviceNS;
|
||||||
|
|
||||||
private LogPrinter logPrinter;
|
private LogPrinter logPrinter;
|
||||||
|
|
||||||
private boolean connected;
|
private boolean connected; // TODO: replace to 'connectionFailure' and invert requests everywhere
|
||||||
|
|
||||||
UsbConnect(LogPrinter logPrinter){
|
public UsbConnect(LogPrinter logPrinter, boolean initForRCM){
|
||||||
this.logPrinter = logPrinter;
|
this.logPrinter = logPrinter;
|
||||||
this.connected = false;
|
this.connected = false;
|
||||||
|
|
||||||
|
short VENDOR_ID;
|
||||||
|
short PRODUCT_ID;
|
||||||
|
|
||||||
|
if (initForRCM){
|
||||||
|
// CORRECT NV:
|
||||||
|
VENDOR_ID = 0x0955;
|
||||||
|
PRODUCT_ID = 0x7321;
|
||||||
|
/* // QA:
|
||||||
|
VENDOR_ID = 0x1a86;
|
||||||
|
PRODUCT_ID = 0x7523;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
VENDOR_ID = 0x057E;
|
||||||
|
PRODUCT_ID = 0x3000;
|
||||||
|
}
|
||||||
|
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
// Creating Context required by libusb. Optional. TODO: Consider removing.
|
// Creating Context required by libusb. Optional. TODO: Consider removing.
|
||||||
|
@ -28,8 +46,7 @@ class UsbConnect {
|
||||||
close();
|
close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
logPrinter.print("libusb initialization", EMsgType.PASS);
|
||||||
logPrinter.print("libusb initialization", EMsgType.PASS);
|
|
||||||
|
|
||||||
// Searching for NS in devices: obtain list of all devices
|
// Searching for NS in devices: obtain list of all devices
|
||||||
DeviceList deviceList = new DeviceList();
|
DeviceList deviceList = new DeviceList();
|
||||||
|
@ -39,11 +56,10 @@ class UsbConnect {
|
||||||
close();
|
close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
logPrinter.print("Get device list", EMsgType.PASS);
|
||||||
logPrinter.print("Get device list", EMsgType.PASS);
|
|
||||||
// Searching for NS in devices: looking for NS
|
// Searching for NS in devices: looking for NS
|
||||||
DeviceDescriptor descriptor;
|
DeviceDescriptor descriptor;
|
||||||
Device deviceNS = null;
|
deviceNS = null;
|
||||||
for (Device device: deviceList){
|
for (Device device: deviceList){
|
||||||
descriptor = new DeviceDescriptor(); // mmm.. leave it as is.
|
descriptor = new DeviceDescriptor(); // mmm.. leave it as is.
|
||||||
result = LibUsb.getDeviceDescriptor(device, descriptor);
|
result = LibUsb.getDeviceDescriptor(device, descriptor);
|
||||||
|
@ -53,21 +69,20 @@ class UsbConnect {
|
||||||
close();
|
close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((descriptor.idVendor() == 0x057E) && descriptor.idProduct() == 0x3000){
|
if ((descriptor.idVendor() == VENDOR_ID) && descriptor.idProduct() == PRODUCT_ID){
|
||||||
deviceNS = device;
|
deviceNS = device;
|
||||||
logPrinter.print("Read file descriptors for USB devices", EMsgType.PASS);
|
logPrinter.print("Read file descriptors for USB devices", EMsgType.PASS);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Free device list.
|
// Free device list.
|
||||||
if (deviceNS != null){
|
if (deviceNS == null){
|
||||||
logPrinter.print("NS in connected USB devices found", EMsgType.PASS);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
logPrinter.print("NS in connected USB devices not found", EMsgType.FAIL);
|
logPrinter.print("NS in connected USB devices not found", EMsgType.FAIL);
|
||||||
close();
|
close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
logPrinter.print("NS in connected USB devices found", EMsgType.PASS);
|
||||||
|
|
||||||
// Handle NS device
|
// Handle NS device
|
||||||
handlerNS = new DeviceHandle();
|
handlerNS = new DeviceHandle();
|
||||||
result = LibUsb.open(deviceNS, handlerNS);
|
result = LibUsb.open(deviceNS, handlerNS);
|
||||||
|
@ -75,10 +90,11 @@ class UsbConnect {
|
||||||
logPrinter.print("Open NS USB device\n Returned: "+UsbErrorCodes.getErrCode(result), EMsgType.FAIL);
|
logPrinter.print("Open NS USB device\n Returned: "+UsbErrorCodes.getErrCode(result), EMsgType.FAIL);
|
||||||
if (result == LibUsb.ERROR_ACCESS)
|
if (result == LibUsb.ERROR_ACCESS)
|
||||||
logPrinter.print("Double check that you have administrator privileges (you're 'root') or check 'udev' rules set for this user (linux only)!\n\n" +
|
logPrinter.print("Double check that you have administrator privileges (you're 'root') or check 'udev' rules set for this user (linux only)!\n\n" +
|
||||||
"Steps to set 'udev' rules:\n" +
|
String.format("Steps to set 'udev' rules:\n" +
|
||||||
"root # vim /etc/udev/rules.d/99-NS.rules\n" +
|
"root # vim /etc/udev/rules.d/99-NS"+(initForRCM?"RCM":"")+".rules\n" +
|
||||||
"SUBSYSTEM==\"usb\", ATTRS{idVendor}==\"057e\", ATTRS{idProduct}==\"3000\", GROUP=\"plugdev\"\n" +
|
"SUBSYSTEM==\"usb\", ATTRS{idVendor}==\"%04x\", ATTRS{idProduct}==\"%04x\", GROUP=\"plugdev\"\n" +
|
||||||
"root # udevadm control --reload-rules && udevadm trigger\n", EMsgType.INFO);
|
"root # udevadm control --reload-rules && udevadm trigger\n", VENDOR_ID, PRODUCT_ID)
|
||||||
|
, EMsgType.INFO);
|
||||||
// Let's make a bit dirty workaround since such shit happened
|
// Let's make a bit dirty workaround since such shit happened
|
||||||
logPrinter.print("Requested context close", EMsgType.INFO);
|
logPrinter.print("Requested context close", EMsgType.INFO);
|
||||||
LibUsb.exit(contextNS);
|
LibUsb.exit(contextNS);
|
||||||
|
@ -107,25 +123,24 @@ class UsbConnect {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
// Set configuration (soft reset if needed)
|
if ( ! initForRCM){
|
||||||
result = LibUsb.setConfiguration(handlerNS, 1); // 1 - configuration all we need
|
// Set configuration (soft reset if needed)
|
||||||
if (result != LibUsb.SUCCESS){
|
result = LibUsb.setConfiguration(handlerNS, 1); // 1 - configuration all we need
|
||||||
logPrinter.print("Set active configuration to device\n Returned: "+UsbErrorCodes.getErrCode(result), EMsgType.FAIL);
|
if (result != LibUsb.SUCCESS){
|
||||||
close();
|
logPrinter.print("Set active configuration to device\n Returned: "+UsbErrorCodes.getErrCode(result), EMsgType.FAIL);
|
||||||
return;
|
close();
|
||||||
}
|
return;
|
||||||
else
|
}
|
||||||
logPrinter.print("Set active configuration to device.", EMsgType.PASS);
|
logPrinter.print("Set active configuration to device.", EMsgType.PASS);
|
||||||
|
}
|
||||||
// Claim interface
|
// Claim interface
|
||||||
result = LibUsb.claimInterface(handlerNS, DEFAULT_INTERFACE);
|
result = LibUsb.claimInterface(handlerNS, DEFAULT_INTERFACE);
|
||||||
if (result != LibUsb.SUCCESS) {
|
if (result != LibUsb.SUCCESS) {
|
||||||
logPrinter.print("Claim interface\n Returned: "+UsbErrorCodes.getErrCode(result), EMsgType.FAIL);
|
logPrinter.print("Claim interface\n Returned: "+UsbErrorCodes.getErrCode(result), EMsgType.FAIL);
|
||||||
close();
|
close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
logPrinter.print("Claim interface", EMsgType.PASS);
|
||||||
logPrinter.print("Claim interface", EMsgType.PASS);
|
|
||||||
|
|
||||||
this.connected = true;
|
this.connected = true;
|
||||||
}
|
}
|
||||||
|
@ -134,23 +149,36 @@ class UsbConnect {
|
||||||
* Get USB status
|
* Get USB status
|
||||||
* @return status of connection
|
* @return status of connection
|
||||||
*/
|
*/
|
||||||
boolean isConnected() { return connected; }
|
public boolean isConnected() { return connected; }
|
||||||
/**
|
/**
|
||||||
* Getter for handler
|
* Getter for handler
|
||||||
* @return DeviceHandle of NS
|
* @return DeviceHandle of NS
|
||||||
*/
|
*/
|
||||||
DeviceHandle getHandlerNS(){ return handlerNS; }
|
public DeviceHandle getNsHandler(){ return handlerNS; }
|
||||||
|
/**
|
||||||
|
* Getter for 'Bus ID' where NS located found
|
||||||
|
*/
|
||||||
|
public int getNsBus(){
|
||||||
|
return LibUsb.getBusNumber(deviceNS);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Getter for 'Device address' where NS located at
|
||||||
|
*/
|
||||||
|
public int getNsAddress(){
|
||||||
|
return LibUsb.getDeviceAddress(deviceNS);
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Correct exit
|
* Correct exit
|
||||||
* */
|
* */
|
||||||
void close(){
|
public void close(){
|
||||||
// Close handler in the end
|
// Close handler in the end
|
||||||
if (handlerNS != null) {
|
if (handlerNS != null) {
|
||||||
// Try to release interface
|
// Try to release interface
|
||||||
int result = LibUsb.releaseInterface(handlerNS, DEFAULT_INTERFACE);
|
int result = LibUsb.releaseInterface(handlerNS, DEFAULT_INTERFACE);
|
||||||
|
|
||||||
if (result != LibUsb.SUCCESS)
|
if (result != LibUsb.SUCCESS)
|
||||||
logPrinter.print("Release interface\n Returned: "+result+" (sometimes it's not an issue)", EMsgType.WARNING);
|
logPrinter.print("Release interface" +
|
||||||
|
"\n Returned: "+result+" (sometimes it's not an issue)", EMsgType.WARNING);
|
||||||
else
|
else
|
||||||
logPrinter.print("Release interface", EMsgType.PASS);
|
logPrinter.print("Release interface", EMsgType.PASS);
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@ package nsusbloader.COM.USB;
|
||||||
|
|
||||||
import org.usb4java.LibUsb;
|
import org.usb4java.LibUsb;
|
||||||
|
|
||||||
class UsbErrorCodes {
|
public class UsbErrorCodes {
|
||||||
static String getErrCode(int value){
|
public static String getErrCode(int value){
|
||||||
switch (value){
|
switch (value){
|
||||||
case LibUsb.ERROR_ACCESS:
|
case LibUsb.ERROR_ACCESS:
|
||||||
return "ERROR_ACCESS";
|
return "ERROR_ACCESS";
|
||||||
|
|
|
@ -2,20 +2,32 @@ package nsusbloader.Controllers;
|
||||||
|
|
||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
import javafx.collections.ObservableList;
|
import javafx.collections.ObservableList;
|
||||||
|
import javafx.concurrent.Task;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.fxml.Initializable;
|
import javafx.fxml.Initializable;
|
||||||
import javafx.scene.control.*;
|
import javafx.scene.control.*;
|
||||||
import javafx.scene.layout.Pane;
|
import javafx.scene.input.DragEvent;
|
||||||
|
import javafx.scene.input.TransferMode;
|
||||||
|
import javafx.scene.layout.AnchorPane;
|
||||||
import javafx.scene.layout.Region;
|
import javafx.scene.layout.Region;
|
||||||
|
import javafx.stage.DirectoryChooser;
|
||||||
|
import javafx.stage.FileChooser;
|
||||||
import nsusbloader.AppPreferences;
|
import nsusbloader.AppPreferences;
|
||||||
|
import nsusbloader.COM.NET.NETCommunications;
|
||||||
|
import nsusbloader.COM.USB.UsbCommunications;
|
||||||
import nsusbloader.MediatorControl;
|
import nsusbloader.MediatorControl;
|
||||||
|
import nsusbloader.NSLDataTypes.EModule;
|
||||||
|
import nsusbloader.ServiceWindow;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.ResourceBundle;
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
public class FrontController implements Initializable {
|
public class FrontController implements Initializable {
|
||||||
@FXML
|
@FXML
|
||||||
private Pane specialPane;
|
private AnchorPane usbNetPane;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private ChoiceBox<String> choiceProtocol, choiceNetUsb;
|
private ChoiceBox<String> choiceProtocol, choiceNetUsb;
|
||||||
|
@ -26,11 +38,19 @@ public class FrontController implements Initializable {
|
||||||
@FXML
|
@FXML
|
||||||
private Button switchThemeBtn;
|
private Button switchThemeBtn;
|
||||||
@FXML
|
@FXML
|
||||||
public NSTableViewController tableFilesListController; // Accessible from Mediator
|
public NSTableViewController tableFilesListController; // Accessible from Mediator (for drag-n-drop support)
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private Button selectNspBtn, selectSplitNspBtn, uploadStopBtn;
|
||||||
|
private String previouslyOpenedPath;
|
||||||
|
private Region btnUpStopImage;
|
||||||
|
private ResourceBundle resourceBundle;
|
||||||
|
private Task<Void> usbNetCommunications;
|
||||||
|
private Thread workThread;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize(URL url, ResourceBundle resourceBundle) {
|
public void initialize(URL url, ResourceBundle resourceBundle) {
|
||||||
specialPane.getStyleClass().add("special-pane-as-border"); // UI hacks
|
this.resourceBundle = resourceBundle;
|
||||||
|
|
||||||
ObservableList<String> choiceProtocolList = FXCollections.observableArrayList("TinFoil", "GoldLeaf");
|
ObservableList<String> choiceProtocolList = FXCollections.observableArrayList("TinFoil", "GoldLeaf");
|
||||||
choiceProtocol.setItems(choiceProtocolList);
|
choiceProtocol.setItems(choiceProtocolList);
|
||||||
|
@ -52,9 +72,9 @@ public class FrontController implements Initializable {
|
||||||
}
|
}
|
||||||
// Really bad disable-enable upload button function
|
// Really bad disable-enable upload button function
|
||||||
if (tableFilesListController.isFilesForUploadListEmpty())
|
if (tableFilesListController.isFilesForUploadListEmpty())
|
||||||
MediatorControl.getInstance().getContoller().disableUploadStopBtn(true);
|
disableUploadStopBtn(true);
|
||||||
else
|
else
|
||||||
MediatorControl.getInstance().getContoller().disableUploadStopBtn(false);
|
disableUploadStopBtn(false);
|
||||||
}); // Add listener to notify tableView controller
|
}); // Add listener to notify tableView controller
|
||||||
tableFilesListController.setNewProtocol(choiceProtocol.getSelectionModel().getSelectedItem()); // Notify tableView controller
|
tableFilesListController.setNewProtocol(choiceProtocol.getSelectionModel().getSelectedItem()); // Notify tableView controller
|
||||||
|
|
||||||
|
@ -92,6 +112,28 @@ public class FrontController implements Initializable {
|
||||||
btnSwitchImage.getStyleClass().add("regionLamp");
|
btnSwitchImage.getStyleClass().add("regionLamp");
|
||||||
switchThemeBtn.setGraphic(btnSwitchImage);
|
switchThemeBtn.setGraphic(btnSwitchImage);
|
||||||
this.switchThemeBtn.setOnAction(e->switchTheme());
|
this.switchThemeBtn.setOnAction(e->switchTheme());
|
||||||
|
|
||||||
|
|
||||||
|
if (getSelectedProtocol().equals("TinFoil"))
|
||||||
|
uploadStopBtn.setDisable(true);
|
||||||
|
else
|
||||||
|
uploadStopBtn.setDisable(false);
|
||||||
|
selectNspBtn.setOnAction(e-> selectFilesBtnAction());
|
||||||
|
|
||||||
|
selectSplitNspBtn.setOnAction(e-> selectSplitBtnAction());
|
||||||
|
selectSplitNspBtn.getStyleClass().add("buttonSelect");
|
||||||
|
|
||||||
|
uploadStopBtn.setOnAction(e-> uploadBtnAction());
|
||||||
|
|
||||||
|
selectNspBtn.getStyleClass().add("buttonSelect");
|
||||||
|
|
||||||
|
this.btnUpStopImage = new Region();
|
||||||
|
btnUpStopImage.getStyleClass().add("regionUpload");
|
||||||
|
|
||||||
|
uploadStopBtn.getStyleClass().add("buttonUp");
|
||||||
|
uploadStopBtn.setGraphic(btnUpStopImage);
|
||||||
|
|
||||||
|
this.previouslyOpenedPath = AppPreferences.getInstance().getRecent();
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Changes UI theme on the go
|
* Changes UI theme on the go
|
||||||
|
@ -125,4 +167,200 @@ public class FrontController implements Initializable {
|
||||||
String getNsIp(){
|
String getNsIp(){
|
||||||
return nsIpTextField.getText();
|
return nsIpTextField.getText();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*-****************************************************************************************************************-*/
|
||||||
|
/**
|
||||||
|
* Functionality for selecting NSP button.
|
||||||
|
* */
|
||||||
|
private void selectFilesBtnAction(){
|
||||||
|
List<File> filesList;
|
||||||
|
FileChooser fileChooser = new FileChooser();
|
||||||
|
fileChooser.setTitle(resourceBundle.getString("btn_OpenFile"));
|
||||||
|
|
||||||
|
File validator = new File(previouslyOpenedPath);
|
||||||
|
if (validator.exists())
|
||||||
|
fileChooser.setInitialDirectory(validator);
|
||||||
|
else
|
||||||
|
fileChooser.setInitialDirectory(new File(System.getProperty("user.home")));
|
||||||
|
|
||||||
|
if (getSelectedProtocol().equals("TinFoil") && MediatorControl.getInstance().getContoller().getSettingsCtrlr().getTfXciNszXczSupport())
|
||||||
|
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("NSP/XCI/NSZ/XCZ", "*.nsp", "*.xci", "*.nsz", "*.xcz"));
|
||||||
|
else if (getSelectedProtocol().equals("GoldLeaf") && (! MediatorControl.getInstance().getContoller().getSettingsCtrlr().getNSPFileFilterForGL()))
|
||||||
|
fileChooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("Any file", "*.*"),
|
||||||
|
new FileChooser.ExtensionFilter("NSP ROM", "*.nsp")
|
||||||
|
);
|
||||||
|
else
|
||||||
|
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("NSP ROM", "*.nsp"));
|
||||||
|
|
||||||
|
filesList = fileChooser.showOpenMultipleDialog(usbNetPane.getScene().getWindow());
|
||||||
|
if (filesList != null && !filesList.isEmpty()) {
|
||||||
|
tableFilesListController.setFiles(filesList);
|
||||||
|
uploadStopBtn.setDisable(false);
|
||||||
|
previouslyOpenedPath = filesList.get(0).getParent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Functionality for selecting Split NSP button.
|
||||||
|
* */
|
||||||
|
private void selectSplitBtnAction(){
|
||||||
|
File splitFile;
|
||||||
|
DirectoryChooser dirChooser = new DirectoryChooser();
|
||||||
|
dirChooser.setTitle(resourceBundle.getString("btn_OpenFile"));
|
||||||
|
|
||||||
|
File validator = new File(previouslyOpenedPath);
|
||||||
|
if (validator.exists())
|
||||||
|
dirChooser.setInitialDirectory(validator);
|
||||||
|
else
|
||||||
|
dirChooser.setInitialDirectory(new File(System.getProperty("user.home")));
|
||||||
|
|
||||||
|
splitFile = dirChooser.showDialog(usbNetPane.getScene().getWindow());
|
||||||
|
|
||||||
|
if (splitFile != null && splitFile.getName().toLowerCase().endsWith(".nsp")) {
|
||||||
|
tableFilesListController.setFile(splitFile);
|
||||||
|
uploadStopBtn.setDisable(false); // Is it useful?
|
||||||
|
previouslyOpenedPath = splitFile.getParent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* It's button listener when no transmission executes
|
||||||
|
* */
|
||||||
|
private void uploadBtnAction(){
|
||||||
|
if ((workThread == null || !workThread.isAlive())){
|
||||||
|
// Collect files
|
||||||
|
List<File> nspToUpload;
|
||||||
|
if (tableFilesListController.getFilesForUpload() == null && getSelectedProtocol().equals("TinFoil")) {
|
||||||
|
MediatorControl.getInstance().getContoller().logArea.setText(resourceBundle.getString("tab3_Txt_NoFolderOrFileSelected"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if ((nspToUpload = tableFilesListController.getFilesForUpload()) != null){
|
||||||
|
MediatorControl.getInstance().getContoller().logArea.setText(resourceBundle.getString("tab3_Txt_FilesToUploadTitle")+"\n");
|
||||||
|
for (File item: nspToUpload)
|
||||||
|
MediatorControl.getInstance().getContoller().logArea.appendText(" "+item.getAbsolutePath()+"\n");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
MediatorControl.getInstance().getContoller().logArea.clear();
|
||||||
|
nspToUpload = new LinkedList<>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If USB selected
|
||||||
|
if (getSelectedProtocol().equals("GoldLeaf") ||
|
||||||
|
( getSelectedProtocol().equals("TinFoil") && getSelectedNetUsb().equals("USB") )
|
||||||
|
){
|
||||||
|
usbNetCommunications = new UsbCommunications(nspToUpload, getSelectedProtocol()+MediatorControl.getInstance().getContoller().getSettingsCtrlr().getGlOldVer(), MediatorControl.getInstance().getContoller().getSettingsCtrlr().getNSPFileFilterForGL());
|
||||||
|
workThread = new Thread(usbNetCommunications);
|
||||||
|
workThread.setDaemon(true);
|
||||||
|
workThread.start();
|
||||||
|
}
|
||||||
|
else { // NET INSTALL OVER TINFOIL
|
||||||
|
if (MediatorControl.getInstance().getContoller().getSettingsCtrlr().isNsIpValidate() && ! getNsIp().matches("^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])$"))
|
||||||
|
if (!ServiceWindow.getConfirmationWindow(resourceBundle.getString("windowTitleBadIp"),resourceBundle.getString("windowBodyBadIp")))
|
||||||
|
return;
|
||||||
|
|
||||||
|
String nsIP = getNsIp();
|
||||||
|
|
||||||
|
if (! MediatorControl.getInstance().getContoller().getSettingsCtrlr().getExpertModeSelected())
|
||||||
|
usbNetCommunications = new NETCommunications(nspToUpload, nsIP, false, "", "", "");
|
||||||
|
else {
|
||||||
|
usbNetCommunications = new NETCommunications(
|
||||||
|
nspToUpload,
|
||||||
|
nsIP,
|
||||||
|
MediatorControl.getInstance().getContoller().getSettingsCtrlr().getNotServeSelected(),
|
||||||
|
MediatorControl.getInstance().getContoller().getSettingsCtrlr().getAutoIpSelected()?"":MediatorControl.getInstance().getContoller().getSettingsCtrlr().getHostIp(),
|
||||||
|
MediatorControl.getInstance().getContoller().getSettingsCtrlr().getRandPortSelected()?"":MediatorControl.getInstance().getContoller().getSettingsCtrlr().getHostPort(),
|
||||||
|
MediatorControl.getInstance().getContoller().getSettingsCtrlr().getNotServeSelected()?MediatorControl.getInstance().getContoller().getSettingsCtrlr().getHostExtra():""
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
workThread = new Thread(usbNetCommunications);
|
||||||
|
workThread.setDaemon(true);
|
||||||
|
workThread.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* It's button listener when transmission in progress
|
||||||
|
* */
|
||||||
|
private void stopBtnAction(){
|
||||||
|
if (workThread != null && workThread.isAlive()){
|
||||||
|
usbNetCommunications.cancel(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Drag-n-drop support (dragOver consumer)
|
||||||
|
* */
|
||||||
|
@FXML
|
||||||
|
private void handleDragOver(DragEvent event){
|
||||||
|
if (event.getDragboard().hasFiles() && ! MediatorControl.getInstance().getTransferActive())
|
||||||
|
event.acceptTransferModes(TransferMode.ANY);
|
||||||
|
event.consume();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Drag-n-drop support (drop consumer)
|
||||||
|
* */
|
||||||
|
@FXML
|
||||||
|
private void handleDrop(DragEvent event){
|
||||||
|
List<File> filesDropped = event.getDragboard().getFiles();
|
||||||
|
|
||||||
|
if (getSelectedProtocol().equals("TinFoil") && MediatorControl.getInstance().getContoller().getSettingsCtrlr().getTfXciNszXczSupport())
|
||||||
|
filesDropped.removeIf(file -> ! file.getName().toLowerCase().matches("(.*\\.nsp$)|(.*\\.xci$)|(.*\\.nsz$)|(.*\\.xcz$)"));
|
||||||
|
else if (getSelectedProtocol().equals("GoldLeaf") && (! MediatorControl.getInstance().getContoller().getSettingsCtrlr().getNSPFileFilterForGL()))
|
||||||
|
filesDropped.removeIf(file -> (file.isDirectory() && ! file.getName().toLowerCase().matches(".*\\.nsp$")));
|
||||||
|
else
|
||||||
|
filesDropped.removeIf(file -> ! file.getName().toLowerCase().matches(".*\\.nsp$"));
|
||||||
|
|
||||||
|
if ( ! filesDropped.isEmpty() )
|
||||||
|
tableFilesListController.setFiles(filesDropped);
|
||||||
|
|
||||||
|
event.setDropCompleted(true);
|
||||||
|
event.consume();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* This thing modify UI for reusing 'Upload to NS' button and make functionality set for "Stop transmission"
|
||||||
|
* Called from mediator
|
||||||
|
* TODO: remove shitcoding practices
|
||||||
|
* */
|
||||||
|
public void notifyTransmThreadStarted(boolean isActive, EModule type){
|
||||||
|
if (! type.equals(EModule.USB_NET_TRANSFERS)){
|
||||||
|
usbNetPane.setDisable(isActive);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (isActive) {
|
||||||
|
selectNspBtn.setDisable(true);
|
||||||
|
selectSplitNspBtn.setDisable(true);
|
||||||
|
btnUpStopImage.getStyleClass().clear();
|
||||||
|
btnUpStopImage.getStyleClass().add("regionStop");
|
||||||
|
|
||||||
|
uploadStopBtn.setOnAction(e-> stopBtnAction());
|
||||||
|
uploadStopBtn.setText(resourceBundle.getString("btn_Stop"));
|
||||||
|
uploadStopBtn.getStyleClass().remove("buttonUp");
|
||||||
|
uploadStopBtn.getStyleClass().add("buttonStop");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
selectNspBtn.setDisable(false);
|
||||||
|
selectSplitNspBtn.setDisable(false);
|
||||||
|
btnUpStopImage.getStyleClass().clear();
|
||||||
|
btnUpStopImage.getStyleClass().add("regionUpload");
|
||||||
|
|
||||||
|
uploadStopBtn.setOnAction(e-> uploadBtnAction());
|
||||||
|
uploadStopBtn.setText(resourceBundle.getString("btn_Upload"));
|
||||||
|
uploadStopBtn.getStyleClass().remove("buttonStop");
|
||||||
|
uploadStopBtn.getStyleClass().add("buttonUp");
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Crunch. This function called from NSTableViewController
|
||||||
|
* */
|
||||||
|
public void disableUploadStopBtn(boolean disable){
|
||||||
|
if (getSelectedProtocol().equals("TinFoil"))
|
||||||
|
uploadStopBtn.setDisable(disable);
|
||||||
|
else
|
||||||
|
uploadStopBtn.setDisable(false);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Get 'Recent' path
|
||||||
|
*/
|
||||||
|
public String getRecentPath(){
|
||||||
|
return previouslyOpenedPath;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,19 +5,10 @@ import javafx.concurrent.Task;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.fxml.Initializable;
|
import javafx.fxml.Initializable;
|
||||||
import javafx.scene.control.*;
|
import javafx.scene.control.*;
|
||||||
import javafx.scene.input.DragEvent;
|
|
||||||
import javafx.scene.input.TransferMode;
|
|
||||||
import javafx.scene.layout.Region;
|
|
||||||
import javafx.stage.DirectoryChooser;
|
|
||||||
import javafx.stage.FileChooser;
|
|
||||||
import nsusbloader.*;
|
import nsusbloader.*;
|
||||||
import nsusbloader.ModelControllers.UpdatesChecker;
|
import nsusbloader.ModelControllers.UpdatesChecker;
|
||||||
import nsusbloader.COM.NET.NETCommunications;
|
|
||||||
import nsusbloader.COM.USB.UsbCommunications;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ResourceBundle;
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
|
@ -27,22 +18,18 @@ public class NSLMainController implements Initializable {
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
public TextArea logArea; // Accessible from Mediator
|
public TextArea logArea; // Accessible from Mediator
|
||||||
@FXML
|
|
||||||
private Button selectNspBtn, selectSplitNspBtn, uploadStopBtn;
|
|
||||||
|
|
||||||
private Region btnUpStopImage;
|
|
||||||
@FXML
|
@FXML
|
||||||
public ProgressBar progressBar; // Accessible from Mediator
|
public ProgressBar progressBar; // Accessible from Mediator
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
public FrontController FrontTabController; // Accessible from Mediator | todo: incapsulate
|
||||||
@FXML
|
@FXML
|
||||||
private SettingsController SettingsTabController;
|
private SettingsController SettingsTabController;
|
||||||
@FXML
|
@FXML
|
||||||
public FrontController FrontTabController; // Accessible from Mediator | todo: incapsulate
|
private SplitMergeController SplitMergeTabController;
|
||||||
|
@FXML
|
||||||
private Task<Void> usbNetCommunications;
|
private RcmController RcmTabController;
|
||||||
private Thread workThread;
|
|
||||||
|
|
||||||
private String previouslyOpenedPath;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize(URL url, ResourceBundle rb) {
|
public void initialize(URL url, ResourceBundle rb) {
|
||||||
|
@ -56,27 +43,6 @@ public class NSLMainController implements Initializable {
|
||||||
|
|
||||||
MediatorControl.getInstance().setController(this);
|
MediatorControl.getInstance().setController(this);
|
||||||
|
|
||||||
if (FrontTabController.getSelectedProtocol().equals("TinFoil"))
|
|
||||||
uploadStopBtn.setDisable(true);
|
|
||||||
else
|
|
||||||
uploadStopBtn.setDisable(false);
|
|
||||||
selectNspBtn.setOnAction(e-> selectFilesBtnAction());
|
|
||||||
|
|
||||||
selectSplitNspBtn.setOnAction(e-> selectSplitBtnAction());
|
|
||||||
selectSplitNspBtn.getStyleClass().add("buttonSelect");
|
|
||||||
|
|
||||||
uploadStopBtn.setOnAction(e-> uploadBtnAction());
|
|
||||||
|
|
||||||
selectNspBtn.getStyleClass().add("buttonSelect");
|
|
||||||
|
|
||||||
this.btnUpStopImage = new Region();
|
|
||||||
btnUpStopImage.getStyleClass().add("regionUpload");
|
|
||||||
|
|
||||||
uploadStopBtn.getStyleClass().add("buttonUp");
|
|
||||||
uploadStopBtn.setGraphic(btnUpStopImage);
|
|
||||||
|
|
||||||
this.previouslyOpenedPath = AppPreferences.getInstance().getRecent();
|
|
||||||
|
|
||||||
if (AppPreferences.getInstance().getAutoCheckUpdates()){
|
if (AppPreferences.getInstance().getAutoCheckUpdates()){
|
||||||
Task<List<String>> updTask = new UpdatesChecker();
|
Task<List<String>> updTask = new UpdatesChecker();
|
||||||
updTask.setOnSucceeded(event->{
|
updTask.setOnSucceeded(event->{
|
||||||
|
@ -110,201 +76,29 @@ public class NSLMainController implements Initializable {
|
||||||
public void setHostServices(HostServices hs ){ SettingsTabController.registerHostServices(hs);}
|
public void setHostServices(HostServices hs ){ SettingsTabController.registerHostServices(hs);}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Functionality for selecting NSP button.
|
* Get 'Settings' controller
|
||||||
|
* Used by FrontController
|
||||||
* */
|
* */
|
||||||
private void selectFilesBtnAction(){
|
public SettingsController getSettingsCtrlr(){
|
||||||
List<File> filesList;
|
return SettingsTabController;
|
||||||
FileChooser fileChooser = new FileChooser();
|
|
||||||
fileChooser.setTitle(resourceBundle.getString("btn_OpenFile"));
|
|
||||||
|
|
||||||
File validator = new File(previouslyOpenedPath);
|
|
||||||
if (validator.exists())
|
|
||||||
fileChooser.setInitialDirectory(validator);
|
|
||||||
else
|
|
||||||
fileChooser.setInitialDirectory(new File(System.getProperty("user.home")));
|
|
||||||
|
|
||||||
if (FrontTabController.getSelectedProtocol().equals("TinFoil") && SettingsTabController.getTfXciNszXczSupport())
|
|
||||||
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("NSP/XCI/NSZ/XCZ", "*.nsp", "*.xci", "*.nsz", "*.xcz"));
|
|
||||||
else if (FrontTabController.getSelectedProtocol().equals("GoldLeaf") && (! SettingsTabController.getNSPFileFilterForGL()))
|
|
||||||
fileChooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("Any file", "*.*"),
|
|
||||||
new FileChooser.ExtensionFilter("NSP ROM", "*.nsp")
|
|
||||||
);
|
|
||||||
else
|
|
||||||
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("NSP ROM", "*.nsp"));
|
|
||||||
|
|
||||||
filesList = fileChooser.showOpenMultipleDialog(logArea.getScene().getWindow());
|
|
||||||
if (filesList != null && !filesList.isEmpty()) {
|
|
||||||
FrontTabController.tableFilesListController.setFiles(filesList);
|
|
||||||
uploadStopBtn.setDisable(false);
|
|
||||||
previouslyOpenedPath = filesList.get(0).getParent();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* Functionality for selecting Split NSP button.
|
|
||||||
* */
|
|
||||||
private void selectSplitBtnAction(){
|
|
||||||
File splitFile;
|
|
||||||
DirectoryChooser dirChooser = new DirectoryChooser();
|
|
||||||
dirChooser.setTitle(resourceBundle.getString("btn_OpenFile"));
|
|
||||||
|
|
||||||
File validator = new File(previouslyOpenedPath);
|
public FrontController getFrontCtrlr(){
|
||||||
if (validator.exists())
|
return FrontTabController;
|
||||||
dirChooser.setInitialDirectory(validator);
|
|
||||||
else
|
|
||||||
dirChooser.setInitialDirectory(new File(System.getProperty("user.home")));
|
|
||||||
|
|
||||||
splitFile = dirChooser.showDialog(logArea.getScene().getWindow());
|
|
||||||
|
|
||||||
if (splitFile != null && splitFile.getName().toLowerCase().endsWith(".nsp")) {
|
|
||||||
FrontTabController.tableFilesListController.setFile(splitFile);
|
|
||||||
uploadStopBtn.setDisable(false); // Is it useful?
|
|
||||||
previouslyOpenedPath = splitFile.getParent();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* It's button listener when no transmission executes
|
|
||||||
* */
|
|
||||||
private void uploadBtnAction(){
|
|
||||||
if ((workThread == null || !workThread.isAlive())){
|
|
||||||
// Collect files
|
|
||||||
List<File> nspToUpload;
|
|
||||||
if (FrontTabController.tableFilesListController.getFilesForUpload() == null && FrontTabController.getSelectedProtocol().equals("TinFoil")) {
|
|
||||||
logArea.setText(resourceBundle.getString("tab3_Txt_NoFolderOrFileSelected"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if ((nspToUpload = FrontTabController.tableFilesListController.getFilesForUpload()) != null){
|
|
||||||
logArea.setText(resourceBundle.getString("tab3_Txt_FilesToUploadTitle")+"\n");
|
|
||||||
for (File item: nspToUpload)
|
|
||||||
logArea.appendText(" "+item.getAbsolutePath()+"\n");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
logArea.clear();
|
|
||||||
nspToUpload = new LinkedList<>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// If USB selected
|
|
||||||
if (FrontTabController.getSelectedProtocol().equals("GoldLeaf") ||
|
|
||||||
( FrontTabController.getSelectedProtocol().equals("TinFoil") && FrontTabController.getSelectedNetUsb().equals("USB") )
|
|
||||||
){
|
|
||||||
usbNetCommunications = new UsbCommunications(nspToUpload, FrontTabController.getSelectedProtocol()+SettingsTabController.getGlOldVer(), SettingsTabController.getNSPFileFilterForGL());
|
|
||||||
workThread = new Thread(usbNetCommunications);
|
|
||||||
workThread.setDaemon(true);
|
|
||||||
workThread.start();
|
|
||||||
}
|
|
||||||
else { // NET INSTALL OVER TINFOIL
|
|
||||||
if (SettingsTabController.isNsIpValidate() && ! FrontTabController.getNsIp().matches("^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])$"))
|
|
||||||
if (!ServiceWindow.getConfirmationWindow(resourceBundle.getString("windowTitleBadIp"),resourceBundle.getString("windowBodyBadIp")))
|
|
||||||
return;
|
|
||||||
|
|
||||||
String nsIP = FrontTabController.getNsIp();
|
public SplitMergeController getSmCtrlr(){
|
||||||
|
return SplitMergeTabController;
|
||||||
if (!SettingsTabController.getExpertModeSelected())
|
|
||||||
usbNetCommunications = new NETCommunications(nspToUpload, nsIP, false, "", "", "");
|
|
||||||
else {
|
|
||||||
usbNetCommunications = new NETCommunications(
|
|
||||||
nspToUpload,
|
|
||||||
nsIP,
|
|
||||||
SettingsTabController.getNotServeSelected(),
|
|
||||||
SettingsTabController.getAutoIpSelected()?"":SettingsTabController.getHostIp(),
|
|
||||||
SettingsTabController.getRandPortSelected()?"":SettingsTabController.getHostPort(),
|
|
||||||
SettingsTabController.getNotServeSelected()?SettingsTabController.getHostExtra():""
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
workThread = new Thread(usbNetCommunications);
|
|
||||||
workThread.setDaemon(true);
|
|
||||||
workThread.start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* It's button listener when transmission in progress
|
|
||||||
* */
|
|
||||||
private void stopBtnAction(){
|
|
||||||
if (workThread != null && workThread.isAlive()){
|
|
||||||
usbNetCommunications.cancel(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* This thing modify UI for reusing 'Upload to NS' button and make functionality set for "Stop transmission"
|
|
||||||
* Called from mediator
|
|
||||||
* */
|
|
||||||
public void notifyTransmissionStarted(boolean isTransmissionStarted){
|
|
||||||
if (isTransmissionStarted) {
|
|
||||||
selectNspBtn.setDisable(true);
|
|
||||||
selectSplitNspBtn.setDisable(true);
|
|
||||||
uploadStopBtn.setOnAction(e-> stopBtnAction());
|
|
||||||
|
|
||||||
uploadStopBtn.setText(resourceBundle.getString("btn_Stop"));
|
public RcmController getRcmCtrlr(){ return RcmTabController; }
|
||||||
|
|
||||||
btnUpStopImage.getStyleClass().remove("regionUpload");
|
|
||||||
btnUpStopImage.getStyleClass().add("regionStop");
|
|
||||||
|
|
||||||
uploadStopBtn.getStyleClass().remove("buttonUp");
|
|
||||||
uploadStopBtn.getStyleClass().add("buttonStop");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
selectNspBtn.setDisable(false);
|
|
||||||
selectSplitNspBtn.setDisable(false);
|
|
||||||
uploadStopBtn.setOnAction(e-> uploadBtnAction());
|
|
||||||
|
|
||||||
uploadStopBtn.setText(resourceBundle.getString("btn_Upload"));
|
|
||||||
|
|
||||||
btnUpStopImage.getStyleClass().remove("regionStop");
|
|
||||||
btnUpStopImage.getStyleClass().add("regionUpload");
|
|
||||||
|
|
||||||
uploadStopBtn.getStyleClass().remove("buttonStop");
|
|
||||||
uploadStopBtn.getStyleClass().add("buttonUp");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Crunch. Now you see that I'm not a programmer.. This function called from NSTableViewController
|
|
||||||
* */
|
|
||||||
public void disableUploadStopBtn(boolean disable){
|
|
||||||
if (FrontTabController.getSelectedProtocol().equals("TinFoil"))
|
|
||||||
uploadStopBtn.setDisable(disable);
|
|
||||||
else
|
|
||||||
uploadStopBtn.setDisable(false);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Drag-n-drop support (dragOver consumer)
|
|
||||||
* */
|
|
||||||
@FXML
|
|
||||||
private void handleDragOver(DragEvent event){
|
|
||||||
if (event.getDragboard().hasFiles())
|
|
||||||
event.acceptTransferModes(TransferMode.ANY);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Drag-n-drop support (drop consumer)
|
|
||||||
* */
|
|
||||||
@FXML
|
|
||||||
private void handleDrop(DragEvent event){
|
|
||||||
if (MediatorControl.getInstance().getTransferActive()) {
|
|
||||||
event.setDropCompleted(true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
List<File> filesDropped = event.getDragboard().getFiles();
|
|
||||||
|
|
||||||
if (FrontTabController.getSelectedProtocol().equals("TinFoil") && SettingsTabController.getTfXciNszXczSupport())
|
|
||||||
filesDropped.removeIf(file -> ! file.getName().toLowerCase().matches("(.*\\.nsp$)|(.*\\.xci$)|(.*\\.nsz$)|(.*\\.xcz$)"));
|
|
||||||
else if (FrontTabController.getSelectedProtocol().equals("GoldLeaf") && (! SettingsTabController.getNSPFileFilterForGL()))
|
|
||||||
filesDropped.removeIf(file -> (file.isDirectory() && ! file.getName().toLowerCase().matches(".*\\.nsp$")));
|
|
||||||
else
|
|
||||||
filesDropped.removeIf(file -> ! file.getName().toLowerCase().matches(".*\\.nsp$"));
|
|
||||||
|
|
||||||
if ( ! filesDropped.isEmpty() )
|
|
||||||
FrontTabController.tableFilesListController.setFiles(filesDropped);
|
|
||||||
|
|
||||||
event.setDropCompleted(true);
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* Save preferences before exit
|
* Save preferences before exit
|
||||||
* */
|
* */
|
||||||
public void exit(){
|
public void exit(){
|
||||||
AppPreferences.getInstance().setAll(
|
AppPreferences.getInstance().setAll(
|
||||||
FrontTabController.getSelectedProtocol(),
|
FrontTabController.getSelectedProtocol(),
|
||||||
previouslyOpenedPath,
|
FrontTabController.getRecentPath(),
|
||||||
FrontTabController.getSelectedNetUsb(),
|
FrontTabController.getSelectedNetUsb(),
|
||||||
FrontTabController.getNsIp(),
|
FrontTabController.getNsIp(),
|
||||||
SettingsTabController.isNsIpValidate(),
|
SettingsTabController.isNsIpValidate(),
|
||||||
|
@ -320,5 +114,8 @@ public class NSLMainController implements Initializable {
|
||||||
SettingsTabController.getNSPFileFilterForGL(),
|
SettingsTabController.getNSPFileFilterForGL(),
|
||||||
SettingsTabController.getGlOldVer()
|
SettingsTabController.getGlOldVer()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
SplitMergeTabController.updatePreferencesOnExit(); // NOTE: This shit above should be re-written to similar pattern
|
||||||
|
RcmTabController.updatePreferencesOnExit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,6 @@ import nsusbloader.NSLDataTypes.EFileStatus;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ResourceBundle;
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
|
@ -39,7 +38,7 @@ public class NSTableViewController implements Initializable {
|
||||||
if (keyEvent.getCode() == KeyCode.DELETE && !MediatorControl.getInstance().getTransferActive()) {
|
if (keyEvent.getCode() == KeyCode.DELETE && !MediatorControl.getInstance().getTransferActive()) {
|
||||||
rowsObsLst.removeAll(table.getSelectionModel().getSelectedItems());
|
rowsObsLst.removeAll(table.getSelectionModel().getSelectedItems());
|
||||||
if (rowsObsLst.isEmpty())
|
if (rowsObsLst.isEmpty())
|
||||||
MediatorControl.getInstance().getContoller().disableUploadStopBtn(true); // TODO: change to something better
|
MediatorControl.getInstance().getContoller().getFrontCtrlr().disableUploadStopBtn(true); // TODO: change to something better
|
||||||
table.refresh();
|
table.refresh();
|
||||||
} else if (keyEvent.getCode() == KeyCode.SPACE) {
|
} else if (keyEvent.getCode() == KeyCode.SPACE) {
|
||||||
for (NSLRowModel item : table.getSelectionModel().getSelectedItems()) {
|
for (NSLRowModel item : table.getSelectionModel().getSelectedItems()) {
|
||||||
|
@ -112,13 +111,13 @@ public class NSTableViewController implements Initializable {
|
||||||
deleteMenuItem.setOnAction(actionEvent -> {
|
deleteMenuItem.setOnAction(actionEvent -> {
|
||||||
rowsObsLst.remove(row.getItem());
|
rowsObsLst.remove(row.getItem());
|
||||||
if (rowsObsLst.isEmpty())
|
if (rowsObsLst.isEmpty())
|
||||||
MediatorControl.getInstance().getContoller().disableUploadStopBtn(true); // TODO: change to something better
|
MediatorControl.getInstance().getContoller().getFrontCtrlr().disableUploadStopBtn(true); // TODO: change to something better
|
||||||
table.refresh();
|
table.refresh();
|
||||||
});
|
});
|
||||||
MenuItem deleteAllMenuItem = new MenuItem(resourceBundle.getString("tab1_table_contextMenu_Btn_DeleteAll"));
|
MenuItem deleteAllMenuItem = new MenuItem(resourceBundle.getString("tab1_table_contextMenu_Btn_DeleteAll"));
|
||||||
deleteAllMenuItem.setOnAction(actionEvent -> {
|
deleteAllMenuItem.setOnAction(actionEvent -> {
|
||||||
rowsObsLst.clear();
|
rowsObsLst.clear();
|
||||||
MediatorControl.getInstance().getContoller().disableUploadStopBtn(true); // TODO: change to something better
|
MediatorControl.getInstance().getContoller().getFrontCtrlr().disableUploadStopBtn(true); // TODO: change to something better
|
||||||
table.refresh();
|
table.refresh();
|
||||||
});
|
});
|
||||||
contextMenu.getItems().addAll(deleteMenuItem, deleteAllMenuItem);
|
contextMenu.getItems().addAll(deleteMenuItem, deleteAllMenuItem);
|
||||||
|
@ -163,7 +162,7 @@ public class NSTableViewController implements Initializable {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rowsObsLst.add(new NSLRowModel(file, true));
|
rowsObsLst.add(new NSLRowModel(file, true));
|
||||||
MediatorControl.getInstance().getContoller().disableUploadStopBtn(false);
|
MediatorControl.getInstance().getContoller().getFrontCtrlr().disableUploadStopBtn(false); // TODO: change to something better
|
||||||
}
|
}
|
||||||
table.refresh();
|
table.refresh();
|
||||||
}
|
}
|
||||||
|
@ -183,7 +182,7 @@ public class NSTableViewController implements Initializable {
|
||||||
else {
|
else {
|
||||||
for (File file: newFiles)
|
for (File file: newFiles)
|
||||||
rowsObsLst.add(new NSLRowModel(file, true));
|
rowsObsLst.add(new NSLRowModel(file, true));
|
||||||
MediatorControl.getInstance().getContoller().disableUploadStopBtn(false);
|
MediatorControl.getInstance().getContoller().getFrontCtrlr().disableUploadStopBtn(false); // TODO: change to something better
|
||||||
}
|
}
|
||||||
//rowsObsLst.get(0).setMarkForUpload(true);
|
//rowsObsLst.get(0).setMarkForUpload(true);
|
||||||
table.refresh();
|
table.refresh();
|
||||||
|
|
329
src/main/java/nsusbloader/Controllers/RcmController.java
Normal file
329
src/main/java/nsusbloader/Controllers/RcmController.java
Normal file
|
@ -0,0 +1,329 @@
|
||||||
|
package nsusbloader.Controllers;
|
||||||
|
|
||||||
|
import javafx.concurrent.Task;
|
||||||
|
import javafx.event.ActionEvent;
|
||||||
|
import javafx.fxml.FXML;
|
||||||
|
import javafx.fxml.Initializable;
|
||||||
|
import javafx.scene.Node;
|
||||||
|
import javafx.scene.control.Button;
|
||||||
|
import javafx.scene.control.Label;
|
||||||
|
import javafx.scene.control.RadioButton;
|
||||||
|
import javafx.scene.control.ToggleGroup;
|
||||||
|
import javafx.scene.input.DragEvent;
|
||||||
|
import javafx.scene.input.MouseEvent;
|
||||||
|
import javafx.scene.input.TransferMode;
|
||||||
|
import javafx.scene.layout.VBox;
|
||||||
|
import javafx.stage.FileChooser;
|
||||||
|
import nsusbloader.AppPreferences;
|
||||||
|
import nsusbloader.MediatorControl;
|
||||||
|
import nsusbloader.NSLDataTypes.EModule;
|
||||||
|
import nsusbloader.ServiceWindow;
|
||||||
|
import nsusbloader.Utilities.RcmTask;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
|
public class RcmController implements Initializable {
|
||||||
|
@FXML
|
||||||
|
private ToggleGroup rcmToggleGrp;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private VBox rcmToolPane;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private RadioButton pldrRadio1,
|
||||||
|
pldrRadio2,
|
||||||
|
pldrRadio3,
|
||||||
|
pldrRadio4,
|
||||||
|
pldrRadio5;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private Button injectPldBtn;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private Label payloadFNameLbl1, payloadFPathLbl1,
|
||||||
|
payloadFNameLbl2, payloadFPathLbl2,
|
||||||
|
payloadFNameLbl3, payloadFPathLbl3,
|
||||||
|
payloadFNameLbl4, payloadFPathLbl4,
|
||||||
|
payloadFNameLbl5, payloadFPathLbl5;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private Label statusLbl;
|
||||||
|
|
||||||
|
private ResourceBundle rb;
|
||||||
|
private String myRegexp;
|
||||||
|
@Override
|
||||||
|
public void initialize(URL url, ResourceBundle resourceBundle) {
|
||||||
|
this.rb = resourceBundle;
|
||||||
|
rcmToggleGrp.selectToggle(pldrRadio1);
|
||||||
|
pldrRadio1.setOnAction(e -> statusLbl.setText(""));
|
||||||
|
pldrRadio2.setOnAction(e -> statusLbl.setText(""));
|
||||||
|
pldrRadio3.setOnAction(e -> statusLbl.setText(""));
|
||||||
|
pldrRadio4.setOnAction(e -> statusLbl.setText(""));
|
||||||
|
pldrRadio5.setOnAction(e -> statusLbl.setText(""));
|
||||||
|
|
||||||
|
String recentRcm1 = AppPreferences.getInstance().getRecentRcm(1);
|
||||||
|
String recentRcm2 = AppPreferences.getInstance().getRecentRcm(2);
|
||||||
|
String recentRcm3 = AppPreferences.getInstance().getRecentRcm(3);
|
||||||
|
String recentRcm4 = AppPreferences.getInstance().getRecentRcm(4);
|
||||||
|
String recentRcm5 = AppPreferences.getInstance().getRecentRcm(5);
|
||||||
|
|
||||||
|
if (File.separator.equals("/"))
|
||||||
|
this.myRegexp = "^.+/";
|
||||||
|
else
|
||||||
|
this.myRegexp = "^.+\\\\";
|
||||||
|
|
||||||
|
if (! recentRcm1.isEmpty()) {
|
||||||
|
payloadFNameLbl1.setText(recentRcm1.replaceAll(myRegexp, ""));
|
||||||
|
payloadFPathLbl1.setText(recentRcm1);
|
||||||
|
}
|
||||||
|
if (! recentRcm2.isEmpty()) {
|
||||||
|
payloadFNameLbl2.setText(recentRcm2.replaceAll(myRegexp, ""));
|
||||||
|
payloadFPathLbl2.setText(recentRcm2);
|
||||||
|
}
|
||||||
|
if (! recentRcm3.isEmpty()) {
|
||||||
|
payloadFNameLbl3.setText(recentRcm3.replaceAll(myRegexp, ""));
|
||||||
|
payloadFPathLbl3.setText(recentRcm3);
|
||||||
|
}
|
||||||
|
if (! recentRcm4.isEmpty()) {
|
||||||
|
payloadFNameLbl4.setText(recentRcm4.replaceAll(myRegexp, ""));
|
||||||
|
payloadFPathLbl4.setText(recentRcm4);
|
||||||
|
}
|
||||||
|
if (! recentRcm5.isEmpty()) {
|
||||||
|
payloadFNameLbl5.setText(recentRcm5.replaceAll(myRegexp, ""));
|
||||||
|
payloadFPathLbl5.setText(recentRcm5);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: write logic ?? Like in case PAYLOADER exist, button active. If not: not active?
|
||||||
|
injectPldBtn.setOnAction(actionEvent -> smash());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Drag-n-drop support (dragOver consumer)
|
||||||
|
* */
|
||||||
|
@FXML
|
||||||
|
private void handleDragOver(DragEvent event){
|
||||||
|
if (event.getDragboard().hasFiles())
|
||||||
|
event.acceptTransferModes(TransferMode.ANY);
|
||||||
|
event.consume();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Drag-n-drop support (drop consumer)
|
||||||
|
* */
|
||||||
|
@FXML
|
||||||
|
private void handleDrop(DragEvent event){
|
||||||
|
Node sourceNode = (Node) event.getSource();
|
||||||
|
File fileDrpd = event.getDragboard().getFiles().get(0);
|
||||||
|
|
||||||
|
if (fileDrpd.isDirectory()){
|
||||||
|
event.setDropCompleted(true);
|
||||||
|
event.consume();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String fileNameDrpd = fileDrpd.getAbsolutePath();
|
||||||
|
|
||||||
|
switch (sourceNode.getId()){
|
||||||
|
case "plHbox1":
|
||||||
|
setPayloadFile( 1, fileNameDrpd);
|
||||||
|
break;
|
||||||
|
case "plHbox2":
|
||||||
|
setPayloadFile( 2, fileNameDrpd);
|
||||||
|
break;
|
||||||
|
case "plHbox3":
|
||||||
|
setPayloadFile( 3, fileNameDrpd);
|
||||||
|
break;
|
||||||
|
case "plHbox4":
|
||||||
|
setPayloadFile( 4, fileNameDrpd);
|
||||||
|
break;
|
||||||
|
case "plHbox5":
|
||||||
|
setPayloadFile( 5, fileNameDrpd);
|
||||||
|
}
|
||||||
|
event.setDropCompleted(true);
|
||||||
|
event.consume();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setPayloadFile(int RcmBoxNo, String fileName){
|
||||||
|
String fileNameShort = fileName.replaceAll(myRegexp, "");
|
||||||
|
switch (RcmBoxNo){
|
||||||
|
case 1:
|
||||||
|
payloadFNameLbl1.setText(fileNameShort);
|
||||||
|
payloadFPathLbl1.setText(fileName);
|
||||||
|
rcmToggleGrp.selectToggle(pldrRadio1);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
payloadFNameLbl2.setText(fileNameShort);
|
||||||
|
payloadFPathLbl2.setText(fileName);
|
||||||
|
rcmToggleGrp.selectToggle(pldrRadio2);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
payloadFNameLbl3.setText(fileNameShort);
|
||||||
|
payloadFPathLbl3.setText(fileName);
|
||||||
|
rcmToggleGrp.selectToggle(pldrRadio3);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
payloadFNameLbl4.setText(fileNameShort);
|
||||||
|
payloadFPathLbl4.setText(fileName);
|
||||||
|
rcmToggleGrp.selectToggle(pldrRadio4);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
payloadFNameLbl5.setText(fileNameShort);
|
||||||
|
payloadFPathLbl5.setText(fileName);
|
||||||
|
rcmToggleGrp.selectToggle(pldrRadio5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void smash(){
|
||||||
|
statusLbl.setText("");
|
||||||
|
if (MediatorControl.getInstance().getTransferActive()) {
|
||||||
|
ServiceWindow.getErrorNotification(rb.getString("windowTitleError"), rb.getString("windowBodyPleaseFinishTransfersFirst"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Task<Boolean> RcmTask;
|
||||||
|
RadioButton selectedRadio = (RadioButton)rcmToggleGrp.getSelectedToggle();
|
||||||
|
switch (selectedRadio.getId()){
|
||||||
|
case "pldrRadio1":
|
||||||
|
RcmTask = new RcmTask(payloadFPathLbl1.getText());
|
||||||
|
break;
|
||||||
|
case "pldrRadio2":
|
||||||
|
RcmTask = new RcmTask(payloadFPathLbl2.getText());
|
||||||
|
break;
|
||||||
|
case "pldrRadio3":
|
||||||
|
RcmTask = new RcmTask(payloadFPathLbl3.getText());
|
||||||
|
break;
|
||||||
|
case "pldrRadio4":
|
||||||
|
RcmTask = new RcmTask(payloadFPathLbl4.getText());
|
||||||
|
break;
|
||||||
|
case "pldrRadio5":
|
||||||
|
RcmTask = new RcmTask(payloadFPathLbl5.getText());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RcmTask.setOnSucceeded(event -> {
|
||||||
|
if (RcmTask.getValue())
|
||||||
|
statusLbl.setText(rb.getString("done_txt"));
|
||||||
|
else
|
||||||
|
statusLbl.setText(rb.getString("failure_txt"));
|
||||||
|
});
|
||||||
|
Thread RcmThread = new Thread(RcmTask);
|
||||||
|
RcmThread.setDaemon(true);
|
||||||
|
RcmThread.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private void bntSelectPayloader(ActionEvent event){
|
||||||
|
FileChooser fileChooser = new FileChooser();
|
||||||
|
fileChooser.setTitle(rb.getString("btn_Select"));
|
||||||
|
|
||||||
|
File validator = new File(payloadFPathLbl1.getText()).getParentFile();
|
||||||
|
if (validator != null && validator.exists())
|
||||||
|
fileChooser.setInitialDirectory(validator);
|
||||||
|
else
|
||||||
|
fileChooser.setInitialDirectory(new File(System.getProperty("user.home")));
|
||||||
|
|
||||||
|
fileChooser.getExtensionFilters().addAll(
|
||||||
|
new FileChooser.ExtensionFilter("bin", "*.bin"),
|
||||||
|
new FileChooser.ExtensionFilter("Any file", "*.*")
|
||||||
|
);
|
||||||
|
|
||||||
|
File payloadFile = fileChooser.showOpenDialog(payloadFPathLbl1.getScene().getWindow());
|
||||||
|
|
||||||
|
if (payloadFile == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
final String fullFileName = payloadFile.getAbsolutePath();
|
||||||
|
final Node btn = (Node)event.getSource();
|
||||||
|
|
||||||
|
switch (btn.getId()){
|
||||||
|
case "selPldBtn1":
|
||||||
|
setPayloadFile(1, fullFileName);
|
||||||
|
break;
|
||||||
|
case "selPldBtn2":
|
||||||
|
setPayloadFile(2, fullFileName);
|
||||||
|
break;
|
||||||
|
case "selPldBtn3":
|
||||||
|
setPayloadFile(3, fullFileName);
|
||||||
|
break;
|
||||||
|
case "selPldBtn4":
|
||||||
|
setPayloadFile(4, fullFileName);
|
||||||
|
break;
|
||||||
|
case "selPldBtn5":
|
||||||
|
setPayloadFile(5, fullFileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@FXML
|
||||||
|
private void bntResetPayloader(ActionEvent event){
|
||||||
|
final Node btn = (Node)event.getSource();
|
||||||
|
|
||||||
|
switch (btn.getId()){
|
||||||
|
case "resPldBtn1":
|
||||||
|
payloadFNameLbl1.setText("");
|
||||||
|
payloadFPathLbl1.setText("");
|
||||||
|
statusLbl.setText("");
|
||||||
|
break;
|
||||||
|
case "resPldBtn2":
|
||||||
|
payloadFNameLbl2.setText("");
|
||||||
|
payloadFPathLbl2.setText("");
|
||||||
|
statusLbl.setText("");
|
||||||
|
break;
|
||||||
|
case "resPldBtn3":
|
||||||
|
payloadFNameLbl3.setText("");
|
||||||
|
payloadFPathLbl3.setText("");
|
||||||
|
statusLbl.setText("");
|
||||||
|
break;
|
||||||
|
case "resPldBtn4":
|
||||||
|
payloadFNameLbl4.setText("");
|
||||||
|
payloadFPathLbl4.setText("");
|
||||||
|
statusLbl.setText("");
|
||||||
|
break;
|
||||||
|
case "resPldBtn5":
|
||||||
|
payloadFNameLbl5.setText("");
|
||||||
|
payloadFPathLbl5.setText("");
|
||||||
|
statusLbl.setText("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
public void selectPldrPane(MouseEvent mouseEvent) {
|
||||||
|
final Node selectedPane = (Node)mouseEvent.getSource();
|
||||||
|
|
||||||
|
switch (selectedPane.getId()){
|
||||||
|
case "pldPane1":
|
||||||
|
pldrRadio1.fire();
|
||||||
|
break;
|
||||||
|
case "pldPane2":
|
||||||
|
pldrRadio2.fire();
|
||||||
|
break;
|
||||||
|
case "pldPane3":
|
||||||
|
pldrRadio3.fire();
|
||||||
|
break;
|
||||||
|
case "pldPane4":
|
||||||
|
pldrRadio4.fire();
|
||||||
|
break;
|
||||||
|
case "pldPane5":
|
||||||
|
pldrRadio5.fire();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void notifySmThreadStarted(boolean isStart, EModule type){
|
||||||
|
rcmToolPane.setDisable(isStart);
|
||||||
|
if (type.equals(EModule.RCM) && isStart){
|
||||||
|
MediatorControl.getInstance().getContoller().logArea.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Save application settings on exit
|
||||||
|
* */
|
||||||
|
public void updatePreferencesOnExit(){
|
||||||
|
AppPreferences.getInstance().setRecentRcm(1, payloadFPathLbl1.getText());
|
||||||
|
AppPreferences.getInstance().setRecentRcm(2, payloadFPathLbl2.getText());
|
||||||
|
AppPreferences.getInstance().setRecentRcm(3, payloadFPathLbl3.getText());
|
||||||
|
AppPreferences.getInstance().setRecentRcm(4, payloadFPathLbl4.getText());
|
||||||
|
AppPreferences.getInstance().setRecentRcm(5, payloadFPathLbl5.getText());
|
||||||
|
}
|
||||||
|
}
|
240
src/main/java/nsusbloader/Controllers/SplitMergeController.java
Normal file
240
src/main/java/nsusbloader/Controllers/SplitMergeController.java
Normal file
|
@ -0,0 +1,240 @@
|
||||||
|
package nsusbloader.Controllers;
|
||||||
|
|
||||||
|
import javafx.concurrent.Task;
|
||||||
|
import javafx.fxml.FXML;
|
||||||
|
import javafx.fxml.Initializable;
|
||||||
|
import javafx.scene.Node;
|
||||||
|
import javafx.scene.control.*;
|
||||||
|
import javafx.scene.input.DragEvent;
|
||||||
|
import javafx.scene.input.TransferMode;
|
||||||
|
import javafx.scene.layout.Region;
|
||||||
|
import javafx.scene.layout.VBox;
|
||||||
|
import javafx.stage.DirectoryChooser;
|
||||||
|
import javafx.stage.FileChooser;
|
||||||
|
import nsusbloader.AppPreferences;
|
||||||
|
import nsusbloader.MediatorControl;
|
||||||
|
import nsusbloader.NSLDataTypes.EModule;
|
||||||
|
import nsusbloader.ServiceWindow;
|
||||||
|
import nsusbloader.Utilities.SplitMergeTool;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
|
public class SplitMergeController implements Initializable {
|
||||||
|
@FXML
|
||||||
|
private ToggleGroup splitMergeTogGrp;
|
||||||
|
@FXML
|
||||||
|
private VBox smToolPane;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private RadioButton splitRad, mergeRad;
|
||||||
|
@FXML
|
||||||
|
private Button selectFileFolderBtn,
|
||||||
|
changeSaveToBtn,
|
||||||
|
convertBtn;
|
||||||
|
@FXML
|
||||||
|
private Label fileFolderLabelLbl,
|
||||||
|
fileFolderActualPathLbl,
|
||||||
|
saveToPathLbl,
|
||||||
|
statusLbl;
|
||||||
|
|
||||||
|
private ResourceBundle resourceBundle;
|
||||||
|
|
||||||
|
private Region convertRegion;
|
||||||
|
private Task<Boolean> smTask;
|
||||||
|
private Thread smThread;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initialize(URL url, ResourceBundle resourceBundle) {
|
||||||
|
this.resourceBundle = resourceBundle;
|
||||||
|
convertRegion = new Region();
|
||||||
|
convertBtn.setGraphic(convertRegion);
|
||||||
|
|
||||||
|
splitRad.setOnAction((actionEvent -> {
|
||||||
|
statusLbl.setText("");
|
||||||
|
convertRegion.getStyleClass().clear();
|
||||||
|
convertRegion.getStyleClass().add("regionSplitToOne");
|
||||||
|
fileFolderLabelLbl.setText(resourceBundle.getString("tabSplMrg_Txt_File"));
|
||||||
|
selectFileFolderBtn.setText(resourceBundle.getString("tabSplMrg_Btn_SelectFile"));
|
||||||
|
fileFolderActualPathLbl.setText("");
|
||||||
|
convertBtn.setDisable(true);
|
||||||
|
}));
|
||||||
|
mergeRad.setOnAction((actionEvent -> {
|
||||||
|
statusLbl.setText("");
|
||||||
|
convertRegion.getStyleClass().clear();
|
||||||
|
convertRegion.getStyleClass().add("regionOneToSplit");
|
||||||
|
fileFolderLabelLbl.setText(resourceBundle.getString("tabSplMrg_Txt_Folder"));
|
||||||
|
selectFileFolderBtn.setText(resourceBundle.getString("tabSplMrg_Btn_SelectFolder"));
|
||||||
|
fileFolderActualPathLbl.setText("");
|
||||||
|
convertBtn.setDisable(true);
|
||||||
|
}));
|
||||||
|
|
||||||
|
if (AppPreferences.getInstance().getSplitMergeType() == 0)
|
||||||
|
splitRad.fire();
|
||||||
|
else
|
||||||
|
mergeRad.fire();
|
||||||
|
|
||||||
|
saveToPathLbl.setText(AppPreferences.getInstance().getSplitMergeRecent());
|
||||||
|
|
||||||
|
changeSaveToBtn.setOnAction((actionEvent -> {
|
||||||
|
DirectoryChooser dc = new DirectoryChooser();
|
||||||
|
dc.setTitle(resourceBundle.getString("tabSplMrg_Btn_SelectFolder"));
|
||||||
|
dc.setInitialDirectory(new File(saveToPathLbl.getText()));
|
||||||
|
File saveToDir = dc.showDialog(changeSaveToBtn.getScene().getWindow());
|
||||||
|
if (saveToDir != null)
|
||||||
|
saveToPathLbl.setText(saveToDir.getAbsolutePath());
|
||||||
|
}));
|
||||||
|
|
||||||
|
selectFileFolderBtn.setOnAction(actionEvent -> {
|
||||||
|
statusLbl.setText("");
|
||||||
|
if (splitRad.isSelected()) {
|
||||||
|
FileChooser fc = new FileChooser();
|
||||||
|
fc.setTitle(resourceBundle.getString("tabSplMrg_Btn_SelectFile"));
|
||||||
|
if (! fileFolderActualPathLbl.getText().isEmpty()){
|
||||||
|
File temporaryFile = new File(fileFolderActualPathLbl.getText()).getParentFile();
|
||||||
|
if (temporaryFile != null && temporaryFile.exists())
|
||||||
|
fc.setInitialDirectory(temporaryFile);
|
||||||
|
else
|
||||||
|
fc.setInitialDirectory(new File(System.getProperty("user.home")));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
fc.setInitialDirectory(new File(System.getProperty("user.home")));
|
||||||
|
File fileFile = fc.showOpenDialog(changeSaveToBtn.getScene().getWindow());
|
||||||
|
if (fileFile == null)
|
||||||
|
return;
|
||||||
|
fileFolderActualPathLbl.setText(fileFile.getAbsolutePath());
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
DirectoryChooser dc = new DirectoryChooser();
|
||||||
|
dc.setTitle(resourceBundle.getString("tabSplMrg_Btn_SelectFolder"));
|
||||||
|
if (! fileFolderActualPathLbl.getText().isEmpty()){
|
||||||
|
File temporaryFile = new File(fileFolderActualPathLbl.getText());
|
||||||
|
if (temporaryFile.exists())
|
||||||
|
dc.setInitialDirectory(temporaryFile);
|
||||||
|
else
|
||||||
|
dc.setInitialDirectory(new File(System.getProperty("user.home")));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
dc.setInitialDirectory(new File(System.getProperty("user.home")));
|
||||||
|
|
||||||
|
File folderFile = dc.showDialog(changeSaveToBtn.getScene().getWindow());
|
||||||
|
if (folderFile == null)
|
||||||
|
return;
|
||||||
|
fileFolderActualPathLbl.setText(folderFile.getAbsolutePath());
|
||||||
|
}
|
||||||
|
convertBtn.setDisable(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
convertBtn.setOnAction(actionEvent -> setConvertBtnAction());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void notifySmThreadStarted(boolean isStart, EModule type){ // todo: refactor: remove everything, place to separate container and just disable.
|
||||||
|
if (! type.equals(EModule.SPLIT_MERGE_TOOL)){
|
||||||
|
smToolPane.setDisable(isStart);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (isStart){
|
||||||
|
MediatorControl.getInstance().getContoller().logArea.clear();
|
||||||
|
splitRad.setDisable(true);
|
||||||
|
mergeRad.setDisable(true);
|
||||||
|
selectFileFolderBtn.setDisable(true);
|
||||||
|
changeSaveToBtn.setDisable(true);
|
||||||
|
|
||||||
|
convertBtn.setOnAction(e -> stopBtnAction());
|
||||||
|
convertBtn.setText(resourceBundle.getString("btn_Stop"));
|
||||||
|
convertRegion.getStyleClass().clear();
|
||||||
|
convertRegion.getStyleClass().add("regionStop");
|
||||||
|
convertBtn.getStyleClass().remove("buttonUp");
|
||||||
|
convertBtn.getStyleClass().add("buttonStop");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
splitRad.setDisable(false);
|
||||||
|
mergeRad.setDisable(false);
|
||||||
|
selectFileFolderBtn.setDisable(false);
|
||||||
|
changeSaveToBtn.setDisable(false);
|
||||||
|
|
||||||
|
convertBtn.setOnAction(e -> setConvertBtnAction());
|
||||||
|
convertBtn.setText(resourceBundle.getString("tabSplMrg_Btn_Convert"));
|
||||||
|
convertRegion.getStyleClass().clear();
|
||||||
|
convertBtn.getStyleClass().remove("buttonStop");
|
||||||
|
convertBtn.getStyleClass().add("buttonUp");
|
||||||
|
if (splitRad.isSelected())
|
||||||
|
convertRegion.getStyleClass().add("regionSplitToOne");
|
||||||
|
else
|
||||||
|
convertRegion.getStyleClass().add("regionOneToSplit");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* It's button listener when convert-process in progress
|
||||||
|
* */
|
||||||
|
private void stopBtnAction(){
|
||||||
|
if (smThread != null && smThread.isAlive())
|
||||||
|
smTask.cancel(false);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* It's button listener when convert-process NOT in progress
|
||||||
|
* */
|
||||||
|
private void setConvertBtnAction(){
|
||||||
|
statusLbl.setText("");
|
||||||
|
if (MediatorControl.getInstance().getTransferActive()) {
|
||||||
|
ServiceWindow.getErrorNotification(
|
||||||
|
resourceBundle.getString("windowTitleError"),
|
||||||
|
resourceBundle.getString("windowBodyPleaseFinishTransfersFirst")
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (splitRad.isSelected())
|
||||||
|
smTask = SplitMergeTool.splitFile(fileFolderActualPathLbl.getText(), saveToPathLbl.getText());
|
||||||
|
else
|
||||||
|
smTask = SplitMergeTool.mergeFile(fileFolderActualPathLbl.getText(), saveToPathLbl.getText());
|
||||||
|
smTask.setOnCancelled(event -> statusLbl.setText(resourceBundle.getString("failure_txt")));
|
||||||
|
smTask.setOnSucceeded(event -> {
|
||||||
|
if (smTask.getValue())
|
||||||
|
statusLbl.setText(resourceBundle.getString("done_txt"));
|
||||||
|
else
|
||||||
|
statusLbl.setText(resourceBundle.getString("failure_txt"));
|
||||||
|
});
|
||||||
|
smThread = new Thread(smTask);
|
||||||
|
smThread.setDaemon(true);
|
||||||
|
smThread.start();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Drag-n-drop support (dragOver consumer)
|
||||||
|
* */
|
||||||
|
@FXML
|
||||||
|
private void handleDragOver(DragEvent event){
|
||||||
|
if (event.getDragboard().hasFiles() && ! MediatorControl.getInstance().getTransferActive())
|
||||||
|
event.acceptTransferModes(TransferMode.ANY);
|
||||||
|
event.consume();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Drag-n-drop support (drop consumer)
|
||||||
|
* */
|
||||||
|
@FXML
|
||||||
|
private void handleDrop(DragEvent event) {
|
||||||
|
Node sourceNode = (Node) event.getSource();
|
||||||
|
File fileDrpd = event.getDragboard().getFiles().get(0);
|
||||||
|
|
||||||
|
if (fileDrpd.isDirectory())
|
||||||
|
mergeRad.fire();
|
||||||
|
else
|
||||||
|
splitRad.fire();
|
||||||
|
fileFolderActualPathLbl.setText(fileDrpd.getAbsolutePath());
|
||||||
|
convertBtn.setDisable(false);
|
||||||
|
event.setDropCompleted(true);
|
||||||
|
event.consume();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Save application settings on exit
|
||||||
|
* */
|
||||||
|
public void updatePreferencesOnExit(){
|
||||||
|
if (splitRad.isSelected())
|
||||||
|
AppPreferences.getInstance().setSplitMergeType(0);
|
||||||
|
else
|
||||||
|
AppPreferences.getInstance().setSplitMergeType(1);
|
||||||
|
|
||||||
|
AppPreferences.getInstance().setSplitMergeRecent(saveToPathLbl.getText());
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,12 +1,13 @@
|
||||||
package nsusbloader;
|
package nsusbloader;
|
||||||
|
|
||||||
import nsusbloader.Controllers.NSLMainController;
|
import nsusbloader.Controllers.NSLMainController;
|
||||||
|
import nsusbloader.NSLDataTypes.EModule;
|
||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
public class MediatorControl {
|
public class MediatorControl {
|
||||||
private AtomicBoolean isTransferActive = new AtomicBoolean(false); // Overcoded just for sure
|
private AtomicBoolean isTransferActive = new AtomicBoolean(false); // Overcoded just for sure
|
||||||
private NSLMainController applicationController;
|
private NSLMainController mainCtrler;
|
||||||
|
|
||||||
public static MediatorControl getInstance(){
|
public static MediatorControl getInstance(){
|
||||||
return MediatorControlHold.INSTANCE;
|
return MediatorControlHold.INSTANCE;
|
||||||
|
@ -16,13 +17,15 @@ public class MediatorControl {
|
||||||
private static final MediatorControl INSTANCE = new MediatorControl();
|
private static final MediatorControl INSTANCE = new MediatorControl();
|
||||||
}
|
}
|
||||||
public void setController(NSLMainController controller){
|
public void setController(NSLMainController controller){
|
||||||
this.applicationController = controller;
|
this.mainCtrler = controller;
|
||||||
}
|
}
|
||||||
public NSLMainController getContoller(){ return this.applicationController; }
|
public NSLMainController getContoller(){ return this.mainCtrler; }
|
||||||
|
|
||||||
public synchronized void setTransferActive(boolean state) {
|
public synchronized void setBgThreadActive(boolean isActive, EModule appModuleType) {
|
||||||
isTransferActive.set(state);
|
isTransferActive.set(isActive);
|
||||||
applicationController.notifyTransmissionStarted(state);
|
mainCtrler.getFrontCtrlr().notifyTransmThreadStarted(isActive, appModuleType);
|
||||||
|
mainCtrler.getSmCtrlr().notifySmThreadStarted(isActive, appModuleType);
|
||||||
|
mainCtrler.getRcmCtrlr().notifySmThreadStarted(isActive, appModuleType);
|
||||||
}
|
}
|
||||||
public synchronized boolean getTransferActive() { return this.isTransferActive.get(); }
|
public synchronized boolean getTransferActive() { return this.isTransferActive.get(); }
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package nsusbloader.ModelControllers;
|
package nsusbloader.ModelControllers;
|
||||||
|
|
||||||
import nsusbloader.NSLDataTypes.EFileStatus;
|
import nsusbloader.NSLDataTypes.EFileStatus;
|
||||||
|
import nsusbloader.NSLDataTypes.EModule;
|
||||||
import nsusbloader.NSLDataTypes.EMsgType;
|
import nsusbloader.NSLDataTypes.EMsgType;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
@ -14,11 +15,11 @@ public class LogPrinter {
|
||||||
private BlockingQueue<Double> progressQueue;
|
private BlockingQueue<Double> progressQueue;
|
||||||
private HashMap<String, EFileStatus> statusMap; // BlockingQueue for literally one object. TODO: read more books ; replace to hashMap
|
private HashMap<String, EFileStatus> statusMap; // BlockingQueue for literally one object. TODO: read more books ; replace to hashMap
|
||||||
|
|
||||||
public LogPrinter(){
|
public LogPrinter(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<>();
|
||||||
this.msgConsumer = new MessagesConsumer(this.msgQueue, this.progressQueue, this.statusMap);
|
this.msgConsumer = new MessagesConsumer(whoIsAsking, this.msgQueue, this.progressQueue, this.statusMap);
|
||||||
this.msgConsumer.start();
|
this.msgConsumer.start();
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
@ -42,7 +43,8 @@ public class LogPrinter {
|
||||||
default:
|
default:
|
||||||
msgQueue.put(message);
|
msgQueue.put(message);
|
||||||
}
|
}
|
||||||
}catch (InterruptedException ie){
|
}
|
||||||
|
catch (InterruptedException ie){
|
||||||
ie.printStackTrace();
|
ie.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import javafx.scene.control.TextArea;
|
||||||
import nsusbloader.Controllers.NSTableViewController;
|
import nsusbloader.Controllers.NSTableViewController;
|
||||||
import nsusbloader.MediatorControl;
|
import nsusbloader.MediatorControl;
|
||||||
import nsusbloader.NSLDataTypes.EFileStatus;
|
import nsusbloader.NSLDataTypes.EFileStatus;
|
||||||
|
import nsusbloader.NSLDataTypes.EModule;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -20,10 +21,12 @@ public class MessagesConsumer extends AnimationTimer {
|
||||||
private final ProgressBar progressBar;
|
private final ProgressBar progressBar;
|
||||||
private final HashMap<String, EFileStatus> statusMap;
|
private final HashMap<String, EFileStatus> statusMap;
|
||||||
private final NSTableViewController tableViewController;
|
private final NSTableViewController tableViewController;
|
||||||
|
private final EModule appModuleType;
|
||||||
|
|
||||||
private boolean isInterrupted;
|
private boolean isInterrupted;
|
||||||
|
|
||||||
MessagesConsumer(BlockingQueue<String> msgQueue, BlockingQueue<Double> progressQueue, HashMap<String, EFileStatus> statusMap){
|
MessagesConsumer(EModule appModuleType, BlockingQueue<String> msgQueue, BlockingQueue<Double> progressQueue, HashMap<String, EFileStatus> statusMap){
|
||||||
|
this.appModuleType = appModuleType;
|
||||||
this.isInterrupted = false;
|
this.isInterrupted = false;
|
||||||
|
|
||||||
this.msgQueue = msgQueue;
|
this.msgQueue = msgQueue;
|
||||||
|
@ -38,7 +41,7 @@ public class MessagesConsumer extends AnimationTimer {
|
||||||
progressBar.setProgress(0.0);
|
progressBar.setProgress(0.0);
|
||||||
|
|
||||||
progressBar.setProgress(ProgressIndicator.INDETERMINATE_PROGRESS);
|
progressBar.setProgress(ProgressIndicator.INDETERMINATE_PROGRESS);
|
||||||
MediatorControl.getInstance().setTransferActive(true);
|
MediatorControl.getInstance().setBgThreadActive(true, appModuleType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -60,7 +63,7 @@ public class MessagesConsumer extends AnimationTimer {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isInterrupted) { // It's safe 'cuz it's could't be interrupted while HashMap populating
|
if (isInterrupted) { // It's safe 'cuz it's could't be interrupted while HashMap populating
|
||||||
MediatorControl.getInstance().setTransferActive(false);
|
MediatorControl.getInstance().setBgThreadActive(false, appModuleType);
|
||||||
progressBar.setProgress(0.0);
|
progressBar.setProgress(0.0);
|
||||||
|
|
||||||
if (statusMap.size() > 0)
|
if (statusMap.size() > 0)
|
||||||
|
|
7
src/main/java/nsusbloader/NSLDataTypes/EModule.java
Normal file
7
src/main/java/nsusbloader/NSLDataTypes/EModule.java
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
package nsusbloader.NSLDataTypes;
|
||||||
|
|
||||||
|
public enum EModule {
|
||||||
|
USB_NET_TRANSFERS,
|
||||||
|
SPLIT_MERGE_TOOL,
|
||||||
|
RCM
|
||||||
|
}
|
|
@ -12,7 +12,9 @@ import java.util.Locale;
|
||||||
import java.util.ResourceBundle;
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
public class NSLMain extends Application {
|
public class NSLMain extends Application {
|
||||||
public static final String appVersion = "v1.0";
|
|
||||||
|
public static final String appVersion = "v2.0";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start(Stage primaryStage) throws Exception{
|
public void start(Stage primaryStage) throws Exception{
|
||||||
FXMLLoader loader = new FXMLLoader(getClass().getResource("/NSLMain.fxml"));
|
FXMLLoader loader = new FXMLLoader(getClass().getResource("/NSLMain.fxml"));
|
||||||
|
|
105
src/main/java/nsusbloader/Utilities/JNIRcmLoader.java
Normal file
105
src/main/java/nsusbloader/Utilities/JNIRcmLoader.java
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
package nsusbloader.Utilities;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
public class JNIRcmLoader {
|
||||||
|
private JNIRcmLoader(){}
|
||||||
|
public static boolean load(){
|
||||||
|
String osName = System.getProperty("os.name").toLowerCase().replace(" ", "");
|
||||||
|
String osArch = System.getProperty("os.arch").toLowerCase().replace(" ", "");
|
||||||
|
String libPostfix;
|
||||||
|
|
||||||
|
if (osName.equals("linux")){
|
||||||
|
switch (osArch){
|
||||||
|
case "i386":
|
||||||
|
case "i586":
|
||||||
|
case "i686":
|
||||||
|
osArch = "x86";
|
||||||
|
break;
|
||||||
|
case "x86_64":
|
||||||
|
case "amd64":
|
||||||
|
osArch = "amd64";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
libPostfix = "so";
|
||||||
|
}
|
||||||
|
else if (osName.contains("windows")){
|
||||||
|
osName = "windows";
|
||||||
|
libPostfix = "dll";
|
||||||
|
switch (osArch){
|
||||||
|
case "x86":
|
||||||
|
case "i386":
|
||||||
|
case "i586":
|
||||||
|
case "i686":
|
||||||
|
osArch = "x86";
|
||||||
|
break;
|
||||||
|
case "x86_64":
|
||||||
|
case "amd64":
|
||||||
|
osArch = "amd64";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
final URL url_ = RcmSmash.class.getResource("/native/"+osName+"/"+osArch+"/smashlib."+libPostfix);
|
||||||
|
if (url_ == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
String proto = url_.getProtocol();
|
||||||
|
|
||||||
|
File libraryFile;
|
||||||
|
if (proto.equals("file")){
|
||||||
|
// We can pick file from disk as is.
|
||||||
|
try {
|
||||||
|
libraryFile = new File(url_.toURI());
|
||||||
|
}
|
||||||
|
catch (URISyntaxException e){
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (proto.equals("jar")){
|
||||||
|
// We have to export file to temp dir.
|
||||||
|
InputStream inStream = RcmSmash.class.getResourceAsStream("/native/"+osName+"/"+osArch+"/smashlib."+libPostfix);
|
||||||
|
if (inStream == null)
|
||||||
|
return false;
|
||||||
|
// Create temp folder
|
||||||
|
try{
|
||||||
|
File tmpDirFile = File.createTempFile("jni", null);
|
||||||
|
if (! tmpDirFile.delete())
|
||||||
|
return false;
|
||||||
|
if (! tmpDirFile.mkdirs())
|
||||||
|
return false;
|
||||||
|
libraryFile = new File(tmpDirFile, "smashlib."+libPostfix);
|
||||||
|
byte[] ioBuffer = new byte[8192];
|
||||||
|
FileOutputStream foStream = new FileOutputStream(libraryFile);
|
||||||
|
while (inStream.read(ioBuffer) != -1)
|
||||||
|
foStream.write(ioBuffer);
|
||||||
|
foStream.close();
|
||||||
|
inStream.close();
|
||||||
|
libraryFile.deleteOnExit();
|
||||||
|
tmpDirFile.deleteOnExit();
|
||||||
|
}
|
||||||
|
catch (IOException ioe){
|
||||||
|
ioe.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
|
||||||
|
//System.out.println("LIB LOCATION: "+libraryFile);
|
||||||
|
System.load(libraryFile.getAbsolutePath());
|
||||||
|
//System.out.println("LIB LOADED");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
17
src/main/java/nsusbloader/Utilities/RcmSmash.java
Normal file
17
src/main/java/nsusbloader/Utilities/RcmSmash.java
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
package nsusbloader.Utilities;
|
||||||
|
|
||||||
|
public class RcmSmash {
|
||||||
|
|
||||||
|
private static final boolean supported;
|
||||||
|
|
||||||
|
static {
|
||||||
|
supported = JNIRcmLoader.load();
|
||||||
|
}
|
||||||
|
|
||||||
|
private RcmSmash(){}
|
||||||
|
|
||||||
|
public static native int smashLinux(final int bus_id, final int device_addr);
|
||||||
|
public static native int smashWindows();
|
||||||
|
|
||||||
|
public static boolean isSupported() { return supported; }
|
||||||
|
}
|
316
src/main/java/nsusbloader/Utilities/RcmTask.java
Normal file
316
src/main/java/nsusbloader/Utilities/RcmTask.java
Normal file
|
@ -0,0 +1,316 @@
|
||||||
|
package nsusbloader.Utilities;
|
||||||
|
/*
|
||||||
|
* Implementation of the 'Fusée Gelée' RCM payload that is inspired by 'fusee-launcher' application by ktemkin.
|
||||||
|
* Definitely uses ideas and even some code.
|
||||||
|
* Check original project: https://github.com/reswitched/fusee-launcher
|
||||||
|
*
|
||||||
|
* This code is not political. It could be used by anyone.
|
||||||
|
* Find details in LICENSE file in the root directory of this project.
|
||||||
|
**/
|
||||||
|
|
||||||
|
import javafx.concurrent.Task;
|
||||||
|
import nsusbloader.COM.USB.UsbConnect;
|
||||||
|
import nsusbloader.COM.USB.UsbErrorCodes;
|
||||||
|
import nsusbloader.ModelControllers.LogPrinter;
|
||||||
|
import nsusbloader.NSLDataTypes.EModule;
|
||||||
|
import nsusbloader.NSLDataTypes.EMsgType;
|
||||||
|
import org.usb4java.*;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.IntBuffer;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
public class RcmTask extends Task<Boolean> {
|
||||||
|
|
||||||
|
private enum ECurrentOS {
|
||||||
|
win, lin, mac, unsupported
|
||||||
|
}
|
||||||
|
|
||||||
|
private LogPrinter logPrinter;
|
||||||
|
private String filePath;
|
||||||
|
|
||||||
|
private DeviceHandle handler;
|
||||||
|
|
||||||
|
private byte[] fullPayload;
|
||||||
|
|
||||||
|
private static final byte[] initSeq = { (byte) 0x98, (byte) 0x02, (byte) 0x03 };
|
||||||
|
|
||||||
|
private static final byte[] mezzo = {
|
||||||
|
(byte) 0x5c, (byte) 0x00, (byte) 0x9f, (byte) 0xe5, (byte) 0x5c, (byte) 0x10, (byte) 0x9f, (byte) 0xe5, (byte) 0x5c, (byte) 0x20, (byte) 0x9f, (byte) 0xe5, (byte) 0x01, (byte) 0x20, (byte) 0x42, (byte) 0xe0,
|
||||||
|
(byte) 0x0e, (byte) 0x00, (byte) 0x00, (byte) 0xeb, (byte) 0x48, (byte) 0x00, (byte) 0x9f, (byte) 0xe5, (byte) 0x10, (byte) 0xff, (byte) 0x2f, (byte) 0xe1, (byte) 0x00, (byte) 0x00, (byte) 0xa0, (byte) 0xe1,
|
||||||
|
(byte) 0x48, (byte) 0x00, (byte) 0x9f, (byte) 0xe5, (byte) 0x48, (byte) 0x10, (byte) 0x9f, (byte) 0xe5, (byte) 0x01, (byte) 0x29, (byte) 0xa0, (byte) 0xe3, (byte) 0x07, (byte) 0x00, (byte) 0x00, (byte) 0xeb,
|
||||||
|
(byte) 0x38, (byte) 0x00, (byte) 0x9f, (byte) 0xe5, (byte) 0x01, (byte) 0x19, (byte) 0xa0, (byte) 0xe3, (byte) 0x01, (byte) 0x00, (byte) 0x80, (byte) 0xe0, (byte) 0x34, (byte) 0x10, (byte) 0x9f, (byte) 0xe5,
|
||||||
|
(byte) 0x03, (byte) 0x28, (byte) 0xa0, (byte) 0xe3, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0xeb, (byte) 0x20, (byte) 0x00, (byte) 0x9f, (byte) 0xe5, (byte) 0x10, (byte) 0xff, (byte) 0x2f, (byte) 0xe1,
|
||||||
|
(byte) 0x04, (byte) 0x30, (byte) 0x91, (byte) 0xe4, (byte) 0x04, (byte) 0x30, (byte) 0x80, (byte) 0xe4, (byte) 0x04, (byte) 0x20, (byte) 0x52, (byte) 0xe2, (byte) 0xfb, (byte) 0xff, (byte) 0xff, (byte) 0x1a,
|
||||||
|
(byte) 0x1e, (byte) 0xff, (byte) 0x2f, (byte) 0xe1, (byte) 0x00, (byte) 0xf0, (byte) 0x00, (byte) 0x40, (byte) 0x20, (byte) 0x00, (byte) 0x01, (byte) 0x40, (byte) 0x7c, (byte) 0x00, (byte) 0x01, (byte) 0x40,
|
||||||
|
(byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x40, (byte) 0x40, (byte) 0x0e, (byte) 0x01, (byte) 0x40, (byte) 0x00, (byte) 0x70, (byte) 0x01, (byte) 0x40
|
||||||
|
}; // 124 bytes
|
||||||
|
|
||||||
|
private static final byte[] sprayPttrn = { 0x00, 0x00, 0x01, 0x40};
|
||||||
|
|
||||||
|
public RcmTask(String filePath){
|
||||||
|
this.logPrinter = new LogPrinter(EModule.RCM);
|
||||||
|
this.filePath = filePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Boolean call() {
|
||||||
|
logPrinter.print("Selected: "+filePath, EMsgType.INFO);
|
||||||
|
logPrinter.print("=============== RCM ===============", EMsgType.INFO);
|
||||||
|
|
||||||
|
ECurrentOS ecurrentOS;
|
||||||
|
String realOsName = System.getProperty("os.name").toLowerCase().replace(" ", "");
|
||||||
|
if (realOsName.equals("macos") || realOsName.equals("macosx") || realOsName.equals("freebsd"))
|
||||||
|
ecurrentOS = ECurrentOS.mac;
|
||||||
|
else if (realOsName.contains("windows"))
|
||||||
|
ecurrentOS = ECurrentOS.win;
|
||||||
|
else if (realOsName.equals("linux"))
|
||||||
|
ecurrentOS = ECurrentOS.lin;
|
||||||
|
else
|
||||||
|
ecurrentOS = ECurrentOS.unsupported;
|
||||||
|
logPrinter.print("Found your OS: "+System.getProperty("os.name"), EMsgType.PASS);
|
||||||
|
|
||||||
|
if (! ecurrentOS.equals(ECurrentOS.mac)){
|
||||||
|
if (! RcmSmash.isSupported()){
|
||||||
|
logPrinter.print("Unfortunately your platform '"+System.getProperty("os.name")+
|
||||||
|
"' of '"+System.getProperty("os.arch")+"' is not supported :("+
|
||||||
|
"\n But you could file a bug with request."+
|
||||||
|
"\n\n Nothing has been sent to NS. Execution stopped.", EMsgType.FAIL);
|
||||||
|
logPrinter.close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (preparePayload()){
|
||||||
|
logPrinter.close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// === TEST THIS ===
|
||||||
|
// writeTestFile();
|
||||||
|
// =================
|
||||||
|
// Bring up USB connection
|
||||||
|
|
||||||
|
UsbConnect usbConnect = new UsbConnect(logPrinter, true);
|
||||||
|
|
||||||
|
if (! usbConnect.isConnected()){
|
||||||
|
logPrinter.close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
this.handler = usbConnect.getNsHandler();
|
||||||
|
|
||||||
|
// Get device ID and show it.
|
||||||
|
if (readUsbDeviceID()){
|
||||||
|
usbConnect.close();
|
||||||
|
logPrinter.close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Send payload
|
||||||
|
for (int i=0; i < fullPayload.length / 4096 ; i++){
|
||||||
|
if (writeUsb(Arrays.copyOfRange(fullPayload, i*4096, (i+1)*4096))){
|
||||||
|
logPrinter.print("Failed to sent payload ["+i+"]"+
|
||||||
|
"\n\n Execution stopped.", EMsgType.FAIL);
|
||||||
|
usbConnect.close();
|
||||||
|
logPrinter.close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
logPrinter.print("Information sent to NS.", EMsgType.PASS);
|
||||||
|
|
||||||
|
if (ecurrentOS.equals(ECurrentOS.mac)){
|
||||||
|
if (smashMacOS()){
|
||||||
|
usbConnect.close();
|
||||||
|
logPrinter.close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// JNI MAGIC HERE
|
||||||
|
int retval;
|
||||||
|
if (ecurrentOS.equals(ECurrentOS.lin))
|
||||||
|
retval = RcmSmash.smashLinux(usbConnect.getNsBus(), usbConnect.getNsAddress());
|
||||||
|
else if (ecurrentOS.equals(ECurrentOS.win))
|
||||||
|
retval = RcmSmash.smashWindows();
|
||||||
|
else {
|
||||||
|
// ( ?_?)
|
||||||
|
logPrinter.print("Failed to smash the stack since your OS is not supported. Please report this issue."+
|
||||||
|
"\n\n Execution stopped and failed. And it's strange.", EMsgType.FAIL);
|
||||||
|
usbConnect.close();
|
||||||
|
logPrinter.close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (retval != 0){
|
||||||
|
logPrinter.print("Failed to smash the stack ("+retval+")"+
|
||||||
|
"\n\n Execution stopped and failed.", EMsgType.FAIL);
|
||||||
|
usbConnect.close();
|
||||||
|
logPrinter.close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
logPrinter.print(".:: Payload complete ::.", EMsgType.PASS);
|
||||||
|
}
|
||||||
|
|
||||||
|
usbConnect.close();
|
||||||
|
logPrinter.close();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Prepare the 'big' or full-size byte-buffer that is actually is a payload that we're about to use.
|
||||||
|
* @return false for issues
|
||||||
|
* true for good result
|
||||||
|
* */
|
||||||
|
private boolean preparePayload(){
|
||||||
|
File pldrFile = new File(filePath);
|
||||||
|
|
||||||
|
// 126296 b <- biggest size per CTCaer; 16384 selected randomly as minimum threshold. It's probably wrong.
|
||||||
|
if (pldrFile.length() > 126296 || pldrFile.length() < 16384) {
|
||||||
|
logPrinter.print("File size of this payload looks wired. It's "+pldrFile.length()+" bytes."+
|
||||||
|
"\n 1. Double-check that you're using the right payload." +
|
||||||
|
"\n 2. Please report this issue in case you're sure that you're doing everything right." +
|
||||||
|
"\n\n Nothing has been sent to NS. Execution stopped.", EMsgType.FAIL);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// Get payload file size
|
||||||
|
int pldFileSize = (int) pldrFile.length();
|
||||||
|
// Get full payload array size
|
||||||
|
int totalSize = 4328 + pldFileSize + 8640;
|
||||||
|
totalSize += 4096 - (totalSize % 4096);
|
||||||
|
if ((totalSize / 4096 % 2) == 0) // Flip buffer story to get 0x40009000 (hi) buf to always smash with 0x7000 (dec: 28672)
|
||||||
|
totalSize += 4096;
|
||||||
|
// Double-check
|
||||||
|
if (totalSize > 0x30298){
|
||||||
|
logPrinter.print("File size of the payload is too big. Comparing to maximum size, it's greater to "+(totalSize - 0x30298)+" bytes!"+
|
||||||
|
"\n 1. Double-check that you're using the right payload." +
|
||||||
|
"\n 2. Please report this issue in case you're sure that you're doing everything right." +
|
||||||
|
"\n\n Nothing has been sent to NS. Execution stopped.", EMsgType.FAIL); // Occurs: never. I'm too lazy to check.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// Define holder of 'everything payload'
|
||||||
|
fullPayload = new byte[totalSize];
|
||||||
|
// Prepare array to store file payload.
|
||||||
|
byte[] dataPldFile = new byte[pldFileSize];
|
||||||
|
|
||||||
|
try{
|
||||||
|
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(pldrFile));
|
||||||
|
int readSize;
|
||||||
|
if ((readSize = bis.read(dataPldFile)) != pldFileSize){
|
||||||
|
logPrinter.print("Failed to retrieve data from payload file." +
|
||||||
|
"\n Got only "+readSize+" bytes while "+pldFileSize+" expected." +
|
||||||
|
"\n\n Nothing has been sent to NS. Execution stopped.", EMsgType.FAIL);
|
||||||
|
bis.close();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bis.close();
|
||||||
|
}
|
||||||
|
catch (Exception e){
|
||||||
|
logPrinter.print("Failed to retrieve data from payload file: " +e.getMessage()+
|
||||||
|
"\n\n Nothing has been sent to NS. Execution stopped.", EMsgType.FAIL);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// Trust me
|
||||||
|
System.arraycopy(initSeq, 0, fullPayload, 0, 3);
|
||||||
|
System.arraycopy(mezzo, 0, fullPayload, 680, 124);
|
||||||
|
System.arraycopy(dataPldFile, 0, fullPayload, 4328, 16384);
|
||||||
|
for (int i = 0; i < 2160; i++)
|
||||||
|
System.arraycopy(sprayPttrn, 0, fullPayload, 20712+i*4, 4);
|
||||||
|
System.arraycopy(dataPldFile, 16384, fullPayload, 29352, pldFileSize-16384);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Read device ID in the early beginning
|
||||||
|
* @return false if NO issues
|
||||||
|
* true if issues
|
||||||
|
* */
|
||||||
|
private boolean readUsbDeviceID(){
|
||||||
|
ByteBuffer readBuffer = ByteBuffer.allocateDirect(16);
|
||||||
|
IntBuffer readBufTransferred = IntBuffer.allocate(1);
|
||||||
|
int result = LibUsb.bulkTransfer(handler, (byte) 0x81, readBuffer, readBufTransferred, 1000);
|
||||||
|
if (result != LibUsb.SUCCESS) {
|
||||||
|
logPrinter.print("Unable to get device ID" +
|
||||||
|
"\n\n Nothing has been sent to NS. Execution stopped.", EMsgType.FAIL);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
int trans = readBufTransferred.get();
|
||||||
|
byte[] receivedBytes = new byte[trans];
|
||||||
|
readBuffer.get(receivedBytes);
|
||||||
|
StringBuilder idStrBld = new StringBuilder("Found device with ID: ");
|
||||||
|
for (byte b: receivedBytes)
|
||||||
|
idStrBld.append(String.format("%02x ", b));
|
||||||
|
logPrinter.print(idStrBld.toString(), EMsgType.PASS);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Sending byte array to USB device
|
||||||
|
* @return 'false' if no issues
|
||||||
|
* 'true' if errors happened
|
||||||
|
* */
|
||||||
|
private boolean writeUsb(byte[] message){
|
||||||
|
ByteBuffer writeBuffer = ByteBuffer.allocateDirect(4096);
|
||||||
|
writeBuffer.put(message);
|
||||||
|
IntBuffer writeBufTransferred = IntBuffer.allocate(1);
|
||||||
|
int result = LibUsb.bulkTransfer(handler, (byte) 0x01, writeBuffer, writeBufTransferred, 5050);
|
||||||
|
|
||||||
|
if (result == LibUsb.SUCCESS) {
|
||||||
|
if (writeBufTransferred.get() == 4096)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
logPrinter.print("RCM Data transfer issue [write]" +
|
||||||
|
"\n Requested: " + message.length +
|
||||||
|
"\n Transferred: " + writeBufTransferred.get()+
|
||||||
|
"\n\n Execution stopped.", EMsgType.FAIL);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
logPrinter.print("RCM Data transfer issue [write]" +
|
||||||
|
"\n Returned: " + UsbErrorCodes.getErrCode(result) +
|
||||||
|
"\n\n Execution stopped.", EMsgType.FAIL);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* MacOS version of RcmSmash class
|
||||||
|
* */
|
||||||
|
boolean smashMacOS(){
|
||||||
|
int result;
|
||||||
|
|
||||||
|
ByteBuffer writeBuffer = ByteBuffer.allocateDirect(28672); //writeBuffer.order() equals BIG_ENDIAN; 28672
|
||||||
|
result = LibUsb.controlTransfer(handler, (byte) 0x82, LibUsb.REQUEST_GET_STATUS, (short) 0, (short) 0, writeBuffer, 1000);
|
||||||
|
if (result < 0){
|
||||||
|
logPrinter.print("Failed to smash the stack ("+UsbErrorCodes.getErrCode(result)+")"+
|
||||||
|
"\n\n Execution stopped and failed.", EMsgType.FAIL);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
logPrinter.print("Payload complete!", EMsgType.PASS);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//*****************************************************************************************************************/
|
||||||
|
/*
|
||||||
|
private void writeTestFile(){
|
||||||
|
try {
|
||||||
|
File testFile = new File("/tmp/dmTests.bin");
|
||||||
|
BufferedOutputStream bos = new BufferedOutputStream(
|
||||||
|
new FileOutputStream(testFile)
|
||||||
|
);
|
||||||
|
bos.write(fullPayload);
|
||||||
|
bos.close();
|
||||||
|
}
|
||||||
|
catch (Exception e){ e.printStackTrace(); }
|
||||||
|
// ------------------ TEST THIS p.2 ----------------------
|
||||||
|
writeUsbTest(fullPayload);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean writeUsbTest(byte[] message){
|
||||||
|
for (int i=0; i < message.length / 0x1000 ;i++){
|
||||||
|
try {
|
||||||
|
File testFile = new File(String.format("/tmp/cnk_%02d.bin", i));
|
||||||
|
BufferedOutputStream bos = new BufferedOutputStream(
|
||||||
|
new FileOutputStream(testFile)
|
||||||
|
);
|
||||||
|
bos.write(Arrays.copyOfRange(message, i*4096, (i+1)*4096));
|
||||||
|
bos.close();
|
||||||
|
}
|
||||||
|
catch (Exception e){ e.printStackTrace(); }
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
285
src/main/java/nsusbloader/Utilities/SplitMergeTool.java
Normal file
285
src/main/java/nsusbloader/Utilities/SplitMergeTool.java
Normal file
|
@ -0,0 +1,285 @@
|
||||||
|
package nsusbloader.Utilities;
|
||||||
|
|
||||||
|
import javafx.concurrent.Task;
|
||||||
|
import nsusbloader.ModelControllers.LogPrinter;
|
||||||
|
import nsusbloader.NSLDataTypes.EModule;
|
||||||
|
import nsusbloader.NSLDataTypes.EMsgType;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
public class SplitMergeTool {
|
||||||
|
|
||||||
|
public static Task<Boolean> splitFile(String filePath, String saveToPath){
|
||||||
|
return new SplitTask(filePath, saveToPath);
|
||||||
|
};
|
||||||
|
|
||||||
|
public static Task<Boolean> mergeFile(String filePath, String saveToPath){
|
||||||
|
return new MergeTask(filePath, saveToPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SplitTask extends Task<Boolean>{
|
||||||
|
|
||||||
|
private LogPrinter logPrinter;
|
||||||
|
private String saveToPath;
|
||||||
|
private String filePath;
|
||||||
|
|
||||||
|
SplitTask(String filePath, String saveToPath){
|
||||||
|
this.filePath = filePath;
|
||||||
|
this.saveToPath = saveToPath;
|
||||||
|
logPrinter = new LogPrinter(EModule.SPLIT_MERGE_TOOL);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Boolean call() {
|
||||||
|
File file = new File(filePath);
|
||||||
|
File folder = new File(saveToPath+File.separator+"!_"+file.getName());
|
||||||
|
|
||||||
|
logPrinter.print("Split file: "+filePath, EMsgType.INFO);
|
||||||
|
|
||||||
|
for (int i = 0; ; i++){
|
||||||
|
if (this.isCancelled()){
|
||||||
|
logPrinter.print("Split task interrupted!", EMsgType.PASS);
|
||||||
|
logPrinter.close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (! folder.mkdir()){
|
||||||
|
if (folder.exists()){
|
||||||
|
if (i >= 50){
|
||||||
|
logPrinter.print("Can't create new file.", EMsgType.FAIL);
|
||||||
|
logPrinter.close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
logPrinter.print("Trying to create a good new folder...", EMsgType.WARNING);
|
||||||
|
folder = new File(saveToPath+File.separator+"!_"+i+"_"+file.getName());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else { // folder not created and not exists - return
|
||||||
|
logPrinter.print("Folder "+folder.getAbsolutePath()+" could not be created. Not enough rights or something like that?", EMsgType.FAIL);
|
||||||
|
logPrinter.close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
logPrinter.print("Save results to: "+folder.getAbsolutePath(), EMsgType.INFO);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
try{
|
||||||
|
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
|
||||||
|
|
||||||
|
BufferedOutputStream fragmentBos;
|
||||||
|
|
||||||
|
long counter;
|
||||||
|
|
||||||
|
long originalFileLen = file.length();
|
||||||
|
|
||||||
|
double chunkPercent = (4194240.0 / (originalFileLen / 100.0) / 100.0);
|
||||||
|
long totalSizeCnt = 0;
|
||||||
|
|
||||||
|
byte[] chunk;
|
||||||
|
int readBytesCnt;
|
||||||
|
|
||||||
|
main_loop:
|
||||||
|
for (int i = 0; ; i++){
|
||||||
|
fragmentBos = new BufferedOutputStream(
|
||||||
|
new FileOutputStream(new File(folder.getAbsolutePath()+File.separator+String.format("%02d", i)))
|
||||||
|
);
|
||||||
|
|
||||||
|
counter = 0;
|
||||||
|
|
||||||
|
while (counter < 1024){ // 0xffff0000 total
|
||||||
|
|
||||||
|
if (this.isCancelled()){
|
||||||
|
fragmentBos.close();
|
||||||
|
bis.close();
|
||||||
|
boolean isDeleted = folder.delete();
|
||||||
|
File[] chArrToDel = folder.listFiles();
|
||||||
|
if (! isDeleted && chArrToDel != null){
|
||||||
|
isDeleted = true;
|
||||||
|
for (File chunkFile : chArrToDel)
|
||||||
|
isDeleted &= chunkFile.delete();
|
||||||
|
isDeleted &= folder.delete();
|
||||||
|
}
|
||||||
|
logPrinter.print("Split task interrupted and folder "+(isDeleted?"deleted.":"is not deleted."), EMsgType.PASS);
|
||||||
|
logPrinter.close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
chunk = new byte[4194240];
|
||||||
|
|
||||||
|
if ((readBytesCnt = bis.read(chunk)) < 4194240){
|
||||||
|
if (readBytesCnt > 0)
|
||||||
|
fragmentBos.write(chunk, 0, readBytesCnt);
|
||||||
|
fragmentBos.close();
|
||||||
|
logPrinter.updateProgress(1.0);
|
||||||
|
break main_loop;
|
||||||
|
}
|
||||||
|
|
||||||
|
fragmentBos.write(chunk);
|
||||||
|
|
||||||
|
logPrinter.updateProgress(chunkPercent * totalSizeCnt);
|
||||||
|
counter++; // NOTE: here we have some redundancy of variables. It has to be fixed one day.
|
||||||
|
totalSizeCnt++;
|
||||||
|
}
|
||||||
|
fragmentBos.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
bis.close();
|
||||||
|
|
||||||
|
//=============== let's check what we have ==============
|
||||||
|
logPrinter.print("Original file size: "+originalFileLen, EMsgType.INFO);
|
||||||
|
long totalChunksSize = 0;
|
||||||
|
File[] chunkFileArr = folder.listFiles();
|
||||||
|
|
||||||
|
if (chunkFileArr == null) {
|
||||||
|
logPrinter.print("Unable to check results. It means that something went wrong.", EMsgType.FAIL);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Arrays.sort(chunkFileArr);
|
||||||
|
for (File chunkFile : chunkFileArr) {
|
||||||
|
logPrinter.print("Chunk " + chunkFile.getName() + " size: " + chunkFile.length(), EMsgType.INFO);
|
||||||
|
totalChunksSize += chunkFile.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
logPrinter.print("Total chunks size: " + totalChunksSize, EMsgType.INFO);
|
||||||
|
|
||||||
|
if (originalFileLen != totalChunksSize)
|
||||||
|
logPrinter.print("Sizes are different! Do NOT use this file for installations!", EMsgType.FAIL);
|
||||||
|
else
|
||||||
|
logPrinter.print("Sizes are the same! Split file should be good!", EMsgType.PASS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e){
|
||||||
|
e.printStackTrace();
|
||||||
|
logPrinter.print("Error: "+e.getMessage(), EMsgType.FAIL);
|
||||||
|
}
|
||||||
|
logPrinter.print("Split task complete!", EMsgType.INFO);
|
||||||
|
logPrinter.close();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MergeTask extends Task<Boolean> {
|
||||||
|
|
||||||
|
private LogPrinter logPrinter;
|
||||||
|
private String saveToPath;
|
||||||
|
private String filePath;
|
||||||
|
|
||||||
|
MergeTask(String filePath, String saveToPath) {
|
||||||
|
this.filePath = filePath;
|
||||||
|
this.saveToPath = saveToPath;
|
||||||
|
logPrinter = new LogPrinter(EModule.SPLIT_MERGE_TOOL);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected Boolean call() {
|
||||||
|
logPrinter.print("Merge file: "+filePath, EMsgType.INFO);
|
||||||
|
|
||||||
|
File folder = new File(filePath);
|
||||||
|
|
||||||
|
long cnkTotalSize = 0;
|
||||||
|
|
||||||
|
File[] chunkFiles = folder.listFiles((file, s) -> s.matches("^[0-9][0-9]$"));
|
||||||
|
|
||||||
|
if (chunkFiles == null || chunkFiles.length == 0){
|
||||||
|
logPrinter.print("Selected folder doesn't have any chunks. Nothing to do here.", EMsgType.FAIL);
|
||||||
|
logPrinter.close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Arrays.sort(chunkFiles);
|
||||||
|
|
||||||
|
logPrinter.print("Next files will be merged in following order: ", EMsgType.INFO);
|
||||||
|
for (File cnk : chunkFiles){
|
||||||
|
logPrinter.print(" "+cnk.getName(), EMsgType.INFO);
|
||||||
|
cnkTotalSize += cnk.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
double chunkPercent = (4194240.0 / (cnkTotalSize / 100.0) / 100.0);
|
||||||
|
long totalSizeCnt = 0;
|
||||||
|
|
||||||
|
File resultFile = new File(saveToPath+File.separator+"!_"+folder.getName());
|
||||||
|
//*******
|
||||||
|
for (int i = 0; ; i++){
|
||||||
|
if (this.isCancelled()){
|
||||||
|
logPrinter.print("Split task interrupted!", EMsgType.PASS);
|
||||||
|
logPrinter.close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resultFile.exists()){
|
||||||
|
if (i >= 50){
|
||||||
|
logPrinter.print("Can't create new file.", EMsgType.FAIL);
|
||||||
|
logPrinter.close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
logPrinter.print("Trying to create a good new file...", EMsgType.WARNING);
|
||||||
|
resultFile = new File(saveToPath+File.separator+"!_"+i+"_"+folder.getName());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
logPrinter.print("Save results to: "+resultFile.getAbsolutePath(), EMsgType.INFO);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//*******
|
||||||
|
|
||||||
|
try {
|
||||||
|
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(resultFile));
|
||||||
|
|
||||||
|
BufferedInputStream bis;
|
||||||
|
byte[] chunk;
|
||||||
|
int readBytesCnt;
|
||||||
|
|
||||||
|
for (File cnk : chunkFiles){
|
||||||
|
bis = new BufferedInputStream(new FileInputStream(cnk));
|
||||||
|
while (true){
|
||||||
|
|
||||||
|
if (this.isCancelled()){
|
||||||
|
bos.close();
|
||||||
|
bis.close();
|
||||||
|
boolean isDeleted = resultFile.delete();
|
||||||
|
logPrinter.print("Split task interrupted and file "+(isDeleted?"deleted.":"is not deleted."), EMsgType.PASS);
|
||||||
|
logPrinter.close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
chunk = new byte[4194240];
|
||||||
|
readBytesCnt = bis.read(chunk);
|
||||||
|
|
||||||
|
logPrinter.updateProgress(chunkPercent * totalSizeCnt);
|
||||||
|
totalSizeCnt++;
|
||||||
|
|
||||||
|
if (readBytesCnt < 4194240){
|
||||||
|
if (readBytesCnt > 0)
|
||||||
|
bos.write(chunk, 0, readBytesCnt);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
bos.write(chunk);
|
||||||
|
}
|
||||||
|
bis.close();
|
||||||
|
}
|
||||||
|
bos.close();
|
||||||
|
//=============== let's check what we have ==============
|
||||||
|
long resultFileSize = resultFile.length();
|
||||||
|
logPrinter.print("Total chunks size: " + cnkTotalSize, EMsgType.INFO);
|
||||||
|
logPrinter.print("Merged file size: " + resultFileSize, EMsgType.INFO);
|
||||||
|
|
||||||
|
if (cnkTotalSize != resultFileSize){
|
||||||
|
logPrinter.print("Sizes are different! Do NOT use this file for installations!", EMsgType.FAIL);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
logPrinter.print("Sizes are the same! Split file should be good!", EMsgType.PASS);
|
||||||
|
}
|
||||||
|
catch (Exception e){
|
||||||
|
e.printStackTrace();
|
||||||
|
logPrinter.print("Error: "+e.getMessage(), EMsgType.FAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
logPrinter.print("Merge task complete!", EMsgType.INFO);
|
||||||
|
logPrinter.close();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,7 @@
|
||||||
<?import javafx.scene.control.Button?>
|
<?import javafx.scene.control.Button?>
|
||||||
<?import javafx.scene.control.ChoiceBox?>
|
<?import javafx.scene.control.ChoiceBox?>
|
||||||
<?import javafx.scene.control.Label?>
|
<?import javafx.scene.control.Label?>
|
||||||
|
<?import javafx.scene.control.Separator?>
|
||||||
<?import javafx.scene.control.TextField?>
|
<?import javafx.scene.control.TextField?>
|
||||||
<?import javafx.scene.control.ToolBar?>
|
<?import javafx.scene.control.ToolBar?>
|
||||||
<?import javafx.scene.layout.AnchorPane?>
|
<?import javafx.scene.layout.AnchorPane?>
|
||||||
|
@ -13,8 +14,9 @@
|
||||||
<?import javafx.scene.layout.Pane?>
|
<?import javafx.scene.layout.Pane?>
|
||||||
<?import javafx.scene.layout.RowConstraints?>
|
<?import javafx.scene.layout.RowConstraints?>
|
||||||
<?import javafx.scene.layout.VBox?>
|
<?import javafx.scene.layout.VBox?>
|
||||||
|
<?import javafx.scene.shape.SVGPath?>
|
||||||
|
|
||||||
<AnchorPane xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="nsusbloader.Controllers.FrontController">
|
<AnchorPane fx:id="usbNetPane" onDragDropped="#handleDrop" onDragOver="#handleDragOver" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="nsusbloader.Controllers.FrontController">
|
||||||
<children>
|
<children>
|
||||||
<VBox layoutX="10.0" layoutY="10.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
<VBox layoutX="10.0" layoutY="10.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||||
<children>
|
<children>
|
||||||
|
@ -38,13 +40,40 @@
|
||||||
<RowConstraints vgrow="SOMETIMES" />
|
<RowConstraints vgrow="SOMETIMES" />
|
||||||
</rowConstraints>
|
</rowConstraints>
|
||||||
<children>
|
<children>
|
||||||
<Pane fx:id="specialPane" GridPane.columnIndex="1" />
|
<Separator prefWidth="200.0" styleClass="strangeSeparator" GridPane.columnIndex="1" />
|
||||||
</children>
|
</children>
|
||||||
<VBox.margin>
|
<VBox.margin>
|
||||||
<Insets bottom="2.0" />
|
<Insets bottom="2.0" />
|
||||||
</VBox.margin>
|
</VBox.margin>
|
||||||
</GridPane>
|
</GridPane>
|
||||||
<fx:include fx:id="tableFilesList" source="TableView.fxml" VBox.vgrow="ALWAYS" />
|
<fx:include fx:id="tableFilesList" source="TableView.fxml" VBox.vgrow="ALWAYS" />
|
||||||
|
|
||||||
|
<HBox alignment="TOP_CENTER" spacing="3.0" VBox.vgrow="NEVER">
|
||||||
|
<children>
|
||||||
|
<Button fx:id="selectNspBtn" contentDisplay="TOP" mnemonicParsing="false" prefHeight="60.0" text="%btn_OpenFile">
|
||||||
|
<HBox.margin>
|
||||||
|
<Insets />
|
||||||
|
</HBox.margin>
|
||||||
|
<graphic>
|
||||||
|
<SVGPath content="M 8,0 C 6.8954305,0 6,0.8954305 6,2 v 16 c 0,1.1 0.89,2 2,2 h 12 c 1.104569,0 2,-0.895431 2,-2 V 2 C 22,0.90484721 21.089844,0 20,0 Z m 2.1,1.2 h 7.8 C 18,1.20208 18,1.2002604 18,1.3 v 0.1 c 0,0.095833 0,0.097917 -0.1,0.1 H 10.1 C 10,1.5057292 10,1.5036458 10,1.4 V 1.3 C 10,1.20026 10,1.1981771 10.1,1.2 Z M 8,2 h 12 c 0.303385,0 0.5,0.2044271 0.5,0.5 v 12 C 20.5,14.789959 20.29836,15 20,15 H 8 C 7.7044271,15 7.5,14.803385 7.5,14.5 V 2.5 C 7.5,2.2083333 7.7122396,2 8,2 Z M 2,4 v 18 c 0,1.104569 0.8954305,2 2,2 H 20 V 22 H 4 V 4 Z m 8,12 h 8 l -4,3 z" fill="#289de8" />
|
||||||
|
</graphic>
|
||||||
|
</Button>
|
||||||
|
<Button fx:id="selectSplitNspBtn" contentDisplay="TOP" mnemonicParsing="false" prefHeight="60.0" text="%btn_OpenSplitFile">
|
||||||
|
<graphic>
|
||||||
|
<SVGPath content="M 2.4003906 2 C 1.0683906 2 0 3.1125 0 4.5 L 0 19.5 A 2.4 2.5 0 0 0 2.4003906 22 L 21.599609 22 A 2.4 2.5 0 0 0 24 19.5 L 24 7 C 24 5.6125 22.919609 4.5 21.599609 4.5 L 12 4.5 L 9.5996094 2 L 2.4003906 2 z M 13.193359 10.962891 C 14.113498 10.962891 14.814236 11.348741 15.296875 12.123047 C 15.779514 12.89388 16.021484 13.935113 16.021484 15.244141 C 16.021484 16.556641 15.779514 17.598741 15.296875 18.373047 C 14.814236 19.14388 14.113498 19.529297 13.193359 19.529297 C 12.276693 19.529297 11.575955 19.14388 11.089844 18.373047 C 10.607205 17.598741 10.365234 16.556641 10.365234 15.244141 C 10.365234 13.935113 10.607205 12.89388 11.089844 12.123047 C 11.575955 11.348741 12.276693 10.962891 13.193359 10.962891 z M 19.589844 10.962891 C 20.509983 10.962891 21.21072 11.348741 21.693359 12.123047 C 22.175998 12.89388 22.417969 13.935113 22.417969 15.244141 C 22.417969 16.556641 22.175998 17.598741 21.693359 18.373047 C 21.21072 19.14388 20.509983 19.529297 19.589844 19.529297 C 18.673177 19.529297 17.970486 19.14388 17.484375 18.373047 C 17.001736 17.598741 16.761719 16.556641 16.761719 15.244141 C 16.761719 13.935113 17.001736 12.89388 17.484375 12.123047 C 17.970486 11.348741 18.673177 10.962891 19.589844 10.962891 z M 13.193359 11.769531 C 12.613498 11.769531 12.173177 12.092448 11.871094 12.738281 C 11.56901 13.380642 11.417969 14.195964 11.417969 15.185547 C 11.417969 15.411241 11.423611 15.655599 11.4375 15.916016 C 11.451389 16.176432 11.511068 16.528212 11.615234 16.972656 L 14.412109 12.591797 C 14.235026 12.26888 14.042318 12.052517 13.833984 11.941406 C 13.629123 11.826823 13.415582 11.769531 13.193359 11.769531 z M 19.589844 11.769531 C 19.009983 11.769531 18.567708 12.092448 18.265625 12.738281 C 17.963542 13.380642 17.8125 14.195964 17.8125 15.185547 C 17.8125 15.411241 17.820095 15.655599 17.833984 15.916016 C 17.847873 16.176432 17.907552 16.528212 18.011719 16.972656 L 20.808594 12.591797 C 20.63151 12.26888 20.438802 12.052517 20.230469 11.941406 C 20.025608 11.826823 19.812066 11.769531 19.589844 11.769531 z M 14.761719 13.556641 L 11.984375 17.962891 C 12.133681 18.216363 12.305556 18.406684 12.5 18.535156 C 12.694444 18.660156 12.91276 18.722656 13.152344 18.722656 C 13.812066 18.722656 14.280816 18.355252 14.558594 17.619141 C 14.836372 16.879557 14.974609 16.059462 14.974609 15.160156 C 14.974609 14.604601 14.90408 14.07053 14.761719 13.556641 z M 21.15625 13.556641 L 18.380859 17.962891 C 18.530165 18.216363 18.70204 18.406684 18.896484 18.535156 C 19.090929 18.660156 19.307292 18.722656 19.546875 18.722656 C 20.206597 18.722656 20.675347 18.355252 20.953125 17.619141 C 21.230903 16.879557 21.371094 16.059462 21.371094 15.160156 C 21.371094 14.604601 21.298611 14.07053 21.15625 13.556641 z" fill="#289de8" />
|
||||||
|
</graphic></Button>
|
||||||
|
<Pane HBox.hgrow="ALWAYS" />
|
||||||
|
<Button fx:id="uploadStopBtn" contentDisplay="TOP" mnemonicParsing="false" prefHeight="60.0" text="%btn_Upload">
|
||||||
|
<HBox.margin>
|
||||||
|
<Insets />
|
||||||
|
</HBox.margin>
|
||||||
|
</Button>
|
||||||
|
</children>
|
||||||
|
<VBox.margin>
|
||||||
|
<Insets left="5.0" right="5.0" top="5.0" />
|
||||||
|
</VBox.margin>
|
||||||
|
</HBox>
|
||||||
|
|
||||||
</children>
|
</children>
|
||||||
</VBox>
|
</VBox>
|
||||||
</children>
|
</children>
|
||||||
|
|
|
@ -1,18 +1,15 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
<?import javafx.geometry.Insets?>
|
<?import javafx.geometry.Insets?>
|
||||||
<?import javafx.scene.control.Button?>
|
|
||||||
<?import javafx.scene.control.ProgressBar?>
|
<?import javafx.scene.control.ProgressBar?>
|
||||||
<?import javafx.scene.control.Tab?>
|
<?import javafx.scene.control.Tab?>
|
||||||
<?import javafx.scene.control.TabPane?>
|
<?import javafx.scene.control.TabPane?>
|
||||||
<?import javafx.scene.control.TextArea?>
|
<?import javafx.scene.control.TextArea?>
|
||||||
<?import javafx.scene.layout.AnchorPane?>
|
<?import javafx.scene.layout.AnchorPane?>
|
||||||
<?import javafx.scene.layout.HBox?>
|
|
||||||
<?import javafx.scene.layout.Pane?>
|
|
||||||
<?import javafx.scene.layout.VBox?>
|
<?import javafx.scene.layout.VBox?>
|
||||||
<?import javafx.scene.shape.SVGPath?>
|
<?import javafx.scene.shape.SVGPath?>
|
||||||
|
|
||||||
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" onDragDropped="#handleDrop" onDragOver="#handleDragOver" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="nsusbloader.Controllers.NSLMainController">
|
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="nsusbloader.Controllers.NSLMainController">
|
||||||
<children>
|
<children>
|
||||||
<VBox AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
<VBox AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||||
<children>
|
<children>
|
||||||
|
@ -26,6 +23,24 @@
|
||||||
<SVGPath content="M21,19V17H8V19H21M21,13V11H8V13H21M8,7H21V5H8V7M4,5V7H6V5H4M3,5A1,1 0 0,1 4,4H6A1,1 0 0,1 7,5V7A1,1 0 0,1 6,8H4A1,1 0 0,1 3,7V5M4,11V13H6V11H4M3,11A1,1 0 0,1 4,10H6A1,1 0 0,1 7,11V13A1,1 0 0,1 6,14H4A1,1 0 0,1 3,13V11M4,17V19H6V17H4M3,17A1,1 0 0,1 4,16H6A1,1 0 0,1 7,17V19A1,1 0 0,1 6,20H4A1,1 0 0,1 3,19V17Z" />
|
<SVGPath content="M21,19V17H8V19H21M21,13V11H8V13H21M8,7H21V5H8V7M4,5V7H6V5H4M3,5A1,1 0 0,1 4,4H6A1,1 0 0,1 7,5V7A1,1 0 0,1 6,8H4A1,1 0 0,1 3,7V5M4,11V13H6V11H4M3,11A1,1 0 0,1 4,10H6A1,1 0 0,1 7,11V13A1,1 0 0,1 6,14H4A1,1 0 0,1 3,13V11M4,17V19H6V17H4M3,17A1,1 0 0,1 4,16H6A1,1 0 0,1 7,17V19A1,1 0 0,1 6,20H4A1,1 0 0,1 3,19V17Z" />
|
||||||
</graphic>
|
</graphic>
|
||||||
</Tab>
|
</Tab>
|
||||||
|
<Tab closable="false">
|
||||||
|
<content>
|
||||||
|
<fx:include fx:id="RcmTab" source="RcmTab.fxml" VBox.vgrow="ALWAYS" />
|
||||||
|
</content>
|
||||||
|
<graphic>
|
||||||
|
<SVGPath content="M 5.2753906 0.9453125 C 3.4702091 0.94491305 2.0128532 1.7453477 1.0566406 2.9082031 C 0.10042811 4.0710585 -0.40065633 5.5585011 -0.55664062 7.0488281 C -0.71262492 8.5391552 -0.52822452 10.042928 0.0078125 11.292969 C 0.54008474 12.534229 1.4899019 13.5834 2.8300781 13.826172 L 2.828125 13.837891 L 4.2050781 13.837891 L 4.6484375 11.080078 L 5.3496094 11.080078 L 5.9257812 13.837891 L 7.4042969 13.837891 L 7.4042969 13.753906 L 6.703125 10.685547 C 7.49408 10.281262 7.9297095 9.5624699 8.0097656 8.5292969 C 8.0610016 7.8485775 7.9209243 7.3118876 7.5878906 6.9179688 C 7.254857 6.5240499 6.7748288 6.3176076 6.1503906 6.296875 L 4.0371094 6.2910156 L 3.0976562 12.150391 C 2.4734416 12.023142 1.945837 11.518943 1.5625 10.625 C 1.1696133 9.7087867 0.99863233 8.4506302 1.1269531 7.2246094 C 1.2552739 5.9985885 1.6798073 4.8135983 2.3632812 3.9824219 C 3.0467553 3.1512454 3.9413986 2.6383771 5.2734375 2.6386719 L 20.007812 2.640625 C 20.496454 2.6407331 20.818797 2.788345 21.136719 3.0976562 C 21.454641 3.4069676 21.743658 3.910529 21.949219 4.5761719 C 22.36034 5.9074576 22.421621 7.8407685 22.128906 9.7714844 C 21.836191 11.7022 21.195943 13.639966 20.339844 15.023438 C 19.483744 16.406908 18.498727 17.154297 17.46875 17.154297 L -0.59375 17.154297 L -0.59375 18.845703 L 17.46875 18.845703 C 19.298148 18.845703 20.755291 17.568872 21.779297 15.914062 C 22.803302 14.259253 23.481257 12.145818 23.802734 10.025391 C 24.124212 7.904966 24.093647 5.7854271 23.566406 4.078125 C 23.302786 3.2244739 22.911503 2.4618437 22.318359 1.8847656 C 21.725216 1.3076876 20.907952 0.94941793 20.007812 0.94921875 L 5.2753906 0.9453125 z M 11.574219 6.1875 C 10.831297 6.1702229 10.207831 6.4450285 9.7050781 7.0117188 C 9.2055276 7.578409 8.8809744 8.3951633 8.7304688 9.4628906 L 8.5527344 10.712891 C 8.5207119 10.975503 8.5072674 11.234984 8.5136719 11.494141 C 8.5328854 12.254335 8.7132962 12.848871 9.0527344 13.277344 C 9.3921725 13.705817 9.8729047 13.927585 10.494141 13.941406 C 11.217848 13.962139 11.814426 13.735112 12.285156 13.261719 C 12.759089 12.78487 13.038539 12.137296 13.125 11.318359 L 11.775391 11.328125 C 11.698537 11.846439 11.565182 12.208239 11.373047 12.412109 C 11.180912 12.612524 10.923036 12.704777 10.599609 12.6875 C 10.080845 12.663312 9.8371182 12.277623 9.8691406 11.53125 C 9.8723429 11.403399 9.8965748 11.131448 9.9414062 10.716797 L 10.113281 9.4160156 C 10.190135 8.7145637 10.339592 8.209426 10.560547 7.8984375 C 10.781502 7.5839935 11.081823 7.4334439 11.462891 7.4472656 C 11.956037 7.4645428 12.209143 7.763238 12.21875 8.34375 L 12.208984 8.8574219 L 13.595703 8.8613281 C 13.595703 7.9974711 13.421311 7.3393799 13.072266 6.8867188 C 12.723221 6.4306022 12.224275 6.1978663 11.574219 6.1875 z M 14.869141 6.2910156 L 13.658203 13.837891 L 15.037109 13.837891 L 15.353516 11.847656 L 15.753906 8.5976562 L 16.28125 13.837891 L 17.21875 13.837891 L 19.361328 8.7675781 L 18.755859 11.748047 L 18.419922 13.837891 L 19.802734 13.837891 L 21.017578 6.2910156 L 19.201172 6.2910156 L 17.054688 11.716797 L 16.646484 6.2910156 L 14.869141 6.2910156 z M 5.2148438 7.5605469 L 6.09375 7.5664062 C 6.4491994 7.5940497 6.6336754 7.8344483 6.6464844 8.2871094 C 6.6496866 8.7466813 6.5554161 9.1146416 6.3632812 9.3945312 C 6.1711464 9.6709655 5.9072524 9.8134016 5.5742188 9.8203125 L 4.8496094 9.8105469 L 5.2148438 7.5605469 z" />
|
||||||
|
</graphic>
|
||||||
|
</Tab>
|
||||||
|
<Tab closable="false">
|
||||||
|
<content>
|
||||||
|
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
|
||||||
|
<fx:include fx:id="SplitMergeTab" source="SplitMergeTab.fxml" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" VBox.vgrow="ALWAYS" />
|
||||||
|
</AnchorPane>
|
||||||
|
</content>
|
||||||
|
<graphic>
|
||||||
|
<SVGPath content="M 2.4003906 2 C 1.0683906 2 2.9605947e-16 3.1125 0 4.5 L 0 19.5 A 2.4 2.5 0 0 0 2.4003906 22 L 21.599609 22 A 2.4 2.5 0 0 0 24 19.5 L 24 7 C 24 5.6125 22.919609 4.5 21.599609 4.5 L 12 4.5 L 9.5996094 2 L 2.4003906 2 z M 9 5 L 13 8.5 L 9 12 L 9 10 L 6 10 L 6 7 L 9 7 L 9 5 z M 5 9 L 5 11 L 8 11 L 8 14 L 5 14 L 5 16 L 1 12.5 L 5 9 z M 13.193359 10.962891 C 14.113498 10.962891 14.814236 11.348741 15.296875 12.123047 C 15.779514 12.89388 16.021484 13.935113 16.021484 15.244141 C 16.021484 16.556641 15.779514 17.598741 15.296875 18.373047 C 14.814236 19.14388 14.113498 19.529297 13.193359 19.529297 C 12.276693 19.529297 11.575955 19.14388 11.089844 18.373047 C 10.607205 17.598741 10.365234 16.556641 10.365234 15.244141 C 10.365234 13.935113 10.607205 12.89388 11.089844 12.123047 C 11.575955 11.348741 12.276693 10.962891 13.193359 10.962891 z M 19.589844 10.962891 C 20.509983 10.962891 21.21072 11.348741 21.693359 12.123047 C 22.175998 12.89388 22.417969 13.935113 22.417969 15.244141 C 22.417969 16.556641 22.175998 17.598741 21.693359 18.373047 C 21.21072 19.14388 20.509983 19.529297 19.589844 19.529297 C 18.673177 19.529297 17.970486 19.14388 17.484375 18.373047 C 17.001736 17.598741 16.761719 16.556641 16.761719 15.244141 C 16.761719 13.935113 17.001736 12.89388 17.484375 12.123047 C 17.970486 11.348741 18.673177 10.962891 19.589844 10.962891 z M 13.193359 11.769531 C 12.613498 11.769531 12.173177 12.092448 11.871094 12.738281 C 11.56901 13.380642 11.417969 14.195964 11.417969 15.185547 C 11.417969 15.411241 11.423611 15.655599 11.4375 15.916016 C 11.451389 16.176432 11.511068 16.528212 11.615234 16.972656 L 14.412109 12.591797 C 14.235026 12.26888 14.042318 12.052517 13.833984 11.941406 C 13.629123 11.826823 13.415582 11.769531 13.193359 11.769531 z M 19.589844 11.769531 C 19.009983 11.769531 18.567708 12.092448 18.265625 12.738281 C 17.963542 13.380642 17.8125 14.195964 17.8125 15.185547 C 17.8125 15.411241 17.820095 15.655599 17.833984 15.916016 C 17.847873 16.176432 17.907552 16.528212 18.011719 16.972656 L 20.808594 12.591797 C 20.63151 12.26888 20.438802 12.052517 20.230469 11.941406 C 20.025608 11.826823 19.812066 11.769531 19.589844 11.769531 z M 14.761719 13.556641 L 11.984375 17.962891 C 12.133681 18.216363 12.305556 18.406684 12.5 18.535156 C 12.694444 18.660156 12.91276 18.722656 13.152344 18.722656 C 13.812066 18.722656 14.280816 18.355252 14.558594 17.619141 C 14.836372 16.879557 14.974609 16.059462 14.974609 15.160156 C 14.974609 14.604601 14.90408 14.07053 14.761719 13.556641 z M 21.15625 13.556641 L 18.380859 17.962891 C 18.530165 18.216363 18.70204 18.406684 18.896484 18.535156 C 19.090929 18.660156 19.307292 18.722656 19.546875 18.722656 C 20.206597 18.722656 20.675347 18.355252 20.953125 17.619141 C 21.230903 16.879557 21.371094 16.059462 21.371094 15.160156 C 21.371094 14.604601 21.298611 14.07053 21.15625 13.556641 z" />
|
||||||
|
</graphic>
|
||||||
|
</Tab>
|
||||||
<Tab closable="false">
|
<Tab closable="false">
|
||||||
<content>
|
<content>
|
||||||
<fx:include fx:id="SettingsTab" source="SettingsTab.fxml" VBox.vgrow="ALWAYS" />
|
<fx:include fx:id="SettingsTab" source="SettingsTab.fxml" VBox.vgrow="ALWAYS" />
|
||||||
|
@ -54,34 +69,9 @@
|
||||||
</TabPane>
|
</TabPane>
|
||||||
<ProgressBar fx:id="progressBar" prefWidth="Infinity" progress="0.0">
|
<ProgressBar fx:id="progressBar" prefWidth="Infinity" progress="0.0">
|
||||||
<VBox.margin>
|
<VBox.margin>
|
||||||
<Insets left="5.0" right="5.0" top="2.0" />
|
<Insets bottom="2.0" left="5.0" right="5.0" top="2.0" />
|
||||||
</VBox.margin>
|
</VBox.margin>
|
||||||
</ProgressBar>
|
</ProgressBar>
|
||||||
<HBox alignment="TOP_CENTER" spacing="3.0" VBox.vgrow="NEVER">
|
|
||||||
<children>
|
|
||||||
<Button fx:id="selectNspBtn" contentDisplay="TOP" mnemonicParsing="false" prefHeight="60.0" text="%btn_OpenFile">
|
|
||||||
<HBox.margin>
|
|
||||||
<Insets />
|
|
||||||
</HBox.margin>
|
|
||||||
<graphic>
|
|
||||||
<SVGPath content="M 8,0 C 6.8954305,0 6,0.8954305 6,2 v 16 c 0,1.1 0.89,2 2,2 h 12 c 1.104569,0 2,-0.895431 2,-2 V 2 C 22,0.90484721 21.089844,0 20,0 Z m 2.1,1.2 h 7.8 C 18,1.20208 18,1.2002604 18,1.3 v 0.1 c 0,0.095833 0,0.097917 -0.1,0.1 H 10.1 C 10,1.5057292 10,1.5036458 10,1.4 V 1.3 C 10,1.20026 10,1.1981771 10.1,1.2 Z M 8,2 h 12 c 0.303385,0 0.5,0.2044271 0.5,0.5 v 12 C 20.5,14.789959 20.29836,15 20,15 H 8 C 7.7044271,15 7.5,14.803385 7.5,14.5 V 2.5 C 7.5,2.2083333 7.7122396,2 8,2 Z M 2,4 v 18 c 0,1.104569 0.8954305,2 2,2 H 20 V 22 H 4 V 4 Z m 8,12 h 8 l -4,3 z" fill="#289de8" />
|
|
||||||
</graphic>
|
|
||||||
</Button>
|
|
||||||
<Button fx:id="selectSplitNspBtn" contentDisplay="TOP" mnemonicParsing="false" prefHeight="60.0" text="%btn_OpenSplitFile">
|
|
||||||
<graphic>
|
|
||||||
<SVGPath content="M 2.4003906 2 C 1.0683906 2 0 3.1125 0 4.5 L 0 19.5 A 2.4 2.5 0 0 0 2.4003906 22 L 21.599609 22 A 2.4 2.5 0 0 0 24 19.5 L 24 7 C 24 5.6125 22.919609 4.5 21.599609 4.5 L 12 4.5 L 9.5996094 2 L 2.4003906 2 z M 13.193359 10.962891 C 14.113498 10.962891 14.814236 11.348741 15.296875 12.123047 C 15.779514 12.89388 16.021484 13.935113 16.021484 15.244141 C 16.021484 16.556641 15.779514 17.598741 15.296875 18.373047 C 14.814236 19.14388 14.113498 19.529297 13.193359 19.529297 C 12.276693 19.529297 11.575955 19.14388 11.089844 18.373047 C 10.607205 17.598741 10.365234 16.556641 10.365234 15.244141 C 10.365234 13.935113 10.607205 12.89388 11.089844 12.123047 C 11.575955 11.348741 12.276693 10.962891 13.193359 10.962891 z M 19.589844 10.962891 C 20.509983 10.962891 21.21072 11.348741 21.693359 12.123047 C 22.175998 12.89388 22.417969 13.935113 22.417969 15.244141 C 22.417969 16.556641 22.175998 17.598741 21.693359 18.373047 C 21.21072 19.14388 20.509983 19.529297 19.589844 19.529297 C 18.673177 19.529297 17.970486 19.14388 17.484375 18.373047 C 17.001736 17.598741 16.761719 16.556641 16.761719 15.244141 C 16.761719 13.935113 17.001736 12.89388 17.484375 12.123047 C 17.970486 11.348741 18.673177 10.962891 19.589844 10.962891 z M 13.193359 11.769531 C 12.613498 11.769531 12.173177 12.092448 11.871094 12.738281 C 11.56901 13.380642 11.417969 14.195964 11.417969 15.185547 C 11.417969 15.411241 11.423611 15.655599 11.4375 15.916016 C 11.451389 16.176432 11.511068 16.528212 11.615234 16.972656 L 14.412109 12.591797 C 14.235026 12.26888 14.042318 12.052517 13.833984 11.941406 C 13.629123 11.826823 13.415582 11.769531 13.193359 11.769531 z M 19.589844 11.769531 C 19.009983 11.769531 18.567708 12.092448 18.265625 12.738281 C 17.963542 13.380642 17.8125 14.195964 17.8125 15.185547 C 17.8125 15.411241 17.820095 15.655599 17.833984 15.916016 C 17.847873 16.176432 17.907552 16.528212 18.011719 16.972656 L 20.808594 12.591797 C 20.63151 12.26888 20.438802 12.052517 20.230469 11.941406 C 20.025608 11.826823 19.812066 11.769531 19.589844 11.769531 z M 14.761719 13.556641 L 11.984375 17.962891 C 12.133681 18.216363 12.305556 18.406684 12.5 18.535156 C 12.694444 18.660156 12.91276 18.722656 13.152344 18.722656 C 13.812066 18.722656 14.280816 18.355252 14.558594 17.619141 C 14.836372 16.879557 14.974609 16.059462 14.974609 15.160156 C 14.974609 14.604601 14.90408 14.07053 14.761719 13.556641 z M 21.15625 13.556641 L 18.380859 17.962891 C 18.530165 18.216363 18.70204 18.406684 18.896484 18.535156 C 19.090929 18.660156 19.307292 18.722656 19.546875 18.722656 C 20.206597 18.722656 20.675347 18.355252 20.953125 17.619141 C 21.230903 16.879557 21.371094 16.059462 21.371094 15.160156 C 21.371094 14.604601 21.298611 14.07053 21.15625 13.556641 z" fill="#289de8" />
|
|
||||||
</graphic></Button>
|
|
||||||
<Pane HBox.hgrow="ALWAYS" />
|
|
||||||
<Button fx:id="uploadStopBtn" contentDisplay="TOP" mnemonicParsing="false" prefHeight="60.0" text="%btn_Upload">
|
|
||||||
<HBox.margin>
|
|
||||||
<Insets />
|
|
||||||
</HBox.margin>
|
|
||||||
</Button>
|
|
||||||
</children>
|
|
||||||
<VBox.margin>
|
|
||||||
<Insets bottom="5.0" left="5.0" right="5.0" top="2.0" />
|
|
||||||
</VBox.margin>
|
|
||||||
</HBox>
|
|
||||||
</children>
|
</children>
|
||||||
</VBox>
|
</VBox>
|
||||||
</children>
|
</children>
|
||||||
|
|
218
src/main/resources/RcmTab.fxml
Normal file
218
src/main/resources/RcmTab.fxml
Normal file
|
@ -0,0 +1,218 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<?import javafx.geometry.Insets?>
|
||||||
|
<?import javafx.scene.control.Button?>
|
||||||
|
<?import javafx.scene.control.Label?>
|
||||||
|
<?import javafx.scene.control.RadioButton?>
|
||||||
|
<?import javafx.scene.control.ScrollPane?>
|
||||||
|
<?import javafx.scene.control.Separator?>
|
||||||
|
<?import javafx.scene.control.ToggleGroup?>
|
||||||
|
<?import javafx.scene.layout.ColumnConstraints?>
|
||||||
|
<?import javafx.scene.layout.GridPane?>
|
||||||
|
<?import javafx.scene.layout.HBox?>
|
||||||
|
<?import javafx.scene.layout.Pane?>
|
||||||
|
<?import javafx.scene.layout.RowConstraints?>
|
||||||
|
<?import javafx.scene.layout.VBox?>
|
||||||
|
<?import javafx.scene.shape.SVGPath?>
|
||||||
|
<?import javafx.scene.text.Font?>
|
||||||
|
|
||||||
|
<ScrollPane fitToWidth="true" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="nsusbloader.Controllers.RcmController">
|
||||||
|
<VBox fx:id="rcmToolPane" spacing="15.0">
|
||||||
|
<Pane minHeight="-Infinity" prefHeight="10.0" style="-fx-background-color: linear-gradient(from 41px 34px to 50px 50px, reflect, #ff1515 40%, transparent 45%);" />
|
||||||
|
<HBox alignment="CENTER">
|
||||||
|
<children>
|
||||||
|
<Label text="Fusée Gelée RCM">
|
||||||
|
<font>
|
||||||
|
<Font name="System Bold" size="15.0" />
|
||||||
|
</font>
|
||||||
|
</Label>
|
||||||
|
</children>
|
||||||
|
</HBox>
|
||||||
|
<GridPane>
|
||||||
|
<columnConstraints>
|
||||||
|
<ColumnConstraints hgrow="SOMETIMES" />
|
||||||
|
<ColumnConstraints hgrow="SOMETIMES" percentWidth="90.0" />
|
||||||
|
<ColumnConstraints hgrow="SOMETIMES" />
|
||||||
|
</columnConstraints>
|
||||||
|
<rowConstraints>
|
||||||
|
<RowConstraints vgrow="SOMETIMES" />
|
||||||
|
</rowConstraints>
|
||||||
|
<children>
|
||||||
|
<Separator prefWidth="200.0" styleClass="strangeSeparator" GridPane.columnIndex="1" />
|
||||||
|
</children>
|
||||||
|
</GridPane>
|
||||||
|
<VBox spacing="8.0">
|
||||||
|
<children>
|
||||||
|
<Label text="Payload: " />
|
||||||
|
<HBox fx:id="plHbox1" alignment="CENTER_LEFT" onDragDropped="#handleDrop" onDragOver="#handleDragOver" spacing="5.0">
|
||||||
|
<children>
|
||||||
|
<RadioButton fx:id="pldrRadio1" mnemonicParsing="false">
|
||||||
|
<toggleGroup>
|
||||||
|
<ToggleGroup fx:id="rcmToggleGrp" />
|
||||||
|
</toggleGroup></RadioButton>
|
||||||
|
<VBox fx:id="pldPane1" onMouseClicked="#selectPldrPane" HBox.hgrow="ALWAYS">
|
||||||
|
<children>
|
||||||
|
<HBox>
|
||||||
|
<children>
|
||||||
|
<Label fx:id="payloadFNameLbl1" />
|
||||||
|
</children>
|
||||||
|
</HBox>
|
||||||
|
<Label fx:id="payloadFPathLbl1" disable="true">
|
||||||
|
<font>
|
||||||
|
<Font name="System Italic" size="13.0" />
|
||||||
|
</font>
|
||||||
|
</Label>
|
||||||
|
</children>
|
||||||
|
</VBox>
|
||||||
|
<Button fx:id="selPldBtn1" mnemonicParsing="false" onAction="#bntSelectPayloader" styleClass="buttonSelect">
|
||||||
|
<graphic>
|
||||||
|
<SVGPath content="M19,20H4C2.89,20 2,19.1 2,18V6C2,4.89 2.89,4 4,4H10L12,6H19A2,2 0 0,1 21,8H21L4,8V18L6.14,10H23.21L20.93,18.5C20.7,19.37 19.92,20 19,20Z" fill="#289de8" />
|
||||||
|
</graphic></Button>
|
||||||
|
<Button fx:id="resPldBtn1" mnemonicParsing="false" onAction="#bntResetPayloader" styleClass="buttonStop">
|
||||||
|
<graphic>
|
||||||
|
<SVGPath content="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z" fill="#fb582c" />
|
||||||
|
</graphic>
|
||||||
|
</Button>
|
||||||
|
</children>
|
||||||
|
</HBox>
|
||||||
|
<Separator prefWidth="200.0" />
|
||||||
|
<HBox fx:id="plHbox2" alignment="CENTER_LEFT" onDragDropped="#handleDrop" onDragOver="#handleDragOver" spacing="5.0">
|
||||||
|
<children>
|
||||||
|
<RadioButton fx:id="pldrRadio2" mnemonicParsing="false" toggleGroup="$rcmToggleGrp" />
|
||||||
|
<VBox fx:id="pldPane2" onMouseClicked="#selectPldrPane" HBox.hgrow="ALWAYS">
|
||||||
|
<children>
|
||||||
|
<HBox>
|
||||||
|
<children>
|
||||||
|
<Label fx:id="payloadFNameLbl2" />
|
||||||
|
</children>
|
||||||
|
</HBox>
|
||||||
|
<Label fx:id="payloadFPathLbl2" disable="true">
|
||||||
|
<font>
|
||||||
|
<Font name="System Italic" size="13.0" />
|
||||||
|
</font>
|
||||||
|
</Label>
|
||||||
|
</children>
|
||||||
|
</VBox>
|
||||||
|
<Button fx:id="selPldBtn2" mnemonicParsing="false" onAction="#bntSelectPayloader" styleClass="buttonSelect">
|
||||||
|
<graphic>
|
||||||
|
<SVGPath content="M19,20H4C2.89,20 2,19.1 2,18V6C2,4.89 2.89,4 4,4H10L12,6H19A2,2 0 0,1 21,8H21L4,8V18L6.14,10H23.21L20.93,18.5C20.7,19.37 19.92,20 19,20Z" fill="#289de8" />
|
||||||
|
</graphic></Button>
|
||||||
|
<Button fx:id="resPldBtn2" mnemonicParsing="false" onAction="#bntResetPayloader" styleClass="buttonStop">
|
||||||
|
<graphic>
|
||||||
|
<SVGPath content="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z" fill="#fb582c" />
|
||||||
|
</graphic>
|
||||||
|
</Button>
|
||||||
|
</children>
|
||||||
|
</HBox>
|
||||||
|
<Separator prefWidth="200.0" />
|
||||||
|
<HBox fx:id="plHbox3" alignment="CENTER_LEFT" onDragDropped="#handleDrop" onDragOver="#handleDragOver" spacing="5.0">
|
||||||
|
<children>
|
||||||
|
<RadioButton fx:id="pldrRadio3" mnemonicParsing="false" toggleGroup="$rcmToggleGrp" />
|
||||||
|
<VBox fx:id="pldPane3" onMouseClicked="#selectPldrPane" HBox.hgrow="ALWAYS">
|
||||||
|
<children>
|
||||||
|
<HBox>
|
||||||
|
<children>
|
||||||
|
<Label fx:id="payloadFNameLbl3" />
|
||||||
|
</children>
|
||||||
|
</HBox>
|
||||||
|
<Label fx:id="payloadFPathLbl3" disable="true">
|
||||||
|
<font>
|
||||||
|
<Font name="System Italic" size="13.0" />
|
||||||
|
</font>
|
||||||
|
</Label>
|
||||||
|
</children>
|
||||||
|
</VBox>
|
||||||
|
<Button fx:id="selPldBtn3" mnemonicParsing="false" onAction="#bntSelectPayloader" styleClass="buttonSelect">
|
||||||
|
<graphic>
|
||||||
|
<SVGPath content="M19,20H4C2.89,20 2,19.1 2,18V6C2,4.89 2.89,4 4,4H10L12,6H19A2,2 0 0,1 21,8H21L4,8V18L6.14,10H23.21L20.93,18.5C20.7,19.37 19.92,20 19,20Z" fill="#289de8" />
|
||||||
|
</graphic></Button>
|
||||||
|
<Button fx:id="resPldBtn3" mnemonicParsing="false" onAction="#bntResetPayloader" styleClass="buttonStop">
|
||||||
|
<graphic>
|
||||||
|
<SVGPath content="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z" fill="#fb582c" />
|
||||||
|
</graphic>
|
||||||
|
</Button>
|
||||||
|
</children>
|
||||||
|
</HBox>
|
||||||
|
<Separator prefWidth="200.0" />
|
||||||
|
<HBox fx:id="plHbox4" alignment="CENTER_LEFT" onDragDropped="#handleDrop" onDragOver="#handleDragOver" spacing="5.0">
|
||||||
|
<children>
|
||||||
|
<RadioButton fx:id="pldrRadio4" mnemonicParsing="false" toggleGroup="$rcmToggleGrp" />
|
||||||
|
<VBox fx:id="pldPane4" onMouseClicked="#selectPldrPane" HBox.hgrow="ALWAYS">
|
||||||
|
<children>
|
||||||
|
<HBox>
|
||||||
|
<children>
|
||||||
|
<Label fx:id="payloadFNameLbl4" />
|
||||||
|
</children>
|
||||||
|
</HBox>
|
||||||
|
<Label fx:id="payloadFPathLbl4" disable="true">
|
||||||
|
<font>
|
||||||
|
<Font name="System Italic" size="13.0" />
|
||||||
|
</font>
|
||||||
|
</Label>
|
||||||
|
</children>
|
||||||
|
</VBox>
|
||||||
|
<Button fx:id="selPldBtn4" mnemonicParsing="false" onAction="#bntSelectPayloader" styleClass="buttonSelect">
|
||||||
|
<graphic>
|
||||||
|
<SVGPath content="M19,20H4C2.89,20 2,19.1 2,18V6C2,4.89 2.89,4 4,4H10L12,6H19A2,2 0 0,1 21,8H21L4,8V18L6.14,10H23.21L20.93,18.5C20.7,19.37 19.92,20 19,20Z" fill="#289de8" />
|
||||||
|
</graphic></Button>
|
||||||
|
<Button fx:id="resPldBtn4" mnemonicParsing="false" onAction="#bntResetPayloader" styleClass="buttonStop">
|
||||||
|
<graphic>
|
||||||
|
<SVGPath content="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z" fill="#fb582c" />
|
||||||
|
</graphic>
|
||||||
|
</Button>
|
||||||
|
</children>
|
||||||
|
</HBox>
|
||||||
|
<Separator prefWidth="200.0" />
|
||||||
|
<HBox fx:id="plHbox5" alignment="CENTER_LEFT" onDragDropped="#handleDrop" onDragOver="#handleDragOver" spacing="5.0">
|
||||||
|
<children>
|
||||||
|
<RadioButton fx:id="pldrRadio5" mnemonicParsing="false" toggleGroup="$rcmToggleGrp" />
|
||||||
|
<VBox fx:id="pldPane5" onMouseClicked="#selectPldrPane" HBox.hgrow="ALWAYS">
|
||||||
|
<children>
|
||||||
|
<HBox>
|
||||||
|
<children>
|
||||||
|
<Label fx:id="payloadFNameLbl5" />
|
||||||
|
</children>
|
||||||
|
</HBox>
|
||||||
|
<Label fx:id="payloadFPathLbl5" disable="true">
|
||||||
|
<font>
|
||||||
|
<Font name="System Italic" size="13.0" />
|
||||||
|
</font>
|
||||||
|
</Label>
|
||||||
|
</children>
|
||||||
|
</VBox>
|
||||||
|
<Button fx:id="selPldBtn5" mnemonicParsing="false" onAction="#bntSelectPayloader" styleClass="buttonSelect">
|
||||||
|
<graphic>
|
||||||
|
<SVGPath content="M19,20H4C2.89,20 2,19.1 2,18V6C2,4.89 2.89,4 4,4H10L12,6H19A2,2 0 0,1 21,8H21L4,8V18L6.14,10H23.21L20.93,18.5C20.7,19.37 19.92,20 19,20Z" fill="#289de8" />
|
||||||
|
</graphic></Button>
|
||||||
|
<Button fx:id="resPldBtn5" mnemonicParsing="false" onAction="#bntResetPayloader" styleClass="buttonStop">
|
||||||
|
<graphic>
|
||||||
|
<SVGPath content="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z" fill="#fb582c" />
|
||||||
|
</graphic>
|
||||||
|
</Button>
|
||||||
|
</children>
|
||||||
|
</HBox>
|
||||||
|
<Separator prefWidth="200.0" />
|
||||||
|
</children>
|
||||||
|
<VBox.margin>
|
||||||
|
<Insets left="15.0" right="15.0" />
|
||||||
|
</VBox.margin>
|
||||||
|
</VBox>
|
||||||
|
<HBox alignment="CENTER">
|
||||||
|
<children>
|
||||||
|
<Label fx:id="statusLbl" />
|
||||||
|
</children>
|
||||||
|
</HBox>
|
||||||
|
<Pane VBox.vgrow="ALWAYS" />
|
||||||
|
<HBox alignment="CENTER">
|
||||||
|
<children>
|
||||||
|
<Button fx:id="injectPldBtn" contentDisplay="TOP" mnemonicParsing="false" styleClass="buttonUp" text="%btn_InjectPayloader">
|
||||||
|
<graphic>
|
||||||
|
<SVGPath content="M 1 1 L 1 13.5 L 21 13.5 L 21 1 L 1 1 z M 26.226562 1.0683594 L 22 5.2949219 L 26.226562 9.5214844 L 27.226562 8.5214844 L 24.697266 6 L 31.158203 6 L 31.158203 20 L 32.566406 20 L 32.566406 4.5917969 L 24.697266 4.5917969 L 27.226562 2.0683594 L 26.226562 1.0683594 z M 2.515625 2.25 L 12.984375 2.25 C 12.993075 2.25 13 2.256995 13 2.265625 L 13 3.984375 C 12.999995 3.993026 12.993031 4 12.984375 4 L 2.515625 4 C 2.5069687 4 2.5 3.993031 2.5 3.984375 L 2.5 2.265625 C 2.5 2.256925 2.50697 2.25 2.515625 2.25 z M 2.515625 5.25 L 17.962891 5.25 C 17.971591 5.25 17.978516 5.256995 17.978516 5.265625 L 17.978516 6.984375 C 17.978516 6.993075 17.971521 7 17.962891 7 L 2.515625 7 C 2.5069687 6.99999 2.5 6.993031 2.5 6.984375 L 2.5 5.265625 C 2.5 5.256925 2.50697 5.25 2.515625 5.25 z M 2.515625 8.25 L 15.421875 8.25 C 15.430575 8.25 15.4375 8.256995 15.4375 8.265625 L 15.4375 9.984375 C 15.4375 9.993075 15.430505 10 15.421875 10 L 2.515625 10 C 2.5069687 9.99999 2.5 9.993031 2.5 9.984375 L 2.5 8.265625 C 2.5 8.256969 2.5069687 8.25 2.515625 8.25 z M 1 14.5 L 1 18 C 1 20 2 21 4 21 L 18 21 C 20 21 21 20 21 18 L 21 14.5 L 1 14.5 z M 5.8515625 16.001953 A 1.8950667 1.8950667 0 0 1 7.7480469 17.898438 A 1.8950667 1.8950667 0 0 1 5.8515625 19.792969 A 1.8950667 1.8950667 0 0 1 3.9570312 17.898438 A 1.8950667 1.8950667 0 0 1 5.8515625 16.001953 z" fill="#71e016" />
|
||||||
|
</graphic></Button>
|
||||||
|
</children>
|
||||||
|
</HBox>
|
||||||
|
<padding>
|
||||||
|
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||||
|
</padding>
|
||||||
|
</VBox>
|
||||||
|
</ScrollPane>
|
|
@ -127,7 +127,7 @@
|
||||||
</VBox>
|
</VBox>
|
||||||
</children>
|
</children>
|
||||||
<padding>
|
<padding>
|
||||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
<Insets bottom="5.0" left="15.0" right="15.0" top="5.0" />
|
||||||
</padding>
|
</padding>
|
||||||
</VBox>
|
</VBox>
|
||||||
</ScrollPane>
|
</ScrollPane>
|
||||||
|
|
107
src/main/resources/SplitMergeTab.fxml
Normal file
107
src/main/resources/SplitMergeTab.fxml
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<?import javafx.geometry.Insets?>
|
||||||
|
<?import javafx.scene.control.Button?>
|
||||||
|
<?import javafx.scene.control.Label?>
|
||||||
|
<?import javafx.scene.control.RadioButton?>
|
||||||
|
<?import javafx.scene.control.Separator?>
|
||||||
|
<?import javafx.scene.control.ToggleGroup?>
|
||||||
|
<?import javafx.scene.layout.ColumnConstraints?>
|
||||||
|
<?import javafx.scene.layout.GridPane?>
|
||||||
|
<?import javafx.scene.layout.HBox?>
|
||||||
|
<?import javafx.scene.layout.Pane?>
|
||||||
|
<?import javafx.scene.layout.RowConstraints?>
|
||||||
|
<?import javafx.scene.layout.VBox?>
|
||||||
|
<?import javafx.scene.text.Font?>
|
||||||
|
|
||||||
|
<VBox fx:id="smToolPane" onDragDropped="#handleDrop" onDragOver="#handleDragOver" spacing="20.0" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="nsusbloader.Controllers.SplitMergeController">
|
||||||
|
<VBox spacing="15.0">
|
||||||
|
<children>
|
||||||
|
<Pane minHeight="-Infinity" prefHeight="10.0" style="-fx-background-color: linear-gradient(from 41px 34px to 50px 50px, reflect, #00c8fc 40%, transparent 45%);" />
|
||||||
|
<HBox alignment="CENTER">
|
||||||
|
<children>
|
||||||
|
<Label text="%tabSplMrg_Lbl_SplitNMergeTitle">
|
||||||
|
<font>
|
||||||
|
<Font name="System Bold" size="15.0" />
|
||||||
|
</font>
|
||||||
|
</Label>
|
||||||
|
</children>
|
||||||
|
</HBox>
|
||||||
|
<GridPane>
|
||||||
|
<columnConstraints>
|
||||||
|
<ColumnConstraints hgrow="SOMETIMES" />
|
||||||
|
<ColumnConstraints hgrow="SOMETIMES" percentWidth="90.0" />
|
||||||
|
<ColumnConstraints hgrow="SOMETIMES" />
|
||||||
|
</columnConstraints>
|
||||||
|
<rowConstraints>
|
||||||
|
<RowConstraints vgrow="SOMETIMES" />
|
||||||
|
</rowConstraints>
|
||||||
|
<children>
|
||||||
|
<Separator prefWidth="200.0" styleClass="strangeSeparator" GridPane.columnIndex="1" />
|
||||||
|
</children>
|
||||||
|
</GridPane>
|
||||||
|
</children>
|
||||||
|
</VBox>
|
||||||
|
<VBox fillWidth="false" spacing="5.0">
|
||||||
|
<children>
|
||||||
|
<RadioButton fx:id="splitRad" contentDisplay="TOP" mnemonicParsing="false" text="%tabSplMrg_RadioBtn_Split">
|
||||||
|
<toggleGroup>
|
||||||
|
<ToggleGroup fx:id="splitMergeTogGrp" />
|
||||||
|
</toggleGroup>
|
||||||
|
</RadioButton>
|
||||||
|
<RadioButton fx:id="mergeRad" contentDisplay="TOP" mnemonicParsing="false" text="%tabSplMrg_RadioBtn_Merge" toggleGroup="$splitMergeTogGrp" />
|
||||||
|
</children>
|
||||||
|
<VBox.margin>
|
||||||
|
<Insets left="15.0" right="15.0" />
|
||||||
|
</VBox.margin>
|
||||||
|
</VBox>
|
||||||
|
<VBox spacing="5.0">
|
||||||
|
<children>
|
||||||
|
<HBox>
|
||||||
|
<children>
|
||||||
|
<Label fx:id="fileFolderLabelLbl" />
|
||||||
|
<Label fx:id="fileFolderActualPathLbl" />
|
||||||
|
</children>
|
||||||
|
</HBox>
|
||||||
|
<Button fx:id="selectFileFolderBtn" contentDisplay="TOP" mnemonicParsing="false" />
|
||||||
|
</children>
|
||||||
|
<VBox.margin>
|
||||||
|
<Insets left="15.0" right="15.0" />
|
||||||
|
</VBox.margin>
|
||||||
|
</VBox>
|
||||||
|
<VBox spacing="5.0">
|
||||||
|
<children>
|
||||||
|
<HBox>
|
||||||
|
<children>
|
||||||
|
<Label text="%tabSplMrg_Lbl_SaveToLocation" />
|
||||||
|
<Label fx:id="saveToPathLbl" />
|
||||||
|
</children>
|
||||||
|
</HBox>
|
||||||
|
<Button fx:id="changeSaveToBtn" contentDisplay="TOP" mnemonicParsing="false" text="%tabSplMrg_Btn_ChangeSaveToLocation" />
|
||||||
|
</children>
|
||||||
|
<VBox.margin>
|
||||||
|
<Insets left="15.0" right="15.0" />
|
||||||
|
</VBox.margin>
|
||||||
|
</VBox>
|
||||||
|
<HBox alignment="CENTER">
|
||||||
|
<children>
|
||||||
|
<Label fx:id="statusLbl" />
|
||||||
|
</children>
|
||||||
|
<VBox.margin>
|
||||||
|
<Insets left="15.0" right="15.0" />
|
||||||
|
</VBox.margin>
|
||||||
|
</HBox>
|
||||||
|
<Pane VBox.vgrow="ALWAYS" />
|
||||||
|
<VBox>
|
||||||
|
<children>
|
||||||
|
<HBox alignment="CENTER">
|
||||||
|
<children>
|
||||||
|
<Button fx:id="convertBtn" contentDisplay="TOP" mnemonicParsing="false" styleClass="buttonUp" text="%tabSplMrg_Btn_Convert" />
|
||||||
|
</children>
|
||||||
|
</HBox>
|
||||||
|
</children>
|
||||||
|
</VBox>
|
||||||
|
<padding>
|
||||||
|
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||||
|
</padding>
|
||||||
|
</VBox>
|
|
@ -39,10 +39,26 @@ windowTitleNewVersionUnknown=Unable to check for new versions
|
||||||
windowBodyNewVersionUnknown=Something went wrong\nMaybe internet unavailable, or GitHub is down
|
windowBodyNewVersionUnknown=Something went wrong\nMaybe internet unavailable, or GitHub is down
|
||||||
windowBodyNewVersionNOTAval=You're using the latest version
|
windowBodyNewVersionNOTAval=You're using the latest version
|
||||||
tab2_Cb_AllowXciNszXcz=Allow XCI / NSZ / XCZ files selection for Tinfoil
|
tab2_Cb_AllowXciNszXcz=Allow XCI / NSZ / XCZ files selection for Tinfoil
|
||||||
tab2_Lbl_AllowXciNszXczDesc=Used by applications that support XCI/NSZ/XCZ and utilizes Tinfoil transfer protocol. Don't change if not sure.
|
tab2_Lbl_AllowXciNszXczDesc=Used by applications that support XCI/NSZ/XCZ and utilizes Tinfoil transfer protocol. Don't change if not sure. Enable for Awoo Installer.
|
||||||
tab2_Lbl_Language=Language
|
tab2_Lbl_Language=Language
|
||||||
windowBodyRestartToApplyLang=Please restart application to apply changes.
|
windowBodyRestartToApplyLang=Please restart application to apply changes.
|
||||||
tab2_Cb_GLshowNspOnly=Show only *.nsp in GoldLeaf.
|
tab2_Cb_GLshowNspOnly=Show only *.nsp in GoldLeaf.
|
||||||
tab2_Cb_UseOldGlVersion=Use old GoldLeaf version
|
tab2_Cb_UseOldGlVersion=Use old GoldLeaf version
|
||||||
btn_OpenSplitFile=Select split NSP
|
btn_OpenSplitFile=Select split NSP
|
||||||
tab2_Lbl_ApplicationSettings=Main settings
|
tab2_Lbl_ApplicationSettings=Main settings
|
||||||
|
tabSplMrg_Lbl_SplitNMergeTitle=Split & merge files tool
|
||||||
|
tabSplMrg_RadioBtn_Split=Split
|
||||||
|
tabSplMrg_RadioBtn_Merge=Merge
|
||||||
|
tabSplMrg_Txt_File=File:
|
||||||
|
tabSplMrg_Txt_Folder=Split file (folder):
|
||||||
|
tabSplMrg_Btn_SelectFile=Select File
|
||||||
|
tabSplMrg_Btn_SelectFolder=Select Folder
|
||||||
|
tabSplMrg_Lbl_SaveToLocation=Save to:
|
||||||
|
tabSplMrg_Btn_ChangeSaveToLocation=Change
|
||||||
|
tabSplMrg_Btn_Convert=Convert
|
||||||
|
windowTitleError=Error
|
||||||
|
windowBodyPleaseFinishTransfersFirst=Unable to split/merge files when application USB/Network process active. Please interrupt active transfers first.
|
||||||
|
done_txt=Done!
|
||||||
|
failure_txt=Failed
|
||||||
|
btn_Select=Select
|
||||||
|
btn_InjectPayloader=Inject payload
|
||||||
|
|
|
@ -39,11 +39,27 @@ windowTitleNewVersionUnknown=\u041D\u0435\u0432\u043E\u0437\u043C\u043E\u0436\u0
|
||||||
windowBodyNewVersionNOTAval=\u0412\u044B \u0443\u0436\u0435 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0435\u0442\u0435 \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u044E\u044E \u0432\u0435\u0440\u0441\u0438\u044E
|
windowBodyNewVersionNOTAval=\u0412\u044B \u0443\u0436\u0435 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0435\u0442\u0435 \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u044E\u044E \u0432\u0435\u0440\u0441\u0438\u044E
|
||||||
windowBodyNewVersionUnknown=\u0427\u0442\u043E-\u0442\u043E \u043F\u043E\u0448\u043B\u043E \u043D\u0435 \u0442\u0430\u043A.\n\u041C\u043E\u0436\u0435\u0442 \u0431\u044B\u0442\u044C \u043D\u0435\u0442 \u0438\u043D\u0442\u0435\u0440\u043D\u0435\u0442\u0430 \u0438\u043B\u0438 GitHub \u043D\u0435\u0434\u043E\u0441\u0442\u0443\u043F\u0435\u043D.
|
windowBodyNewVersionUnknown=\u0427\u0442\u043E-\u0442\u043E \u043F\u043E\u0448\u043B\u043E \u043D\u0435 \u0442\u0430\u043A.\n\u041C\u043E\u0436\u0435\u0442 \u0431\u044B\u0442\u044C \u043D\u0435\u0442 \u0438\u043D\u0442\u0435\u0440\u043D\u0435\u0442\u0430 \u0438\u043B\u0438 GitHub \u043D\u0435\u0434\u043E\u0441\u0442\u0443\u043F\u0435\u043D.
|
||||||
tab2_Cb_AllowXciNszXcz=\u0420\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u044C \u0432\u044B\u0431\u043E\u0440 XCI, NSZ \u0438 XCZ \u0444\u0430\u0439\u043B\u043E\u0432 \u0434\u043B\u044F Tinfoil
|
tab2_Cb_AllowXciNszXcz=\u0420\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u044C \u0432\u044B\u0431\u043E\u0440 XCI, NSZ \u0438 XCZ \u0444\u0430\u0439\u043B\u043E\u0432 \u0434\u043B\u044F Tinfoil
|
||||||
tab2_Lbl_AllowXciNszXczDesc=\u0418\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0435\u0442\u0441\u044F \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F\u043C\u0438, \u043A\u043E\u0442\u043E\u0440\u044B\u0435 \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044E\u0442 XCI, NSZ, XCZ \u0438 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u044E\u0442 \u043F\u0440\u043E\u0442\u043E\u043A\u043E\u043B \u043F\u0435\u0440\u0435\u0434\u0430\u0447\u0438 Tinfoil. \u041D\u0435 \u043C\u0435\u043D\u044F\u0439\u0442\u0435 \u0435\u0441\u043B\u0438 \u043D\u0435 \u0443\u0432\u0435\u0440\u0435\u043D\u044B.
|
tab2_Lbl_AllowXciNszXczDesc=\u0418\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0435\u0442\u0441\u044F \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F\u043C\u0438, \u043A\u043E\u0442\u043E\u0440\u044B\u0435 \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044E\u0442 XCI, NSZ, XCZ \u0438 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u044E\u0442 \u043F\u0440\u043E\u0442\u043E\u043A\u043E\u043B \u043F\u0435\u0440\u0435\u0434\u0430\u0447\u0438 Tinfoil. \u041D\u0435 \u043C\u0435\u043D\u044F\u0439\u0442\u0435 \u0435\u0441\u043B\u0438 \u043D\u0435 \u0443\u0432\u0435\u0440\u0435\u043D\u044B. \u0412\u043A\u043B\u044E\u0447\u0438\u0442\u0435 \u043F\u0440\u0438 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u0438 Awoo Installer.
|
||||||
tab2_Lbl_Language=\u042F\u0437\u044B\u043A
|
tab2_Lbl_Language=\u042F\u0437\u044B\u043A
|
||||||
windowBodyRestartToApplyLang=\u041F\u043E\u0436\u0430\u043B\u0443\u0439\u0441\u0442\u0430, \u043F\u0435\u0440\u0435\u0437\u0430\u043F\u0443\u0441\u0442\u0438\u0442\u0435 \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u0435 \u0447\u0442\u043E\u0431\u044B \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u044F \u0432\u0441\u0442\u0443\u043F\u0438\u043B\u0438 \u0432 \u0441\u0438\u043B\u0443.
|
windowBodyRestartToApplyLang=\u041F\u043E\u0436\u0430\u043B\u0443\u0439\u0441\u0442\u0430, \u043F\u0435\u0440\u0435\u0437\u0430\u043F\u0443\u0441\u0442\u0438\u0442\u0435 \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u0435 \u0447\u0442\u043E\u0431\u044B \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u044F \u0432\u0441\u0442\u0443\u043F\u0438\u043B\u0438 \u0432 \u0441\u0438\u043B\u0443.
|
||||||
tab2_Cb_GLshowNspOnly=\u041E\u0442\u043E\u0431\u0440\u0430\u0436\u0430\u0442\u044C \u0438\u0441\u043A\u043B\u044E\u0447\u0438\u0442\u0435\u043B\u044C\u043D\u043E \u0444\u0430\u0439\u043B\u044B *.nsp \u0432 GoldLeaf.
|
tab2_Cb_GLshowNspOnly=\u041E\u0442\u043E\u0431\u0440\u0430\u0436\u0430\u0442\u044C \u0438\u0441\u043A\u043B\u044E\u0447\u0438\u0442\u0435\u043B\u044C\u043D\u043E \u0444\u0430\u0439\u043B\u044B *.nsp \u0432 GoldLeaf.
|
||||||
tab2_Cb_UseOldGlVersion=\u0418\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u044C \u0441\u0442\u0430\u0440\u0443\u044E \u0432\u0435\u0440\u0441\u0438\u044E GoldLeaf
|
tab2_Cb_UseOldGlVersion=\u0418\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u044C \u0441\u0442\u0430\u0440\u0443\u044E \u0432\u0435\u0440\u0441\u0438\u044E GoldLeaf
|
||||||
btn_OpenSplitFile=\u0412\u044B\u0431\u0440\u0430\u0442\u044C \u0440\u0430\u0437\u0431\u0438\u0442\u044B\u0439 NSP
|
btn_OpenSplitFile=\u0412\u044B\u0431\u0440\u0430\u0442\u044C \u0440\u0430\u0437\u0431\u0438\u0442\u044B\u0439 NSP
|
||||||
tab2_Lbl_ApplicationSettings=\u041E\u0441\u043D\u043E\u0432\u043D\u044B\u0435 \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438
|
tab2_Lbl_ApplicationSettings=\u041E\u0441\u043D\u043E\u0432\u043D\u044B\u0435 \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438
|
||||||
|
tabSplMrg_Lbl_SplitNMergeTitle=\u0423\u0442\u0438\u043B\u0438\u0442\u0430 \u0440\u0430\u0437\u0431\u0438\u0432\u043A\u0438 \u0438 \u0441\u043B\u0438\u044F\u043D\u0438\u044F \u0444\u0430\u0439\u043B\u043E\u0432
|
||||||
|
tabSplMrg_Btn_Convert=\u041A\u043E\u043D\u0432\u0435\u0440\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C
|
||||||
|
tabSplMrg_RadioBtn_Split=\u0420\u0430\u0437\u0431\u0438\u0442\u044C
|
||||||
|
tabSplMrg_RadioBtn_Merge=\u041E\u0431\u044A\u0435\u0434\u0438\u043D\u0438\u0442\u044C
|
||||||
|
tabSplMrg_Txt_File=\u0424\u0430\u0439\u043B:
|
||||||
|
tabSplMrg_Txt_Folder=\u0420\u0430\u0437\u0431\u0438\u0442\u044B\u0439 \u0444\u0430\u0439\u043B (\u043F\u0430\u043F\u043A\u0430):
|
||||||
|
tabSplMrg_Lbl_SaveToLocation=\u0421\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442 \u0432:
|
||||||
|
tabSplMrg_Btn_ChangeSaveToLocation=\u0418\u0437\u043C\u0435\u043D\u0438\u0442\u044C
|
||||||
|
tabSplMrg_Btn_SelectFile=\u0412\u044B\u0431\u0440\u0430\u0442\u044C \u0444\u0430\u0439\u043B
|
||||||
|
tabSplMrg_Btn_SelectFolder=\u0412\u044B\u0431\u0440\u0430\u0442\u044C \u043F\u0430\u043F\u043A\u0443
|
||||||
|
windowTitleError=\u041E\u0448\u0438\u0431\u043A\u0430
|
||||||
|
windowBodyPleaseFinishTransfersFirst=\u041D\u0435\u0432\u043E\u0437\u043C\u043E\u0436\u043D\u043E \u043F\u0440\u043E\u0438\u0437\u0432\u043E\u0434\u0438\u0442\u044C \u0440\u0430\u0437\u0431\u0438\u0432\u043A\u0443 \u0438\u043B\u0438 \u0441\u043B\u0438\u044F\u043D\u0438\u0435 \u0444\u0430\u0439\u043B\u0430 \u0432 \u0442\u043E\u0442 \u043C\u043E\u043C\u0435\u043D\u0442, \u043A\u043E\u0433\u0434\u0430 \u0430\u043A\u0442\u0438\u0432\u0435\u043D \u043F\u0440\u043E\u0446\u0435\u0441\u0441 USB \u0438\u043B\u0438 \u0421\u0435\u0442\u0435\u0432\u043E\u0439 \u043F\u0435\u0440\u0435\u0434\u0430\u0447\u0438. \u0421\u043F\u0435\u0440\u0432\u0430 \u043F\u0440\u0435\u0440\u0432\u0438\u0442\u0435 \u0435\u0433\u043E.
|
||||||
|
done_txt=\u0413\u043E\u0442\u043E\u0432\u043E!
|
||||||
|
failure_txt=\u041D\u0435\u0443\u0434\u0430\u0447\u0430
|
||||||
|
btn_Select=\u0412\u044B\u0431\u0440\u0430\u0442\u044C
|
||||||
|
btn_InjectPayloader=\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C payload
|
||||||
|
|
||||||
|
|
|
@ -39,10 +39,26 @@ windowTitleNewVersionUnknown=\u041D\u0435\u043C\u043E\u0436\u043B\u0438\u0432\u0
|
||||||
windowBodyNewVersionNOTAval=\u0412\u0438 \u0432\u0436\u0435 \u0432\u0438\u043A\u043E\u0440\u0438\u0441\u0442\u043E\u0432\u0443\u0454\u0442\u0435 \u043E\u0441\u0442\u0430\u043D\u043D\u044E \u0432\u0435\u0440\u0441\u0456\u044E
|
windowBodyNewVersionNOTAval=\u0412\u0438 \u0432\u0436\u0435 \u0432\u0438\u043A\u043E\u0440\u0438\u0441\u0442\u043E\u0432\u0443\u0454\u0442\u0435 \u043E\u0441\u0442\u0430\u043D\u043D\u044E \u0432\u0435\u0440\u0441\u0456\u044E
|
||||||
windowBodyNewVersionUnknown=\u0429\u043E\u0441\u044C \u043F\u0456\u0448\u043B\u043E \u043D\u0435 \u0442\u0430\u043A.\n\u041C\u043E\u0436\u043B\u0438\u0432\u043E, \u0456\u043D\u0442\u0435\u0440\u043D\u0435\u0442 \u043D\u0435\u0434\u043E\u0441\u0442\u0443\u043F\u043D\u0438\u0439, \u0430\u0431\u043E GitHub \u043D\u0435 \u043F\u0440\u0430\u0446\u044E\u0454.
|
windowBodyNewVersionUnknown=\u0429\u043E\u0441\u044C \u043F\u0456\u0448\u043B\u043E \u043D\u0435 \u0442\u0430\u043A.\n\u041C\u043E\u0436\u043B\u0438\u0432\u043E, \u0456\u043D\u0442\u0435\u0440\u043D\u0435\u0442 \u043D\u0435\u0434\u043E\u0441\u0442\u0443\u043F\u043D\u0438\u0439, \u0430\u0431\u043E GitHub \u043D\u0435 \u043F\u0440\u0430\u0446\u044E\u0454.
|
||||||
tab2_Cb_AllowXciNszXcz=\u0414\u043E\u0437\u0432\u043E\u043B\u0438\u0442\u0438 \u0432\u0438\u0431\u0456\u0440 XCI, NSZ \u0442\u0430 XCZ \u0444\u0430\u0439\u043B\u0456\u0432 \u0434\u043B\u044F \u0432\u0438\u043A\u043E\u0440\u0438\u0441\u0442\u0430\u043D\u043D\u044F \u0443 Tinfoil
|
tab2_Cb_AllowXciNszXcz=\u0414\u043E\u0437\u0432\u043E\u043B\u0438\u0442\u0438 \u0432\u0438\u0431\u0456\u0440 XCI, NSZ \u0442\u0430 XCZ \u0444\u0430\u0439\u043B\u0456\u0432 \u0434\u043B\u044F \u0432\u0438\u043A\u043E\u0440\u0438\u0441\u0442\u0430\u043D\u043D\u044F \u0443 Tinfoil
|
||||||
tab2_Lbl_AllowXciNszXczDesc=\u0412\u0438\u043A\u043E\u0440\u0438\u0441\u0442\u043E\u0432\u0443\u0454\u0442\u044C\u0441\u044F \u0434\u043E\u0434\u0430\u0442\u043A\u0430\u043C\u0438, \u0449\u043E \u043C\u0430\u044E\u0442\u044C \u043F\u0456\u0434\u0442\u0440\u0438\u043C\u043A\u0443 XCI, NSZ, XCZ \u0456 \u0432\u0438\u043A\u043E\u0440\u0438\u0441\u0442\u043E\u0432\u0443\u044E\u0442\u044C \u043F\u0440\u043E\u0442\u043E\u043A\u043E\u043B \u043F\u0435\u0440\u0435\u0434\u0430\u0447\u0456 Tinfoil. \u041D\u0435 \u0437\u043C\u0456\u043D\u044E\u0439\u0442\u0435, \u044F\u043A\u0449\u043E \u043D\u0435 \u0432\u043F\u0435\u0432\u043D\u0435\u043D\u0456.
|
tab2_Lbl_AllowXciNszXczDesc=\u0412\u0438\u043A\u043E\u0440\u0438\u0441\u0442\u043E\u0432\u0443\u0454\u0442\u044C\u0441\u044F \u0434\u043E\u0434\u0430\u0442\u043A\u0430\u043C\u0438, \u0449\u043E \u043C\u0430\u044E\u0442\u044C \u043F\u0456\u0434\u0442\u0440\u0438\u043C\u043A\u0443 XCI, NSZ, XCZ \u0456 \u0432\u0438\u043A\u043E\u0440\u0438\u0441\u0442\u043E\u0432\u0443\u044E\u0442\u044C \u043F\u0440\u043E\u0442\u043E\u043A\u043E\u043B \u043F\u0435\u0440\u0435\u0434\u0430\u0447\u0456 Tinfoil. \u041D\u0435 \u0437\u043C\u0456\u043D\u044E\u0439\u0442\u0435, \u044F\u043A\u0449\u043E \u043D\u0435 \u0432\u043F\u0435\u0432\u043D\u0435\u043D\u0456. \u0423\u0432\u0456\u043C\u043A\u043D\u0456\u0442\u044C \u044F\u043A\u0449\u043E \u0432\u0438\u043A\u043E\u0440\u0438\u0441\u0442\u043E\u0432\u0443\u0454\u0442\u0435 Awoo Installer
|
||||||
tab2_Lbl_Language=\u041C\u043E\u0432\u0430
|
tab2_Lbl_Language=\u041C\u043E\u0432\u0430
|
||||||
windowBodyRestartToApplyLang=\u0411\u0443\u0434\u044C \u043B\u0430\u0441\u043A\u0430, \u043F\u0435\u0440\u0435\u0437\u0430\u043F\u0443\u0441\u0442\u0456\u0442\u044C \u0434\u043E\u0434\u0430\u0442\u043E\u043A \u0449\u043E\u0431 \u0437\u043C\u0456\u043D\u0438 \u0432\u0441\u0442\u0443\u043F\u0438\u043B\u0438 \u0432 \u0441\u0438\u043B\u0443.
|
windowBodyRestartToApplyLang=\u0411\u0443\u0434\u044C \u043B\u0430\u0441\u043A\u0430, \u043F\u0435\u0440\u0435\u0437\u0430\u043F\u0443\u0441\u0442\u0456\u0442\u044C \u0434\u043E\u0434\u0430\u0442\u043E\u043A \u0449\u043E\u0431 \u0437\u043C\u0456\u043D\u0438 \u0432\u0441\u0442\u0443\u043F\u0438\u043B\u0438 \u0432 \u0441\u0438\u043B\u0443.
|
||||||
tab2_Cb_GLshowNspOnly=\u0412\u0456\u0434\u043E\u0431\u0440\u0430\u0436\u0430\u0442\u0438 \u0432\u0438\u043A\u043B\u044E\u0447\u043D\u043E *.nsp \u0444\u0430\u0439\u043B\u0438 \u0443 GoldLeaf.
|
tab2_Cb_GLshowNspOnly=\u0412\u0456\u0434\u043E\u0431\u0440\u0430\u0436\u0430\u0442\u0438 \u0432\u0438\u043A\u043B\u044E\u0447\u043D\u043E *.nsp \u0444\u0430\u0439\u043B\u0438 \u0443 GoldLeaf.
|
||||||
tab2_Cb_UseOldGlVersion=\u0412\u0438\u043A\u043E\u0440\u0438\u0441\u0442\u043E\u0432\u0443\u0432\u0430\u0442\u0438 \u0441\u0442\u0430\u0440\u0443 \u0432\u0435\u0440\u0441\u0456\u044E GoldLeaf
|
tab2_Cb_UseOldGlVersion=\u0412\u0438\u043A\u043E\u0440\u0438\u0441\u0442\u043E\u0432\u0443\u0432\u0430\u0442\u0438 \u0441\u0442\u0430\u0440\u0443 \u0432\u0435\u0440\u0441\u0456\u044E GoldLeaf
|
||||||
btn_OpenSplitFile=\u0412\u0438\u0431\u0440\u0430\u0442\u0438 \u0440\u043E\u0437\u0431\u0438\u0442\u0438\u0439 NSP
|
btn_OpenSplitFile=\u0412\u0438\u0431\u0440\u0430\u0442\u0438 \u0440\u043E\u0437\u0431\u0438\u0442\u0438\u0439 NSP
|
||||||
tab2_Lbl_ApplicationSettings=\u041E\u0441\u043D\u043E\u0432\u043D\u0456 \u043D\u0430\u043B\u0430\u0448\u0442\u0443\u0432\u0430\u043D\u043D\u044F
|
tab2_Lbl_ApplicationSettings=\u041E\u0441\u043D\u043E\u0432\u043D\u0456 \u043D\u0430\u043B\u0430\u0448\u0442\u0443\u0432\u0430\u043D\u043D\u044F
|
||||||
|
tabSplMrg_Lbl_SplitNMergeTitle=\u041F\u043E\u043C\u0456\u0447\u043D\u0438\u043A \u0440\u043E\u0437\u0431\u0432\u043A\u0438 \u0442\u0430 \u043E\u0431'\u0454\u0434\u043D\u0430\u043D\u043D\u044F \u0444\u0430\u0439\u043B\u0456\u0432
|
||||||
|
tabSplMrg_Btn_Convert=\u041A\u043E\u043D\u0432\u0435\u0440\u0442\u0443\u0432\u0430\u0442\u0438
|
||||||
|
tabSplMrg_RadioBtn_Split=\u0420\u043E\u0437\u0431\u0438\u0442\u0438
|
||||||
|
tabSplMrg_RadioBtn_Merge=\u041E\u0431'\u0454\u0434\u043D\u0430\u0442\u0438
|
||||||
|
tabSplMrg_Txt_File=\u0424\u0430\u0439\u043B:
|
||||||
|
tabSplMrg_Txt_Folder=\u0420\u043E\u0437\u0431\u0438\u0442\u0438\u0439 \u0444\u0430\u0439\u043B (\u043F\u0430\u043F\u043A\u0430):
|
||||||
|
tabSplMrg_Lbl_SaveToLocation=\u0417\u0431\u0435\u0440\u0435\u0433\u0442\u0438 \u0432:
|
||||||
|
tabSplMrg_Btn_ChangeSaveToLocation=\u0417\u043C\u0456\u043D\u0438\u0442\u0438
|
||||||
|
tabSplMrg_Btn_SelectFile=\u0412\u0438\u0431\u0440\u0430\u0442\u0438 \u0444\u0430\u0439\u043B
|
||||||
|
tabSplMrg_Btn_SelectFolder=\u0412\u0438\u0431\u0440\u0430\u0442\u0438 \u043F\u0430\u043F\u043A\u0443
|
||||||
|
windowTitleError=\u041F\u043E\u043C\u0438\u043B\u043A\u0430
|
||||||
|
windowBodyPleaseFinishTransfersFirst=\u041D\u0435\u043C\u043E\u0436\u043B\u0438\u0432\u043E \u0437\u0434\u0456\u0439\u0441\u043D\u044E\u0432\u0430\u0442\u0438 \u0440\u043E\u0437\u0431\u0438\u0432\u043A\u0443 \u0430\u0431\u043E \u0437'\u0454\u0434\u043D\u0430\u043D\u043D\u044F \u0444\u0430\u0439\u043B\u0443 \u0443 \u0442\u043E\u0439 \u043C\u043E\u043C\u0435\u043D\u0442, \u044F\u043A \u043F\u0440\u043E\u0446\u0435\u0441 \u043F\u0435\u0440\u0435\u0434\u0430\u0447\u0456 \u0447\u0435\u0440\u0435\u0437 USB \u0447\u0438 \u0442\u043E \u0447\u0435\u0440\u0435\u0437 \u043C\u0435\u0440\u0435\u0436\u0443 \u0449\u0435 \u0430\u043A\u0442\u0438\u0432\u043D\u0438\u0439. \u0421\u043F\u043E\u0447\u0430\u0442\u043A\u0443 \u043F\u0440\u0438\u043F\u0438\u043D\u0456\u0442\u044C \u0439\u043E\u0433\u043E.
|
||||||
|
done_txt=\u0413\u043E\u0442\u043E\u0432\u043E!
|
||||||
|
failure_txt=\u041D\u0435\u0432\u0434\u0430\u0447\u0430
|
||||||
|
btn_Select=\u0412\u0438\u0431\u0440\u0430\u0442\u0438
|
||||||
|
btn_InjectPayloader=\u0417\u0430\u0432\u0430\u043D\u0442\u0430\u0436\u0438\u0442\u0438 payload
|
BIN
src/main/resources/native/linux/amd64/smashlib.so
Executable file
BIN
src/main/resources/native/linux/amd64/smashlib.so
Executable file
Binary file not shown.
BIN
src/main/resources/native/linux/x86/smashlib.so
Executable file
BIN
src/main/resources/native/linux/x86/smashlib.so
Executable file
Binary file not shown.
BIN
src/main/resources/native/windows/amd64/smashlib.dll
Normal file
BIN
src/main/resources/native/windows/amd64/smashlib.dll
Normal file
Binary file not shown.
BIN
src/main/resources/native/windows/x86/smashlib.dll
Normal file
BIN
src/main/resources/native/windows/x86/smashlib.dll
Normal file
Binary file not shown.
|
@ -92,11 +92,6 @@
|
||||||
.tool-bar{
|
.tool-bar{
|
||||||
-fx-background-color: transparent;
|
-fx-background-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.special-pane-as-border{
|
|
||||||
-fx-background-color: #f7fafa;
|
|
||||||
-fx-min-height: 1;
|
|
||||||
}
|
|
||||||
// -======================== Choice box =========================-
|
// -======================== Choice box =========================-
|
||||||
.choice-box {
|
.choice-box {
|
||||||
-fx-background-color: #4f4f4f;
|
-fx-background-color: #4f4f4f;
|
||||||
|
@ -144,16 +139,16 @@
|
||||||
-fx-fill: #7effff;
|
-fx-fill: #7effff;
|
||||||
}
|
}
|
||||||
.tab-pane .tab{
|
.tab-pane .tab{
|
||||||
-fx-background-color: #424242;
|
-fx-background-color: transparent;
|
||||||
-fx-focus-color: transparent;
|
-fx-focus-color: transparent;
|
||||||
-fx-faint-focus-color: transparent;
|
-fx-faint-focus-color: transparent;
|
||||||
-fx-border-radius: 0 0 0 0;
|
-fx-border-radius: 0 0 0 0;
|
||||||
-fx-border-width: 3 0 0 0;
|
-fx-border-width: 3 0 0 0;
|
||||||
-fx-border-color: #424242;
|
-fx-border-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab-pane .tab:selected{
|
.tab-pane .tab:selected{
|
||||||
-fx-background-color: #2d2d2d;
|
-fx-background-color: transparent;
|
||||||
-fx-focus-color: transparent;
|
-fx-focus-color: transparent;
|
||||||
-fx-faint-focus-color: transparent;
|
-fx-faint-focus-color: transparent;
|
||||||
-fx-border-radius: 0 0 0 0;
|
-fx-border-radius: 0 0 0 0;
|
||||||
|
@ -168,8 +163,7 @@
|
||||||
|
|
||||||
.tab-pane > .tab-header-area > .tab-header-background
|
.tab-pane > .tab-header-area > .tab-header-background
|
||||||
{
|
{
|
||||||
-fx-background-color: #424242;
|
-fx-background-color: linear-gradient(to right, #2d2d2d 0%, #343434 7.5%, #343434 100%); //#424242; //
|
||||||
|
|
||||||
}
|
}
|
||||||
.tab-pane > .tab-header-area > .headers-region > .tab {
|
.tab-pane > .tab-header-area > .headers-region > .tab {
|
||||||
-fx-padding: 10;
|
-fx-padding: 10;
|
||||||
|
@ -255,8 +249,18 @@
|
||||||
-fx-background-radius : 0.0em;
|
-fx-background-radius : 0.0em;
|
||||||
-fx-border-radius :2.0em;
|
-fx-border-radius :2.0em;
|
||||||
}
|
}
|
||||||
|
/* -========================= Separator ===================- */
|
||||||
// -========================== Scroll =====================-
|
.separator *.line {
|
||||||
|
-fx-border-style: solid;
|
||||||
|
-fx-border-width: 0 0 1 0;
|
||||||
|
-fx-border-color: #3a3738;
|
||||||
|
}
|
||||||
|
.strangeSeparator *.line {
|
||||||
|
-fx-border-style: solid;
|
||||||
|
-fx-border-width: 0 0 1 0;
|
||||||
|
-fx-border-color: #f7fafa;
|
||||||
|
}
|
||||||
|
/* -========================== Scroll =====================- */
|
||||||
.scroll-bar .increment-arrow,
|
.scroll-bar .increment-arrow,
|
||||||
.scroll-bar .decrement-arrow {
|
.scroll-bar .decrement-arrow {
|
||||||
-fx-background-color: #71e016;
|
-fx-background-color: #71e016;
|
||||||
|
@ -307,7 +311,6 @@
|
||||||
-fx-background-radius: 5;
|
-fx-background-radius: 5;
|
||||||
-fx-border-color: #2d2d2d;
|
-fx-border-color: #2d2d2d;
|
||||||
-fx-border-radius: 3;
|
-fx-border-radius: 3;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.check-box:hover .box {
|
.check-box:hover .box {
|
||||||
|
@ -324,7 +327,46 @@
|
||||||
.check-box:selected .mark, .check-box:selected:hover .mark{
|
.check-box:selected .mark, .check-box:selected:hover .mark{
|
||||||
-fx-background-color: #4f4f4f;
|
-fx-background-color: #4f4f4f;
|
||||||
}
|
}
|
||||||
|
/*-======================= Radio Button =====================-*/
|
||||||
|
.radio-button .radio, .radio-button:selected .radio {
|
||||||
|
-fx-background-color: #4f4f4f;
|
||||||
|
-fx-background-insets: 0 0 0 0, 0, 1, 1;
|
||||||
|
-fx-background-radius: 45;
|
||||||
|
-fx-border-color: transparent;
|
||||||
|
-fx-border-radius: 45;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-button:hover .radio {
|
||||||
|
-fx-background-color: #4f4f4f;
|
||||||
|
-fx-background-insets: 0 0 0 0, 0, 1, 1;
|
||||||
|
-fx-background-radius: 45;
|
||||||
|
-fx-border-color: #a4ffff;
|
||||||
|
-fx-border-radius: 45;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-button:selected .radio, .radio-button:selected:hover .radio {
|
||||||
|
-fx-background-color: #71e016;
|
||||||
|
}
|
||||||
|
.radio-button:selected .dot, .radio-button:selected:hover .dot{
|
||||||
|
-fx-background-color: #2d2d2d;
|
||||||
|
-fx-shape: "M9,20.42L2.79,14.21L5.62,11.38L9,14.77L18.88,4.88L21.71,7.71L9,20.42Z";
|
||||||
|
-fx-scale-x: 1.2;
|
||||||
|
-fx-scale-y: 1.2;
|
||||||
|
}
|
||||||
/***********************************************************/
|
/***********************************************************/
|
||||||
|
.regionSplitToOne {
|
||||||
|
-fx-shape: "m 3,23 c -1.104569,0 -2,0.895431 -2,2 v 16 c 0,1.1 0.89,2 2,2 h 12 c 1.104569,0 2,-0.895431 2,-2 V 25 c 0,-1.095153 -0.910156,-2 -2,-2 z m 39.400391,0 C 41.068391,23 40,24.1125 40,25.5 v 15 A 2.4,2.5 0 0 0 42.400391,43 H 61.599609 A 2.4,2.5 0 0 0 64,40.5 V 28 c 0,-1.3875 -1.080391,-2.5 -2.400391,-2.5 H 52 L 49.599609,23 Z M 5.099609,24.199219 h 7.800782 c 0.1,0.0021 0.09961,0.0018 0.09961,0.101562 v 0.09961 c -10e-7,0.09583 3.91e-4,0.09753 -0.09961,0.09961 H 5.099609 c -0.1,0.0057 -0.09961,0.004 -0.09961,-0.09961 v -0.09961 c 0,-0.09974 -3.91e-4,-0.103386 0.09961,-0.101562 z M 29,24.75 v 4 h -8 v 8 h 8 v 4 l 8,-8 z M 3,25 h 12 c 0.303385,0 0.5,0.204427 0.5,0.5 v 13 C 15.5,38.789959 15.29836,39 15,39 H 3 C 2.704427,39 2.5,38.803385 2.5,38.5 v -13 C 2.5,25.208333 2.71224,25 3,25 Z m 50.193359,6.962891 c 0.920139,0 1.620877,0.38585 2.103516,1.160156 0.482639,0.770833 0.724609,1.812066 0.724609,3.121094 0,1.3125 -0.24197,2.3546 -0.724609,3.128906 -0.482639,0.770833 -1.183377,1.15625 -2.103516,1.15625 -0.916666,0 -1.617404,-0.385417 -2.103515,-1.15625 -0.482639,-0.774306 -0.72461,-1.816406 -0.72461,-3.128906 0,-1.309028 0.241971,-2.350261 0.72461,-3.121094 0.486111,-0.774306 1.186849,-1.160156 2.103515,-1.160156 z m 6.396485,0 c 0.920139,0 1.620876,0.38585 2.103515,1.160156 0.482639,0.770833 0.72461,1.812066 0.72461,3.121094 0,1.3125 -0.241971,2.3546 -0.72461,3.128906 -0.482639,0.770833 -1.183376,1.15625 -2.103515,1.15625 -0.916667,0 -1.619358,-0.385417 -2.105469,-1.15625 -0.482639,-0.774306 -0.722656,-1.816406 -0.722656,-3.128906 0,-1.309028 0.240017,-2.350261 0.722656,-3.121094 0.486111,-0.774306 1.188802,-1.160156 2.105469,-1.160156 z m -10.025391,0.52539 h 0.01953 l -0.01953,0.01758 z m 3.628906,0.28125 c -0.579861,0 -1.020182,0.322917 -1.322265,0.96875 -0.302084,0.642361 -0.453125,1.457683 -0.453125,2.447266 0,0.225694 0.0056,0.470052 0.01953,0.730469 0.01389,0.260416 0.07357,0.612196 0.177734,1.05664 l 2.796875,-4.380859 c -0.177083,-0.322917 -0.369791,-0.53928 -0.578125,-0.650391 -0.204861,-0.114583 -0.418402,-0.171875 -0.640624,-0.171875 z m 6.396485,0 c -0.579861,0 -1.022136,0.322917 -1.324219,0.96875 -0.302083,0.642361 -0.453125,1.457683 -0.453125,2.447266 0,0.225694 0.0076,0.470052 0.02148,0.730469 0.01389,0.260416 0.07357,0.612196 0.177735,1.05664 l 2.796875,-4.380859 c -0.17708,-0.322917 -0.369788,-0.53928 -0.578121,-0.650391 -0.204861,-0.114583 -0.418403,-0.171875 -0.640625,-0.171875 z m -4.828125,1.78711 -2.777344,4.40625 c 0.149306,0.253472 0.321181,0.443793 0.515625,0.572265 0.194444,0.125 0.41276,0.1875 0.652344,0.1875 0.659722,0 1.128472,-0.367404 1.40625,-1.103515 0.277778,-0.739584 0.416015,-1.559679 0.416015,-2.458985 0,-0.555555 -0.07053,-1.089626 -0.21289,-1.603515 z m 6.394531,0 -2.775391,4.40625 c 0.149306,0.253472 0.321181,0.443793 0.515625,0.572265 0.194445,0.125 0.410808,0.1875 0.650391,0.1875 0.659722,0 1.128472,-0.367404 1.40625,-1.103515 0.277778,-0.739584 0.417969,-1.559679 0.417969,-2.458985 0,-0.555555 -0.07248,-1.089626 -0.214844,-1.603515 z M 6,40 h 6 l -3,2 z";
|
||||||
|
-fx-min-height: 20;
|
||||||
|
-fx-min-width: 64;
|
||||||
|
-fx-background-color: #71e016;
|
||||||
|
}
|
||||||
|
|
||||||
|
.regionOneToSplit {
|
||||||
|
-fx-shape: "M 50 1 C 48.895431 1 48 1.895431 48 3 L 48 19 C 48 20.1 48.89 21 50 21 L 62 21 C 63.104569 21 64 20.104569 64 19 L 64 3 C 64 1.904847 63.089844 1 62 1 L 50 1 z M 3.4160156 1.0371094 C 2.0840156 1.0371094 1.015625 2.1496094 1.015625 3.5371094 L 1.015625 18.537109 A 2.4 2.5 0 0 0 3.4160156 21.037109 L 22.615234 21.037109 A 2.4 2.5 0 0 0 25.015625 18.537109 L 25.015625 6.0371094 C 25.015625 4.6496094 23.935234 3.5371094 22.615234 3.5371094 L 13.015625 3.5371094 L 10.615234 1.0371094 L 3.4160156 1.0371094 z M 52.099609 2.1992188 L 59.900391 2.1992188 C 60.000391 2.2013185 60 2.2010194 60 2.3007812 L 60 2.4003906 C 59.999999 2.4962206 60.000391 2.49792 59.900391 2.5 L 52.099609 2.5 C 51.999609 2.5057 52 2.5040006 52 2.4003906 L 52 2.3007812 C 52 2.2010414 51.999609 2.1973947 52.099609 2.1992188 z M 37 3 L 37 7 L 29 7 L 29 15 L 37 15 L 37 19 L 45 11 L 37 3 z M 50 3 L 62 3 C 62.303385 3 62.5 3.204427 62.5 3.5 L 62.5 16.5 C 62.5 16.789959 62.29836 17 62 17 L 50 17 C 49.704427 17 49.5 16.803385 49.5 16.5 L 49.5 3.5 C 49.5 3.208333 49.71224 3 50 3 z M 14.208984 10 C 15.129123 10 15.829861 10.38585 16.3125 11.160156 C 16.795139 11.930989 17.037109 12.972222 17.037109 14.28125 C 17.037109 15.59375 16.795139 16.63585 16.3125 17.410156 C 15.829861 18.180989 15.129123 18.566406 14.208984 18.566406 C 13.292318 18.566406 12.59158 18.180989 12.105469 17.410156 C 11.62283 16.63585 11.380859 15.59375 11.380859 14.28125 C 11.380859 12.972222 11.62283 11.930989 12.105469 11.160156 C 12.59158 10.38585 13.292318 10 14.208984 10 z M 20.605469 10 C 21.525608 10 22.226345 10.38585 22.708984 11.160156 C 23.191623 11.930989 23.433594 12.972222 23.433594 14.28125 C 23.433594 15.59375 23.191623 16.63585 22.708984 17.410156 C 22.226345 18.180989 21.525608 18.566406 20.605469 18.566406 C 19.688802 18.566406 18.986111 18.180989 18.5 17.410156 C 18.017361 16.63585 17.777344 15.59375 17.777344 14.28125 C 17.777344 12.972222 18.017361 11.930989 18.5 11.160156 C 18.986111 10.38585 19.688802 10 20.605469 10 z M 14.208984 10.806641 C 13.629123 10.806641 13.188802 11.129558 12.886719 11.775391 C 12.584635 12.417752 12.433594 13.233073 12.433594 14.222656 C 12.433594 14.44835 12.439195 14.692708 12.453125 14.953125 C 12.467015 15.213541 12.526695 15.565322 12.630859 16.009766 L 15.427734 11.628906 C 15.250651 11.305989 15.057943 11.089627 14.849609 10.978516 C 14.644748 10.863933 14.431206 10.806641 14.208984 10.806641 z M 20.605469 10.806641 C 20.025608 10.806641 19.583333 11.129558 19.28125 11.775391 C 18.979167 12.417752 18.828125 13.233073 18.828125 14.222656 C 18.828125 14.44835 18.835729 14.692708 18.849609 14.953125 C 18.863499 15.213541 18.923179 15.565322 19.027344 16.009766 L 21.824219 11.628906 C 21.647139 11.305989 21.454427 11.089627 21.246094 10.978516 C 21.041233 10.863933 20.827691 10.806641 20.605469 10.806641 z M 15.777344 12.59375 L 13 17 C 13.149306 17.253472 13.321181 17.443794 13.515625 17.572266 C 13.710069 17.697266 13.928385 17.759766 14.167969 17.759766 C 14.827691 17.759766 15.296441 17.392361 15.574219 16.65625 C 15.851997 15.916666 15.990234 15.096572 15.990234 14.197266 C 15.990234 13.641711 15.919704 13.107639 15.777344 12.59375 z M 22.171875 12.59375 L 19.396484 17 C 19.54579 17.253472 19.717665 17.443794 19.912109 17.572266 C 20.106554 17.697266 20.322917 17.759766 20.5625 17.759766 C 21.222222 17.759766 21.690972 17.392361 21.96875 16.65625 C 22.246528 15.916666 22.386719 15.096572 22.386719 14.197266 C 22.386719 13.641711 22.314239 13.107639 22.171875 12.59375 z M 53 18 L 59 18 L 56 20 L 53 18 z";
|
||||||
|
-fx-min-height: 20;
|
||||||
|
-fx-min-width: 64;
|
||||||
|
-fx-background-color: #71e016;
|
||||||
|
}
|
||||||
.regionUpload{
|
.regionUpload{
|
||||||
-fx-shape: "M 4.0078125,0 C 1.5078125,0 0,1.4882812 0,3.984375 V 15.988281 C 0,18.417969 1.4927148,20 4.0078125,20 H 6.5 V 0 Z M 15,2.9 7,13 h 5 c 0,1.661689 -0.0097,6.246588 -0.0098,7.011719 H 18 V 13 h 5 z M 23.5,0 v 20 c 1.004057,-7.06e-4 1.659943,0 2.492187,0 C 28.414063,20 30,18.496094 30,15.996094 V 3.9765625 C 30,1.5195311 28.508727,0 26.003907,0 Z M 3.1015625,2.9570312 C 4.1485235,2.9562481 4.9977514,3.8046013 4.9980469,4.8515625 4.998831,5.8992865 4.1492865,6.748831 3.1015625,6.7480469 2.0546013,6.7477514 1.2062481,5.8985235 1.2070312,4.8515625 1.2073268,3.8053642 2.0553642,2.9573267 3.1015625,2.9570312 Z M 26.865234,11.148438 c 1.047724,-7.85e-4 1.897269,0.84876 1.896485,1.896484 -2.96e-4,1.046961 -0.849524,1.895314 -1.896485,1.894531 -1.046198,-2.95e-4 -1.894235,-0.848333 -1.894531,-1.894531 -7.83e-4,-1.046961 0.84757,-1.896189 1.894531,-1.896484 z";
|
-fx-shape: "M 4.0078125,0 C 1.5078125,0 0,1.4882812 0,3.984375 V 15.988281 C 0,18.417969 1.4927148,20 4.0078125,20 H 6.5 V 0 Z M 15,2.9 7,13 h 5 c 0,1.661689 -0.0097,6.246588 -0.0098,7.011719 H 18 V 13 h 5 z M 23.5,0 v 20 c 1.004057,-7.06e-4 1.659943,0 2.492187,0 C 28.414063,20 30,18.496094 30,15.996094 V 3.9765625 C 30,1.5195311 28.508727,0 26.003907,0 Z M 3.1015625,2.9570312 C 4.1485235,2.9562481 4.9977514,3.8046013 4.9980469,4.8515625 4.998831,5.8992865 4.1492865,6.748831 3.1015625,6.7480469 2.0546013,6.7477514 1.2062481,5.8985235 1.2070312,4.8515625 1.2073268,3.8053642 2.0553642,2.9573267 3.1015625,2.9570312 Z M 26.865234,11.148438 c 1.047724,-7.85e-4 1.897269,0.84876 1.896485,1.896484 -2.96e-4,1.046961 -0.849524,1.895314 -1.896485,1.894531 -1.046198,-2.95e-4 -1.894235,-0.848333 -1.894531,-1.894531 -7.83e-4,-1.046961 0.84757,-1.896189 1.894531,-1.896484 z";
|
||||||
-fx-background-color: #71e016;
|
-fx-background-color: #71e016;
|
||||||
|
@ -352,3 +394,7 @@
|
||||||
-size: 17.5;
|
-size: 17.5;
|
||||||
-fx-min-width: 20;
|
-fx-min-width: 20;
|
||||||
}
|
}
|
||||||
|
//
|
||||||
|
//.lineGradient {
|
||||||
|
// -fx-background-color: linear-gradient(from 41px 34px to 50px 50px, reflect, #00c8fc 30%, transparent 45%);
|
||||||
|
//}
|
|
@ -109,12 +109,7 @@
|
||||||
.tool-bar{
|
.tool-bar{
|
||||||
-fx-background-color: transparent;
|
-fx-background-color: transparent;
|
||||||
}
|
}
|
||||||
|
/* -======================== Choice box =========================- */
|
||||||
.special-pane-as-border{
|
|
||||||
-fx-background-color: #2c2c2c;
|
|
||||||
-fx-min-height: 1;
|
|
||||||
}
|
|
||||||
// -======================== Choice box =========================-
|
|
||||||
.choice-box {
|
.choice-box {
|
||||||
-fx-background-color: #fefefe;
|
-fx-background-color: #fefefe;
|
||||||
-fx-border-color: #fefefe;
|
-fx-border-color: #fefefe;
|
||||||
|
@ -150,7 +145,7 @@
|
||||||
-fx-text-fill: #2c2c2c;
|
-fx-text-fill: #2c2c2c;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -======================== TAB PANE =========================-
|
/* -======================== TAB PANE =========================- */
|
||||||
.tab-pane .tab SVGPath{
|
.tab-pane .tab SVGPath{
|
||||||
-fx-fill: #2c2c2c;
|
-fx-fill: #2c2c2c;
|
||||||
}
|
}
|
||||||
|
@ -161,16 +156,16 @@
|
||||||
-fx-fill: #1c6fa2;
|
-fx-fill: #1c6fa2;
|
||||||
}
|
}
|
||||||
.tab-pane .tab{
|
.tab-pane .tab{
|
||||||
-fx-background-color: #fefefe;
|
-fx-background-color: transparent;
|
||||||
-fx-focus-color: transparent;
|
-fx-focus-color: transparent;
|
||||||
-fx-faint-focus-color: transparent;
|
-fx-faint-focus-color: transparent;
|
||||||
-fx-border-radius: 0 0 0 0;
|
-fx-border-radius: 0 0 0 0;
|
||||||
-fx-border-width: 3 0 0 0;
|
-fx-border-width: 3 0 0 0;
|
||||||
-fx-border-color: #fefefe;
|
-fx-border-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab-pane .tab:selected{
|
.tab-pane .tab:selected{
|
||||||
-fx-background-color: #ebebeb;
|
-fx-background-color: #fefefe;
|
||||||
-fx-focus-color: transparent;
|
-fx-focus-color: transparent;
|
||||||
-fx-faint-focus-color: transparent;
|
-fx-faint-focus-color: transparent;
|
||||||
-fx-border-radius: 0 0 0 0;
|
-fx-border-radius: 0 0 0 0;
|
||||||
|
@ -185,13 +180,13 @@
|
||||||
|
|
||||||
.tab-pane > .tab-header-area > .tab-header-background
|
.tab-pane > .tab-header-area > .tab-header-background
|
||||||
{
|
{
|
||||||
-fx-background-color: #fefefe;
|
-fx-background-color: #ebebeb;
|
||||||
|
|
||||||
}
|
}
|
||||||
.tab-pane > .tab-header-area > .headers-region > .tab {
|
.tab-pane > .tab-header-area > .headers-region > .tab {
|
||||||
-fx-padding: 10;
|
-fx-padding: 10;
|
||||||
}
|
}
|
||||||
// -=========================== TABLE ======================-
|
/* -=========================== TABLE ======================- */
|
||||||
.table-view {
|
.table-view {
|
||||||
-fx-background-color: #fefefe;
|
-fx-background-color: #fefefe;
|
||||||
-fx-background-image: url(app_logo.png);
|
-fx-background-image: url(app_logo.png);
|
||||||
|
@ -240,7 +235,18 @@
|
||||||
-fx-padding: 0.0em; /* 0 */
|
-fx-padding: 0.0em; /* 0 */
|
||||||
-fx-table-cell-border-color: #b0b0b0;
|
-fx-table-cell-border-color: #b0b0b0;
|
||||||
}
|
}
|
||||||
// -========================== Context menu =====================-
|
/* -========================= Separator ===================- */
|
||||||
|
.separator *.line {
|
||||||
|
-fx-border-style: solid;
|
||||||
|
-fx-border-width: 0 0 1 0;
|
||||||
|
-fx-border-color: #a7a7a7;
|
||||||
|
}
|
||||||
|
.strangeSeparator *.line {
|
||||||
|
-fx-border-style: solid;
|
||||||
|
-fx-border-width: 0 0 1 0;
|
||||||
|
-fx-border-color: #2c2c2c;
|
||||||
|
}
|
||||||
|
/* -========================== Context menu =====================- */
|
||||||
.context-menu {
|
.context-menu {
|
||||||
-fx-background-color: #fefefe;
|
-fx-background-color: #fefefe;
|
||||||
-fx-cursor: hand;
|
-fx-cursor: hand;
|
||||||
|
@ -251,7 +257,7 @@
|
||||||
.context-menu .menu-item:focused .label {
|
.context-menu .menu-item:focused .label {
|
||||||
-fx-text-fill: white;
|
-fx-text-fill: white;
|
||||||
}
|
}
|
||||||
// -========================== Text Field =====================-
|
/* -========================== Text Field =====================- */
|
||||||
.text-field {
|
.text-field {
|
||||||
-fx-border-color: #289de8;
|
-fx-border-color: #289de8;
|
||||||
-fx-border-width: 0 0 1 0;
|
-fx-border-width: 0 0 1 0;
|
||||||
|
@ -265,8 +271,19 @@
|
||||||
-fx-text-fill: #e82382;
|
-fx-text-fill: #e82382;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.regionSplitToOne {
|
||||||
|
-fx-shape: "m 3,23 c -1.104569,0 -2,0.895431 -2,2 v 16 c 0,1.1 0.89,2 2,2 h 12 c 1.104569,0 2,-0.895431 2,-2 V 25 c 0,-1.095153 -0.910156,-2 -2,-2 z m 39.400391,0 C 41.068391,23 40,24.1125 40,25.5 v 15 A 2.4,2.5 0 0 0 42.400391,43 H 61.599609 A 2.4,2.5 0 0 0 64,40.5 V 28 c 0,-1.3875 -1.080391,-2.5 -2.400391,-2.5 H 52 L 49.599609,23 Z M 5.099609,24.199219 h 7.800782 c 0.1,0.0021 0.09961,0.0018 0.09961,0.101562 v 0.09961 c -10e-7,0.09583 3.91e-4,0.09753 -0.09961,0.09961 H 5.099609 c -0.1,0.0057 -0.09961,0.004 -0.09961,-0.09961 v -0.09961 c 0,-0.09974 -3.91e-4,-0.103386 0.09961,-0.101562 z M 29,24.75 v 4 h -8 v 8 h 8 v 4 l 8,-8 z M 3,25 h 12 c 0.303385,0 0.5,0.204427 0.5,0.5 v 13 C 15.5,38.789959 15.29836,39 15,39 H 3 C 2.704427,39 2.5,38.803385 2.5,38.5 v -13 C 2.5,25.208333 2.71224,25 3,25 Z m 50.193359,6.962891 c 0.920139,0 1.620877,0.38585 2.103516,1.160156 0.482639,0.770833 0.724609,1.812066 0.724609,3.121094 0,1.3125 -0.24197,2.3546 -0.724609,3.128906 -0.482639,0.770833 -1.183377,1.15625 -2.103516,1.15625 -0.916666,0 -1.617404,-0.385417 -2.103515,-1.15625 -0.482639,-0.774306 -0.72461,-1.816406 -0.72461,-3.128906 0,-1.309028 0.241971,-2.350261 0.72461,-3.121094 0.486111,-0.774306 1.186849,-1.160156 2.103515,-1.160156 z m 6.396485,0 c 0.920139,0 1.620876,0.38585 2.103515,1.160156 0.482639,0.770833 0.72461,1.812066 0.72461,3.121094 0,1.3125 -0.241971,2.3546 -0.72461,3.128906 -0.482639,0.770833 -1.183376,1.15625 -2.103515,1.15625 -0.916667,0 -1.619358,-0.385417 -2.105469,-1.15625 -0.482639,-0.774306 -0.722656,-1.816406 -0.722656,-3.128906 0,-1.309028 0.240017,-2.350261 0.722656,-3.121094 0.486111,-0.774306 1.188802,-1.160156 2.105469,-1.160156 z m -10.025391,0.52539 h 0.01953 l -0.01953,0.01758 z m 3.628906,0.28125 c -0.579861,0 -1.020182,0.322917 -1.322265,0.96875 -0.302084,0.642361 -0.453125,1.457683 -0.453125,2.447266 0,0.225694 0.0056,0.470052 0.01953,0.730469 0.01389,0.260416 0.07357,0.612196 0.177734,1.05664 l 2.796875,-4.380859 c -0.177083,-0.322917 -0.369791,-0.53928 -0.578125,-0.650391 -0.204861,-0.114583 -0.418402,-0.171875 -0.640624,-0.171875 z m 6.396485,0 c -0.579861,0 -1.022136,0.322917 -1.324219,0.96875 -0.302083,0.642361 -0.453125,1.457683 -0.453125,2.447266 0,0.225694 0.0076,0.470052 0.02148,0.730469 0.01389,0.260416 0.07357,0.612196 0.177735,1.05664 l 2.796875,-4.380859 c -0.17708,-0.322917 -0.369788,-0.53928 -0.578121,-0.650391 -0.204861,-0.114583 -0.418403,-0.171875 -0.640625,-0.171875 z m -4.828125,1.78711 -2.777344,4.40625 c 0.149306,0.253472 0.321181,0.443793 0.515625,0.572265 0.194444,0.125 0.41276,0.1875 0.652344,0.1875 0.659722,0 1.128472,-0.367404 1.40625,-1.103515 0.277778,-0.739584 0.416015,-1.559679 0.416015,-2.458985 0,-0.555555 -0.07053,-1.089626 -0.21289,-1.603515 z m 6.394531,0 -2.775391,4.40625 c 0.149306,0.253472 0.321181,0.443793 0.515625,0.572265 0.194445,0.125 0.410808,0.1875 0.650391,0.1875 0.659722,0 1.128472,-0.367404 1.40625,-1.103515 0.277778,-0.739584 0.417969,-1.559679 0.417969,-2.458985 0,-0.555555 -0.07248,-1.089626 -0.214844,-1.603515 z M 6,40 h 6 l -3,2 z";
|
||||||
|
-fx-min-height: 20;
|
||||||
|
-fx-min-width: 64;
|
||||||
|
-fx-background-color: #71e016;
|
||||||
|
}
|
||||||
|
|
||||||
|
.regionOneToSplit {
|
||||||
|
-fx-shape: "M 50 1 C 48.895431 1 48 1.895431 48 3 L 48 19 C 48 20.1 48.89 21 50 21 L 62 21 C 63.104569 21 64 20.104569 64 19 L 64 3 C 64 1.904847 63.089844 1 62 1 L 50 1 z M 3.4160156 1.0371094 C 2.0840156 1.0371094 1.015625 2.1496094 1.015625 3.5371094 L 1.015625 18.537109 A 2.4 2.5 0 0 0 3.4160156 21.037109 L 22.615234 21.037109 A 2.4 2.5 0 0 0 25.015625 18.537109 L 25.015625 6.0371094 C 25.015625 4.6496094 23.935234 3.5371094 22.615234 3.5371094 L 13.015625 3.5371094 L 10.615234 1.0371094 L 3.4160156 1.0371094 z M 52.099609 2.1992188 L 59.900391 2.1992188 C 60.000391 2.2013185 60 2.2010194 60 2.3007812 L 60 2.4003906 C 59.999999 2.4962206 60.000391 2.49792 59.900391 2.5 L 52.099609 2.5 C 51.999609 2.5057 52 2.5040006 52 2.4003906 L 52 2.3007812 C 52 2.2010414 51.999609 2.1973947 52.099609 2.1992188 z M 37 3 L 37 7 L 29 7 L 29 15 L 37 15 L 37 19 L 45 11 L 37 3 z M 50 3 L 62 3 C 62.303385 3 62.5 3.204427 62.5 3.5 L 62.5 16.5 C 62.5 16.789959 62.29836 17 62 17 L 50 17 C 49.704427 17 49.5 16.803385 49.5 16.5 L 49.5 3.5 C 49.5 3.208333 49.71224 3 50 3 z M 14.208984 10 C 15.129123 10 15.829861 10.38585 16.3125 11.160156 C 16.795139 11.930989 17.037109 12.972222 17.037109 14.28125 C 17.037109 15.59375 16.795139 16.63585 16.3125 17.410156 C 15.829861 18.180989 15.129123 18.566406 14.208984 18.566406 C 13.292318 18.566406 12.59158 18.180989 12.105469 17.410156 C 11.62283 16.63585 11.380859 15.59375 11.380859 14.28125 C 11.380859 12.972222 11.62283 11.930989 12.105469 11.160156 C 12.59158 10.38585 13.292318 10 14.208984 10 z M 20.605469 10 C 21.525608 10 22.226345 10.38585 22.708984 11.160156 C 23.191623 11.930989 23.433594 12.972222 23.433594 14.28125 C 23.433594 15.59375 23.191623 16.63585 22.708984 17.410156 C 22.226345 18.180989 21.525608 18.566406 20.605469 18.566406 C 19.688802 18.566406 18.986111 18.180989 18.5 17.410156 C 18.017361 16.63585 17.777344 15.59375 17.777344 14.28125 C 17.777344 12.972222 18.017361 11.930989 18.5 11.160156 C 18.986111 10.38585 19.688802 10 20.605469 10 z M 14.208984 10.806641 C 13.629123 10.806641 13.188802 11.129558 12.886719 11.775391 C 12.584635 12.417752 12.433594 13.233073 12.433594 14.222656 C 12.433594 14.44835 12.439195 14.692708 12.453125 14.953125 C 12.467015 15.213541 12.526695 15.565322 12.630859 16.009766 L 15.427734 11.628906 C 15.250651 11.305989 15.057943 11.089627 14.849609 10.978516 C 14.644748 10.863933 14.431206 10.806641 14.208984 10.806641 z M 20.605469 10.806641 C 20.025608 10.806641 19.583333 11.129558 19.28125 11.775391 C 18.979167 12.417752 18.828125 13.233073 18.828125 14.222656 C 18.828125 14.44835 18.835729 14.692708 18.849609 14.953125 C 18.863499 15.213541 18.923179 15.565322 19.027344 16.009766 L 21.824219 11.628906 C 21.647139 11.305989 21.454427 11.089627 21.246094 10.978516 C 21.041233 10.863933 20.827691 10.806641 20.605469 10.806641 z M 15.777344 12.59375 L 13 17 C 13.149306 17.253472 13.321181 17.443794 13.515625 17.572266 C 13.710069 17.697266 13.928385 17.759766 14.167969 17.759766 C 14.827691 17.759766 15.296441 17.392361 15.574219 16.65625 C 15.851997 15.916666 15.990234 15.096572 15.990234 14.197266 C 15.990234 13.641711 15.919704 13.107639 15.777344 12.59375 z M 22.171875 12.59375 L 19.396484 17 C 19.54579 17.253472 19.717665 17.443794 19.912109 17.572266 C 20.106554 17.697266 20.322917 17.759766 20.5625 17.759766 C 21.222222 17.759766 21.690972 17.392361 21.96875 16.65625 C 22.246528 15.916666 22.386719 15.096572 22.386719 14.197266 C 22.386719 13.641711 22.314239 13.107639 22.171875 12.59375 z M 53 18 L 59 18 L 56 20 L 53 18 z";
|
||||||
|
-fx-min-height: 20;
|
||||||
|
-fx-min-width: 64;
|
||||||
|
-fx-background-color: #71e016;
|
||||||
|
}
|
||||||
|
|
||||||
.regionUpload{
|
.regionUpload{
|
||||||
-fx-shape: "M 4.0078125,0 C 1.5078125,0 0,1.4882812 0,3.984375 V 15.988281 C 0,18.417969 1.4927148,20 4.0078125,20 H 6.5 V 0 Z M 15,2.9 7,13 h 5 c 0,1.661689 -0.0097,6.246588 -0.0098,7.011719 H 18 V 13 h 5 z M 23.5,0 v 20 c 1.004057,-7.06e-4 1.659943,0 2.492187,0 C 28.414063,20 30,18.496094 30,15.996094 V 3.9765625 C 30,1.5195311 28.508727,0 26.003907,0 Z M 3.1015625,2.9570312 C 4.1485235,2.9562481 4.9977514,3.8046013 4.9980469,4.8515625 4.998831,5.8992865 4.1492865,6.748831 3.1015625,6.7480469 2.0546013,6.7477514 1.2062481,5.8985235 1.2070312,4.8515625 1.2073268,3.8053642 2.0553642,2.9573267 3.1015625,2.9570312 Z M 26.865234,11.148438 c 1.047724,-7.85e-4 1.897269,0.84876 1.896485,1.896484 -2.96e-4,1.046961 -0.849524,1.895314 -1.896485,1.894531 -1.046198,-2.95e-4 -1.894235,-0.848333 -1.894531,-1.894531 -7.83e-4,-1.046961 0.84757,-1.896189 1.894531,-1.896484 z";
|
-fx-shape: "M 4.0078125,0 C 1.5078125,0 0,1.4882812 0,3.984375 V 15.988281 C 0,18.417969 1.4927148,20 4.0078125,20 H 6.5 V 0 Z M 15,2.9 7,13 h 5 c 0,1.661689 -0.0097,6.246588 -0.0098,7.011719 H 18 V 13 h 5 z M 23.5,0 v 20 c 1.004057,-7.06e-4 1.659943,0 2.492187,0 C 28.414063,20 30,18.496094 30,15.996094 V 3.9765625 C 30,1.5195311 28.508727,0 26.003907,0 Z M 3.1015625,2.9570312 C 4.1485235,2.9562481 4.9977514,3.8046013 4.9980469,4.8515625 4.998831,5.8992865 4.1492865,6.748831 3.1015625,6.7480469 2.0546013,6.7477514 1.2062481,5.8985235 1.2070312,4.8515625 1.2073268,3.8053642 2.0553642,2.9573267 3.1015625,2.9570312 Z M 26.865234,11.148438 c 1.047724,-7.85e-4 1.897269,0.84876 1.896485,1.896484 -2.96e-4,1.046961 -0.849524,1.895314 -1.896485,1.894531 -1.046198,-2.95e-4 -1.894235,-0.848333 -1.894531,-1.894531 -7.83e-4,-1.046961 0.84757,-1.896189 1.894531,-1.896484 z";
|
||||||
|
|
Loading…
Reference in a new issue