mirror of
https://github.com/NinjaCheetah/NUSGet.git
synced 2026-02-27 23:25:29 -05:00
Compare commits
42 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
85763cae60 | ||
| a1b071b9c6 | |||
|
|
96e2f5fa0d | ||
| ffac804ada | |||
| 74acfff007 | |||
|
|
6ae2a71e5c | ||
| b655dd161b | |||
|
|
3700154578 | ||
|
a272fbc097
|
|||
|
3a8dfb95a1
|
|||
| 58d3f7bd3e | |||
|
|
f55cb05703 | ||
|
|
33b30b4aa5 | ||
|
|
dd79be0b48 | ||
|
|
9c15eac1fd | ||
|
|
0dbe28914d | ||
|
bc1858a5a5
|
|||
|
0ca2cc272a
|
|||
|
ac42de6efc
|
|||
|
e2decf8d6f
|
|||
|
bcf82a011f
|
|||
|
1b4324e9b8
|
|||
|
cbbac55743
|
|||
|
adc8be9cbb
|
|||
|
8e326aeb56
|
|||
|
807e632505
|
|||
| 911c01a066 | |||
|
|
f4c61ed020 | ||
|
|
6d1e53c777 | ||
|
|
9829ae0365 | ||
|
f21357c01d
|
|||
|
439aebbdb8
|
|||
|
bf09f3b18e
|
|||
|
7f788ae36c
|
|||
|
96cab930f0
|
|||
| 7518a5e663 | |||
|
|
8193fe029b | ||
|
62467bb616
|
|||
|
ca81c2e6d3
|
|||
|
47904c72be
|
|||
|
dc82790aef
|
|||
|
2db66af177
|
26
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
26
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
---
|
||||||
|
name: Bug report
|
||||||
|
about: Create a report to help us improve NUSGet.
|
||||||
|
title: ''
|
||||||
|
labels: bug
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Describe the bug
|
||||||
|
|
||||||
|
|
||||||
|
### Steps to Reproduce
|
||||||
|
|
||||||
|
|
||||||
|
### Screenshot(s) (if applicable)
|
||||||
|
|
||||||
|
|
||||||
|
### System information:
|
||||||
|
- **OS and version:**
|
||||||
|
- **NUSGet version:**
|
||||||
|
|
||||||
|
If you're running the app from source, provide the below information:
|
||||||
|
- **Are you compiling NUSGet, or running the Python script directly?**
|
||||||
|
- **Python version:**
|
||||||
|
- **Installed libWiiPy version:**
|
||||||
10
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
10
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
name: Feature request
|
||||||
|
about: Suggest an idea for NUSGet!
|
||||||
|
title: ''
|
||||||
|
labels: enhancement
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Your idea...**
|
||||||
27
.github/workflows/python-build.yml
vendored
27
.github/workflows/python-build.yml
vendored
@@ -31,21 +31,21 @@ jobs:
|
|||||||
pip install -r requirements.txt
|
pip install -r requirements.txt
|
||||||
- name: Build Package
|
- name: Build Package
|
||||||
run: |
|
run: |
|
||||||
nuitka3 --show-progress --include-data-dir=data=data --include-data-dir=resources=resources --assume-yes-for-downloads --onefile --plugin-enable=pyside6 NUSGet.py
|
make linux
|
||||||
- name: Prepare Package for Upload
|
- name: Prepare Package for Upload
|
||||||
run: |
|
run: |
|
||||||
mv NUSGet.bin ~/NUSGet.bin
|
mv NUSGet ~/NUSGet
|
||||||
cd ~
|
cd ~
|
||||||
tar cvf NUSGet.tar NUSGet.bin
|
tar cvf NUSGet.tar NUSGet
|
||||||
- name: Upload Package
|
- name: Upload Package
|
||||||
uses: actions/upload-artifact@v4.3.0
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
path: ~/NUSGet.tar
|
path: ~/NUSGet.tar
|
||||||
name: NUSGet-linux-bin
|
name: NUSGet-linux-bin
|
||||||
|
|
||||||
build-macos:
|
build-macos:
|
||||||
|
|
||||||
runs-on: macos-12
|
runs-on: macos-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
@@ -59,14 +59,15 @@ jobs:
|
|||||||
pip install -r requirements.txt
|
pip install -r requirements.txt
|
||||||
- name: Build Package
|
- name: Build Package
|
||||||
run: |
|
run: |
|
||||||
nuitka3 --show-progress --include-data-dir=data=data --include-data-dir=resources=resources --assume-yes-for-downloads --standalone --plugin-enable=pyside6 NUSGet.py --macos-create-app-bundle --macos-app-icon=resources/icon.png
|
python build_translations.py
|
||||||
|
python -m nuitka --show-progress --include-data-dir=data=data --include-data-dir=resources=resources --assume-yes-for-downloads --standalone --plugin-enable=pyside6 NUSGet.py --macos-create-app-bundle --macos-app-icon=resources/icon.png
|
||||||
- name: Prepare Package for Upload
|
- name: Prepare Package for Upload
|
||||||
run: |
|
run: |
|
||||||
mv NUSGet.app ~/NUSGet.app
|
mv NUSGet.app ~/NUSGet.app
|
||||||
cd ~
|
cd ~
|
||||||
tar cvf NUSGet.tar NUSGet.app
|
tar cvf NUSGet.tar NUSGet.app
|
||||||
- name: Upload Package
|
- name: Upload Package
|
||||||
uses: actions/upload-artifact@v4.3.0
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
path: ~/NUSGet.tar
|
path: ~/NUSGet.tar
|
||||||
name: NUSGet-macos-bin
|
name: NUSGet-macos-bin
|
||||||
@@ -89,10 +90,16 @@ jobs:
|
|||||||
pip install -r requirements.txt
|
pip install -r requirements.txt
|
||||||
- name: Build Package
|
- name: Build Package
|
||||||
run: |
|
run: |
|
||||||
nuitka --show-progress --include-data-dir=data=data --include-data-dir=resources=resources --assume-yes-for-downloads --onefile --windows-icon-from-ico=resources/icon.png --plugin-enable=pyside6 NUSGet.py --windows-console-mode=disable
|
python build_translations.py
|
||||||
|
python -m nuitka --show-progress --include-data-dir=data=data --include-data-dir=resources=resources --assume-yes-for-downloads --onefile --windows-icon-from-ico=resources/icon.png --plugin-enable=pyside6 NUSGet.py --windows-console-mode=disable
|
||||||
- name: Upload Package
|
- name: Upload Package
|
||||||
uses: actions/upload-artifact@v4.3.0
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
path: D:\a\NUSGet\NUSGet\NUSGet.dist
|
||||||
|
name: NUSGet-windows-bin
|
||||||
|
- name: Upload Onefile Package
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
path: D:\a\NUSGet\NUSGet\NUSGet.exe
|
path: D:\a\NUSGet\NUSGet\NUSGet.exe
|
||||||
name: NUSGet-windows-bin
|
name: NUSGet-windows-onefile-bin
|
||||||
|
|
||||||
|
|||||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -27,6 +27,7 @@ main.dist/
|
|||||||
NUSGet.build/
|
NUSGet.build/
|
||||||
NUSGet.dist/
|
NUSGet.dist/
|
||||||
NUSGet.onefile-build/
|
NUSGet.onefile-build/
|
||||||
|
NUSGet
|
||||||
.installed.cfg
|
.installed.cfg
|
||||||
*.egg
|
*.egg
|
||||||
MANIFEST
|
MANIFEST
|
||||||
@@ -174,3 +175,6 @@ remakewad.pl
|
|||||||
# Also awful macOS files
|
# Also awful macOS files
|
||||||
*._*
|
*._*
|
||||||
*.DS_Store
|
*.DS_Store
|
||||||
|
|
||||||
|
# Compiled Qt files
|
||||||
|
*.qm
|
||||||
|
|||||||
17
Makefile
Normal file
17
Makefile
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
CC=python -m nuitka
|
||||||
|
|
||||||
|
linux:
|
||||||
|
python build_translations.py
|
||||||
|
$(CC) --show-progress --include-data-dir=data=data --include-data-dir=resources=resources --assume-yes-for-downloads --onefile --plugin-enable=pyside6 NUSGet.py -o NUSGet
|
||||||
|
|
||||||
|
linux-install:
|
||||||
|
install -d /opt/NUSGet
|
||||||
|
install NUSGet /opt/NUSGet/
|
||||||
|
install ./packaging/icon.png /opt/NUSGet/NUSGet.png
|
||||||
|
install ./packaging/NUSGet.desktop /usr/share/applications
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm NUSGet
|
||||||
|
rm -rd NUSGet.build/
|
||||||
|
rm -rd NUSGet.dist/
|
||||||
|
rm -rd NUSGet.onefile-build/
|
||||||
626
NUSGet.py
626
NUSGet.py
@@ -1,23 +1,26 @@
|
|||||||
# NUSGet.py, licensed under the MIT license
|
# "NUSGet.py", licensed under the MIT license
|
||||||
# Copyright 2024 NinjaCheetah
|
# Copyright 2024 NinjaCheetah
|
||||||
import sys
|
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
import json
|
import json
|
||||||
import pathlib
|
import pathlib
|
||||||
import platform
|
import platform
|
||||||
|
import webbrowser
|
||||||
from importlib.metadata import version
|
from importlib.metadata import version
|
||||||
|
|
||||||
import libWiiPy
|
|
||||||
import libTWLPy
|
|
||||||
|
|
||||||
from PySide6.QtGui import QIcon
|
from PySide6.QtGui import QIcon
|
||||||
|
|
||||||
from PySide6.QtWidgets import (QApplication, QMainWindow, QMessageBox, QTreeWidgetItem, QHeaderView, QStyle,
|
from PySide6.QtWidgets import (QApplication, QMainWindow, QMessageBox, QTreeWidgetItem, QHeaderView, QStyle,
|
||||||
QStyleFactory)
|
QStyleFactory, QFileDialog)
|
||||||
from PySide6.QtCore import QRunnable, Slot, QThreadPool, Signal, QObject
|
from PySide6.QtCore import QRunnable, Slot, QThreadPool, Signal, QObject, QLibraryInfo, QTranslator, QLocale
|
||||||
|
|
||||||
from qt.py.ui_MainMenu import Ui_MainWindow
|
from qt.py.ui_MainMenu import Ui_MainWindow
|
||||||
|
|
||||||
|
from modules.core import *
|
||||||
|
from modules.download_wii import run_nus_download_wii, run_nus_download_wii_batch
|
||||||
|
from modules.download_dsi import run_nus_download_dsi, run_nus_download_dsi_batch
|
||||||
|
|
||||||
|
nusget_version = "1.2.0"
|
||||||
|
|
||||||
regions = {"World": ["41"], "USA/NTSC": ["45"], "Europe/PAL": ["50"], "Japan": ["4A"], "Korea": ["4B"], "China": ["43"],
|
regions = {"World": ["41"], "USA/NTSC": ["45"], "Europe/PAL": ["50"], "Japan": ["4A"], "Korea": ["4B"], "China": ["43"],
|
||||||
"Australia/NZ": ["55"]}
|
"Australia/NZ": ["55"]}
|
||||||
@@ -25,15 +28,16 @@ regions = {"World": ["41"], "USA/NTSC": ["45"], "Europe/PAL": ["50"], "Japan": [
|
|||||||
|
|
||||||
# Signals needed for the worker used for threading the downloads.
|
# Signals needed for the worker used for threading the downloads.
|
||||||
class WorkerSignals(QObject):
|
class WorkerSignals(QObject):
|
||||||
result = Signal(int)
|
result = Signal(object)
|
||||||
progress = Signal(str)
|
progress = Signal(str)
|
||||||
|
|
||||||
|
|
||||||
# Worker class used to thread the downloads.
|
# Worker class used to thread the downloads.
|
||||||
class Worker(QRunnable):
|
class Worker(QRunnable):
|
||||||
def __init__(self, fn, **kwargs):
|
def __init__(self, fn, *args, **kwargs):
|
||||||
super(Worker, self).__init__()
|
super(Worker, self).__init__()
|
||||||
self.fn = fn
|
self.fn = fn
|
||||||
|
self.args = args
|
||||||
self.kwargs = kwargs
|
self.kwargs = kwargs
|
||||||
self.signals = WorkerSignals()
|
self.signals = WorkerSignals()
|
||||||
|
|
||||||
@@ -45,7 +49,7 @@ class Worker(QRunnable):
|
|||||||
# unlikely event that an unexpected error happens, it can only possibly be a ValueError, so handle that and
|
# unlikely event that an unexpected error happens, it can only possibly be a ValueError, so handle that and
|
||||||
# return code 1.
|
# return code 1.
|
||||||
try:
|
try:
|
||||||
result = self.fn(**self.kwargs)
|
result = self.fn(*self.args, **self.kwargs)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
self.signals.result.emit(1)
|
self.signals.result.emit(1)
|
||||||
else:
|
else:
|
||||||
@@ -57,10 +61,11 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|||||||
super(MainWindow, self).__init__()
|
super(MainWindow, self).__init__()
|
||||||
self.ui = Ui_MainWindow()
|
self.ui = Ui_MainWindow()
|
||||||
self.ui.setupUi(self)
|
self.ui.setupUi(self)
|
||||||
self.log_text = ""
|
|
||||||
self.threadpool = QThreadPool()
|
self.threadpool = QThreadPool()
|
||||||
self.ui.download_btn.clicked.connect(self.download_btn_pressed)
|
self.ui.download_btn.clicked.connect(self.download_btn_pressed)
|
||||||
|
self.ui.script_btn.clicked.connect(self.script_btn_pressed)
|
||||||
self.ui.pack_archive_chkbox.clicked.connect(self.pack_wad_chkbox_toggled)
|
self.ui.pack_archive_chkbox.clicked.connect(self.pack_wad_chkbox_toggled)
|
||||||
|
self.ui.tid_entry.textChanged.connect(self.tid_updated)
|
||||||
# noinspection PyUnresolvedReferences
|
# noinspection PyUnresolvedReferences
|
||||||
self.ui.wii_title_tree.header().setSectionResizeMode(QHeaderView.ResizeToContents)
|
self.ui.wii_title_tree.header().setSectionResizeMode(QHeaderView.ResizeToContents)
|
||||||
# noinspection PyUnresolvedReferences
|
# noinspection PyUnresolvedReferences
|
||||||
@@ -70,13 +75,16 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|||||||
# Basic intro text set to automatically show when the app loads. This may be changed in the future.
|
# Basic intro text set to automatically show when the app loads. This may be changed in the future.
|
||||||
libwiipy_version = "v" + version("libWiiPy")
|
libwiipy_version = "v" + version("libWiiPy")
|
||||||
libtwlpy_version = "v" + version("libTWLPy")
|
libtwlpy_version = "v" + version("libTWLPy")
|
||||||
self.ui.log_text_browser.setText(f"NUSGet v1.0\nDeveloped by NinjaCheetah\nPowered by libWiiPy "
|
self.log_text = (app.translate("MainWindow", "NUSGet v{nusget_version}\nDeveloped by NinjaCheetah\nPowered by libWiiPy "
|
||||||
f"{libwiipy_version}\nDSi support provided by libTWLPy {libtwlpy_version}\n\n"
|
"{libwiipy_version}\nDSi support provided by libTWLPy {libtwlpy_version}\n\n"
|
||||||
f"Select a title from the list on the left, or enter a Title ID to begin.\n\n"
|
"Select a title from the list on the left, or enter a Title ID to begin.\n\n"
|
||||||
f"Titles marked with a checkmark are free and have a ticket available, and can"
|
"Titles marked with a checkmark are free and have a ticket available, and can"
|
||||||
f" be decrypted and/or packed into a WAD or TAD. Titles with an X do not have "
|
" be decrypted and/or packed into a WAD or TAD. Titles with an X do not have "
|
||||||
f"a ticket, and only their encrypted contents can be saved.\n\nTitles will be "
|
"a ticket, and only their encrypted contents can be saved.\n\nTitles will be "
|
||||||
f"downloaded to a folder named \"NUSGet\" inside your downloads folder.")
|
"downloaded to a folder named \"NUSGet\" inside your downloads folder.")
|
||||||
|
.format(nusget_version=nusget_version, libwiipy_version=libwiipy_version,
|
||||||
|
libtwlpy_version=libtwlpy_version))
|
||||||
|
self.ui.log_text_browser.setText(self.log_text)
|
||||||
# Add console entries to dropdown and attach on change signal.
|
# Add console entries to dropdown and attach on change signal.
|
||||||
self.ui.console_select_dropdown.addItem("Wii")
|
self.ui.console_select_dropdown.addItem("Wii")
|
||||||
self.ui.console_select_dropdown.addItem("vWii")
|
self.ui.console_select_dropdown.addItem("vWii")
|
||||||
@@ -118,6 +126,15 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|||||||
# Connect the double click signal for handling when titles are selected.
|
# Connect the double click signal for handling when titles are selected.
|
||||||
tree[0].itemDoubleClicked.connect(self.onItemClicked)
|
tree[0].itemDoubleClicked.connect(self.onItemClicked)
|
||||||
|
|
||||||
|
# Prevent resizing, Qt makes us look stupid here
|
||||||
|
self.setFixedSize(self.size())
|
||||||
|
|
||||||
|
# Do a quick check to see if there's a newer release available, and inform the user if there is.
|
||||||
|
worker = Worker(check_nusget_updates, app, nusget_version)
|
||||||
|
worker.signals.result.connect(self.prompt_for_update)
|
||||||
|
worker.signals.progress.connect(self.update_log_text)
|
||||||
|
self.threadpool.start(worker)
|
||||||
|
|
||||||
@Slot(QTreeWidgetItem, int)
|
@Slot(QTreeWidgetItem, int)
|
||||||
def onItemClicked(self, item, col):
|
def onItemClicked(self, item, col):
|
||||||
if self.ui.download_btn.isEnabled() is True:
|
if self.ui.download_btn.isEnabled() is True:
|
||||||
@@ -127,84 +144,104 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|||||||
category = item.parent().parent().parent().text(0)
|
category = item.parent().parent().parent().text(0)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
return
|
return
|
||||||
for tree in self.trees:
|
tree = self.trees[self.ui.platform_tabs.currentIndex()]
|
||||||
try:
|
for title in tree[1][category]:
|
||||||
for title in tree[1][category]:
|
# Check to see if the current title matches the selected one, and if it does, pass that info on.
|
||||||
# Check to see if the current title matches the selected one, and if it does, pass that info on.
|
if item.parent().parent().text(0) == (title["TID"] + " - " + title["Name"]):
|
||||||
if item.parent().parent().text(0) == (title["TID"] + " - " + title["Name"]):
|
self.ui.console_select_dropdown.setCurrentIndex(self.ui.platform_tabs.currentIndex())
|
||||||
selected_title = title
|
try:
|
||||||
selected_version = item.text(0)
|
danger_text = title["Danger"]
|
||||||
selected_region = item.parent().text(0)
|
except KeyError:
|
||||||
self.ui.console_select_dropdown.setCurrentIndex(self.ui.platform_tabs.currentIndex())
|
danger_text = ""
|
||||||
self.load_title_data(selected_title, selected_version, selected_region)
|
selected_title = SelectedTitle(title["TID"], title["Name"], title["Archive Name"], item.text(0)[1:],
|
||||||
except KeyError:
|
title["Ticket"], item.parent().text(0), category,
|
||||||
pass
|
self.ui.console_select_dropdown.currentText(), danger_text)
|
||||||
|
self.load_title_data(selected_title)
|
||||||
|
|
||||||
|
def tid_updated(self):
|
||||||
|
tid = self.ui.tid_entry.text()
|
||||||
|
if len(tid) == 16:
|
||||||
|
if tid[:8] == "00000001" and int(tid[-2:], 16) > 2:
|
||||||
|
self.ui.patch_ios_chkbox.setEnabled(True)
|
||||||
|
return
|
||||||
|
self.ui.patch_ios_chkbox.setEnabled(False)
|
||||||
|
|
||||||
def update_log_text(self, new_text):
|
def update_log_text(self, new_text):
|
||||||
# This function primarily exists to be the handler for the progress signal emitted by the worker thread.
|
# This method primarily exists to be the handler for the progress signal emitted by the worker thread.
|
||||||
self.log_text += new_text + "\n"
|
self.log_text += new_text + "\n"
|
||||||
self.ui.log_text_browser.setText(self.log_text)
|
self.ui.log_text_browser.setText(self.log_text)
|
||||||
# Always auto-scroll to the bottom of the log.
|
# Always auto-scroll to the bottom of the log.
|
||||||
scroll_bar = self.ui.log_text_browser.verticalScrollBar()
|
scroll_bar = self.ui.log_text_browser.verticalScrollBar()
|
||||||
scroll_bar.setValue(scroll_bar.maximum())
|
scroll_bar.setValue(scroll_bar.maximum())
|
||||||
|
|
||||||
def load_title_data(self, selected_title, selected_version, selected_region=None):
|
def prompt_for_update(self, new_version):
|
||||||
|
# This method is designed to display a message box informing the user that a new NUSGet version is available.
|
||||||
|
if new_version is not None:
|
||||||
|
msg_box = QMessageBox()
|
||||||
|
msg_box.setIcon(QMessageBox.Icon.Information)
|
||||||
|
msg_box.setStandardButtons(QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No)
|
||||||
|
msg_box.setDefaultButton(QMessageBox.StandardButton.Yes)
|
||||||
|
msg_box.setWindowTitle(app.translate("MainWindow", "NUSGet Update Available"))
|
||||||
|
msg_box.setText(app.translate("MainWindow", "There's a newer version of NUSGet available!"))
|
||||||
|
msg_box.setInformativeText(app.translate("MainWindow", "You're currently running v{nusget_version}, "
|
||||||
|
"but v{new_version} is available on GitHub. Would you like to view"
|
||||||
|
" the latest version?"
|
||||||
|
.format(nusget_version=nusget_version, new_version=new_version)))
|
||||||
|
ret = msg_box.exec()
|
||||||
|
if ret == QMessageBox.StandardButton.Yes:
|
||||||
|
webbrowser.open("https://github.com/NinjaCheetah/NUSGet/releases/latest")
|
||||||
|
|
||||||
|
def load_title_data(self, selected_title: SelectedTitle):
|
||||||
# Use the information passed from the double click callback to prepare a title for downloading.
|
# Use the information passed from the double click callback to prepare a title for downloading.
|
||||||
selected_version = selected_version[1:]
|
|
||||||
# If the last two characters are "XX", then this title has multiple regions, and each region uses its own
|
# If the last two characters are "XX", then this title has multiple regions, and each region uses its own
|
||||||
# two-digit code. Use the region info passed to load the correct code.
|
# two-digit code. Use the region info passed to load the correct code.
|
||||||
if selected_title["TID"][-2:] == "XX":
|
if selected_title.tid[-2:] == "XX":
|
||||||
global regions
|
global regions
|
||||||
region_code = regions[selected_region][0]
|
region_code = regions[selected_title.region][0]
|
||||||
tid = selected_title["TID"][:-2] + region_code
|
tid = selected_title.tid[:-2] + region_code
|
||||||
else:
|
else:
|
||||||
tid = selected_title["TID"]
|
tid = selected_title.tid
|
||||||
# Load the TID and version into the entry boxes.
|
# Load the TID and version into the entry boxes.
|
||||||
self.ui.tid_entry.setText(tid)
|
self.ui.tid_entry.setText(tid)
|
||||||
self.ui.version_entry.setText(selected_version)
|
self.ui.version_entry.setText(selected_title.version)
|
||||||
# Load the WAD name, assuming it exists. This shouldn't ever be able to fail as the database has a WAD name
|
# Load the WAD name, assuming it exists. This shouldn't ever be able to fail as the database has a WAD name
|
||||||
# for every single title, regardless of whether it can be packed or not.
|
# for every single title, regardless of whether it can be packed or not.
|
||||||
try:
|
try:
|
||||||
|
archive_name = f"{selected_title.archive_name}"
|
||||||
|
if selected_title.category != "System" and selected_title.category != "IOS":
|
||||||
|
archive_name += f"-{str(bytes.fromhex(tid).decode())[-4:]}"
|
||||||
|
archive_name += f"-v{selected_title.version}"
|
||||||
|
if selected_title.region != "World":
|
||||||
|
archive_name += f"-{selected_title.region.split('/')[0]}"
|
||||||
if self.ui.console_select_dropdown.currentText() == "DSi":
|
if self.ui.console_select_dropdown.currentText() == "DSi":
|
||||||
archive_name = selected_title["TAD Name"] + "-v" + selected_version + ".tad"
|
archive_name += ".tad"
|
||||||
|
elif self.ui.console_select_dropdown.currentText() == "vWii":
|
||||||
|
if selected_title.category.find("System") != -1 or selected_title.category == "IOS":
|
||||||
|
archive_name += "-vWii"
|
||||||
|
archive_name += ".wad"
|
||||||
else:
|
else:
|
||||||
archive_name = selected_title["WAD Name"] + "-v" + selected_version + ".wad"
|
if selected_title.category.find("System") != -1 or selected_title.category == "IOS":
|
||||||
|
archive_name += "-Wii"
|
||||||
|
archive_name += ".wad"
|
||||||
self.ui.archive_file_entry.setText(archive_name)
|
self.ui.archive_file_entry.setText(archive_name)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
# Same idea for the danger string, however this only exists for certain titles and will frequently be an error.
|
danger_text = selected_title.danger
|
||||||
danger_text = ""
|
|
||||||
try:
|
|
||||||
danger_text = selected_title["Danger"]
|
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
# Add warning text to the log if the selected title has no ticket.
|
# Add warning text to the log if the selected title has no ticket.
|
||||||
if selected_title["Ticket"] is False:
|
if selected_title.ticket is False:
|
||||||
danger_text = danger_text + ("Note: This Title does not have a Ticket available, so it cannot be decrypted"
|
danger_text = danger_text + ("Note: This Title does not have a Ticket available, so it cannot be decrypted"
|
||||||
" or packed into a WAD/TAD.")
|
" or packed into a WAD/TAD.")
|
||||||
# Print log info about the selected title and version.
|
# Print log info about the selected title and version.
|
||||||
self.log_text = (tid + " - " + selected_title["Name"] + "\n" + "Version: " + selected_version + "\n\n" +
|
self.log_text = f"{tid} - {selected_title.name}\nVersion: {selected_title.version}\n\n{danger_text}\n"
|
||||||
danger_text + "\n")
|
|
||||||
self.ui.log_text_browser.setText(self.log_text)
|
self.ui.log_text_browser.setText(self.log_text)
|
||||||
|
|
||||||
def download_btn_pressed(self):
|
def lock_ui_for_download(self):
|
||||||
# Throw an error and make a message box appear if you haven't selected any options to output the title.
|
|
||||||
if (self.ui.pack_archive_chkbox.isChecked() is False and self.ui.keep_enc_chkbox.isChecked() is False and
|
|
||||||
self.ui.create_dec_chkbox.isChecked() is False):
|
|
||||||
msg_box = QMessageBox()
|
|
||||||
msg_box.setIcon(QMessageBox.Icon.Critical)
|
|
||||||
msg_box.setStandardButtons(QMessageBox.StandardButton.Ok)
|
|
||||||
msg_box.setDefaultButton(QMessageBox.StandardButton.Ok)
|
|
||||||
msg_box.setWindowTitle("No Output Selected")
|
|
||||||
msg_box.setText("You have not selected any format to output the data in!")
|
|
||||||
msg_box.setInformativeText("Please select at least one option for how you would like the download to be "
|
|
||||||
"saved.")
|
|
||||||
msg_box.exec()
|
|
||||||
return
|
|
||||||
# Lock the UI prior to the download beginning to avoid spawning multiple threads or changing info part way in.
|
# Lock the UI prior to the download beginning to avoid spawning multiple threads or changing info part way in.
|
||||||
|
# Also resets the log.
|
||||||
self.ui.tid_entry.setEnabled(False)
|
self.ui.tid_entry.setEnabled(False)
|
||||||
self.ui.version_entry.setEnabled(False)
|
self.ui.version_entry.setEnabled(False)
|
||||||
self.ui.download_btn.setEnabled(False)
|
self.ui.download_btn.setEnabled(False)
|
||||||
|
self.ui.script_btn.setEnabled(False)
|
||||||
self.ui.pack_archive_chkbox.setEnabled(False)
|
self.ui.pack_archive_chkbox.setEnabled(False)
|
||||||
self.ui.keep_enc_chkbox.setEnabled(False)
|
self.ui.keep_enc_chkbox.setEnabled(False)
|
||||||
self.ui.create_dec_chkbox.setEnabled(False)
|
self.ui.create_dec_chkbox.setEnabled(False)
|
||||||
@@ -215,11 +252,37 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|||||||
self.ui.console_select_dropdown.setEnabled(False)
|
self.ui.console_select_dropdown.setEnabled(False)
|
||||||
self.log_text = ""
|
self.log_text = ""
|
||||||
self.ui.log_text_browser.setText(self.log_text)
|
self.ui.log_text_browser.setText(self.log_text)
|
||||||
|
|
||||||
|
def download_btn_pressed(self):
|
||||||
|
# Throw an error and make a message box appear if you haven't selected any options to output the title.
|
||||||
|
if (self.ui.pack_archive_chkbox.isChecked() is False and self.ui.keep_enc_chkbox.isChecked() is False and
|
||||||
|
self.ui.create_dec_chkbox.isChecked() is False):
|
||||||
|
msg_box = QMessageBox()
|
||||||
|
msg_box.setIcon(QMessageBox.Icon.Critical)
|
||||||
|
msg_box.setStandardButtons(QMessageBox.StandardButton.Ok)
|
||||||
|
msg_box.setDefaultButton(QMessageBox.StandardButton.Ok)
|
||||||
|
msg_box.setWindowTitle(app.translate("MainWindow", "No Output Selected"))
|
||||||
|
msg_box.setText(app.translate("MainWindow", "You have not selected any format to output the data in!"))
|
||||||
|
msg_box.setInformativeText(app.translate("MainWindow", "Please select at least one option for how you would "
|
||||||
|
"like the download to be saved."))
|
||||||
|
msg_box.exec()
|
||||||
|
return
|
||||||
|
|
||||||
|
self.lock_ui_for_download()
|
||||||
|
|
||||||
# Create a new worker object to handle the download in a new thread.
|
# Create a new worker object to handle the download in a new thread.
|
||||||
if self.ui.console_select_dropdown.currentText() == "DSi":
|
if self.ui.console_select_dropdown.currentText() == "DSi":
|
||||||
worker = Worker(self.run_nus_download_dsi)
|
worker = Worker(run_nus_download_dsi, out_folder, self.ui.tid_entry.text(),
|
||||||
|
self.ui.version_entry.text(), self.ui.pack_archive_chkbox.isChecked(),
|
||||||
|
self.ui.keep_enc_chkbox.isChecked(), self.ui.create_dec_chkbox.isChecked(),
|
||||||
|
self.ui.use_local_chkbox.isChecked(), self.ui.archive_file_entry.text())
|
||||||
else:
|
else:
|
||||||
worker = Worker(self.run_nus_download_wii)
|
worker = Worker(run_nus_download_wii, out_folder, self.ui.tid_entry.text(),
|
||||||
|
self.ui.version_entry.text(), self.ui.pack_archive_chkbox.isChecked(),
|
||||||
|
self.ui.keep_enc_chkbox.isChecked(), self.ui.create_dec_chkbox.isChecked(),
|
||||||
|
self.ui.use_wiiu_nus_chkbox.isChecked(), self.ui.use_local_chkbox.isChecked(),
|
||||||
|
self.ui.pack_vwii_mode_chkbox.isChecked(), self.ui.patch_ios_chkbox.isChecked(),
|
||||||
|
self.ui.archive_file_entry.text())
|
||||||
worker.signals.result.connect(self.check_download_result)
|
worker.signals.result.connect(self.check_download_result)
|
||||||
worker.signals.progress.connect(self.update_log_text)
|
worker.signals.progress.connect(self.update_log_text)
|
||||||
self.threadpool.start(worker)
|
self.threadpool.start(worker)
|
||||||
@@ -231,39 +294,43 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|||||||
msg_box.setStandardButtons(QMessageBox.StandardButton.Ok)
|
msg_box.setStandardButtons(QMessageBox.StandardButton.Ok)
|
||||||
msg_box.setDefaultButton(QMessageBox.StandardButton.Ok)
|
msg_box.setDefaultButton(QMessageBox.StandardButton.Ok)
|
||||||
if result == -1:
|
if result == -1:
|
||||||
msg_box.setWindowTitle("Invalid Title ID")
|
window_title = app.translate("MainWindow", "Invalid Title ID")
|
||||||
msg_box.setText("The Title ID you have entered is not in a valid format!")
|
title_text = app.translate("MainWindow", "The Title ID you have entered is not in a valid format!")
|
||||||
msg_box.setInformativeText("Title IDs must be 16 digit strings of numbers and letters. Please enter a "
|
body_text = app.translate("MainWindow", "Title IDs must be 16 digit strings of numbers and letters. Please enter a correctly "
|
||||||
"correctly formatted Title ID, or select one from the menu on the left.")
|
"formatted Title ID, or select one from the menu on the left.")
|
||||||
msg_box.exec()
|
|
||||||
elif result == -2:
|
elif result == -2:
|
||||||
msg_box.setWindowTitle("Title ID/Version Not Found")
|
window_title = app.translate("MainWindow", "Title ID/Version Not Found")
|
||||||
msg_box.setText("No title with the provided Title ID or version could be found!")
|
title_text = app.translate("MainWindow", "No title with the provided Title ID or version could be found!")
|
||||||
msg_box.setInformativeText("Please make sure that you have entered a valid Title ID, or selected one from "
|
body_text = app.translate("MainWindow", "Please make sure that you have entered a valid Title ID, or selected one from the "
|
||||||
" the title database, and that the provided version exists for the title you are"
|
"title database, and that the provided version exists for the title you are attempting to download.")
|
||||||
" attempting to download.")
|
|
||||||
msg_box.exec()
|
|
||||||
elif result == -3:
|
elif result == -3:
|
||||||
msg_box.setWindowTitle("Content Decryption Failed")
|
window_title = app.translate("MainWindow", "Content Decryption Failed")
|
||||||
msg_box.setText("Content decryption was not successful! Decrypted contents could not be created.")
|
title_text = app.translate("MainWindow", "Content decryption was not successful! Decrypted contents could not be created.")
|
||||||
msg_box.setInformativeText("Your TMD or Ticket may be damaged, or they may not correspond with the content "
|
body_text = app.translate("MainWindow", "Your TMD or Ticket may be damaged, or they may not correspond with the content being "
|
||||||
"being decrypted. If you have checked \"Use local files, if they exist\", try "
|
"decrypted. If you have checked \"Use local files, if they exist\", try disabling that "
|
||||||
"disabling that option before trying the download again to fix potential issues "
|
"option before trying the download again to fix potential issues with local data.")
|
||||||
"with local data.")
|
|
||||||
msg_box.exec()
|
|
||||||
elif result == 1:
|
elif result == 1:
|
||||||
msg_box.setIcon(QMessageBox.Icon.Warning)
|
msg_box.setIcon(QMessageBox.Icon.Warning)
|
||||||
msg_box.setWindowTitle("Ticket Not Available")
|
window_title = app.translate("MainWindow", "Ticket Not Available")
|
||||||
msg_box.setText("No Ticket is Available for the Requested Title!")
|
title_text = app.translate("MainWindow", "No Ticket is Available for the Requested Title!")
|
||||||
msg_box.setInformativeText(
|
body_text = app.translate("MainWindow", "A ticket could not be downloaded for the requested title, but you have selected \"Pack"
|
||||||
"A ticket could not be downloaded for the requested title, but you have selected \"Pack installable "
|
" installable archive\" or \"Create decrypted contents\". These options are not "
|
||||||
" archive\" or \"Create decrypted contents\". These options are not available for titles without a "
|
"available for titles without a ticket. Only encrypted contents have been saved.")
|
||||||
" ticket. Only encrypted contents have been saved.")
|
else:
|
||||||
|
window_title = app.translate("MainWindow", "Unknown Error")
|
||||||
|
title_text = app.translate("MainWindow", "An Unknown Error has Occurred!")
|
||||||
|
body_text = app.translate("MainWindow", "Please try again. If this issue persists, please open a new issue on GitHub detailing"
|
||||||
|
" what you were trying to do when this error occurred.")
|
||||||
|
if result != 0:
|
||||||
|
msg_box.setWindowTitle(window_title)
|
||||||
|
msg_box.setText(title_text)
|
||||||
|
msg_box.setInformativeText(body_text)
|
||||||
msg_box.exec()
|
msg_box.exec()
|
||||||
# Now that the thread has closed, unlock the UI to allow for the next download.
|
# Now that the thread has closed, unlock the UI to allow for the next download.
|
||||||
self.ui.tid_entry.setEnabled(True)
|
self.ui.tid_entry.setEnabled(True)
|
||||||
self.ui.version_entry.setEnabled(True)
|
self.ui.version_entry.setEnabled(True)
|
||||||
self.ui.download_btn.setEnabled(True)
|
self.ui.download_btn.setEnabled(True)
|
||||||
|
self.ui.script_btn.setEnabled(True)
|
||||||
self.ui.pack_archive_chkbox.setEnabled(True)
|
self.ui.pack_archive_chkbox.setEnabled(True)
|
||||||
self.ui.keep_enc_chkbox.setEnabled(True)
|
self.ui.keep_enc_chkbox.setEnabled(True)
|
||||||
self.ui.create_dec_chkbox.setEnabled(True)
|
self.ui.create_dec_chkbox.setEnabled(True)
|
||||||
@@ -276,283 +343,6 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|||||||
# on the currently selected console, and saves on duplicate code.
|
# on the currently selected console, and saves on duplicate code.
|
||||||
self.selected_console_changed()
|
self.selected_console_changed()
|
||||||
|
|
||||||
def run_nus_download_wii(self, progress_callback):
|
|
||||||
# Actual NUS download function that runs in a separate thread.
|
|
||||||
tid = self.ui.tid_entry.text()
|
|
||||||
# Immediately knock out any invalidly formatted Title IDs.
|
|
||||||
if len(tid) != 16:
|
|
||||||
return -1
|
|
||||||
# An error here is acceptable, because it may just mean the box is empty. Or the version string is nonsense.
|
|
||||||
# Either way, just fall back on downloading the latest version of the title.
|
|
||||||
try:
|
|
||||||
title_version = int(self.ui.version_entry.text())
|
|
||||||
except ValueError:
|
|
||||||
title_version = None
|
|
||||||
# Set variables for these two options so that their state can be compared against the user's choices later.
|
|
||||||
pack_wad_enabled = self.ui.pack_archive_chkbox.isChecked()
|
|
||||||
decrypt_contents_enabled = self.ui.create_dec_chkbox.isChecked()
|
|
||||||
# Check whether we're going to be using the (faster) Wii U NUS or not.
|
|
||||||
wiiu_nus_enabled = self.ui.use_wiiu_nus_chkbox.isChecked()
|
|
||||||
# Create a new libWiiPy Title.
|
|
||||||
title = libWiiPy.title.Title()
|
|
||||||
# Make a directory for this title if it doesn't exist.
|
|
||||||
title_dir = pathlib.Path(os.path.join(out_folder, tid))
|
|
||||||
if not title_dir.is_dir():
|
|
||||||
title_dir.mkdir()
|
|
||||||
# Announce the title being downloaded, and the version if applicable.
|
|
||||||
if title_version is not None:
|
|
||||||
progress_callback.emit("Downloading title " + tid + " v" + str(title_version) + ", please wait...")
|
|
||||||
else:
|
|
||||||
progress_callback.emit("Downloading title " + tid + " vLatest, please wait...")
|
|
||||||
progress_callback.emit(" - Downloading and parsing TMD...")
|
|
||||||
# Download a specific TMD version if a version was specified, otherwise just download the latest TMD.
|
|
||||||
try:
|
|
||||||
if title_version is not None:
|
|
||||||
title.load_tmd(libWiiPy.title.download_tmd(tid, title_version, wiiu_endpoint=wiiu_nus_enabled))
|
|
||||||
else:
|
|
||||||
title.load_tmd(libWiiPy.title.download_tmd(tid, wiiu_endpoint=wiiu_nus_enabled))
|
|
||||||
title_version = title.tmd.title_version
|
|
||||||
# If libWiiPy returns an error, that means that either the TID or version doesn't exist, so return code -2.
|
|
||||||
except ValueError:
|
|
||||||
return -2
|
|
||||||
# Make a directory for this version if it doesn't exist.
|
|
||||||
version_dir = pathlib.Path(os.path.join(title_dir, str(title_version)))
|
|
||||||
if not version_dir.is_dir():
|
|
||||||
version_dir.mkdir()
|
|
||||||
# Write out the TMD to a file.
|
|
||||||
tmd_out = open(os.path.join(version_dir, "tmd." + str(title_version)), "wb")
|
|
||||||
tmd_out.write(title.tmd.dump())
|
|
||||||
tmd_out.close()
|
|
||||||
# Use a local ticket, if one exists and "use local files" is enabled.
|
|
||||||
if self.ui.use_local_chkbox.isChecked() is True and os.path.exists(os.path.join(version_dir, "tik")):
|
|
||||||
progress_callback.emit(" - Parsing local copy of Ticket...")
|
|
||||||
local_ticket = open(os.path.join(version_dir, "tik"), "rb")
|
|
||||||
title.load_ticket(local_ticket.read())
|
|
||||||
else:
|
|
||||||
progress_callback.emit(" - Downloading and parsing Ticket...")
|
|
||||||
try:
|
|
||||||
title.load_ticket(libWiiPy.title.download_ticket(tid, wiiu_endpoint=wiiu_nus_enabled))
|
|
||||||
ticket_out = open(os.path.join(version_dir, "tik"), "wb")
|
|
||||||
ticket_out.write(title.ticket.dump())
|
|
||||||
ticket_out.close()
|
|
||||||
except ValueError:
|
|
||||||
# If libWiiPy returns an error, then no ticket is available. Log this, and disable options requiring a
|
|
||||||
# ticket so that they aren't attempted later.
|
|
||||||
progress_callback.emit(" - No Ticket is available!")
|
|
||||||
pack_wad_enabled = False
|
|
||||||
decrypt_contents_enabled = False
|
|
||||||
# Load the content records from the TMD, and begin iterating over the records.
|
|
||||||
title.load_content_records()
|
|
||||||
content_list = []
|
|
||||||
for content in range(len(title.tmd.content_records)):
|
|
||||||
# Generate the correct file name by converting the content ID into hex, minus the 0x, and then appending
|
|
||||||
# that to the end of 000000. I refuse to believe there isn't a better way to do this here and in libWiiPy.
|
|
||||||
content_file_name = hex(title.tmd.content_records[content].content_id)[2:]
|
|
||||||
while len(content_file_name) < 8:
|
|
||||||
content_file_name = "0" + content_file_name
|
|
||||||
# Check for a local copy of the current content if "use local files" is enabled, and use it.
|
|
||||||
if self.ui.use_local_chkbox.isChecked() is True and os.path.exists(os.path.join(version_dir,
|
|
||||||
content_file_name)):
|
|
||||||
progress_callback.emit(" - Using local copy of content " + str(content + 1) + " of " +
|
|
||||||
str(len(title.tmd.content_records)))
|
|
||||||
local_file = open(os.path.join(version_dir, content_file_name), "rb")
|
|
||||||
content_list.append(local_file.read())
|
|
||||||
else:
|
|
||||||
progress_callback.emit(" - Downloading content " + str(content + 1) + " of " +
|
|
||||||
str(len(title.tmd.content_records)) + " (Content ID: " +
|
|
||||||
str(title.tmd.content_records[content].content_id) + ", Size: " +
|
|
||||||
str(title.tmd.content_records[content].content_size) + " bytes)...")
|
|
||||||
content_list.append(libWiiPy.title.download_content(tid, title.tmd.content_records[content].content_id,
|
|
||||||
wiiu_endpoint=wiiu_nus_enabled))
|
|
||||||
progress_callback.emit(" - Done!")
|
|
||||||
# If keep encrypted contents is on, write out each content after its downloaded.
|
|
||||||
if self.ui.keep_enc_chkbox.isChecked() is True:
|
|
||||||
enc_content_out = open(os.path.join(version_dir, content_file_name), "wb")
|
|
||||||
enc_content_out.write(content_list[content])
|
|
||||||
enc_content_out.close()
|
|
||||||
title.content.content_list = content_list
|
|
||||||
# If decrypt local contents is still true, decrypt each content and write out the decrypted file.
|
|
||||||
if decrypt_contents_enabled is True:
|
|
||||||
try:
|
|
||||||
for content in range(len(title.tmd.content_records)):
|
|
||||||
progress_callback.emit(" - Decrypting content " + str(content + 1) + " of " +
|
|
||||||
str(len(title.tmd.content_records)) + " (Content ID: " +
|
|
||||||
str(title.tmd.content_records[content].content_id) + ")...")
|
|
||||||
dec_content = title.get_content_by_index(content)
|
|
||||||
content_file_name = hex(title.tmd.content_records[content].content_id)[2:]
|
|
||||||
while len(content_file_name) < 8:
|
|
||||||
content_file_name = "0" + content_file_name
|
|
||||||
content_file_name = content_file_name + ".app"
|
|
||||||
dec_content_out = open(os.path.join(version_dir, content_file_name), "wb")
|
|
||||||
dec_content_out.write(dec_content)
|
|
||||||
dec_content_out.close()
|
|
||||||
except ValueError:
|
|
||||||
# If libWiiPy throws an error during decryption, return code -3. This should only be possible if using
|
|
||||||
# local encrypted contents that have been altered at present.
|
|
||||||
return -3
|
|
||||||
# If pack WAD is still true, pack the TMD, ticket, and contents all into a WAD.
|
|
||||||
if pack_wad_enabled is True:
|
|
||||||
# If the option to pack for vWii mode instead of Wii U mode is enabled, then the Title Key needs to be
|
|
||||||
# re-encrypted with the common key instead of the vWii key, so that the title can be installed from within
|
|
||||||
# vWii mode. (vWii mode does not have access to the vWii key, only Wii U mode has that.)
|
|
||||||
if self.ui.pack_vwii_mode_chkbox.isChecked() is True and (tid[3] == "7" or tid[7] == "7"):
|
|
||||||
progress_callback.emit(" - Re-encrypting Title Key with the common key...")
|
|
||||||
title_key_dec = title.ticket.get_title_key()
|
|
||||||
title_key_common = libWiiPy.title.encrypt_title_key(title_key_dec, 0, title.tmd.title_id)
|
|
||||||
title.ticket.common_key_index = 0
|
|
||||||
title.ticket.title_key_enc = title_key_common
|
|
||||||
# Get the WAD certificate chain, courtesy of libWiiPy.
|
|
||||||
progress_callback.emit(" - Building certificate...")
|
|
||||||
title.wad.set_cert_data(libWiiPy.title.download_cert(wiiu_endpoint=wiiu_nus_enabled))
|
|
||||||
# Use a typed WAD name if there is one, and auto generate one based on the TID and version if there isn't.
|
|
||||||
progress_callback.emit("Packing WAD...")
|
|
||||||
if self.ui.archive_file_entry.text() != "":
|
|
||||||
wad_file_name = self.ui.archive_file_entry.text()
|
|
||||||
if wad_file_name[-4:] != ".wad":
|
|
||||||
wad_file_name = wad_file_name + ".wad"
|
|
||||||
else:
|
|
||||||
wad_file_name = tid + "-v" + str(title_version) + ".wad"
|
|
||||||
# Have libWiiPy dump the WAD, and write that data out.
|
|
||||||
file = open(os.path.join(version_dir, wad_file_name), "wb")
|
|
||||||
file.write(title.dump_wad())
|
|
||||||
file.close()
|
|
||||||
progress_callback.emit("Download complete!")
|
|
||||||
# This is where the variables come in. If the state of these variables doesn't match the user's choice by this
|
|
||||||
# point, it means that they enabled decryption or WAD packing for a title that doesn't have a ticket. Return
|
|
||||||
# code 1 so that a warning popup is shown informing them of this.
|
|
||||||
if ((not pack_wad_enabled and self.ui.pack_archive_chkbox.isChecked()) or
|
|
||||||
(not decrypt_contents_enabled and self.ui.create_dec_chkbox.isChecked())):
|
|
||||||
return 1
|
|
||||||
return 0
|
|
||||||
|
|
||||||
def run_nus_download_dsi(self, progress_callback):
|
|
||||||
# Actual NUS download function that runs in a separate thread, but DSi flavored.
|
|
||||||
tid = self.ui.tid_entry.text()
|
|
||||||
# Immediately knock out any invalidly formatted Title IDs.
|
|
||||||
if len(tid) != 16:
|
|
||||||
return -1
|
|
||||||
# An error here is acceptable, because it may just mean the box is empty. Or the version string is nonsense.
|
|
||||||
# Either way, just fall back on downloading the latest version of the title.
|
|
||||||
try:
|
|
||||||
title_version = int(self.ui.version_entry.text())
|
|
||||||
except ValueError:
|
|
||||||
title_version = None
|
|
||||||
# Set variables for these two options so that their state can be compared against the user's choices later.
|
|
||||||
pack_tad_enabled = self.ui.pack_archive_chkbox.isChecked()
|
|
||||||
decrypt_contents_enabled = self.ui.create_dec_chkbox.isChecked()
|
|
||||||
# Create a new libTWLPy Title.
|
|
||||||
title = libTWLPy.Title()
|
|
||||||
# Make a directory for this title if it doesn't exist.
|
|
||||||
title_dir = pathlib.Path(os.path.join(out_folder, tid))
|
|
||||||
if not title_dir.is_dir():
|
|
||||||
title_dir.mkdir()
|
|
||||||
# Announce the title being downloaded, and the version if applicable.
|
|
||||||
if title_version is not None:
|
|
||||||
progress_callback.emit("Downloading title " + tid + " v" + str(title_version) + ", please wait...")
|
|
||||||
else:
|
|
||||||
progress_callback.emit("Downloading title " + tid + " vLatest, please wait...")
|
|
||||||
progress_callback.emit(" - Downloading and parsing TMD...")
|
|
||||||
# Download a specific TMD version if a version was specified, otherwise just download the latest TMD.
|
|
||||||
try:
|
|
||||||
if title_version is not None:
|
|
||||||
title.load_tmd(libTWLPy.download_tmd(tid, title_version))
|
|
||||||
else:
|
|
||||||
title.load_tmd(libTWLPy.download_tmd(tid))
|
|
||||||
title_version = title.tmd.title_version
|
|
||||||
# If libTWLPy returns an error, that means that either the TID or version doesn't exist, so return code -2.
|
|
||||||
except ValueError:
|
|
||||||
return -2
|
|
||||||
# Make a directory for this version if it doesn't exist.
|
|
||||||
version_dir = pathlib.Path(os.path.join(title_dir, str(title_version)))
|
|
||||||
if not version_dir.is_dir():
|
|
||||||
version_dir.mkdir()
|
|
||||||
# Write out the TMD to a file.
|
|
||||||
tmd_out = open(os.path.join(version_dir, "tmd." + str(title_version)), "wb")
|
|
||||||
tmd_out.write(title.tmd.dump())
|
|
||||||
tmd_out.close()
|
|
||||||
# Use a local ticket, if one exists and "use local files" is enabled.
|
|
||||||
if self.ui.use_local_chkbox.isChecked() is True and os.path.exists(os.path.join(version_dir, "tik")):
|
|
||||||
progress_callback.emit(" - Parsing local copy of Ticket...")
|
|
||||||
local_ticket = open(os.path.join(version_dir, "tik"), "rb")
|
|
||||||
title.load_ticket(local_ticket.read())
|
|
||||||
else:
|
|
||||||
progress_callback.emit(" - Downloading and parsing Ticket...")
|
|
||||||
try:
|
|
||||||
title.load_ticket(libTWLPy.download_ticket(tid))
|
|
||||||
ticket_out = open(os.path.join(version_dir, "tik"), "wb")
|
|
||||||
ticket_out.write(title.ticket.dump())
|
|
||||||
ticket_out.close()
|
|
||||||
except ValueError:
|
|
||||||
# If libTWLPy returns an error, then no ticket is available. Log this, and disable options requiring a
|
|
||||||
# ticket so that they aren't attempted later.
|
|
||||||
progress_callback.emit(" - No Ticket is available!")
|
|
||||||
pack_tad_enabled = False
|
|
||||||
decrypt_contents_enabled = False
|
|
||||||
# Load the content record from the TMD, and download the content it lists. DSi titles only have one content.
|
|
||||||
title.load_content_records()
|
|
||||||
content_file_name = hex(title.tmd.content_record.content_id)[2:]
|
|
||||||
while len(content_file_name) < 8:
|
|
||||||
content_file_name = "0" + content_file_name
|
|
||||||
# Check for a local copy of the current content if "use local files" is enabled, and use it.
|
|
||||||
if self.ui.use_local_chkbox.isChecked() is True and os.path.exists(os.path.join(version_dir,
|
|
||||||
content_file_name)):
|
|
||||||
progress_callback.emit(" - Using local copy of content")
|
|
||||||
local_file = open(os.path.join(version_dir, content_file_name), "rb")
|
|
||||||
content = local_file.read()
|
|
||||||
else:
|
|
||||||
progress_callback.emit(" - Downloading content (Content ID: " + str(title.tmd.content_record.content_id) +
|
|
||||||
", Size: " + str(title.tmd.content_record.content_size) + " bytes)...")
|
|
||||||
content = libTWLPy.download_content(tid, title.tmd.content_record.content_id)
|
|
||||||
progress_callback.emit(" - Done!")
|
|
||||||
# If keep encrypted contents is on, write out each content after its downloaded.
|
|
||||||
if self.ui.keep_enc_chkbox.isChecked() is True:
|
|
||||||
enc_content_out = open(os.path.join(version_dir, content_file_name), "wb")
|
|
||||||
enc_content_out.write(content)
|
|
||||||
enc_content_out.close()
|
|
||||||
title.content.content = content
|
|
||||||
# If decrypt local contents is still true, decrypt each content and write out the decrypted file.
|
|
||||||
if decrypt_contents_enabled is True:
|
|
||||||
try:
|
|
||||||
progress_callback.emit(" - Decrypting content (Content ID: " + str(title.tmd.content_record.content_id)
|
|
||||||
+ ")...")
|
|
||||||
dec_content = title.get_content()
|
|
||||||
content_file_name = hex(title.tmd.content_record.content_id)[2:]
|
|
||||||
while len(content_file_name) < 8:
|
|
||||||
content_file_name = "0" + content_file_name
|
|
||||||
content_file_name = content_file_name + ".app"
|
|
||||||
dec_content_out = open(os.path.join(version_dir, content_file_name), "wb")
|
|
||||||
dec_content_out.write(dec_content)
|
|
||||||
dec_content_out.close()
|
|
||||||
except ValueError:
|
|
||||||
# If libWiiPy throws an error during decryption, return code -3. This should only be possible if using
|
|
||||||
# local encrypted contents that have been altered at present.
|
|
||||||
return -3
|
|
||||||
# If pack TAD is still true, pack the TMD, ticket, and content into a TAD.
|
|
||||||
if pack_tad_enabled is True:
|
|
||||||
# Get the TAD certificate chain, courtesy of libTWLPy.
|
|
||||||
progress_callback.emit(" - Building certificate...")
|
|
||||||
title.tad.set_cert_data(libTWLPy.download_cert())
|
|
||||||
# Use a typed TAD name if there is one, and auto generate one based on the TID and version if there isn't.
|
|
||||||
progress_callback.emit("Packing TAD...")
|
|
||||||
if self.ui.archive_file_entry.text() != "":
|
|
||||||
tad_file_name = self.ui.archive_file_entry.text()
|
|
||||||
if tad_file_name[-4:] != ".tad":
|
|
||||||
tad_file_name = tad_file_name + ".tad"
|
|
||||||
else:
|
|
||||||
tad_file_name = tid + "-v" + str(title_version) + ".tad"
|
|
||||||
# Have libTWLPy dump the TAD, and write that data out.
|
|
||||||
file = open(os.path.join(version_dir, tad_file_name), "wb")
|
|
||||||
file.write(title.dump_tad())
|
|
||||||
file.close()
|
|
||||||
progress_callback.emit("Download complete!")
|
|
||||||
# This is where the variables come in. If the state of these variables doesn't match the user's choice by this
|
|
||||||
# point, it means that they enabled decryption or TAD packing for a title that doesn't have a ticket. Return
|
|
||||||
# code 1 so that a warning popup is shown informing them of this.
|
|
||||||
if ((not pack_tad_enabled and self.ui.pack_archive_chkbox.isChecked()) or
|
|
||||||
(not decrypt_contents_enabled and self.ui.create_dec_chkbox.isChecked())):
|
|
||||||
return 1
|
|
||||||
return 0
|
|
||||||
|
|
||||||
def pack_wad_chkbox_toggled(self):
|
def pack_wad_chkbox_toggled(self):
|
||||||
# Simple function to catch when the WAD/TAD checkbox is toggled and enable/disable the file name entry box
|
# Simple function to catch when the WAD/TAD checkbox is toggled and enable/disable the file name entry box
|
||||||
# accordingly.
|
# accordingly.
|
||||||
@@ -570,6 +360,88 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|||||||
elif self.ui.console_select_dropdown.currentText() == "DSi":
|
elif self.ui.console_select_dropdown.currentText() == "DSi":
|
||||||
self.ui.pack_vwii_mode_chkbox.setEnabled(False)
|
self.ui.pack_vwii_mode_chkbox.setEnabled(False)
|
||||||
|
|
||||||
|
def script_btn_pressed(self):
|
||||||
|
file_name = QFileDialog.getOpenFileName(self, caption=app.translate("MainWindow", "Open NUS script"), filter=app.translate("MainWindow", "NUS Scripts (*.nus *.txt)"), options=QFileDialog.Option.ReadOnly)
|
||||||
|
if len(file_name[0]) == 0:
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
file = open(file_name[0], "r")
|
||||||
|
except:
|
||||||
|
QMessageBox.critical(self, app.translate("MainWindow", "Script Failure"), app.translate("MainWindow", "Failed to open the script."), buttons=QMessageBox.StandardButton.Ok, defaultButton=QMessageBox.StandardButton.Ok)
|
||||||
|
return
|
||||||
|
|
||||||
|
content = file.readlines()
|
||||||
|
|
||||||
|
# Decoding NUS Scripts
|
||||||
|
# NUS Scripts are plaintext UTF-8 files that list a title per line, terminated with newlines.
|
||||||
|
# Every title is its u64 TID, a space and its u16 version, *both* written in hexadecimal.
|
||||||
|
# NUS itself expects versions as decimal notation, so they need to be decoded first, but TIDs are always written in hexadecimal notation.
|
||||||
|
|
||||||
|
titles = []
|
||||||
|
|
||||||
|
for index, title in enumerate(content):
|
||||||
|
decoded = title.replace("\n", "").split(" ", 1)
|
||||||
|
if len(decoded[0]) != 16:
|
||||||
|
QMessageBox.critical(self, app.translate("MainWindow", "Script Failure"), app.translate("MainWindow", "The TID for title #%n is not valid.", "", index+1), buttons=QMessageBox.StandardButton.Ok, defaultButton=QMessageBox.StandardButton.Ok)
|
||||||
|
return
|
||||||
|
elif len(decoded[1]) != 4:
|
||||||
|
QMessageBox.critical(self, app.translate("MainWindow", "Script Failure"), app.translate("MainWindow", "The version for title #%n is not valid.", "", index+1), buttons=QMessageBox.StandardButton.Ok, defaultButton=QMessageBox.StandardButton.Ok)
|
||||||
|
return
|
||||||
|
|
||||||
|
tid = decoded[0]
|
||||||
|
|
||||||
|
try:
|
||||||
|
version = int(decoded[1], 16)
|
||||||
|
except:
|
||||||
|
QMessageBox.critical(self, app.translate("MainWindow", "Script Failure"), app.translate("MainWindow", "The version for title #%n is not valid.", "", index+1), buttons=QMessageBox.StandardButton.Ok, defaultButton=QMessageBox.StandardButton.Ok)
|
||||||
|
return
|
||||||
|
|
||||||
|
title = None
|
||||||
|
for category in self.trees[self.ui.platform_tabs.currentIndex()][1]:
|
||||||
|
for title_ in self.trees[self.ui.platform_tabs.currentIndex()][1][category]:
|
||||||
|
# The last two digits are either identifying the title type (e.g IOS slot, BC type, etc) or a region code; in case of the latter, skip the region here to match it
|
||||||
|
if not ((title_["TID"][-2:] == "XX" and title_["TID"][:-2] == tid[:-2]) or title_["TID"] == tid):
|
||||||
|
continue
|
||||||
|
|
||||||
|
found_ver = False
|
||||||
|
for region in title_["Versions"]:
|
||||||
|
for db_version in title_["Versions"][region]:
|
||||||
|
if db_version == version:
|
||||||
|
found_ver = True
|
||||||
|
break
|
||||||
|
|
||||||
|
if not found_ver:
|
||||||
|
QMessageBox.critical(self, app.translate("MainWindow", "Script Failure"), app.translate("MainWindow", "The version for title #%n could not be discovered in the database.", "", index+1), buttons=QMessageBox.StandardButton.Ok, defaultButton=QMessageBox.StandardButton.Ok)
|
||||||
|
return
|
||||||
|
|
||||||
|
title = title_
|
||||||
|
break
|
||||||
|
|
||||||
|
if title == None:
|
||||||
|
QMessageBox.critical(self, app.translate("MainWindow", "Script Failure"), app.translate("MainWindow", "Title #%n could not be discovered in the database.", "", index+1), buttons=QMessageBox.StandardButton.Ok, defaultButton=QMessageBox.StandardButton.Ok)
|
||||||
|
return
|
||||||
|
|
||||||
|
titles.append((title["TID"], str(version), title["Archive Name"]))
|
||||||
|
|
||||||
|
self.lock_ui_for_download()
|
||||||
|
|
||||||
|
self.update_log_text(f"Found {len(titles)} titles, starting batch download.")
|
||||||
|
|
||||||
|
if self.ui.console_select_dropdown.currentText() == "DSi":
|
||||||
|
worker = Worker(run_nus_download_dsi_batch, out_folder, titles, self.ui.pack_archive_chkbox.isChecked(),
|
||||||
|
self.ui.keep_enc_chkbox.isChecked(), self.ui.create_dec_chkbox.isChecked(),
|
||||||
|
self.ui.use_local_chkbox.isChecked(), self.ui.archive_file_entry.text())
|
||||||
|
else:
|
||||||
|
worker = Worker(run_nus_download_wii_batch, out_folder, titles, self.ui.pack_archive_chkbox.isChecked(),
|
||||||
|
self.ui.keep_enc_chkbox.isChecked(), self.ui.create_dec_chkbox.isChecked(),
|
||||||
|
self.ui.use_wiiu_nus_chkbox.isChecked(), self.ui.use_local_chkbox.isChecked(),
|
||||||
|
self.ui.pack_vwii_mode_chkbox.isChecked(), self.ui.patch_ios_chkbox.isChecked())
|
||||||
|
|
||||||
|
worker.signals.result.connect(self.check_download_result)
|
||||||
|
worker.signals.progress.connect(self.update_log_text)
|
||||||
|
self.threadpool.start(worker)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
app = QApplication(sys.argv)
|
app = QApplication(sys.argv)
|
||||||
@@ -586,15 +458,15 @@ if __name__ == "__main__":
|
|||||||
sub_key = r'SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders'
|
sub_key = r'SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders'
|
||||||
downloads_guid = '{374DE290-123F-4565-9164-39C4925E467B}'
|
downloads_guid = '{374DE290-123F-4565-9164-39C4925E467B}'
|
||||||
with winreg.OpenKey(winreg.HKEY_CURRENT_USER, sub_key) as key:
|
with winreg.OpenKey(winreg.HKEY_CURRENT_USER, sub_key) as key:
|
||||||
location = winreg.QueryValueEx(key, downloads_guid)[0]
|
location = pathlib.Path(winreg.QueryValueEx(key, downloads_guid)[0])
|
||||||
else:
|
else:
|
||||||
location = os.path.join(os.path.expanduser('~'), 'Downloads')
|
location = pathlib.Path(os.path.expanduser('~')).joinpath('Downloads')
|
||||||
# Build the path by combining the path to the Downloads photo with "NUSGet".
|
# Build the path by combining the path to the Downloads photo with "NUSGet".
|
||||||
out_folder = os.path.join(location, "NUSGet")
|
out_folder = location.joinpath("NUSGet")
|
||||||
# Create the "NUSGet" directory if it doesn't exist. In the future, this will be user-customizable, but this works
|
# Create the "NUSGet" directory if it doesn't exist. In the future, this will be user-customizable, but this works
|
||||||
# for now, and avoids the issues from when it used to use a directory next to the binary (mostly on macOS).
|
# for now, and avoids the issues from when it used to use a directory next to the binary (mostly on macOS).
|
||||||
if not os.path.isdir(out_folder):
|
if not out_folder.is_dir():
|
||||||
os.mkdir(out_folder)
|
out_folder.mkdir()
|
||||||
|
|
||||||
# Load the system plugins directory on Linux for system styles, if it exists. Try using Breeze if available, because
|
# Load the system plugins directory on Linux for system styles, if it exists. Try using Breeze if available, because
|
||||||
# it looks nice, but fallback on kvantum if it isn't, since kvantum is likely to exist. If all else fails, fusion.
|
# it looks nice, but fallback on kvantum if it isn't, since kvantum is likely to exist. If all else fails, fusion.
|
||||||
@@ -606,6 +478,16 @@ if __name__ == "__main__":
|
|||||||
elif "kvantum" in QStyleFactory.keys():
|
elif "kvantum" in QStyleFactory.keys():
|
||||||
app.setStyle("kvantum")
|
app.setStyle("kvantum")
|
||||||
|
|
||||||
|
# Load qtbase translations, and then apps-specific translations.
|
||||||
|
path = QLibraryInfo.path(QLibraryInfo.LibraryPath.TranslationsPath)
|
||||||
|
translator = QTranslator(app)
|
||||||
|
if translator.load(QLocale.system(), 'qtbase', '_', path):
|
||||||
|
app.installTranslator(translator)
|
||||||
|
translator = QTranslator(app)
|
||||||
|
path = os.path.join(os.path.dirname(__file__), "resources/translations")
|
||||||
|
if translator.load(QLocale.system(), 'nusget', '_', path):
|
||||||
|
app.installTranslator(translator)
|
||||||
|
|
||||||
window = MainWindow()
|
window = MainWindow()
|
||||||
window.setWindowTitle("NUSGet")
|
window.setWindowTitle("NUSGet")
|
||||||
window.setWindowIcon(QIcon(os.path.join(os.path.dirname(__file__), "resources/icon.png")))
|
window.setWindowIcon(QIcon(os.path.join(os.path.dirname(__file__), "resources/icon.png")))
|
||||||
|
|||||||
14
NUSGet.pyproject
Normal file
14
NUSGet.pyproject
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"files": [
|
||||||
|
"NUSGet.py",
|
||||||
|
"./modules/core.py",
|
||||||
|
"./qt/ui/MainMenu.ui",
|
||||||
|
"./resources/translations/nusget_es.ts",
|
||||||
|
"./resources/translations/nusget_no.ts",
|
||||||
|
"./resources/translations/nusget_nb.ts",
|
||||||
|
"./resources/translations/nusget_fr.ts",
|
||||||
|
"./resources/translations/nusget_it.ts",
|
||||||
|
"./resources/translations/nusget_de.ts",
|
||||||
|
"./resources/translations/nusget_ro.ts"
|
||||||
|
]
|
||||||
|
}
|
||||||
42
README.md
42
README.md
@@ -6,7 +6,7 @@ A modern and supercharged NUS downloader built with Python and Qt6. Powered by l
|
|||||||
The name is a play on NuGet, the .NET package manager. Thank you [@Janni9009](https://github.com/Janni9009) for the name idea!
|
The name is a play on NuGet, the .NET package manager. Thank you [@Janni9009](https://github.com/Janni9009) for the name idea!
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
NUSDGet allows you to download any content from the Nintendo Update Servers. Free content (content with a Ticket freely available on the servers) can be decrypted or packed directly into an installable archive (WAD/TAD).
|
NUSGet allows you to download any content from the Nintendo Update Servers. Free content (content with a Ticket freely available on the servers) can be decrypted or packed directly into an installable archive (WAD/TAD).
|
||||||
|
|
||||||
NUSGet also offers the ability to create vWii WADs that can be installed from within vWii mode, since the content directly from the update servers is only designed to be installed from Wii U mode.
|
NUSGet also offers the ability to create vWii WADs that can be installed from within vWii mode, since the content directly from the update servers is only designed to be installed from Wii U mode.
|
||||||
|
|
||||||
@@ -18,18 +18,26 @@ The following features are available for all supported consoles:
|
|||||||
- "Pack installable archive (WAD/TAD)": Pack the encrypted contents, TMD, and Ticket into a WAD file that can be installed on a Wii or in Dolphin Emulator. Only supported for free titles.
|
- "Pack installable archive (WAD/TAD)": Pack the encrypted contents, TMD, and Ticket into a WAD file that can be installed on a Wii or in Dolphin Emulator. Only supported for free titles.
|
||||||
|
|
||||||
**For vWii titles only:**
|
**For vWii titles only:**
|
||||||
- "Pack for vWii mode instead of Wii U mode": Re-encrpyt the Title Key in a vWii title's Ticket before packing a WAD, so that the WAD can be installed from inside the vWii on a Wii U. **This also creates WADs that can be installed directly in Dolphin, allowing for running the vWii System Menu in Dolphin without a vWii NAND dump!**
|
- "Re-encrypt title using the Wii Common Key": Re-encrypt the Title Key in a vWii title's Ticket before packing the WAD, so that the WAD can be installed via a normal WAD manager on the vWii, and can be extracted with legacy tools. **This also creates WADs that can be installed directly in Dolphin, allowing for running the vWii System Menu in Dolphin without a vWii NAND dump!**
|
||||||
|
|
||||||
**For DSi titles only:**
|
**For DSi titles only:**
|
||||||
- "Pack installable archive (WAD/TAD)": Pack the encrypted contents, TMD, and Ticket into a TAD file that can be installed on a TAD or in a DSi-capable emulator. Only supported for free titles. For real hardware, these titles can be installed using [@rvtr](https://github.com/rvtr)'s handy [TAD Delivery Tool](https://github.com/rvtr/TDT).
|
- "Pack installable archive (WAD/TAD)": Pack the encrypted contents, TMD, and Ticket into a TAD file that can be installed on a TAD or in a DSi-capable emulator. Only supported for free titles. For real hardware, these titles can be installed using [@rvtr](https://github.com/rvtr)'s handy [TAD Delivery Tool](https://github.com/rvtr/TDT).
|
||||||
|
|
||||||
|
## Using NUSGet
|
||||||
|
For basic usage on all platforms, you can download the latest release for your operating system from [here](https://github.com/NinjaCheetah/NUSGet/releases/latest), and then run the executable.
|
||||||
|
|
||||||
|
**Platform-Specific Notes:**
|
||||||
|
- **macOS:** To use NUSGet on macOS, you'll need to either open NUSGet.app using right-click -> Open, or by using the terminal command `xattr -d com.apple.quarantine NUSGet.app`. After doing either of those things once, you'll be able to double-click NUSGet to open it like you normally would for an app. Note that changes in macOS Sequoia require using the latter method.
|
||||||
|
- **Windows:** On Windows, you'll likely need to allow NUSGet.exe in your antivirus program. This includes Windows Defender, which is almost guaranteed to prevent the app from being run. This is not because NUSGet is malicious in any way, it's just that NUSGet isn't popular enough to be "known" to Windows, and I don't have the expensive signing certificate necessary to work around this. If you're in doubt, you can look at all of NUSGet's code in this repository.
|
||||||
|
- **Linux:** No special information applies on Linux, however you can build NUSGet yourself if you'd like to have it as an installed application with an icon that will appear in your favorite application launcher. See [here](https://github.com/NinjaCheetah/NUSGet?tab=readme-ov-file#for-linux-users) for more information.
|
||||||
|
|
||||||
## Building
|
## Building
|
||||||
### System Requirements
|
### System Requirements
|
||||||
- **Windows:** Python 3.11 (Requires Windows 8.1 or later)
|
- **Windows:** Python 3.11 (Requires Windows 8.1 or later)
|
||||||
- **Linux:** Python 3.11
|
- **Linux:** Python 3.11
|
||||||
- **macOS:** Python 3.11 (Requires macOS 10.9 or later, however macOS 11.0 or later may be required for library support)
|
- **macOS:** Python 3.11 (Requires macOS 10.9 or later, however macOS 11.0 or later may be required for library support)
|
||||||
|
|
||||||
**Python 3.12 is not supported at this time.**
|
**Python 3.12 may be supported now, however it is not tested at this time.**
|
||||||
|
|
||||||
First, install the required dependencies:
|
First, install the required dependencies:
|
||||||
```
|
```
|
||||||
@@ -38,21 +46,35 @@ pip install -r requirements.txt
|
|||||||
Then, use the command for your platform to build an executable with Nuitka:
|
Then, use the command for your platform to build an executable with Nuitka:
|
||||||
|
|
||||||
**Windows**
|
**Windows**
|
||||||
```
|
```shell
|
||||||
nuitka --show-progress --include-data-dir=data=data --include-data-dir=resources=resources --assume-yes-for-downloads --onefile --windows-icon-from-ico=resources/icon.png --plugin-enable=pyside6 NUSGet.py --windows-console-mode=disable
|
python -m nuitka --show-progress --include-data-dir=data=data --include-data-dir=resources=resources --assume-yes-for-downloads --onefile --windows-icon-from-ico=resources/icon.png --plugin-enable=pyside6 NUSGet.py --windows-console-mode=disable
|
||||||
```
|
```
|
||||||
|
|
||||||
**Linux**
|
**Linux**
|
||||||
```
|
```shell
|
||||||
nuitka3 --show-progress --include-data-dir=data=data --include-data-dir=resources=resources --assume-yes-for-downloads --onefile --plugin-enable=pyside6 NUSGet.py
|
python -m nuitka --show-progress --include-data-dir=data=data --include-data-dir=resources=resources --assume-yes-for-downloads --onefile --plugin-enable=pyside6 NUSGet.py -o NUSGet
|
||||||
```
|
```
|
||||||
|
|
||||||
**macOS**
|
**macOS**
|
||||||
```
|
```shell
|
||||||
nuitka3 --show-progress --include-data-dir=data=data --include-data-dir=resources=resources --assume-yes-for-downloads --onefile --plugin-enable=pyside6 NUSGet.py --macos-create-app-bundle --macos-app-icon=resources/icon.png
|
python -m nuitka --show-progress --include-data-dir=data=data --include-data-dir=resources=resources --assume-yes-for-downloads --onefile --plugin-enable=pyside6 NUSGet.py --macos-create-app-bundle --macos-app-icon=resources/icon.png
|
||||||
```
|
```
|
||||||
|
|
||||||
The result will be a single binary named `NUSGet` that contains everything required to run NUSGet. No dependencies are needed on the target system.
|
The result will be a single binary named `NUSGet` that contains everything required to run NUSGet. No dependencies are needed on the target system. On Windows and macOS, this will also embed the icon in the program.
|
||||||
|
|
||||||
|
|
||||||
|
### For Linux Users:
|
||||||
|
A Makefile has been included to both build and install NUSGet on Linux. This will automatically set up NUSGet under `/opt/` and install a .desktop file to `/usr/share/applications/` so you can use it like any other application.
|
||||||
|
|
||||||
|
First, use make to build NUSGet (this automates the step above):
|
||||||
|
```shell
|
||||||
|
make linux
|
||||||
|
```
|
||||||
|
|
||||||
|
Then, run the install command with `sudo` (or your favorite alternative):
|
||||||
|
```shell
|
||||||
|
sudo make linux-install
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## Why this and not NUSD?
|
## Why this and not NUSD?
|
||||||
|
|||||||
35
TRANSLATING.md
Normal file
35
TRANSLATING.md
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
# Translating NUSGet
|
||||||
|
Since v1.2.0, NUSGet has support for loading Qt translation files. If you'd like to translate NUSGet into your language, see the following directions.
|
||||||
|
|
||||||
|
### 1. Get Qt Linguist
|
||||||
|
The first thing you'll need to get is Qt Linguist.
|
||||||
|
|
||||||
|
For Windows and macOS users, this comes included with a normal Qt install. You'll want to get the official online Qt installer for open-source development, which is free and can be obtained [here](https://www.qt.io/download-qt-installer-oss). You do **not** need the paid/commercial version of Qt, as NUSGet is free software and is developed with the OSS version of Qt.
|
||||||
|
|
||||||
|
For Linux users, you'll likely be able to get Qt's development tools, including Qt Linguist, via your system package manager. You **must** get the Qt 6 version of the development tools, not the Qt 5 version. On Arch, for example, the package you'll need is `qt6-tools`. Depending on how the package is handled, Linguist may not appear in your application menu. If that's the case, you can start it by running `linguist6`.
|
||||||
|
|
||||||
|
|
||||||
|
### 2. Load Your Translation
|
||||||
|
NUSGet's raw translation files are stored in `resources/translations/`.
|
||||||
|
|
||||||
|
If your language doesn't already exist, open up `NUSGet.pyproject` and add a new line for your language. These files must follow the standard two-letter language codes, and you must provide the full path to the file, like with the existing entries. An example entry for Spanish would look like this:
|
||||||
|
```json
|
||||||
|
"./resources/translations/nusget_es.ts"
|
||||||
|
```
|
||||||
|
|
||||||
|
If your language already exists, or if you just added it, run `python update_translations.py` to generate any new translation files and update existing ones.
|
||||||
|
|
||||||
|
Once your translation file is ready, open it up in Qt Linguist. You should see NUSGet's interface on the right, so you have the context of where these strings are being used.
|
||||||
|
|
||||||
|
|
||||||
|
### 3. Translate
|
||||||
|
Qt Linguist will show you a list of all strings that need to be translated, along with their status. For strings that are part of the UI, the corresponding UI element will be shown so that you know what you're translating. For strings only present in the code, the code will be shown instead, which can generally be ignored.
|
||||||
|
|
||||||
|
When you've finished with your translations (or if you just want to test them), head back to the project and run `python build_translations.py`, which will build the translations to QM files in the same directory as the original TS files. These files are packaged as part of the executable when you build NUSGet, and are the actual resources that Qt loads the translations from at runtime.
|
||||||
|
|
||||||
|
|
||||||
|
### 4. Submit Your Changes
|
||||||
|
Once you've finished with your translations, open a new pull request on NUSGet's repo with your changes, and make sure to use the `translations` label. Please **do not** submit any unrelated changes as part of a translation pull request. Other changes should be submitted separately.
|
||||||
|
|
||||||
|
|
||||||
|
If you have any questions about translations, feel free to reach out and ask for help.
|
||||||
26
build_translations.py
Normal file
26
build_translations.py
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
# "build_translations.py", licensed under the MIT license
|
||||||
|
# Copyright 2024 NinjaCheetah
|
||||||
|
# This script exists to work around an issue in PySide6 where the "pyside6-project build" command incorrectly places
|
||||||
|
# translation files in the root of the project directory while building.
|
||||||
|
|
||||||
|
import json
|
||||||
|
import pathlib
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
|
||||||
|
LRELEASE_CMD = "pyside6-lrelease"
|
||||||
|
|
||||||
|
|
||||||
|
pyproject_file = pathlib.Path("NUSGet.pyproject")
|
||||||
|
pyproject = json.load(open(pyproject_file, "r"))
|
||||||
|
files = []
|
||||||
|
for key in pyproject["files"]:
|
||||||
|
files.append(pathlib.Path(key))
|
||||||
|
ts_files = []
|
||||||
|
for file in files:
|
||||||
|
if file.suffix == ".ts":
|
||||||
|
ts_files.append(file)
|
||||||
|
|
||||||
|
for translation in ts_files:
|
||||||
|
cmd = [LRELEASE_CMD] + [translation] + ["-qm"] + [translation.with_suffix(".qm")]
|
||||||
|
subprocess.run(cmd, cwd=str(pyproject_file.parent))
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
"World": [256, 512]
|
"World": [256, 512]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"TAD Name": "Nintendo-DS-Cartridge-Whitelist-NUS"
|
"Archive Name": "Nintendo-DS-Cartridge-Whitelist"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "Launcher (System Menu)",
|
"Name": "Launcher (System Menu)",
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
"Australia/NZ": [512, 768, 1024, 1280, 1536, 1792]
|
"Australia/NZ": [512, 768, 1024, 1280, 1536, 1792]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"TAD Name": "Launcher-NUS",
|
"Archive Name": "Launcher",
|
||||||
"Danger": "The Launcher (DSi Menu) is a critical part of the DSi's operation, and should not be modified unless you have Unlaunch installed."
|
"Danger": "The Launcher (DSi Menu) is a critical part of the DSi's operation, and should not be modified unless you have Unlaunch installed."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
"Australia/NZ": [3, 4, 5, 6, 7, 8, 9]
|
"Australia/NZ": [3, 4, 5, 6, 7, 8, 9]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"TAD Name": "Version-Data-NUS"
|
"Archive Name": "Version-Data"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "WiFi Firmware",
|
"Name": "WiFi Firmware",
|
||||||
@@ -45,8 +45,8 @@
|
|||||||
"World": [256, 512]
|
"World": [256, 512]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"TAD Name": "WiFi-Firmware-NUS",
|
"Archive Name": "WiFi-Firmware",
|
||||||
"Danger": "The WiFi Firmware is the firmware that runs on the DSi's WiFi chip, and should not be modified. WiFi will not work properly if this title is missing or damaged."
|
"Danger": "The WiFi Firmware is the firmware that runs on the DSi's WiFi chip, and should not be modified. Your console WILL be bricked if this title is damaged or missing."
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"System Apps": [
|
"System Apps": [
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
"World": [256]
|
"World": [256]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"TAD Name": "DS-Download-Play-NUS"
|
"Archive Name": "DS-Download-Play"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "Flipnote Studio",
|
"Name": "Flipnote Studio",
|
||||||
@@ -68,7 +68,7 @@
|
|||||||
"Japan": [512]
|
"Japan": [512]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"TAD Name": "Flipnote-Studio-NUS"
|
"Archive Name": "Flipnote-Studio"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "Nintendo 3DS Transfer Tool",
|
"Name": "Nintendo 3DS Transfer Tool",
|
||||||
@@ -81,7 +81,7 @@
|
|||||||
"Australia/NZ": [512, 768]
|
"Australia/NZ": [512, 768]
|
||||||
},
|
},
|
||||||
"Ticket": false,
|
"Ticket": false,
|
||||||
"TAD Name": "Nintendo-3DS-Transfer-Tool-NUS"
|
"Archive Name": "Nintendo-3DS-Transfer-Tool"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "Nintendo DSi Browser",
|
"Name": "Nintendo DSi Browser",
|
||||||
@@ -92,7 +92,7 @@
|
|||||||
"Japan": [768]
|
"Japan": [768]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"TAD Name": "Nintendo-DSi-Browser-NUS"
|
"Archive Name": "Nintendo-DSi-Browser"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "Nintendo DSi Camera",
|
"Name": "Nintendo DSi Camera",
|
||||||
@@ -104,7 +104,7 @@
|
|||||||
"Australia/NZ": [768, 1024]
|
"Australia/NZ": [768, 1024]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"TAD Name": "Nintendo-DSi-Camera-NUS"
|
"Archive Name": "Nintendo-DSi-Camera"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "Nintendo DSi Shop",
|
"Name": "Nintendo DSi Shop",
|
||||||
@@ -118,7 +118,7 @@
|
|||||||
"Australia/NZ": [1536, 1792, 2048, 2304, 2560, 2816, 3072]
|
"Australia/NZ": [1536, 1792, 2048, 2304, 2560, 2816, 3072]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"TAD Name": "Nintendo-DSi-Shop-NUS"
|
"Archive Name": "Nintendo-DSi-Shop"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "Nintendo DSi Sound",
|
"Name": "Nintendo DSi Sound",
|
||||||
@@ -130,7 +130,7 @@
|
|||||||
"Australia/NZ": [256, 512]
|
"Australia/NZ": [256, 512]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"TAD Name": "Nintendo-DSi-Sound-NUS"
|
"Archive Name": "Nintendo-DSi-Sound"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "Nintendo Zone",
|
"Name": "Nintendo Zone",
|
||||||
@@ -142,7 +142,7 @@
|
|||||||
"Australia/NZ": [512, 768]
|
"Australia/NZ": [512, 768]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"TAD Name": "Nintendo-DSi-Sound-NUS"
|
"Archive Name": "Nintendo-DSi-Sound"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "System Settings",
|
"Name": "System Settings",
|
||||||
@@ -156,7 +156,7 @@
|
|||||||
"Australia/NZ": [512, 768]
|
"Australia/NZ": [512, 768]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"TAD Name": "System-Settings-NUS"
|
"Archive Name": "System-Settings"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"DSiWare": [
|
"DSiWare": [
|
||||||
|
|||||||
@@ -7,8 +7,8 @@
|
|||||||
"World": [6, 7]
|
"World": [6, 7]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "BC-NAND-NUS",
|
"Archive Name": "BC-NAND",
|
||||||
"Danger": "BC-NAND is required for the Wii U to be able to boot any vWii titles. DO NOT modify it, or your Wii U will no longer be able to load into the vWii without restoring it from Wii U mode."
|
"Danger": "BC-NAND is required for the Wii U to boot Wii titles. DO NOT modify it, or your Wii U will no longer be able to enter Wii mode."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "BC-WFS",
|
"Name": "BC-WFS",
|
||||||
@@ -17,8 +17,8 @@
|
|||||||
"World": [1]
|
"World": [1]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "BC-WFS-NUS",
|
"Archive Name": "BC-WFS",
|
||||||
"Danger": "BC-WFS is required for the Wii U to be able to boot Dragon Quest X Online. While not generally essential, this is a system title and should not be modified."
|
"Danger": "BC-WFS is required for the Wii U to be able to boot Dragon Quest X Online. Do NOT modify it, or your Wii U may experience issues with Wii mode."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "System Menu",
|
"Name": "System Menu",
|
||||||
@@ -29,8 +29,8 @@
|
|||||||
"Japan": [512, 544, 608]
|
"Japan": [512, 544, 608]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "vWii-System-Menu",
|
"Archive Name": "System-Menu",
|
||||||
"Danger": "The System Menu is a critical part of the vWii's operation, and should not be modified. If it is deleted, it will need to be restored from Wii U mode to be able to access the vWii again."
|
"Danger": "The System Menu is a critical part of the vWii's operation, and should not be modified. If you intend to modify it, you should have Preloader installed, or else you may not be able to use the vWii."
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"System Channels": [
|
"System Channels": [
|
||||||
@@ -41,19 +41,7 @@
|
|||||||
"World": [6]
|
"World": [6]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "Mii-Channel-NUS"
|
"Archive Name": "Mii-Channel"
|
||||||
},
|
|
||||||
{
|
|
||||||
"Name": "Region Select",
|
|
||||||
"TID": "0007000848414CXX",
|
|
||||||
"Versions": {
|
|
||||||
"USA/NTSC": [2],
|
|
||||||
"Europe/PAL": [2],
|
|
||||||
"Japan": [2]
|
|
||||||
},
|
|
||||||
"Ticket": true,
|
|
||||||
"WAD Name": "Region-Select-NUS",
|
|
||||||
"Danger": "\"Region Select\" is a hidden channel used during the Wii's initial setup. If this title is damaged or missing, you will not be able to set up your Wii again after a factory reset. This title will need to be reinstalled to fix your console."
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "Shopping Channel",
|
"Name": "Shopping Channel",
|
||||||
@@ -62,7 +50,7 @@
|
|||||||
"World": [21]
|
"World": [21]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "Shopping-Channel-NUS"
|
"Archive Name": "Shopping-Channel"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "Return to Wii U Menu",
|
"Name": "Return to Wii U Menu",
|
||||||
@@ -71,7 +59,7 @@
|
|||||||
"World": [0]
|
"World": [0]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "Return-to-Wii-U-Menu-NUS",
|
"Archive Name": "Return-to-Wii-U-Menu",
|
||||||
"Danger": "\"Return to Wii U Menu\" is the channel launched from the vWii menu to reboot your console back into Wii U mode. While it generally should not be modified, modifying or removing it will not prevent the vWii from working."
|
"Danger": "\"Return to Wii U Menu\" is the channel launched from the vWii menu to reboot your console back into Wii U mode. While it generally should not be modified, modifying or removing it will not prevent the vWii from working."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -83,7 +71,21 @@
|
|||||||
"Japan": [0, 1, 2, 3, 5]
|
"Japan": [0, 1, 2, 3, 5]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "Wii-Electronic-Manual-NUS"
|
"Archive Name": "Wii-Electronic-Manual"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Hidden Channels": [
|
||||||
|
{
|
||||||
|
"Name": "Region Select",
|
||||||
|
"TID": "0007000848414CXX",
|
||||||
|
"Versions": {
|
||||||
|
"USA/NTSC": [2],
|
||||||
|
"Europe/PAL": [2],
|
||||||
|
"Japan": [2]
|
||||||
|
},
|
||||||
|
"Ticket": true,
|
||||||
|
"Archive Name": "Region-Select",
|
||||||
|
"Danger": "\"Region Select\" is a hidden channel used during the Wii's initial setup. If this title is damaged or missing, you will not be able to set up your Wii again after a factory reset."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "Wii System Transfer (WagonCompat)",
|
"Name": "Wii System Transfer (WagonCompat)",
|
||||||
@@ -94,7 +96,7 @@
|
|||||||
"Japan": [29, 31]
|
"Japan": [29, 31]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "Wii-System-Transfer-WC-NUS",
|
"Archive Name": "Wii-System-Transfer-WC",
|
||||||
"Danger": "Note: It is currently unknown how this channel works, but it is involved somehow in the Wii to vWii transfer process. It is recommended to not modify it. Also note that this is separate from the normal, non-hidden channel \"Wii System Transfer Tool\" that works alongside \"Wii U Transfer Tool\" on a source Wii."
|
"Danger": "Note: It is currently unknown how this channel works, but it is involved somehow in the Wii to vWii transfer process. It is recommended to not modify it. Also note that this is separate from the normal, non-hidden channel \"Wii System Transfer Tool\" that works alongside \"Wii U Transfer Tool\" on a source Wii."
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -108,7 +110,7 @@
|
|||||||
"Japan": [516]
|
"Japan": [516]
|
||||||
},
|
},
|
||||||
"Ticket": false,
|
"Ticket": false,
|
||||||
"WAD Name": "Wii-System-Transfer-Tool-WNP-NUS"
|
"Archive Name": "Wii-System-Transfer-Tool-WNP"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"IOS": [
|
"IOS": [
|
||||||
@@ -119,7 +121,7 @@
|
|||||||
"World": [1290]
|
"World": [1290]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS9-64-vWii"
|
"Archive Name": "IOS9"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 12",
|
"Name": "IOS 12",
|
||||||
@@ -128,7 +130,7 @@
|
|||||||
"World": [782]
|
"World": [782]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS12-64-vWii"
|
"Archive Name": "IOS12"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 13",
|
"Name": "IOS 13",
|
||||||
@@ -137,7 +139,7 @@
|
|||||||
"World": [1288]
|
"World": [1288]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS13-64-vWii"
|
"Archive Name": "IOS13"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 14",
|
"Name": "IOS 14",
|
||||||
@@ -146,7 +148,7 @@
|
|||||||
"World": [1288]
|
"World": [1288]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS14-64-vWii"
|
"Archive Name": "IOS14"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 15",
|
"Name": "IOS 15",
|
||||||
@@ -155,7 +157,7 @@
|
|||||||
"World": [1288]
|
"World": [1288]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS15-64-vWii"
|
"Archive Name": "IOS15"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 17",
|
"Name": "IOS 17",
|
||||||
@@ -164,7 +166,7 @@
|
|||||||
"World": [1288]
|
"World": [1288]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS17-64-vWii"
|
"Archive Name": "IOS17"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 21",
|
"Name": "IOS 21",
|
||||||
@@ -173,7 +175,7 @@
|
|||||||
"World": [1295]
|
"World": [1295]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS21-64-vWii"
|
"Archive Name": "IOS21"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 22",
|
"Name": "IOS 22",
|
||||||
@@ -182,7 +184,7 @@
|
|||||||
"World": [1550]
|
"World": [1550]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS22-64-vWii"
|
"Archive Name": "IOS22"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 28",
|
"Name": "IOS 28",
|
||||||
@@ -191,7 +193,7 @@
|
|||||||
"World": [2063]
|
"World": [2063]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS28-64-vWii"
|
"Archive Name": "IOS28"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 31",
|
"Name": "IOS 31",
|
||||||
@@ -200,7 +202,7 @@
|
|||||||
"World": [3864]
|
"World": [3864]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS31-64-vWii"
|
"Archive Name": "IOS31"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 33",
|
"Name": "IOS 33",
|
||||||
@@ -209,7 +211,7 @@
|
|||||||
"World": [3864]
|
"World": [3864]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS33-64-vWii"
|
"Archive Name": "IOS33"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 34",
|
"Name": "IOS 34",
|
||||||
@@ -218,7 +220,7 @@
|
|||||||
"World": [3864]
|
"World": [3864]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS34-64-vWii"
|
"Archive Name": "IOS34"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 35",
|
"Name": "IOS 35",
|
||||||
@@ -227,7 +229,7 @@
|
|||||||
"World": [3864]
|
"World": [3864]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS35-64-vWii"
|
"Archive Name": "IOS35"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 36",
|
"Name": "IOS 36",
|
||||||
@@ -236,7 +238,7 @@
|
|||||||
"World": [3864]
|
"World": [3864]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS36-64-vWii"
|
"Archive Name": "IOS36"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 37",
|
"Name": "IOS 37",
|
||||||
@@ -245,7 +247,7 @@
|
|||||||
"World": [5919]
|
"World": [5919]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS37-64-vWii"
|
"Archive Name": "IOS37"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 38",
|
"Name": "IOS 38",
|
||||||
@@ -254,7 +256,7 @@
|
|||||||
"World": [4380]
|
"World": [4380]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS38-64-vWii"
|
"Archive Name": "IOS38"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 41",
|
"Name": "IOS 41",
|
||||||
@@ -263,7 +265,7 @@
|
|||||||
"World": [3863]
|
"World": [3863]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS41-64-vWii"
|
"Archive Name": "IOS41"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 43",
|
"Name": "IOS 43",
|
||||||
@@ -272,7 +274,7 @@
|
|||||||
"World": [3863]
|
"World": [3863]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS43-64-vWii"
|
"Archive Name": "IOS43"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 45",
|
"Name": "IOS 45",
|
||||||
@@ -281,7 +283,7 @@
|
|||||||
"World": [3863]
|
"World": [3863]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS45-64-vWii"
|
"Archive Name": "IOS45"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 46",
|
"Name": "IOS 46",
|
||||||
@@ -290,7 +292,7 @@
|
|||||||
"World": [3863]
|
"World": [3863]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS46-64-vWii"
|
"Archive Name": "IOS46"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 48",
|
"Name": "IOS 48",
|
||||||
@@ -299,7 +301,7 @@
|
|||||||
"World": [4380]
|
"World": [4380]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS48-64-vWii"
|
"Archive Name": "IOS48"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 53",
|
"Name": "IOS 53",
|
||||||
@@ -308,7 +310,7 @@
|
|||||||
"World": [5919]
|
"World": [5919]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS53-64-vWii"
|
"Archive Name": "IOS53"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 55",
|
"Name": "IOS 55",
|
||||||
@@ -317,7 +319,7 @@
|
|||||||
"World": [5919]
|
"World": [5919]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS55-64-vWii"
|
"Archive Name": "IOS55"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 56",
|
"Name": "IOS 56",
|
||||||
@@ -326,7 +328,7 @@
|
|||||||
"World": [5918]
|
"World": [5918]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS56-64-vWii"
|
"Archive Name": "IOS56"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 57",
|
"Name": "IOS 57",
|
||||||
@@ -335,7 +337,7 @@
|
|||||||
"World": [6175]
|
"World": [6175]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS57-64-vWii"
|
"Archive Name": "IOS57"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 58",
|
"Name": "IOS 58",
|
||||||
@@ -344,7 +346,7 @@
|
|||||||
"World": [6432]
|
"World": [6432]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS58-64-vWii"
|
"Archive Name": "IOS58"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 59",
|
"Name": "IOS 59",
|
||||||
@@ -353,7 +355,7 @@
|
|||||||
"World": [7201, 8737, 9249]
|
"World": [7201, 8737, 9249]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS59-64-vWii"
|
"Archive Name": "IOS59"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 62",
|
"Name": "IOS 62",
|
||||||
@@ -362,7 +364,7 @@
|
|||||||
"World": [6430, 6686, 6942]
|
"World": [6430, 6686, 6942]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS62-64-vWii"
|
"Archive Name": "IOS62"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 80",
|
"Name": "IOS 80",
|
||||||
@@ -371,7 +373,7 @@
|
|||||||
"World": [7200]
|
"World": [7200]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS80-64-vWii"
|
"Archive Name": "IOS80"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
"World": [2, 4, 5, 6]
|
"World": [2, 4, 5, 6]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "BC-NUS",
|
"Archive Name": "BC",
|
||||||
"Danger": "BC is required for the Wii's backwards compatibility with the GameCube. GameCube games will not run properly if BC is damaged or missing."
|
"Danger": "BC is required for the Wii's backwards compatibility with the GameCube. GameCube games will not run properly if BC is damaged or missing."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -17,22 +17,9 @@
|
|||||||
"World": [4]
|
"World": [4]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "boot2-NUS",
|
"Archive Name": "boot2",
|
||||||
"Danger": "boot2 is a critical part of the Wii's boot process, and should not be modified. Most updated Wiis will already be running boot2v4, which is the only version of boot2 available on the NUS."
|
"Danger": "boot2 is a critical part of the Wii's boot process, and should not be modified. Most updated Wiis will already be running boot2v4, which is the only version of boot2 available on the NUS."
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"Name": "EULA",
|
|
||||||
"TID": "0001000848414BXX",
|
|
||||||
"Versions": {
|
|
||||||
"USA/NTSC": [1, 2, 3],
|
|
||||||
"Europe/PAL": [1, 2, 3],
|
|
||||||
"Japan": [1, 2, 3],
|
|
||||||
"Korea": [1, 2, 3]
|
|
||||||
},
|
|
||||||
"Ticket": true,
|
|
||||||
"WAD Name": "EULA-NUS",
|
|
||||||
"Danger": "\"EULA\" is a hidden channel used to display the End User License Agreement that must be accepted to connect to WiiConnect24. Online services may not work correctly if this channel is damaged or missing."
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"Name": "MIOS",
|
"Name": "MIOS",
|
||||||
"TID": "0000000100000101",
|
"TID": "0000000100000101",
|
||||||
@@ -40,22 +27,9 @@
|
|||||||
"World": [4, 5, 8, 9, 10]
|
"World": [4, 5, 8, 9, 10]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "MIOS-NUS",
|
"Archive Name": "MIOS",
|
||||||
"Danger": "MIOS is required for the Wii's backwards compatibility with the GameCube. GameCube games will not run properly if MIOS is damaged or missing."
|
"Danger": "MIOS is required for the Wii's backwards compatibility with the GameCube. GameCube games will not run properly if MIOS is damaged or missing."
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"Name": "Region Select",
|
|
||||||
"TID": "0001000848414CXX",
|
|
||||||
"Versions": {
|
|
||||||
"USA/NTSC": [1, 2],
|
|
||||||
"Europe/PAL": [1, 2],
|
|
||||||
"Japan": [1, 2],
|
|
||||||
"Korea": [2]
|
|
||||||
},
|
|
||||||
"Ticket": true,
|
|
||||||
"WAD Name": "Region-Select-NUS",
|
|
||||||
"Danger": "\"Region Select\" is a hidden channel used during the Wii's initial setup. If this title is damaged or missing, you will not be able to set up your Wii again after a factory reset. This title will need to be reinstalled to fix your console."
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"Name": "System Menu",
|
"Name": "System Menu",
|
||||||
"TID": "0000000100000002",
|
"TID": "0000000100000002",
|
||||||
@@ -66,7 +40,7 @@
|
|||||||
"Korea": [390, 454, 486, 518]
|
"Korea": [390, 454, 486, 518]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "Wii-System-Menu",
|
"Archive Name": "System-Menu",
|
||||||
"Danger": "The System Menu is a critical part of the Wii's operation, and should not be modified without proper brick prevention in place. You should have BootMii installed as boot2 if possible, and if not, Priiloader installed before making changes to the System Menu."
|
"Danger": "The System Menu is a critical part of the Wii's operation, and should not be modified without proper brick prevention in place. You should have BootMii installed as boot2 if possible, and if not, Priiloader installed before making changes to the System Menu."
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -81,7 +55,7 @@
|
|||||||
"Japan": [6, 7]
|
"Japan": [6, 7]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "Forecast-Channel-NUS"
|
"Archive Name": "Forecast-Channel"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "Mii Channel",
|
"Name": "Mii Channel",
|
||||||
@@ -90,7 +64,7 @@
|
|||||||
"World": [2, 3, 4, 5, 6]
|
"World": [2, 3, 4, 5, 6]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "Mii-Channel-NUS"
|
"Archive Name": "Mii-Channel"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "News Channel",
|
"Name": "News Channel",
|
||||||
@@ -102,7 +76,7 @@
|
|||||||
"Japan": [6, 7]
|
"Japan": [6, 7]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "News-Channel-NUS"
|
"Archive Name": "News-Channel"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "Photo Channel",
|
"Name": "Photo Channel",
|
||||||
@@ -111,7 +85,7 @@
|
|||||||
"World": [1, 2]
|
"World": [1, 2]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "Photo-Channel-NUS"
|
"Archive Name": "Photo-Channel"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "Photo Channel 1.1",
|
"Name": "Photo Channel 1.1",
|
||||||
@@ -121,7 +95,7 @@
|
|||||||
"Korea": [3]
|
"Korea": [3]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "Photo-Channel-1.1-NUS"
|
"Archive Name": "Photo-Channel-1.1"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "Shopping Channel",
|
"Name": "Shopping Channel",
|
||||||
@@ -131,7 +105,44 @@
|
|||||||
"Korea": [3, 4, 5, 6, 7, 8, 10, 13, 14, 16, 17, 18, 19, 20, 21]
|
"Korea": [3, 4, 5, 6, 7, 8, 10, 13, 14, 16, 17, 18, 19, 20, 21]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "Shopping-Channel-NUS"
|
"Archive Name": "Shopping-Channel"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Hidden Channels": [
|
||||||
|
{
|
||||||
|
"Name": "EULA",
|
||||||
|
"TID": "0001000848414BXX",
|
||||||
|
"Versions": {
|
||||||
|
"USA/NTSC": [1, 2, 3],
|
||||||
|
"Europe/PAL": [1, 2, 3],
|
||||||
|
"Japan": [1, 2, 3],
|
||||||
|
"Korea": [1, 2, 3]
|
||||||
|
},
|
||||||
|
"Ticket": true,
|
||||||
|
"Archive Name": "EULA",
|
||||||
|
"Danger": "\"EULA\" is a hidden channel used to display the End User License Agreement that must be accepted to connect to WiiConnect24. Online services may not work correctly if this channel is damaged or missing."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Region Select",
|
||||||
|
"TID": "0001000848414CXX",
|
||||||
|
"Versions": {
|
||||||
|
"USA/NTSC": [1, 2],
|
||||||
|
"Europe/PAL": [1, 2],
|
||||||
|
"Japan": [1, 2],
|
||||||
|
"Korea": [2]
|
||||||
|
},
|
||||||
|
"Ticket": true,
|
||||||
|
"Archive Name": "Region-Select",
|
||||||
|
"Danger": "\"Region Select\" is a hidden channel used during the Wii's initial setup. If this title is damaged or missing, you will not be able to set up your Wii again after a factory reset. This title will need to be reinstalled to fix your console."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Set Personal Data Channel",
|
||||||
|
"TID": "00010008484343XX",
|
||||||
|
"Versions": {
|
||||||
|
"Japan": [0, 1, 2]
|
||||||
|
},
|
||||||
|
"Ticket": true,
|
||||||
|
"Archive Name": "Set-Personal-Data-Channel"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"Downloadable Channels": [
|
"Downloadable Channels": [
|
||||||
@@ -142,7 +153,7 @@
|
|||||||
"USA/NTSC": [1280]
|
"USA/NTSC": [1280]
|
||||||
},
|
},
|
||||||
"Ticket": false,
|
"Ticket": false,
|
||||||
"WAD Name": "Amazon-Instant-Video-NUS"
|
"Archive Name": "Amazon-Instant-Video"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "BBC iPlayer Channel",
|
"Name": "BBC iPlayer Channel",
|
||||||
@@ -151,7 +162,7 @@
|
|||||||
"Europe/PAL": [768]
|
"Europe/PAL": [768]
|
||||||
},
|
},
|
||||||
"Ticket": false,
|
"Ticket": false,
|
||||||
"WAD Name": "BBC-iPlayer-Channel-NUS"
|
"Archive Name": "BBC-iPlayer-Channel"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "Check Mii Out Channel",
|
"Name": "Check Mii Out Channel",
|
||||||
@@ -162,16 +173,16 @@
|
|||||||
"Japan": [1, 3, 512]
|
"Japan": [1, 3, 512]
|
||||||
},
|
},
|
||||||
"Ticket": false,
|
"Ticket": false,
|
||||||
"WAD Name": "Check-Mii-Out-Channel-NUS"
|
"Archive Name": "Check-Mii-Out-Channel"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "Demae Channel",
|
"Name": "Demae Channel",
|
||||||
"TID": "00010008484343XX",
|
"TID": "00010001484348XX",
|
||||||
"Versions": {
|
"Versions": {
|
||||||
"Japan": [0, 1, 2]
|
"Japan": [512]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "Demae-Channel-NUS"
|
"Archive Name": "Demae-Channel"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "Digicam Print Channel",
|
"Name": "Digicam Print Channel",
|
||||||
@@ -180,7 +191,7 @@
|
|||||||
"Japan": [1024]
|
"Japan": [1024]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "Digicam-Print-Channel-NUS"
|
"Archive Name": "Digicam-Print-Channel"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "Everyone Votes Channel",
|
"Name": "Everyone Votes Channel",
|
||||||
@@ -191,7 +202,7 @@
|
|||||||
"Japan": [1, 2, 3]
|
"Japan": [1, 2, 3]
|
||||||
},
|
},
|
||||||
"Ticket": false,
|
"Ticket": false,
|
||||||
"WAD Name": "Everyone-Votes-Channel-NUS"
|
"Archive Name": "Everyone-Votes-Channel"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "Hulu Plus",
|
"Name": "Hulu Plus",
|
||||||
@@ -201,7 +212,7 @@
|
|||||||
"Japan": [1024]
|
"Japan": [1024]
|
||||||
},
|
},
|
||||||
"Ticket": false,
|
"Ticket": false,
|
||||||
"WAD Name": "Hulu-Plus-NUS"
|
"Archive Name": "Hulu-Plus"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "Internet Channel",
|
"Name": "Internet Channel",
|
||||||
@@ -212,7 +223,7 @@
|
|||||||
"Japan": [1, 3, 257, 512, 1024]
|
"Japan": [1, 3, 257, 512, 1024]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "Internet-Channel-NUS"
|
"Archive Name": "Internet-Channel"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "Jam With The Band Live Channel",
|
"Name": "Jam With The Band Live Channel",
|
||||||
@@ -222,7 +233,7 @@
|
|||||||
"Japan": [2]
|
"Japan": [2]
|
||||||
},
|
},
|
||||||
"Ticket": false,
|
"Ticket": false,
|
||||||
"WAD Name": "Jam-With-The-Band-Live-Channel-NUS"
|
"Archive Name": "Jam-With-The-Band-Live-Channel"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "Kirby TV Channel",
|
"Name": "Kirby TV Channel",
|
||||||
@@ -231,7 +242,7 @@
|
|||||||
"Europe/PAL": [257]
|
"Europe/PAL": [257]
|
||||||
},
|
},
|
||||||
"Ticket": false,
|
"Ticket": false,
|
||||||
"WAD Name": "Kirby-TV-Channel-NUS"
|
"Archive Name": "Kirby-TV-Channel"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "Metroid Prime 3 Preview",
|
"Name": "Metroid Prime 3 Preview",
|
||||||
@@ -241,7 +252,7 @@
|
|||||||
"Japan": [1, 2]
|
"Japan": [1, 2]
|
||||||
},
|
},
|
||||||
"Ticket": false,
|
"Ticket": false,
|
||||||
"WAD Name": "Metroid-Prime-3-Preview-NUS"
|
"Archive Name": "Metroid-Prime-3-Preview"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "Netflix Channel",
|
"Name": "Netflix Channel",
|
||||||
@@ -251,7 +262,7 @@
|
|||||||
"Europe/PAL": [2049]
|
"Europe/PAL": [2049]
|
||||||
},
|
},
|
||||||
"Ticket": false,
|
"Ticket": false,
|
||||||
"WAD Name": "Netflix-Channel-NUS"
|
"Archive Name": "Netflix-Channel"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "Nintendo Channel",
|
"Name": "Nintendo Channel",
|
||||||
@@ -262,7 +273,7 @@
|
|||||||
"Japan": [1792]
|
"Japan": [1792]
|
||||||
},
|
},
|
||||||
"Ticket": false,
|
"Ticket": false,
|
||||||
"WAD Name": "Nintendo-Channel-NUS"
|
"Archive Name": "Nintendo-Channel"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "Photo Channel 1.0 Restore Program",
|
"Name": "Photo Channel 1.0 Restore Program",
|
||||||
@@ -271,7 +282,7 @@
|
|||||||
"Japan": [0]
|
"Japan": [0]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "Photo-Channel-1.0-Restore-Program-NUS"
|
"Archive Name": "Photo-Channel-1.0-Restore-Program"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "The Legend of Zelda: Skyward Sword Save Data Update Channel",
|
"Name": "The Legend of Zelda: Skyward Sword Save Data Update Channel",
|
||||||
@@ -282,7 +293,7 @@
|
|||||||
"Japan": [1]
|
"Japan": [1]
|
||||||
},
|
},
|
||||||
"Ticket": false,
|
"Ticket": false,
|
||||||
"WAD Name": "Skyward-Sword-Save-Data-Update-Channel-NUS"
|
"Archive Name": "Skyward-Sword-Save-Data-Update-Channel"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "Today and Tomorrow Channel",
|
"Name": "Today and Tomorrow Channel",
|
||||||
@@ -291,8 +302,8 @@
|
|||||||
"Europe/PAL": [1],
|
"Europe/PAL": [1],
|
||||||
"Japan": [1]
|
"Japan": [1]
|
||||||
},
|
},
|
||||||
"Ticket": false,
|
"Ticket": true,
|
||||||
"WAD Name": "Today-and-Tomorrow-Channel-NUS"
|
"Archive Name": "Today-and-Tomorrow-Channel"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "TV Friend Channel / G-Guide for Wii",
|
"Name": "TV Friend Channel / G-Guide for Wii",
|
||||||
@@ -301,7 +312,7 @@
|
|||||||
"Japan": [1]
|
"Japan": [1]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "TV-Friend-Channel-NUS"
|
"Archive Name": "TV-Friend-Channel"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "USB Memory Repair Program",
|
"Name": "USB Memory Repair Program",
|
||||||
@@ -310,7 +321,7 @@
|
|||||||
"Japan": [12]
|
"Japan": [12]
|
||||||
},
|
},
|
||||||
"Ticket": false,
|
"Ticket": false,
|
||||||
"WAD Name": "USB-Repair-Program-NUS"
|
"Archive Name": "USB-Repair-Program"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "Wii no Ma Channel",
|
"Name": "Wii no Ma Channel",
|
||||||
@@ -319,7 +330,7 @@
|
|||||||
"Japan": [0]
|
"Japan": [0]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "Wii-no-Ma-Channel-NUS"
|
"Archive Name": "Wii-no-Ma-Channel"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "Wii Speak Channel",
|
"Name": "Wii Speak Channel",
|
||||||
@@ -327,10 +338,11 @@
|
|||||||
"Versions": {
|
"Versions": {
|
||||||
"USA/NTSC": [1, 256, 512],
|
"USA/NTSC": [1, 256, 512],
|
||||||
"Europe/PAL": [1, 256, 512],
|
"Europe/PAL": [1, 256, 512],
|
||||||
"Japan": [1, 256, 512]
|
"Japan": [1, 256, 512],
|
||||||
|
"Korea": [512]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "Wii-Speak-Channel-NUS"
|
"Archive Name": "Wii-Speak-Channel"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "Wii U Transfer Tool",
|
"Name": "Wii U Transfer Tool",
|
||||||
@@ -341,7 +353,7 @@
|
|||||||
"Japan": [516]
|
"Japan": [516]
|
||||||
},
|
},
|
||||||
"Ticket": false,
|
"Ticket": false,
|
||||||
"WAD Name": "Wii-U-Transfer-Tool-NUS"
|
"Archive Name": "Wii-U-Transfer-Tool"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "YouTube",
|
"Name": "YouTube",
|
||||||
@@ -351,7 +363,7 @@
|
|||||||
"Japan": [768]
|
"Japan": [768]
|
||||||
},
|
},
|
||||||
"Ticket": false,
|
"Ticket": false,
|
||||||
"WAD Name": "YouTube-NUS"
|
"Archive Name": "YouTube"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"IOS": [
|
"IOS": [
|
||||||
@@ -362,7 +374,7 @@
|
|||||||
"World": [65280]
|
"World": [65280]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS4-64",
|
"Archive Name": "IOS4",
|
||||||
"Danger": "This IOS is a stub, and no longer offers any functionality. It cannot be used to run any code."
|
"Danger": "This IOS is a stub, and no longer offers any functionality. It cannot be used to run any code."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -372,7 +384,7 @@
|
|||||||
"World": [520, 521, 778, 1034]
|
"World": [520, 521, 778, 1034]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS9-64"
|
"Archive Name": "IOS9"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 10",
|
"Name": "IOS 10",
|
||||||
@@ -381,7 +393,7 @@
|
|||||||
"World": [768]
|
"World": [768]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS10-64"
|
"Archive Name": "IOS10"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 11",
|
"Name": "IOS 11",
|
||||||
@@ -390,7 +402,7 @@
|
|||||||
"World": [10, 256]
|
"World": [10, 256]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS11-64",
|
"Archive Name": "IOS11",
|
||||||
"Danger": "Version 256 of IOS 11 is a stub, and no longer offers any functionality. It cannot be used to run any code. If you're using System Menu 2.0-2.1, DO NOT install version 256, as the System Menu relies on IOS 11."
|
"Danger": "Version 256 of IOS 11 is a stub, and no longer offers any functionality. It cannot be used to run any code. If you're using System Menu 2.0-2.1, DO NOT install version 256, as the System Menu relies on IOS 11."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -400,7 +412,7 @@
|
|||||||
"World": [6, 11, 12, 269, 525, 526]
|
"World": [6, 11, 12, 269, 525, 526]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS12-64"
|
"Archive Name": "IOS12"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 13",
|
"Name": "IOS 13",
|
||||||
@@ -409,7 +421,7 @@
|
|||||||
"World": [10, 15, 16, 273, 1031, 1032]
|
"World": [10, 15, 16, 273, 1031, 1032]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS13-64"
|
"Archive Name": "IOS13"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 14",
|
"Name": "IOS 14",
|
||||||
@@ -418,7 +430,7 @@
|
|||||||
"World": [262, 263, 520, 1031, 1032]
|
"World": [262, 263, 520, 1031, 1032]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS14-64"
|
"Archive Name": "IOS14"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 15",
|
"Name": "IOS 15",
|
||||||
@@ -427,7 +439,7 @@
|
|||||||
"World": [257, 258, 259, 260, 265, 266, 523, 1031, 1032]
|
"World": [257, 258, 259, 260, 265, 266, 523, 1031, 1032]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS15-64"
|
"Archive Name": "IOS15"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 16",
|
"Name": "IOS 16",
|
||||||
@@ -436,7 +448,7 @@
|
|||||||
"World": [512]
|
"World": [512]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS16-64",
|
"Archive Name": "IOS16",
|
||||||
"Danger": "This IOS is a stub, and no longer offers any functionality. It cannot be used to run any code."
|
"Danger": "This IOS is a stub, and no longer offers any functionality. It cannot be used to run any code."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -446,7 +458,7 @@
|
|||||||
"World": [512, 517, 518, 775, 1031, 1032]
|
"World": [512, 517, 518, 775, 1031, 1032]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS17-64"
|
"Archive Name": "IOS17"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 20",
|
"Name": "IOS 20",
|
||||||
@@ -455,7 +467,7 @@
|
|||||||
"World": [12, 256]
|
"World": [12, 256]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS20-64",
|
"Archive Name": "IOS20",
|
||||||
"Danger": "Version 256 of IOS 20 is a stub, and no longer offers any functionality. It cannot be used to run any code. If you're using System Menu 2.2, DO NOT install version 256, as the System Menu relies on IOS 20."
|
"Danger": "Version 256 of IOS 20 is a stub, and no longer offers any functionality. It cannot be used to run any code. If you're using System Menu 2.2, DO NOT install version 256, as the System Menu relies on IOS 20."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -465,7 +477,7 @@
|
|||||||
"World": [514, 515, 516, 517, 522, 525, 782, 1038, 1039]
|
"World": [514, 515, 516, 517, 522, 525, 782, 1038, 1039]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS21-64"
|
"Archive Name": "IOS21"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 22",
|
"Name": "IOS 22",
|
||||||
@@ -474,7 +486,7 @@
|
|||||||
"World": [777, 780, 1037, 1293, 1294]
|
"World": [777, 780, 1037, 1293, 1294]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS22-64"
|
"Archive Name": "IOS22"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 28",
|
"Name": "IOS 28",
|
||||||
@@ -483,7 +495,7 @@
|
|||||||
"World": [1292, 1293, 1550, 1806, 1807]
|
"World": [1292, 1293, 1550, 1806, 1807]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS28-64"
|
"Archive Name": "IOS28"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 30",
|
"Name": "IOS 30",
|
||||||
@@ -492,7 +504,7 @@
|
|||||||
"World": [1037, 1039, 1040, 2576, 2816]
|
"World": [1037, 1039, 1040, 2576, 2816]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS30-64",
|
"Archive Name": "IOS30",
|
||||||
"Danger": "Version 2816 of IOS 30 is a stub, and no longer offers any functionality. It cannot be used to run any code. If you're using System Menu 3.0-3.3, DO NOT install version 2816, as the System Menu relies on IOS 30."
|
"Danger": "Version 2816 of IOS 30 is a stub, and no longer offers any functionality. It cannot be used to run any code. If you're using System Menu 3.0-3.3, DO NOT install version 2816, as the System Menu relies on IOS 30."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -502,7 +514,7 @@
|
|||||||
"World": [1037, 1039, 1040, 2576, 3088, 3092, 3349, 3607, 3608]
|
"World": [1037, 1039, 1040, 2576, 3088, 3092, 3349, 3607, 3608]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS31-64"
|
"Archive Name": "IOS31"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 33",
|
"Name": "IOS 33",
|
||||||
@@ -511,7 +523,7 @@
|
|||||||
"World": [1040, 2832, 2834, 3091, 3607, 3608]
|
"World": [1040, 2832, 2834, 3091, 3607, 3608]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS33-64"
|
"Archive Name": "IOS33"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 34",
|
"Name": "IOS 34",
|
||||||
@@ -520,7 +532,7 @@
|
|||||||
"World": [1039, 3087, 3091, 3348, 3607, 3608]
|
"World": [1039, 3087, 3091, 3348, 3607, 3608]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS34-64"
|
"Archive Name": "IOS34"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 35",
|
"Name": "IOS 35",
|
||||||
@@ -529,7 +541,7 @@
|
|||||||
"World": [1040, 3088, 3092, 3349, 3607, 3608]
|
"World": [1040, 3088, 3092, 3349, 3607, 3608]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS35-64"
|
"Archive Name": "IOS35"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 36",
|
"Name": "IOS 36",
|
||||||
@@ -538,7 +550,7 @@
|
|||||||
"World": [1042, 3090, 3094, 3351, 3607, 3608]
|
"World": [1042, 3090, 3094, 3351, 3607, 3608]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS36-64"
|
"Archive Name": "IOS36"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 37",
|
"Name": "IOS 37",
|
||||||
@@ -547,7 +559,7 @@
|
|||||||
"World": [2070, 3609, 3612, 3869, 5662, 5663]
|
"World": [2070, 3609, 3612, 3869, 5662, 5663]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS37-64"
|
"Archive Name": "IOS37"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 38",
|
"Name": "IOS 38",
|
||||||
@@ -556,7 +568,7 @@
|
|||||||
"World": [3610, 3867, 4123, 4124]
|
"World": [3610, 3867, 4123, 4124]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS38-64"
|
"Archive Name": "IOS38"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 40",
|
"Name": "IOS 40",
|
||||||
@@ -565,7 +577,7 @@
|
|||||||
"World": [3072]
|
"World": [3072]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS40-64",
|
"Archive Name": "IOS40",
|
||||||
"Danger": "Version 3072 of IOS 40 is a stub, and no longer offers any functionality. It cannot be used to run any code. If you're using System Menu 3.3K, DO NOT install version 3072, as the System Menu relies on IOS 40."
|
"Danger": "Version 3072 of IOS 40 is a stub, and no longer offers any functionality. It cannot be used to run any code. If you're using System Menu 3.3K, DO NOT install version 3072, as the System Menu relies on IOS 40."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -575,7 +587,7 @@
|
|||||||
"World": [2835, 3091, 3348, 3606, 3607]
|
"World": [2835, 3091, 3348, 3606, 3607]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS41-64"
|
"Archive Name": "IOS41"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 43",
|
"Name": "IOS 43",
|
||||||
@@ -584,7 +596,7 @@
|
|||||||
"World": [2835, 3091, 3348, 3606, 3607]
|
"World": [2835, 3091, 3348, 3606, 3607]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS43-64"
|
"Archive Name": "IOS43"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 45",
|
"Name": "IOS 45",
|
||||||
@@ -593,7 +605,7 @@
|
|||||||
"World": [2835, 3091, 3348, 3606, 3607]
|
"World": [2835, 3091, 3348, 3606, 3607]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS45-64"
|
"Archive Name": "IOS45"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 46",
|
"Name": "IOS 46",
|
||||||
@@ -602,7 +614,7 @@
|
|||||||
"World": [2837, 3093, 3350, 3606, 3607]
|
"World": [2837, 3093, 3350, 3606, 3607]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS46-64"
|
"Archive Name": "IOS46"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 48",
|
"Name": "IOS 48",
|
||||||
@@ -611,7 +623,7 @@
|
|||||||
"World": [4123, 4124]
|
"World": [4123, 4124]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS48-64"
|
"Archive Name": "IOS48"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 50",
|
"Name": "IOS 50",
|
||||||
@@ -620,7 +632,7 @@
|
|||||||
"World": [4889, 5120]
|
"World": [4889, 5120]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS50-64",
|
"Archive Name": "IOS50",
|
||||||
"Danger": "Version 5120 of IOS 50 is a stub, and no longer offers any functionality. It cannot be used to run any code. If you're using System Menu 3.3K, DO NOT install version 5120, as the System Menu relies on IOS 50."
|
"Danger": "Version 5120 of IOS 50 is a stub, and no longer offers any functionality. It cannot be used to run any code. If you're using System Menu 3.3K, DO NOT install version 5120, as the System Menu relies on IOS 50."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -630,7 +642,7 @@
|
|||||||
"World": [4633, 4864]
|
"World": [4633, 4864]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS51-64",
|
"Archive Name": "IOS51",
|
||||||
"Danger": "Version 4864 of IOS 51 is a stub, and no longer offers any functionality. It cannot be used to run any code."
|
"Danger": "Version 4864 of IOS 51 is a stub, and no longer offers any functionality. It cannot be used to run any code."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -640,7 +652,7 @@
|
|||||||
"World": [5661, 5888]
|
"World": [5661, 5888]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS52-64",
|
"Archive Name": "IOS52",
|
||||||
"Danger": "Version 5888 of IOS 50 is a stub, and no longer offers any functionality. It cannot be used to run any code. If you're using System Menu 3.5, DO NOT install version 5888, as the System Menu relies on IOS 50."
|
"Danger": "Version 5888 of IOS 50 is a stub, and no longer offers any functionality. It cannot be used to run any code. If you're using System Menu 3.5, DO NOT install version 5888, as the System Menu relies on IOS 50."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -650,7 +662,7 @@
|
|||||||
"World": [4113, 5149, 5406, 5662, 5663]
|
"World": [4113, 5149, 5406, 5662, 5663]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS53-64"
|
"Archive Name": "IOS53"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 55",
|
"Name": "IOS 55",
|
||||||
@@ -659,7 +671,7 @@
|
|||||||
"World": [4633, 5149, 5406, 5662, 5663]
|
"World": [4633, 5149, 5406, 5662, 5663]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS55-64"
|
"Archive Name": "IOS55"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 56",
|
"Name": "IOS 56",
|
||||||
@@ -668,7 +680,7 @@
|
|||||||
"World": [4890, 5405, 5661, 5662]
|
"World": [4890, 5405, 5661, 5662]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS56-64"
|
"Archive Name": "IOS56"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 57",
|
"Name": "IOS 57",
|
||||||
@@ -677,7 +689,7 @@
|
|||||||
"World": [5404, 5661, 5918, 5919]
|
"World": [5404, 5661, 5918, 5919]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS57-64"
|
"Archive Name": "IOS57"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 58",
|
"Name": "IOS 58",
|
||||||
@@ -686,7 +698,7 @@
|
|||||||
"World": [6175, 6176]
|
"World": [6175, 6176]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS58-64"
|
"Archive Name": "IOS58"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 59",
|
"Name": "IOS 59",
|
||||||
@@ -695,7 +707,7 @@
|
|||||||
"World": [8737, 9249]
|
"World": [8737, 9249]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS59-64"
|
"Archive Name": "IOS59"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 60",
|
"Name": "IOS 60",
|
||||||
@@ -704,7 +716,7 @@
|
|||||||
"World": [6174, 6400]
|
"World": [6174, 6400]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS60-64",
|
"Archive Name": "IOS60",
|
||||||
"Danger": "Version 6400 of IOS 60 is a stub, and no longer offers any functionality. It cannot be used to run any code. If you're using System Menu 4.0 or 4.1, DO NOT install version 6400, as the System Menu relies on IOS 60."
|
"Danger": "Version 6400 of IOS 60 is a stub, and no longer offers any functionality. It cannot be used to run any code. If you're using System Menu 4.0 or 4.1, DO NOT install version 6400, as the System Menu relies on IOS 60."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -714,7 +726,7 @@
|
|||||||
"World": [4890, 5405, 5661, 5662]
|
"World": [4890, 5405, 5661, 5662]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS61-64"
|
"Archive Name": "IOS61"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 62",
|
"Name": "IOS 62",
|
||||||
@@ -723,7 +735,7 @@
|
|||||||
"World": [6430]
|
"World": [6430]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS62-64"
|
"Archive Name": "IOS62"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 70",
|
"Name": "IOS 70",
|
||||||
@@ -732,8 +744,8 @@
|
|||||||
"World": [6687,6912]
|
"World": [6687,6912]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS70-64",
|
"Archive Name": "IOS70",
|
||||||
"Danger": "Version 6912 of IOS 60 is a stub, and no longer offers any functionality. It cannot be used to run any code. If you're using System Menu 4.2, DO NOT install version 6912, as the System Menu relies on IOS 70."
|
"Danger": "Version 6912 of IOS 70 is a stub, and no longer offers any functionality. It cannot be used to run any code. If you're using System Menu 4.2, DO NOT install version 6912, as the System Menu relies on IOS 70."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 80",
|
"Name": "IOS 80",
|
||||||
@@ -742,8 +754,8 @@
|
|||||||
"World": [6943, 6944]
|
"World": [6943, 6944]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS80-64",
|
"Archive Name": "IOS80",
|
||||||
"Danger": "IOS 80 is the IOS that the current System Menu, 4.3, relies on, and is required to load the System Menu. Do not modify or remove this IOS unless you have BootMii installed as boot2 to recover from a brick."
|
"Danger": "IOS 80 is the IOS that the final System Menu, 4.3, relies on, and is required to load the System Menu. Do not modify or remove this IOS unless you have BootMii installed as boot2 to recover from a brick."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "IOS 222",
|
"Name": "IOS 222",
|
||||||
@@ -752,7 +764,7 @@
|
|||||||
"World": [65280]
|
"World": [65280]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS222-64",
|
"Archive Name": "IOS222",
|
||||||
"Danger": "This IOS is a stub, and offers no functionality. It cannot be used to run any code."
|
"Danger": "This IOS is a stub, and offers no functionality. It cannot be used to run any code."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -762,7 +774,7 @@
|
|||||||
"World": [65280]
|
"World": [65280]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS223-64",
|
"Archive Name": "IOS223",
|
||||||
"Danger": "This IOS is a stub, and offers no functionality. It cannot be used to run any code."
|
"Danger": "This IOS is a stub, and offers no functionality. It cannot be used to run any code."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -772,7 +784,7 @@
|
|||||||
"World": [65280]
|
"World": [65280]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS249-64",
|
"Archive Name": "IOS249",
|
||||||
"Danger": "This IOS is a stub, and offers no functionality. It cannot be used to run any code."
|
"Danger": "This IOS is a stub, and offers no functionality. It cannot be used to run any code."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -782,7 +794,7 @@
|
|||||||
"World": [65280]
|
"World": [65280]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS250-64",
|
"Archive Name": "IOS250",
|
||||||
"Danger": "This IOS is a stub, and offers no functionality. It cannot be used to run any code."
|
"Danger": "This IOS is a stub, and offers no functionality. It cannot be used to run any code."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -792,7 +804,7 @@
|
|||||||
"World": [2, 3, 260, 65280]
|
"World": [2, 3, 260, 65280]
|
||||||
},
|
},
|
||||||
"Ticket": true,
|
"Ticket": true,
|
||||||
"WAD Name": "IOS254-64",
|
"Archive Name": "IOS254",
|
||||||
"Danger": "This IOS is a stub, and offers no functionality. It cannot be used to run any code."
|
"Danger": "This IOS is a stub, and offers no functionality. It cannot be used to run any code."
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
37
modules/core.py
Normal file
37
modules/core.py
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
# "modules/core.py", licensed under the MIT license
|
||||||
|
# Copyright 2024 NinjaCheetah
|
||||||
|
|
||||||
|
import requests
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class SelectedTitle:
|
||||||
|
# Class to store all components of a selected title to make tracking it easier.
|
||||||
|
tid: str
|
||||||
|
name: str
|
||||||
|
archive_name: str
|
||||||
|
version: str
|
||||||
|
ticket: bool
|
||||||
|
region: str
|
||||||
|
category: str
|
||||||
|
console: str
|
||||||
|
danger: str
|
||||||
|
|
||||||
|
|
||||||
|
def check_nusget_updates(app, current_version: str, progress_callback=None) -> str | None:
|
||||||
|
# Simple function to make a request to the GitHub API and then check if the latest available version is newer.
|
||||||
|
gh_api_request = requests.get(url="https://api.github.com/repos/NinjaCheetah/NUSGet/releases/latest", stream=True)
|
||||||
|
if gh_api_request.status_code != 200:
|
||||||
|
progress_callback.emit(app.translate("MainWindow", "\n\nCould not check for updates."))
|
||||||
|
else:
|
||||||
|
api_response = gh_api_request.json()
|
||||||
|
new_version: str = api_response["tag_name"].replace('v', '')
|
||||||
|
new_version_split = new_version.split('.')
|
||||||
|
current_version_split = current_version.split('.')
|
||||||
|
for place in range(len(new_version_split)):
|
||||||
|
if new_version_split[place] > current_version_split[place]:
|
||||||
|
progress_callback.emit(app.translate("MainWindow", "\n\nThere's a newer version of NUSGet available!"))
|
||||||
|
return new_version
|
||||||
|
progress_callback.emit(app.translate("MainWindow", "\n\nYou're running the latest release of NUSGet."))
|
||||||
|
return None
|
||||||
145
modules/download_dsi.py
Normal file
145
modules/download_dsi.py
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
# "modules/download_dsi.py", licensed under the MIT license
|
||||||
|
# Copyright 2024 NinjaCheetah
|
||||||
|
|
||||||
|
import os
|
||||||
|
import pathlib
|
||||||
|
from typing import List, Tuple
|
||||||
|
|
||||||
|
import libTWLPy
|
||||||
|
|
||||||
|
|
||||||
|
def run_nus_download_dsi(out_folder: pathlib.Path, tid: str, version: str, pack_tad_chkbox: bool, keep_enc_chkbox: bool,
|
||||||
|
decrypt_contents_chkbox: bool, use_local_chkbox: bool, tad_file_name: str,
|
||||||
|
progress_callback=None):
|
||||||
|
# Actual NUS download function that runs in a separate thread, but DSi flavored.
|
||||||
|
# Immediately knock out any invalidly formatted Title IDs.
|
||||||
|
if len(tid) != 16:
|
||||||
|
return -1
|
||||||
|
# An error here is acceptable, because it may just mean the box is empty. Or the version string is nonsense.
|
||||||
|
# Either way, just fall back on downloading the latest version of the title.
|
||||||
|
try:
|
||||||
|
title_version = int(version)
|
||||||
|
except ValueError:
|
||||||
|
title_version = None
|
||||||
|
# Set variables for these two options so that their state can be compared against the user's choices later.
|
||||||
|
pack_tad_enabled = pack_tad_chkbox
|
||||||
|
decrypt_contents_enabled = decrypt_contents_chkbox
|
||||||
|
# Create a new libTWLPy Title.
|
||||||
|
title = libTWLPy.Title()
|
||||||
|
# Make a directory for this title if it doesn't exist.
|
||||||
|
title_dir = pathlib.Path(os.path.join(out_folder, tid))
|
||||||
|
if not title_dir.is_dir():
|
||||||
|
title_dir.mkdir()
|
||||||
|
# Announce the title being downloaded, and the version if applicable.
|
||||||
|
if title_version is not None:
|
||||||
|
progress_callback.emit("Downloading title " + tid + " v" + str(title_version) + ", please wait...")
|
||||||
|
else:
|
||||||
|
progress_callback.emit("Downloading title " + tid + " vLatest, please wait...")
|
||||||
|
progress_callback.emit(" - Downloading and parsing TMD...")
|
||||||
|
# Download a specific TMD version if a version was specified, otherwise just download the latest TMD.
|
||||||
|
try:
|
||||||
|
if title_version is not None:
|
||||||
|
title.load_tmd(libTWLPy.download_tmd(tid, title_version))
|
||||||
|
else:
|
||||||
|
title.load_tmd(libTWLPy.download_tmd(tid))
|
||||||
|
title_version = title.tmd.title_version
|
||||||
|
# If libTWLPy returns an error, that means that either the TID or version doesn't exist, so return code -2.
|
||||||
|
except ValueError:
|
||||||
|
return -2
|
||||||
|
# Make a directory for this version if it doesn't exist.
|
||||||
|
version_dir = pathlib.Path(os.path.join(title_dir, str(title_version)))
|
||||||
|
if not version_dir.is_dir():
|
||||||
|
version_dir.mkdir()
|
||||||
|
# Write out the TMD to a file.
|
||||||
|
tmd_out = open(os.path.join(version_dir, "tmd." + str(title_version)), "wb")
|
||||||
|
tmd_out.write(title.tmd.dump())
|
||||||
|
tmd_out.close()
|
||||||
|
# Use a local ticket, if one exists and "use local files" is enabled.
|
||||||
|
if use_local_chkbox is True and os.path.exists(os.path.join(version_dir, "tik")):
|
||||||
|
progress_callback.emit(" - Parsing local copy of Ticket...")
|
||||||
|
local_ticket = open(os.path.join(version_dir, "tik"), "rb")
|
||||||
|
title.load_ticket(local_ticket.read())
|
||||||
|
else:
|
||||||
|
progress_callback.emit(" - Downloading and parsing Ticket...")
|
||||||
|
try:
|
||||||
|
title.load_ticket(libTWLPy.download_ticket(tid))
|
||||||
|
ticket_out = open(os.path.join(version_dir, "tik"), "wb")
|
||||||
|
ticket_out.write(title.ticket.dump())
|
||||||
|
ticket_out.close()
|
||||||
|
except ValueError:
|
||||||
|
# If libTWLPy returns an error, then no ticket is available. Log this, and disable options requiring a
|
||||||
|
# ticket so that they aren't attempted later.
|
||||||
|
progress_callback.emit(" - No Ticket is available!")
|
||||||
|
pack_tad_enabled = False
|
||||||
|
decrypt_contents_enabled = False
|
||||||
|
# Load the content record from the TMD, and download the content it lists. DSi titles only have one content.
|
||||||
|
title.load_content_records()
|
||||||
|
content_file_name = hex(title.tmd.content_record.content_id)[2:]
|
||||||
|
while len(content_file_name) < 8:
|
||||||
|
content_file_name = "0" + content_file_name
|
||||||
|
# Check for a local copy of the current content if "use local files" is enabled, and use it.
|
||||||
|
if use_local_chkbox is True and os.path.exists(os.path.join(version_dir, content_file_name)):
|
||||||
|
progress_callback.emit(" - Using local copy of content")
|
||||||
|
local_file = open(os.path.join(version_dir, content_file_name), "rb")
|
||||||
|
content = local_file.read()
|
||||||
|
else:
|
||||||
|
progress_callback.emit(" - Downloading content (Content ID: " + str(title.tmd.content_record.content_id) +
|
||||||
|
", Size: " + str(title.tmd.content_record.content_size) + " bytes)...")
|
||||||
|
content = libTWLPy.download_content(tid, title.tmd.content_record.content_id)
|
||||||
|
progress_callback.emit(" - Done!")
|
||||||
|
# If keep encrypted contents is on, write out each content after its downloaded.
|
||||||
|
if keep_enc_chkbox is True:
|
||||||
|
enc_content_out = open(os.path.join(version_dir, content_file_name), "wb")
|
||||||
|
enc_content_out.write(content)
|
||||||
|
enc_content_out.close()
|
||||||
|
title.content.content = content
|
||||||
|
# If decrypt local contents is still true, decrypt each content and write out the decrypted file.
|
||||||
|
if decrypt_contents_enabled is True:
|
||||||
|
try:
|
||||||
|
progress_callback.emit(" - Decrypting content (Content ID: " + str(title.tmd.content_record.content_id)
|
||||||
|
+ ")...")
|
||||||
|
dec_content = title.get_content()
|
||||||
|
content_file_name = hex(title.tmd.content_record.content_id)[2:]
|
||||||
|
while len(content_file_name) < 8:
|
||||||
|
content_file_name = "0" + content_file_name
|
||||||
|
content_file_name = content_file_name + ".app"
|
||||||
|
dec_content_out = open(os.path.join(version_dir, content_file_name), "wb")
|
||||||
|
dec_content_out.write(dec_content)
|
||||||
|
dec_content_out.close()
|
||||||
|
except ValueError:
|
||||||
|
# If libWiiPy throws an error during decryption, return code -3. This should only be possible if using
|
||||||
|
# local encrypted contents that have been altered at present.
|
||||||
|
return -3
|
||||||
|
# If pack TAD is still true, pack the TMD, ticket, and content into a TAD.
|
||||||
|
if pack_tad_enabled is True:
|
||||||
|
# Get the TAD certificate chain, courtesy of libTWLPy.
|
||||||
|
progress_callback.emit(" - Building certificate...")
|
||||||
|
title.tad.set_cert_data(libTWLPy.download_cert())
|
||||||
|
# Use a typed TAD name if there is one, and auto generate one based on the TID and version if there isn't.
|
||||||
|
progress_callback.emit("Packing TAD...")
|
||||||
|
if tad_file_name != "" and tad_file_name is not None:
|
||||||
|
if tad_file_name[-4:] != ".tad":
|
||||||
|
tad_file_name = tad_file_name + ".tad"
|
||||||
|
else:
|
||||||
|
tad_file_name = tid + "-v" + str(title_version) + ".tad"
|
||||||
|
# Have libTWLPy dump the TAD, and write that data out.
|
||||||
|
file = open(os.path.join(version_dir, tad_file_name), "wb")
|
||||||
|
file.write(title.dump_tad())
|
||||||
|
file.close()
|
||||||
|
progress_callback.emit("Download complete!")
|
||||||
|
# This is where the variables come in. If the state of these variables doesn't match the user's choice by this
|
||||||
|
# point, it means that they enabled decryption or TAD packing for a title that doesn't have a ticket. Return
|
||||||
|
# code 1 so that a warning popup is shown informing them of this.
|
||||||
|
if (not pack_tad_enabled and pack_tad_chkbox) or (not decrypt_contents_enabled and decrypt_contents_chkbox):
|
||||||
|
return 1
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def run_nus_download_dsi_batch(out_folder: pathlib.Path, titles: List[Tuple[str, str, str]], pack_tad_chkbox: bool, keep_enc_chkbox: bool,
|
||||||
|
decrypt_contents_chkbox: bool, use_local_chkbox: bool, progress_callback=None):
|
||||||
|
for title in titles:
|
||||||
|
result = run_nus_download_dsi(out_folder, title[0], title[1], pack_tad_chkbox, keep_enc_chkbox, decrypt_contents_chkbox, use_local_chkbox, f"{title[2]}-{title[1]}.tad", progress_callback)
|
||||||
|
if result != 0:
|
||||||
|
return result
|
||||||
|
|
||||||
|
progress_callback.emit(f"Batch download finished.")
|
||||||
|
return 0
|
||||||
179
modules/download_wii.py
Normal file
179
modules/download_wii.py
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
# "modules/download_wii.py", licensed under the MIT license
|
||||||
|
# Copyright 2024 NinjaCheetah
|
||||||
|
|
||||||
|
import os
|
||||||
|
import pathlib
|
||||||
|
from typing import List, Tuple
|
||||||
|
|
||||||
|
import libWiiPy
|
||||||
|
|
||||||
|
|
||||||
|
def run_nus_download_wii(out_folder: pathlib.Path, tid: str, version: str, pack_wad_chkbox: bool, keep_enc_chkbox: bool,
|
||||||
|
decrypt_contents_chkbox: bool, wiiu_nus_chkbox: bool, use_local_chkbox: bool,
|
||||||
|
repack_vwii_chkbox: bool, patch_ios: bool, wad_file_name: str, progress_callback=None):
|
||||||
|
# Actual NUS download function that runs in a separate thread.
|
||||||
|
# Immediately knock out any invalidly formatted Title IDs.
|
||||||
|
if len(tid) != 16:
|
||||||
|
return -1
|
||||||
|
# An error here is acceptable, because it may just mean the box is empty. Or the version string is nonsense.
|
||||||
|
# Either way, just fall back on downloading the latest version of the title.
|
||||||
|
try:
|
||||||
|
title_version = int(version)
|
||||||
|
except ValueError:
|
||||||
|
title_version = None
|
||||||
|
# Set variables for these two options so that their state can be compared against the user's choices later.
|
||||||
|
pack_wad_enabled = pack_wad_chkbox
|
||||||
|
decrypt_contents_enabled = decrypt_contents_chkbox
|
||||||
|
# Check whether we're going to be using the (faster) Wii U NUS or not.
|
||||||
|
wiiu_nus_enabled = wiiu_nus_chkbox
|
||||||
|
# Create a new libWiiPy Title.
|
||||||
|
title = libWiiPy.title.Title()
|
||||||
|
# Make a directory for this title if it doesn't exist.
|
||||||
|
title_dir = pathlib.Path(os.path.join(out_folder, tid))
|
||||||
|
if not title_dir.is_dir():
|
||||||
|
title_dir.mkdir()
|
||||||
|
# Announce the title being downloaded, and the version if applicable.
|
||||||
|
if title_version is not None:
|
||||||
|
progress_callback.emit("Downloading title " + tid + " v" + str(title_version) + ", please wait...")
|
||||||
|
else:
|
||||||
|
progress_callback.emit("Downloading title " + tid + " vLatest, please wait...")
|
||||||
|
progress_callback.emit(" - Downloading and parsing TMD...")
|
||||||
|
# Download a specific TMD version if a version was specified, otherwise just download the latest TMD.
|
||||||
|
try:
|
||||||
|
if title_version is not None:
|
||||||
|
title.load_tmd(libWiiPy.title.download_tmd(tid, title_version, wiiu_endpoint=wiiu_nus_enabled))
|
||||||
|
else:
|
||||||
|
title.load_tmd(libWiiPy.title.download_tmd(tid, wiiu_endpoint=wiiu_nus_enabled))
|
||||||
|
title_version = title.tmd.title_version
|
||||||
|
# If libWiiPy returns an error, that means that either the TID or version doesn't exist, so return code -2.
|
||||||
|
except ValueError:
|
||||||
|
return -2
|
||||||
|
# Make a directory for this version if it doesn't exist.
|
||||||
|
version_dir = pathlib.Path(os.path.join(title_dir, str(title_version)))
|
||||||
|
if not version_dir.is_dir():
|
||||||
|
version_dir.mkdir()
|
||||||
|
# Write out the TMD to a file.
|
||||||
|
tmd_out = open(os.path.join(version_dir, "tmd." + str(title_version)), "wb")
|
||||||
|
tmd_out.write(title.tmd.dump())
|
||||||
|
tmd_out.close()
|
||||||
|
# Use a local ticket, if one exists and "use local files" is enabled.
|
||||||
|
if use_local_chkbox is True and os.path.exists(os.path.join(version_dir, "tik")):
|
||||||
|
progress_callback.emit(" - Parsing local copy of Ticket...")
|
||||||
|
local_ticket = open(os.path.join(version_dir, "tik"), "rb")
|
||||||
|
title.load_ticket(local_ticket.read())
|
||||||
|
else:
|
||||||
|
progress_callback.emit(" - Downloading and parsing Ticket...")
|
||||||
|
try:
|
||||||
|
title.load_ticket(libWiiPy.title.download_ticket(tid, wiiu_endpoint=wiiu_nus_enabled))
|
||||||
|
ticket_out = open(os.path.join(version_dir, "tik"), "wb")
|
||||||
|
ticket_out.write(title.ticket.dump())
|
||||||
|
ticket_out.close()
|
||||||
|
except ValueError:
|
||||||
|
# If libWiiPy returns an error, then no ticket is available. Log this, and disable options requiring a
|
||||||
|
# ticket so that they aren't attempted later.
|
||||||
|
progress_callback.emit(" - No Ticket is available!")
|
||||||
|
pack_wad_enabled = False
|
||||||
|
decrypt_contents_enabled = False
|
||||||
|
# Load the content records from the TMD, and begin iterating over the records.
|
||||||
|
title.load_content_records()
|
||||||
|
content_list = []
|
||||||
|
for content in range(len(title.tmd.content_records)):
|
||||||
|
# Generate the correct file name by converting the content ID into hex, minus the 0x, and then appending
|
||||||
|
# that to the end of 000000. I refuse to believe there isn't a better way to do this here and in libWiiPy.
|
||||||
|
content_file_name = hex(title.tmd.content_records[content].content_id)[2:]
|
||||||
|
while len(content_file_name) < 8:
|
||||||
|
content_file_name = "0" + content_file_name
|
||||||
|
# Check for a local copy of the current content if "use local files" is enabled, and use it.
|
||||||
|
if use_local_chkbox is True and os.path.exists(os.path.join(version_dir,
|
||||||
|
content_file_name)):
|
||||||
|
progress_callback.emit(" - Using local copy of content " + str(content + 1) + " of " +
|
||||||
|
str(len(title.tmd.content_records)))
|
||||||
|
local_file = open(os.path.join(version_dir, content_file_name), "rb")
|
||||||
|
content_list.append(local_file.read())
|
||||||
|
else:
|
||||||
|
progress_callback.emit(" - Downloading content " + str(content + 1) + " of " +
|
||||||
|
str(len(title.tmd.content_records)) + " (Content ID: " +
|
||||||
|
str(title.tmd.content_records[content].content_id) + ", Size: " +
|
||||||
|
str(title.tmd.content_records[content].content_size) + " bytes)...")
|
||||||
|
content_list.append(libWiiPy.title.download_content(tid, title.tmd.content_records[content].content_id,
|
||||||
|
wiiu_endpoint=wiiu_nus_enabled))
|
||||||
|
progress_callback.emit(" - Done!")
|
||||||
|
# If keep encrypted contents is on, write out each content after its downloaded.
|
||||||
|
if keep_enc_chkbox is True:
|
||||||
|
enc_content_out = open(os.path.join(version_dir, content_file_name), "wb")
|
||||||
|
enc_content_out.write(content_list[content])
|
||||||
|
enc_content_out.close()
|
||||||
|
title.content.content_list = content_list
|
||||||
|
# If decrypt local contents is still true, decrypt each content and write out the decrypted file.
|
||||||
|
if decrypt_contents_enabled is True:
|
||||||
|
try:
|
||||||
|
for content in range(len(title.tmd.content_records)):
|
||||||
|
progress_callback.emit(" - Decrypting content " + str(content + 1) + " of " +
|
||||||
|
str(len(title.tmd.content_records)) + " (Content ID: " +
|
||||||
|
str(title.tmd.content_records[content].content_id) + ")...")
|
||||||
|
dec_content = title.get_content_by_index(content)
|
||||||
|
content_file_name = hex(title.tmd.content_records[content].content_id)[2:]
|
||||||
|
while len(content_file_name) < 8:
|
||||||
|
content_file_name = "0" + content_file_name
|
||||||
|
content_file_name = content_file_name + ".app"
|
||||||
|
dec_content_out = open(os.path.join(version_dir, content_file_name), "wb")
|
||||||
|
dec_content_out.write(dec_content)
|
||||||
|
dec_content_out.close()
|
||||||
|
except ValueError:
|
||||||
|
# If libWiiPy throws an error during decryption, return code -3. This should only be possible if using
|
||||||
|
# local encrypted contents that have been altered at present.
|
||||||
|
return -3
|
||||||
|
# If pack WAD is still true, pack the TMD, ticket, and contents all into a WAD.
|
||||||
|
if pack_wad_enabled is True:
|
||||||
|
# If the option to pack for vWii mode instead of Wii U mode is enabled, then the Title Key needs to be
|
||||||
|
# re-encrypted with the common key instead of the vWii key, so that the title can be installed from within
|
||||||
|
# vWii mode. (vWii mode does not have access to the vWii key, only Wii U mode has that.)
|
||||||
|
if repack_vwii_chkbox is True and (tid[3] == "7" or tid[7] == "7"):
|
||||||
|
progress_callback.emit(" - Re-encrypting Title Key with the common key...")
|
||||||
|
title_key_dec = title.ticket.get_title_key()
|
||||||
|
title_key_common = libWiiPy.title.encrypt_title_key(title_key_dec, 0, title.tmd.title_id)
|
||||||
|
title.ticket.common_key_index = 0
|
||||||
|
title.ticket.title_key_enc = title_key_common
|
||||||
|
# Get the WAD certificate chain, courtesy of libWiiPy.
|
||||||
|
progress_callback.emit(" - Building certificate...")
|
||||||
|
title.wad.set_cert_data(libWiiPy.title.download_cert(wiiu_endpoint=wiiu_nus_enabled))
|
||||||
|
# Use a typed WAD name if there is one, and auto generate one based on the TID and version if there isn't.
|
||||||
|
progress_callback.emit(" - Packing WAD...")
|
||||||
|
if wad_file_name != "" and wad_file_name is not None:
|
||||||
|
if wad_file_name[-4:] != ".wad":
|
||||||
|
wad_file_name = wad_file_name + ".wad"
|
||||||
|
else:
|
||||||
|
wad_file_name = tid + "-v" + str(title_version) + ".wad"
|
||||||
|
# If enabled (after we make sure it's an IOS), apply all main IOS patches.
|
||||||
|
if patch_ios and (tid[:8] == "00000001" and int(tid[-2:], 16) > 2):
|
||||||
|
progress_callback.emit(" - Patching IOS...")
|
||||||
|
ios_patcher = libWiiPy.title.IOSPatcher()
|
||||||
|
ios_patcher.load(title)
|
||||||
|
patch_count = ios_patcher.patch_all()
|
||||||
|
if patch_count > 0:
|
||||||
|
progress_callback.emit(f" - Applied {patch_count} patches!")
|
||||||
|
else:
|
||||||
|
progress_callback.emit(" - No patches could be applied! Is this a stub IOS?")
|
||||||
|
title = ios_patcher.dump()
|
||||||
|
# Have libWiiPy dump the WAD, and write that data out.
|
||||||
|
file = open(os.path.join(version_dir, wad_file_name), "wb")
|
||||||
|
file.write(title.dump_wad())
|
||||||
|
file.close()
|
||||||
|
progress_callback.emit("Download complete!")
|
||||||
|
# This is where the variables come in. If the state of these variables doesn't match the user's choice by this
|
||||||
|
# point, it means that they enabled decryption or WAD packing for a title that doesn't have a ticket. Return
|
||||||
|
# code 1 so that a warning popup is shown informing them of this.
|
||||||
|
if (not pack_wad_enabled and pack_wad_chkbox) or (not decrypt_contents_enabled and decrypt_contents_chkbox):
|
||||||
|
return 1
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def run_nus_download_wii_batch(out_folder: pathlib.Path, titles: List[Tuple[str, str, str]], pack_wad_chkbox: bool, keep_enc_chkbox: bool,
|
||||||
|
decrypt_contents_chkbox: bool, wiiu_nus_chkbox: bool, use_local_chkbox: bool,
|
||||||
|
repack_vwii_chkbox: bool, patch_ios: bool, progress_callback=None):
|
||||||
|
for title in titles:
|
||||||
|
result = run_nus_download_wii(out_folder, title[0], title[1], pack_wad_chkbox, keep_enc_chkbox, decrypt_contents_chkbox, wiiu_nus_chkbox, use_local_chkbox, repack_vwii_chkbox, patch_ios, f"{title[2]}-{title[1]}.wad", progress_callback)
|
||||||
|
if result != 0:
|
||||||
|
return result
|
||||||
|
|
||||||
|
progress_callback.emit(f"Batch download finished.")
|
||||||
|
return 0
|
||||||
9
packaging/NUSGet.desktop
Normal file
9
packaging/NUSGet.desktop
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
[Desktop Entry]
|
||||||
|
Name=NUSGet
|
||||||
|
Exec=/opt/NUSGet/NUSGet %U
|
||||||
|
Terminal=false
|
||||||
|
Type=Application
|
||||||
|
Icon=/opt/NUSGet/NUSGet.png
|
||||||
|
StartupWMClass=NUSGet
|
||||||
|
Comment=A modern and supercharged NUS downloader built with Python and Qt6.
|
||||||
|
Categories=Utility;
|
||||||
BIN
packaging/icon.png
Normal file
BIN
packaging/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 40 KiB |
@@ -3,7 +3,7 @@
|
|||||||
################################################################################
|
################################################################################
|
||||||
## Form generated from reading UI file 'MainMenu.ui'
|
## Form generated from reading UI file 'MainMenu.ui'
|
||||||
##
|
##
|
||||||
## Created by: Qt User Interface Compiler version 6.7.0
|
## Created by: Qt User Interface Compiler version 6.8.0
|
||||||
##
|
##
|
||||||
## WARNING! All changes made in this file will be lost when recompiling UI file!
|
## WARNING! All changes made in this file will be lost when recompiling UI file!
|
||||||
################################################################################
|
################################################################################
|
||||||
@@ -32,6 +32,7 @@ class Ui_MainWindow(object):
|
|||||||
self.centralwidget.setObjectName(u"centralwidget")
|
self.centralwidget.setObjectName(u"centralwidget")
|
||||||
self.horizontalLayout_3 = QHBoxLayout(self.centralwidget)
|
self.horizontalLayout_3 = QHBoxLayout(self.centralwidget)
|
||||||
self.horizontalLayout_3.setObjectName(u"horizontalLayout_3")
|
self.horizontalLayout_3.setObjectName(u"horizontalLayout_3")
|
||||||
|
self.horizontalLayout_3.setSizeConstraint(QLayout.SizeConstraint.SetDefaultConstraint)
|
||||||
self.vertical_layout_trees = QVBoxLayout()
|
self.vertical_layout_trees = QVBoxLayout()
|
||||||
self.vertical_layout_trees.setObjectName(u"vertical_layout_trees")
|
self.vertical_layout_trees.setObjectName(u"vertical_layout_trees")
|
||||||
self.label_2 = QLabel(self.centralwidget)
|
self.label_2 = QLabel(self.centralwidget)
|
||||||
@@ -111,7 +112,7 @@ class Ui_MainWindow(object):
|
|||||||
|
|
||||||
self.vertical_layout_controls = QVBoxLayout()
|
self.vertical_layout_controls = QVBoxLayout()
|
||||||
self.vertical_layout_controls.setObjectName(u"vertical_layout_controls")
|
self.vertical_layout_controls.setObjectName(u"vertical_layout_controls")
|
||||||
self.vertical_layout_controls.setSizeConstraint(QLayout.SetDefaultConstraint)
|
self.vertical_layout_controls.setSizeConstraint(QLayout.SizeConstraint.SetDefaultConstraint)
|
||||||
self.horizontal_layout_title_entry = QHBoxLayout()
|
self.horizontal_layout_title_entry = QHBoxLayout()
|
||||||
self.horizontal_layout_title_entry.setObjectName(u"horizontal_layout_title_entry")
|
self.horizontal_layout_title_entry.setObjectName(u"horizontal_layout_title_entry")
|
||||||
self.tid_entry = QLineEdit(self.centralwidget)
|
self.tid_entry = QLineEdit(self.centralwidget)
|
||||||
@@ -145,25 +146,71 @@ class Ui_MainWindow(object):
|
|||||||
|
|
||||||
self.vertical_layout_controls.addLayout(self.horizontal_layout_title_entry)
|
self.vertical_layout_controls.addLayout(self.horizontal_layout_title_entry)
|
||||||
|
|
||||||
|
self.horizontalLayout = QHBoxLayout()
|
||||||
|
self.horizontalLayout.setObjectName(u"horizontalLayout")
|
||||||
self.download_btn = QPushButton(self.centralwidget)
|
self.download_btn = QPushButton(self.centralwidget)
|
||||||
self.download_btn.setObjectName(u"download_btn")
|
self.download_btn.setObjectName(u"download_btn")
|
||||||
|
sizePolicy1 = QSizePolicy(QSizePolicy.Policy.MinimumExpanding, QSizePolicy.Policy.Fixed)
|
||||||
|
sizePolicy1.setHorizontalStretch(0)
|
||||||
|
sizePolicy1.setVerticalStretch(0)
|
||||||
|
sizePolicy1.setHeightForWidth(self.download_btn.sizePolicy().hasHeightForWidth())
|
||||||
|
self.download_btn.setSizePolicy(sizePolicy1)
|
||||||
|
|
||||||
self.vertical_layout_controls.addWidget(self.download_btn)
|
self.horizontalLayout.addWidget(self.download_btn)
|
||||||
|
|
||||||
|
self.script_btn = QPushButton(self.centralwidget)
|
||||||
|
self.script_btn.setObjectName(u"script_btn")
|
||||||
|
sizePolicy2 = QSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Fixed)
|
||||||
|
sizePolicy2.setHorizontalStretch(0)
|
||||||
|
sizePolicy2.setVerticalStretch(0)
|
||||||
|
sizePolicy2.setHeightForWidth(self.script_btn.sizePolicy().hasHeightForWidth())
|
||||||
|
self.script_btn.setSizePolicy(sizePolicy2)
|
||||||
|
|
||||||
|
self.horizontalLayout.addWidget(self.script_btn)
|
||||||
|
|
||||||
|
|
||||||
|
self.vertical_layout_controls.addLayout(self.horizontalLayout)
|
||||||
|
|
||||||
self.horizontalLayout_5 = QHBoxLayout()
|
self.horizontalLayout_5 = QHBoxLayout()
|
||||||
self.horizontalLayout_5.setObjectName(u"horizontalLayout_5")
|
self.horizontalLayout_5.setObjectName(u"horizontalLayout_5")
|
||||||
|
self.horizontalLayout_5.setSizeConstraint(QLayout.SizeConstraint.SetMinimumSize)
|
||||||
self.verticalLayout_7 = QVBoxLayout()
|
self.verticalLayout_7 = QVBoxLayout()
|
||||||
|
self.verticalLayout_7.setSpacing(5)
|
||||||
self.verticalLayout_7.setObjectName(u"verticalLayout_7")
|
self.verticalLayout_7.setObjectName(u"verticalLayout_7")
|
||||||
|
self.verticalLayout_7.setSizeConstraint(QLayout.SizeConstraint.SetMinimumSize)
|
||||||
self.label_3 = QLabel(self.centralwidget)
|
self.label_3 = QLabel(self.centralwidget)
|
||||||
self.label_3.setObjectName(u"label_3")
|
self.label_3.setObjectName(u"label_3")
|
||||||
self.label_3.setFont(font)
|
self.label_3.setFont(font)
|
||||||
|
|
||||||
self.verticalLayout_7.addWidget(self.label_3)
|
self.verticalLayout_7.addWidget(self.label_3)
|
||||||
|
|
||||||
|
self.pack_archive_row = QHBoxLayout()
|
||||||
|
self.pack_archive_row.setSpacing(10)
|
||||||
|
self.pack_archive_row.setObjectName(u"pack_archive_row")
|
||||||
self.pack_archive_chkbox = QCheckBox(self.centralwidget)
|
self.pack_archive_chkbox = QCheckBox(self.centralwidget)
|
||||||
self.pack_archive_chkbox.setObjectName(u"pack_archive_chkbox")
|
self.pack_archive_chkbox.setObjectName(u"pack_archive_chkbox")
|
||||||
|
sizePolicy3 = QSizePolicy(QSizePolicy.Policy.Maximum, QSizePolicy.Policy.Fixed)
|
||||||
|
sizePolicy3.setHorizontalStretch(0)
|
||||||
|
sizePolicy3.setVerticalStretch(0)
|
||||||
|
sizePolicy3.setHeightForWidth(self.pack_archive_chkbox.sizePolicy().hasHeightForWidth())
|
||||||
|
self.pack_archive_chkbox.setSizePolicy(sizePolicy3)
|
||||||
|
self.pack_archive_chkbox.setText(u"")
|
||||||
|
|
||||||
self.verticalLayout_7.addWidget(self.pack_archive_chkbox)
|
self.pack_archive_row.addWidget(self.pack_archive_chkbox)
|
||||||
|
|
||||||
|
self.label_7 = QLabel(self.centralwidget)
|
||||||
|
self.label_7.setObjectName(u"label_7")
|
||||||
|
sizePolicy4 = QSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.MinimumExpanding)
|
||||||
|
sizePolicy4.setHorizontalStretch(0)
|
||||||
|
sizePolicy4.setVerticalStretch(0)
|
||||||
|
sizePolicy4.setHeightForWidth(self.label_7.sizePolicy().hasHeightForWidth())
|
||||||
|
self.label_7.setSizePolicy(sizePolicy4)
|
||||||
|
self.label_7.setWordWrap(True)
|
||||||
|
|
||||||
|
self.pack_archive_row.addWidget(self.label_7)
|
||||||
|
|
||||||
|
|
||||||
|
self.verticalLayout_7.addLayout(self.pack_archive_row)
|
||||||
|
|
||||||
self.archive_file_entry = QLineEdit(self.centralwidget)
|
self.archive_file_entry = QLineEdit(self.centralwidget)
|
||||||
self.archive_file_entry.setObjectName(u"archive_file_entry")
|
self.archive_file_entry.setObjectName(u"archive_file_entry")
|
||||||
@@ -171,54 +218,177 @@ class Ui_MainWindow(object):
|
|||||||
|
|
||||||
self.verticalLayout_7.addWidget(self.archive_file_entry)
|
self.verticalLayout_7.addWidget(self.archive_file_entry)
|
||||||
|
|
||||||
|
self.keep_enc_row = QHBoxLayout()
|
||||||
|
self.keep_enc_row.setSpacing(10)
|
||||||
|
self.keep_enc_row.setObjectName(u"keep_enc_row")
|
||||||
self.keep_enc_chkbox = QCheckBox(self.centralwidget)
|
self.keep_enc_chkbox = QCheckBox(self.centralwidget)
|
||||||
self.keep_enc_chkbox.setObjectName(u"keep_enc_chkbox")
|
self.keep_enc_chkbox.setObjectName(u"keep_enc_chkbox")
|
||||||
|
sizePolicy3.setHeightForWidth(self.keep_enc_chkbox.sizePolicy().hasHeightForWidth())
|
||||||
|
self.keep_enc_chkbox.setSizePolicy(sizePolicy3)
|
||||||
|
self.keep_enc_chkbox.setText(u"")
|
||||||
self.keep_enc_chkbox.setChecked(True)
|
self.keep_enc_chkbox.setChecked(True)
|
||||||
|
|
||||||
self.verticalLayout_7.addWidget(self.keep_enc_chkbox)
|
self.keep_enc_row.addWidget(self.keep_enc_chkbox)
|
||||||
|
|
||||||
|
self.label_6 = QLabel(self.centralwidget)
|
||||||
|
self.label_6.setObjectName(u"label_6")
|
||||||
|
sizePolicy4.setHeightForWidth(self.label_6.sizePolicy().hasHeightForWidth())
|
||||||
|
self.label_6.setSizePolicy(sizePolicy4)
|
||||||
|
self.label_6.setWordWrap(True)
|
||||||
|
|
||||||
|
self.keep_enc_row.addWidget(self.label_6)
|
||||||
|
|
||||||
|
|
||||||
|
self.verticalLayout_7.addLayout(self.keep_enc_row)
|
||||||
|
|
||||||
|
self.create_dec_row = QHBoxLayout()
|
||||||
|
self.create_dec_row.setSpacing(10)
|
||||||
|
self.create_dec_row.setObjectName(u"create_dec_row")
|
||||||
self.create_dec_chkbox = QCheckBox(self.centralwidget)
|
self.create_dec_chkbox = QCheckBox(self.centralwidget)
|
||||||
self.create_dec_chkbox.setObjectName(u"create_dec_chkbox")
|
self.create_dec_chkbox.setObjectName(u"create_dec_chkbox")
|
||||||
|
sizePolicy3.setHeightForWidth(self.create_dec_chkbox.sizePolicy().hasHeightForWidth())
|
||||||
|
self.create_dec_chkbox.setSizePolicy(sizePolicy3)
|
||||||
|
self.create_dec_chkbox.setText(u"")
|
||||||
|
|
||||||
self.verticalLayout_7.addWidget(self.create_dec_chkbox)
|
self.create_dec_row.addWidget(self.create_dec_chkbox)
|
||||||
|
|
||||||
|
self.create_dec_chkbox_lbl = QLabel(self.centralwidget)
|
||||||
|
self.create_dec_chkbox_lbl.setObjectName(u"create_dec_chkbox_lbl")
|
||||||
|
sizePolicy4.setHeightForWidth(self.create_dec_chkbox_lbl.sizePolicy().hasHeightForWidth())
|
||||||
|
self.create_dec_chkbox_lbl.setSizePolicy(sizePolicy4)
|
||||||
|
self.create_dec_chkbox_lbl.setWordWrap(True)
|
||||||
|
|
||||||
|
self.create_dec_row.addWidget(self.create_dec_chkbox_lbl)
|
||||||
|
|
||||||
|
|
||||||
|
self.verticalLayout_7.addLayout(self.create_dec_row)
|
||||||
|
|
||||||
|
self.use_local_row = QHBoxLayout()
|
||||||
|
self.use_local_row.setSpacing(10)
|
||||||
|
self.use_local_row.setObjectName(u"use_local_row")
|
||||||
self.use_local_chkbox = QCheckBox(self.centralwidget)
|
self.use_local_chkbox = QCheckBox(self.centralwidget)
|
||||||
self.use_local_chkbox.setObjectName(u"use_local_chkbox")
|
self.use_local_chkbox.setObjectName(u"use_local_chkbox")
|
||||||
self.use_local_chkbox.setEnabled(True)
|
self.use_local_chkbox.setEnabled(True)
|
||||||
|
sizePolicy3.setHeightForWidth(self.use_local_chkbox.sizePolicy().hasHeightForWidth())
|
||||||
|
self.use_local_chkbox.setSizePolicy(sizePolicy3)
|
||||||
|
self.use_local_chkbox.setText(u"")
|
||||||
|
|
||||||
self.verticalLayout_7.addWidget(self.use_local_chkbox)
|
self.use_local_row.addWidget(self.use_local_chkbox)
|
||||||
|
|
||||||
|
self.use_local_chkbox_lbl = QLabel(self.centralwidget)
|
||||||
|
self.use_local_chkbox_lbl.setObjectName(u"use_local_chkbox_lbl")
|
||||||
|
sizePolicy4.setHeightForWidth(self.use_local_chkbox_lbl.sizePolicy().hasHeightForWidth())
|
||||||
|
self.use_local_chkbox_lbl.setSizePolicy(sizePolicy4)
|
||||||
|
self.use_local_chkbox_lbl.setWordWrap(True)
|
||||||
|
|
||||||
|
self.use_local_row.addWidget(self.use_local_chkbox_lbl)
|
||||||
|
|
||||||
|
|
||||||
|
self.verticalLayout_7.addLayout(self.use_local_row)
|
||||||
|
|
||||||
|
self.use_wiiu_nus_row = QHBoxLayout()
|
||||||
|
self.use_wiiu_nus_row.setSpacing(10)
|
||||||
|
self.use_wiiu_nus_row.setObjectName(u"use_wiiu_nus_row")
|
||||||
|
self.use_wiiu_nus_row.setSizeConstraint(QLayout.SizeConstraint.SetDefaultConstraint)
|
||||||
self.use_wiiu_nus_chkbox = QCheckBox(self.centralwidget)
|
self.use_wiiu_nus_chkbox = QCheckBox(self.centralwidget)
|
||||||
self.use_wiiu_nus_chkbox.setObjectName(u"use_wiiu_nus_chkbox")
|
self.use_wiiu_nus_chkbox.setObjectName(u"use_wiiu_nus_chkbox")
|
||||||
|
sizePolicy.setHeightForWidth(self.use_wiiu_nus_chkbox.sizePolicy().hasHeightForWidth())
|
||||||
|
self.use_wiiu_nus_chkbox.setSizePolicy(sizePolicy)
|
||||||
|
self.use_wiiu_nus_chkbox.setLayoutDirection(Qt.LayoutDirection.LeftToRight)
|
||||||
|
self.use_wiiu_nus_chkbox.setText(u"")
|
||||||
self.use_wiiu_nus_chkbox.setChecked(True)
|
self.use_wiiu_nus_chkbox.setChecked(True)
|
||||||
|
|
||||||
self.verticalLayout_7.addWidget(self.use_wiiu_nus_chkbox)
|
self.use_wiiu_nus_row.addWidget(self.use_wiiu_nus_chkbox)
|
||||||
|
|
||||||
self.verticalSpacer_2 = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding)
|
self.use_wiiu_nus_chkbox_lbl = QLabel(self.centralwidget)
|
||||||
|
self.use_wiiu_nus_chkbox_lbl.setObjectName(u"use_wiiu_nus_chkbox_lbl")
|
||||||
|
sizePolicy4.setHeightForWidth(self.use_wiiu_nus_chkbox_lbl.sizePolicy().hasHeightForWidth())
|
||||||
|
self.use_wiiu_nus_chkbox_lbl.setSizePolicy(sizePolicy4)
|
||||||
|
self.use_wiiu_nus_chkbox_lbl.setWordWrap(True)
|
||||||
|
|
||||||
|
self.use_wiiu_nus_row.addWidget(self.use_wiiu_nus_chkbox_lbl)
|
||||||
|
|
||||||
|
|
||||||
|
self.verticalLayout_7.addLayout(self.use_wiiu_nus_row)
|
||||||
|
|
||||||
|
self.patch_ios_row = QHBoxLayout()
|
||||||
|
self.patch_ios_row.setSpacing(10)
|
||||||
|
self.patch_ios_row.setObjectName(u"patch_ios_row")
|
||||||
|
self.patch_ios_chkbox = QCheckBox(self.centralwidget)
|
||||||
|
self.patch_ios_chkbox.setObjectName(u"patch_ios_chkbox")
|
||||||
|
self.patch_ios_chkbox.setEnabled(False)
|
||||||
|
sizePolicy3.setHeightForWidth(self.patch_ios_chkbox.sizePolicy().hasHeightForWidth())
|
||||||
|
self.patch_ios_chkbox.setSizePolicy(sizePolicy3)
|
||||||
|
self.patch_ios_chkbox.setText(u"")
|
||||||
|
|
||||||
|
self.patch_ios_row.addWidget(self.patch_ios_chkbox)
|
||||||
|
|
||||||
|
self.patch_ios_lbl = QLabel(self.centralwidget)
|
||||||
|
self.patch_ios_lbl.setObjectName(u"patch_ios_lbl")
|
||||||
|
self.patch_ios_lbl.setEnabled(True)
|
||||||
|
sizePolicy4.setHeightForWidth(self.patch_ios_lbl.sizePolicy().hasHeightForWidth())
|
||||||
|
self.patch_ios_lbl.setSizePolicy(sizePolicy4)
|
||||||
|
self.patch_ios_lbl.setWordWrap(True)
|
||||||
|
|
||||||
|
self.patch_ios_row.addWidget(self.patch_ios_lbl)
|
||||||
|
|
||||||
|
|
||||||
|
self.verticalLayout_7.addLayout(self.patch_ios_row)
|
||||||
|
|
||||||
|
self.verticalSpacer_2 = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Ignored)
|
||||||
|
|
||||||
self.verticalLayout_7.addItem(self.verticalSpacer_2)
|
self.verticalLayout_7.addItem(self.verticalSpacer_2)
|
||||||
|
|
||||||
|
self.horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Policy.MinimumExpanding, QSizePolicy.Policy.Minimum)
|
||||||
|
|
||||||
|
self.verticalLayout_7.addItem(self.horizontalSpacer)
|
||||||
|
|
||||||
|
|
||||||
self.horizontalLayout_5.addLayout(self.verticalLayout_7)
|
self.horizontalLayout_5.addLayout(self.verticalLayout_7)
|
||||||
|
|
||||||
self.verticalLayout_8 = QVBoxLayout()
|
self.verticalLayout_8 = QVBoxLayout()
|
||||||
self.verticalLayout_8.setObjectName(u"verticalLayout_8")
|
self.verticalLayout_8.setObjectName(u"verticalLayout_8")
|
||||||
|
self.verticalLayout_8.setSizeConstraint(QLayout.SizeConstraint.SetMinimumSize)
|
||||||
self.label_4 = QLabel(self.centralwidget)
|
self.label_4 = QLabel(self.centralwidget)
|
||||||
self.label_4.setObjectName(u"label_4")
|
self.label_4.setObjectName(u"label_4")
|
||||||
self.label_4.setFont(font)
|
self.label_4.setFont(font)
|
||||||
|
|
||||||
self.verticalLayout_8.addWidget(self.label_4)
|
self.verticalLayout_8.addWidget(self.label_4)
|
||||||
|
|
||||||
|
self.pack_vwii_mode_row = QHBoxLayout()
|
||||||
|
self.pack_vwii_mode_row.setObjectName(u"pack_vwii_mode_row")
|
||||||
self.pack_vwii_mode_chkbox = QCheckBox(self.centralwidget)
|
self.pack_vwii_mode_chkbox = QCheckBox(self.centralwidget)
|
||||||
self.pack_vwii_mode_chkbox.setObjectName(u"pack_vwii_mode_chkbox")
|
self.pack_vwii_mode_chkbox.setObjectName(u"pack_vwii_mode_chkbox")
|
||||||
self.pack_vwii_mode_chkbox.setEnabled(False)
|
self.pack_vwii_mode_chkbox.setEnabled(False)
|
||||||
|
sizePolicy3.setHeightForWidth(self.pack_vwii_mode_chkbox.sizePolicy().hasHeightForWidth())
|
||||||
|
self.pack_vwii_mode_chkbox.setSizePolicy(sizePolicy3)
|
||||||
|
self.pack_vwii_mode_chkbox.setText(u"")
|
||||||
|
|
||||||
self.verticalLayout_8.addWidget(self.pack_vwii_mode_chkbox)
|
self.pack_vwii_mode_row.addWidget(self.pack_vwii_mode_chkbox)
|
||||||
|
|
||||||
self.verticalSpacer = QSpacerItem(20, 50, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding)
|
self.pack_vwii_mode_lbl = QLabel(self.centralwidget)
|
||||||
|
self.pack_vwii_mode_lbl.setObjectName(u"pack_vwii_mode_lbl")
|
||||||
|
self.pack_vwii_mode_lbl.setEnabled(True)
|
||||||
|
sizePolicy5 = QSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Preferred)
|
||||||
|
sizePolicy5.setHorizontalStretch(0)
|
||||||
|
sizePolicy5.setVerticalStretch(0)
|
||||||
|
sizePolicy5.setHeightForWidth(self.pack_vwii_mode_lbl.sizePolicy().hasHeightForWidth())
|
||||||
|
self.pack_vwii_mode_lbl.setSizePolicy(sizePolicy5)
|
||||||
|
self.pack_vwii_mode_lbl.setWordWrap(True)
|
||||||
|
|
||||||
|
self.pack_vwii_mode_row.addWidget(self.pack_vwii_mode_lbl)
|
||||||
|
|
||||||
|
|
||||||
|
self.verticalLayout_8.addLayout(self.pack_vwii_mode_row)
|
||||||
|
|
||||||
|
self.verticalSpacer = QSpacerItem(20, 50, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.MinimumExpanding)
|
||||||
|
|
||||||
self.verticalLayout_8.addItem(self.verticalSpacer)
|
self.verticalLayout_8.addItem(self.verticalSpacer)
|
||||||
|
|
||||||
|
self.horizontalSpacer_2 = QSpacerItem(40, 20, QSizePolicy.Policy.MinimumExpanding, QSizePolicy.Policy.Minimum)
|
||||||
|
|
||||||
|
self.verticalLayout_8.addItem(self.horizontalSpacer_2)
|
||||||
|
|
||||||
|
|
||||||
self.horizontalLayout_5.addLayout(self.verticalLayout_8)
|
self.horizontalLayout_5.addLayout(self.verticalLayout_8)
|
||||||
|
|
||||||
@@ -227,7 +397,7 @@ class Ui_MainWindow(object):
|
|||||||
|
|
||||||
self.log_text_browser = QTextBrowser(self.centralwidget)
|
self.log_text_browser = QTextBrowser(self.centralwidget)
|
||||||
self.log_text_browser.setObjectName(u"log_text_browser")
|
self.log_text_browser.setObjectName(u"log_text_browser")
|
||||||
self.log_text_browser.setMinimumSize(QSize(0, 312))
|
self.log_text_browser.setMinimumSize(QSize(0, 247))
|
||||||
|
|
||||||
self.vertical_layout_controls.addWidget(self.log_text_browser)
|
self.vertical_layout_controls.addWidget(self.log_text_browser)
|
||||||
|
|
||||||
@@ -237,7 +407,7 @@ class Ui_MainWindow(object):
|
|||||||
MainWindow.setCentralWidget(self.centralwidget)
|
MainWindow.setCentralWidget(self.centralwidget)
|
||||||
self.menubar = QMenuBar(MainWindow)
|
self.menubar = QMenuBar(MainWindow)
|
||||||
self.menubar.setObjectName(u"menubar")
|
self.menubar.setObjectName(u"menubar")
|
||||||
self.menubar.setGeometry(QRect(0, 0, 1010, 29))
|
self.menubar.setGeometry(QRect(0, 0, 1010, 30))
|
||||||
MainWindow.setMenuBar(self.menubar)
|
MainWindow.setMenuBar(self.menubar)
|
||||||
|
|
||||||
self.retranslateUi(MainWindow)
|
self.retranslateUi(MainWindow)
|
||||||
@@ -262,20 +432,25 @@ class Ui_MainWindow(object):
|
|||||||
self.label_5.setText(QCoreApplication.translate("MainWindow", u"Console:", None))
|
self.label_5.setText(QCoreApplication.translate("MainWindow", u"Console:", None))
|
||||||
self.console_select_dropdown.setCurrentText("")
|
self.console_select_dropdown.setCurrentText("")
|
||||||
self.download_btn.setText(QCoreApplication.translate("MainWindow", u"Start Download", None))
|
self.download_btn.setText(QCoreApplication.translate("MainWindow", u"Start Download", None))
|
||||||
|
self.script_btn.setText(QCoreApplication.translate("MainWindow", u"Run Script", None))
|
||||||
self.label_3.setText(QCoreApplication.translate("MainWindow", u"General Settings", None))
|
self.label_3.setText(QCoreApplication.translate("MainWindow", u"General Settings", None))
|
||||||
self.pack_archive_chkbox.setText(QCoreApplication.translate("MainWindow", u"Pack installable archive (WAD/TAD)", None))
|
self.label_7.setText(QCoreApplication.translate("MainWindow", u"Pack installable archive (WAD/TAD)", None))
|
||||||
self.archive_file_entry.setPlaceholderText(QCoreApplication.translate("MainWindow", u"File Name", None))
|
self.archive_file_entry.setPlaceholderText(QCoreApplication.translate("MainWindow", u"File Name", None))
|
||||||
self.keep_enc_chkbox.setText(QCoreApplication.translate("MainWindow", u"Keep encrypted contents", None))
|
self.label_6.setText(QCoreApplication.translate("MainWindow", u"Keep encrypted contents", None))
|
||||||
self.create_dec_chkbox.setText(QCoreApplication.translate("MainWindow", u"Create decrypted contents (*.app)", None))
|
self.create_dec_chkbox_lbl.setText(QCoreApplication.translate("MainWindow", u"Create decrypted contents (*.app)", None))
|
||||||
self.use_local_chkbox.setText(QCoreApplication.translate("MainWindow", u"Use local files, if they exist", None))
|
self.use_local_chkbox_lbl.setText(QCoreApplication.translate("MainWindow", u"Use local files, if they exist", None))
|
||||||
self.use_wiiu_nus_chkbox.setText(QCoreApplication.translate("MainWindow", u"Use the Wii U NUS (faster, only effects Wii/vWii)", None))
|
self.use_wiiu_nus_chkbox_lbl.setText(QCoreApplication.translate("MainWindow", u"Use the Wii U NUS (faster, only effects Wii/vWii)", None))
|
||||||
|
self.patch_ios_lbl.setText(QCoreApplication.translate("MainWindow", u"Apply patches to IOS (Applies to WADs only)", None))
|
||||||
self.label_4.setText(QCoreApplication.translate("MainWindow", u"vWii Title Settings", None))
|
self.label_4.setText(QCoreApplication.translate("MainWindow", u"vWii Title Settings", None))
|
||||||
self.pack_vwii_mode_chkbox.setText(QCoreApplication.translate("MainWindow", u"Pack for vWii mode instead of Wii U mode", None))
|
self.pack_vwii_mode_lbl.setText(QCoreApplication.translate("MainWindow", u"Re-encrypt title using the Wii Common Key", None))
|
||||||
self.log_text_browser.setMarkdown("")
|
self.log_text_browser.setMarkdown("")
|
||||||
self.log_text_browser.setHtml(QCoreApplication.translate("MainWindow", u"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
|
self.log_text_browser.setHtml(QCoreApplication.translate("MainWindow", u"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
|
||||||
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
|
"<html><head><meta name=\"qrichtext\" content=\"1\" /><meta charset=\"utf-8\" /><style type=\"text/css\">\n"
|
||||||
"p, li { white-space: pre-wrap; }\n"
|
"p, li { white-space: pre-wrap; }\n"
|
||||||
"</style></head><body style=\" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;\">\n"
|
"hr { height: 1px; border-width: 0; }\n"
|
||||||
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><br /></p></body></html>", None))
|
"li.unchecked::marker { content: \"\\2610\"; }\n"
|
||||||
|
"li.checked::marker { content: \"\\2612\"; }\n"
|
||||||
|
"</style></head><body style=\" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;\">\n"
|
||||||
|
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;\"><br /></p></body></html>", None))
|
||||||
# retranslateUi
|
# retranslateUi
|
||||||
|
|
||||||
|
|||||||
401
qt/ui/MainMenu.ui
Normal file → Executable file
401
qt/ui/MainMenu.ui
Normal file → Executable file
@@ -27,13 +27,15 @@
|
|||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="centralwidget">
|
<widget class="QWidget" name="centralwidget">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
|
<property name="sizeConstraint">
|
||||||
|
<enum>QLayout::SizeConstraint::SetDefaultConstraint</enum>
|
||||||
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="vertical_layout_trees">
|
<layout class="QVBoxLayout" name="vertical_layout_trees">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label_2">
|
<widget class="QLabel" name="label_2">
|
||||||
<property name="font">
|
<property name="font">
|
||||||
<font>
|
<font>
|
||||||
<weight>75</weight>
|
|
||||||
<bold>true</bold>
|
<bold>true</bold>
|
||||||
</font>
|
</font>
|
||||||
</property>
|
</property>
|
||||||
@@ -159,7 +161,7 @@
|
|||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="vertical_layout_controls">
|
<layout class="QVBoxLayout" name="vertical_layout_controls">
|
||||||
<property name="sizeConstraint">
|
<property name="sizeConstraint">
|
||||||
<enum>QLayout::SetDefaultConstraint</enum>
|
<enum>QLayout::SizeConstraint::SetDefaultConstraint</enum>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontal_layout_title_entry">
|
<layout class="QHBoxLayout" name="horizontal_layout_title_entry">
|
||||||
@@ -222,21 +224,52 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="download_btn">
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
<property name="text">
|
<item>
|
||||||
<string>Start Download</string>
|
<widget class="QPushButton" name="download_btn">
|
||||||
</property>
|
<property name="sizePolicy">
|
||||||
</widget>
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Start Download</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="script_btn">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Run Script</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||||
|
<property name="sizeConstraint">
|
||||||
|
<enum>QLayout::SizeConstraint::SetMinimumSize</enum>
|
||||||
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_7">
|
<layout class="QVBoxLayout" name="verticalLayout_7">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="sizeConstraint">
|
||||||
|
<enum>QLayout::SizeConstraint::SetMinimumSize</enum>
|
||||||
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label_3">
|
<widget class="QLabel" name="label_3">
|
||||||
<property name="font">
|
<property name="font">
|
||||||
<font>
|
<font>
|
||||||
<weight>75</weight>
|
|
||||||
<bold>true</bold>
|
<bold>true</bold>
|
||||||
</font>
|
</font>
|
||||||
</property>
|
</property>
|
||||||
@@ -246,11 +279,40 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="pack_archive_chkbox">
|
<layout class="QHBoxLayout" name="pack_archive_row">
|
||||||
<property name="text">
|
<property name="spacing">
|
||||||
<string>Pack installable archive (WAD/TAD)</string>
|
<number>10</number>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
<item>
|
||||||
|
<widget class="QCheckBox" name="pack_archive_chkbox">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true"/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_7">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Pack installable archive (WAD/TAD)</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLineEdit" name="archive_file_entry">
|
<widget class="QLineEdit" name="archive_file_entry">
|
||||||
@@ -263,46 +325,213 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="keep_enc_chkbox">
|
<layout class="QHBoxLayout" name="keep_enc_row">
|
||||||
<property name="text">
|
<property name="spacing">
|
||||||
<string>Keep encrypted contents</string>
|
<number>10</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="checked">
|
<item>
|
||||||
<bool>true</bool>
|
<widget class="QCheckBox" name="keep_enc_chkbox">
|
||||||
</property>
|
<property name="sizePolicy">
|
||||||
</widget>
|
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true"/>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_6">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Keep encrypted contents</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="create_dec_chkbox">
|
<layout class="QHBoxLayout" name="create_dec_row">
|
||||||
<property name="text">
|
<property name="spacing">
|
||||||
<string>Create decrypted contents (*.app)</string>
|
<number>10</number>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
<item>
|
||||||
|
<widget class="QCheckBox" name="create_dec_chkbox">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true"/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="create_dec_chkbox_lbl">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Create decrypted contents (*.app)</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="use_local_chkbox">
|
<layout class="QHBoxLayout" name="use_local_row">
|
||||||
<property name="enabled">
|
<property name="spacing">
|
||||||
<bool>true</bool>
|
<number>10</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<item>
|
||||||
<string>Use local files, if they exist</string>
|
<widget class="QCheckBox" name="use_local_chkbox">
|
||||||
</property>
|
<property name="enabled">
|
||||||
</widget>
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true"/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="use_local_chkbox_lbl">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Use local files, if they exist</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="use_wiiu_nus_chkbox">
|
<layout class="QHBoxLayout" name="use_wiiu_nus_row">
|
||||||
<property name="text">
|
<property name="spacing">
|
||||||
<string>Use the Wii U NUS (faster, only effects Wii/vWii)</string>
|
<number>10</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="checked">
|
<property name="sizeConstraint">
|
||||||
<bool>true</bool>
|
<enum>QLayout::SizeConstraint::SetDefaultConstraint</enum>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
<item>
|
||||||
|
<widget class="QCheckBox" name="use_wiiu_nus_chkbox">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Maximum" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="layoutDirection">
|
||||||
|
<enum>Qt::LayoutDirection::LeftToRight</enum>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true"/>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="use_wiiu_nus_chkbox_lbl">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Use the Wii U NUS (faster, only effects Wii/vWii)</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="patch_ios_row">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>10</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="patch_ios_chkbox">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true"/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="patch_ios_lbl">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Apply patches to IOS (Applies to WADs only)</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="verticalSpacer_2">
|
<spacer name="verticalSpacer_2">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Vertical</enum>
|
<enum>Qt::Orientation::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeType">
|
||||||
|
<enum>QSizePolicy::Policy::Ignored</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizeHint" stdset="0">
|
<property name="sizeHint" stdset="0">
|
||||||
<size>
|
<size>
|
||||||
@@ -312,15 +541,33 @@
|
|||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Orientation::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeType">
|
||||||
|
<enum>QSizePolicy::Policy::MinimumExpanding</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_8">
|
<layout class="QVBoxLayout" name="verticalLayout_8">
|
||||||
|
<property name="sizeConstraint">
|
||||||
|
<enum>QLayout::SizeConstraint::SetMinimumSize</enum>
|
||||||
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label_4">
|
<widget class="QLabel" name="label_4">
|
||||||
<property name="font">
|
<property name="font">
|
||||||
<font>
|
<font>
|
||||||
<weight>75</weight>
|
|
||||||
<bold>true</bold>
|
<bold>true</bold>
|
||||||
</font>
|
</font>
|
||||||
</property>
|
</property>
|
||||||
@@ -330,22 +577,51 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="pack_vwii_mode_chkbox">
|
<layout class="QHBoxLayout" name="pack_vwii_mode_row">
|
||||||
<property name="enabled">
|
<item>
|
||||||
<bool>false</bool>
|
<widget class="QCheckBox" name="pack_vwii_mode_chkbox">
|
||||||
</property>
|
<property name="enabled">
|
||||||
<property name="text">
|
<bool>false</bool>
|
||||||
<string>Pack for vWii mode instead of Wii U mode</string>
|
</property>
|
||||||
</property>
|
<property name="sizePolicy">
|
||||||
</widget>
|
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true"/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="pack_vwii_mode_lbl">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Re-encrypt title using the Wii Common Key</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="verticalSpacer">
|
<spacer name="verticalSpacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Vertical</enum>
|
<enum>Qt::Orientation::Vertical</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizeType">
|
<property name="sizeType">
|
||||||
<enum>QSizePolicy::Expanding</enum>
|
<enum>QSizePolicy::Policy::MinimumExpanding</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizeHint" stdset="0">
|
<property name="sizeHint" stdset="0">
|
||||||
<size>
|
<size>
|
||||||
@@ -355,6 +631,22 @@
|
|||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Orientation::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeType">
|
||||||
|
<enum>QSizePolicy::Policy::MinimumExpanding</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
@@ -364,7 +656,7 @@
|
|||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>0</width>
|
<width>0</width>
|
||||||
<height>312</height>
|
<height>247</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="markdown">
|
<property name="markdown">
|
||||||
@@ -372,10 +664,13 @@
|
|||||||
</property>
|
</property>
|
||||||
<property name="html">
|
<property name="html">
|
||||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
<html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><style type="text/css">
|
||||||
p, li { white-space: pre-wrap; }
|
p, li { white-space: pre-wrap; }
|
||||||
</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;">
|
hr { height: 1px; border-width: 0; }
|
||||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html></string>
|
li.unchecked::marker { content: "\2610"; }
|
||||||
|
li.checked::marker { content: "\2612"; }
|
||||||
|
</style></head><body style=" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;">
|
||||||
|
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html></string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@@ -389,7 +684,7 @@ p, li { white-space: pre-wrap; }
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>1010</width>
|
<width>1010</width>
|
||||||
<height>29</height>
|
<height>30</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
|
|||||||
@@ -3,4 +3,5 @@ nuitka
|
|||||||
libWiiPy
|
libWiiPy
|
||||||
libTWLPy
|
libTWLPy
|
||||||
zstandard
|
zstandard
|
||||||
|
requests
|
||||||
imageio
|
imageio
|
||||||
312
resources/translations/nusget_de.ts
Normal file
312
resources/translations/nusget_de.ts
Normal file
@@ -0,0 +1,312 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!DOCTYPE TS>
|
||||||
|
<TS version="2.1" language="de_DE">
|
||||||
|
<context>
|
||||||
|
<name>MainWindow</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="85"/>
|
||||||
|
<source>NUSGet v{nusget_version}
|
||||||
|
Developed by NinjaCheetah
|
||||||
|
Powered by libWiiPy {libwiipy_version}
|
||||||
|
DSi support provided by libTWLPy {libtwlpy_version}
|
||||||
|
|
||||||
|
Select a title from the list on the left, or enter a Title ID to begin.
|
||||||
|
|
||||||
|
Titles marked with a checkmark are free and have a ticket available, and can be decrypted and/or packed into a WAD or TAD. Titles with an X do not have a ticket, and only their encrypted contents can be saved.
|
||||||
|
|
||||||
|
Titles will be downloaded to a folder named "NUSGet" inside your downloads folder.</source>
|
||||||
|
<translatorcomment>"Downloads" in German copies of Windows and macOS isn't translated
|
||||||
|
Specified that the tickets for titles with a checkmark are publicly available, for clarity in the translation</translatorcomment>
|
||||||
|
<translation>NUSGet v{nusget_version}
|
||||||
|
Entwickelt von NinjaCheetah
|
||||||
|
Nutzt libWiiPy {libwiipy_version}
|
||||||
|
Unterstützung für DSi bereitgestelt durch libTWLPy {libtwlpy_version}
|
||||||
|
|
||||||
|
Wähle einen Titel aus der Liste auf der linken Seite oder gebe eine Title-ID ein, um zu beginnen.
|
||||||
|
|
||||||
|
Titel, welche mit einem Häkchen markiert sind, sind frei verfügbar und haben ein öffentliches Ticket, und können daher entschlüsselt und/oder in eine WAD/TAD verpackt werden. Titel mit einem Kreuz haben kein öffentlich verfügbares Ticket und können nur verschlüsselt heruntergeladen werden.
|
||||||
|
|
||||||
|
Titel werden in einem "NUSGet" Ordner innerhalb des Downloads-Ordners gespeichert.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="184"/>
|
||||||
|
<source>NUSGet Update Available</source>
|
||||||
|
<translation>NUSGet-Update verfügbar</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="185"/>
|
||||||
|
<source>There's a newer version of NUSGet available!</source>
|
||||||
|
<translation>Eine neuere Version von NUSGet ist verfügbar.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="264"/>
|
||||||
|
<source>No Output Selected</source>
|
||||||
|
<translatorcomment>Changed from "output" to "packaging" for clarity</translatorcomment>
|
||||||
|
<translation>Keine Verpackmethode ausgewählt</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="265"/>
|
||||||
|
<source>You have not selected any format to output the data in!</source>
|
||||||
|
<translation>Es wurde keine Methode zum Verpacken der Inhalte ausgewählt.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="267"/>
|
||||||
|
<source>Please select at least one option for how you would like the download to be saved.</source>
|
||||||
|
<translatorcomment>Explicitly mentions options for clarity</translatorcomment>
|
||||||
|
<translation>Es muss mindestens "verschlüsselte Inhalte speichern", "entschlüsselte Inhalte speichern" oder "Verpacke als WAD/TAD" ausgewählt worden sein.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="298"/>
|
||||||
|
<source>Invalid Title ID</source>
|
||||||
|
<translation>Fehlerhafte Title-ID</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="299"/>
|
||||||
|
<source>The Title ID you have entered is not in a valid format!</source>
|
||||||
|
<translation>Die eingegebene Title-ID ist nicht korrekt.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="301"/>
|
||||||
|
<source>Title IDs must be 16 digit strings of numbers and letters. Please enter a correctly formatted Title ID, or select one from the menu on the left.</source>
|
||||||
|
<translation>Die Title-ID muss mindestens 16 alphanumerische Zeichen enthalten.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="303"/>
|
||||||
|
<source>Title ID/Version Not Found</source>
|
||||||
|
<translation>Title-ID/Version nicht gefunden</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="304"/>
|
||||||
|
<source>No title with the provided Title ID or version could be found!</source>
|
||||||
|
<translatorcomment>The title was moved into the body, and the title was made less of a mouthful, for ease of translation</translatorcomment>
|
||||||
|
<translation>Es konnte kein Titel mit der gegebenen Title-ID oder Version gefunden werden.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="306"/>
|
||||||
|
<source>Please make sure that you have entered a valid Title ID, or selected one from the title database, and that the provided version exists for the title you are attempting to download.</source>
|
||||||
|
<translation>Die Title-ID könnte möglicherweise fehlerhaft sein.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="308"/>
|
||||||
|
<source>Content Decryption Failed</source>
|
||||||
|
<translation>Entschlüsselung fehlgeschlagen</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="309"/>
|
||||||
|
<source>Content decryption was not successful! Decrypted contents could not be created.</source>
|
||||||
|
<translation>Die Inhalte des Titels konnten nicht korrekt entschlüsselt werden.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="312"/>
|
||||||
|
<source>Your TMD or Ticket may be damaged, or they may not correspond with the content being decrypted. If you have checked "Use local files, if they exist", try disabling that option before trying the download again to fix potential issues with local data.</source>
|
||||||
|
<translation>Die gespeicherte TMD oder das Ticket könnten möglicherweise fehlerhaft sein. "Lokale Dateien nutzen" kann ausgeschaltet werden, um diese erneut herunterzuladen.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="315"/>
|
||||||
|
<source>Ticket Not Available</source>
|
||||||
|
<translation>Ticket nicht verfügbar</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="316"/>
|
||||||
|
<source>No Ticket is Available for the Requested Title!</source>
|
||||||
|
<translation>Kein Ticket konnte für den geforderten Titel gefunden werden.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="319"/>
|
||||||
|
<source>A ticket could not be downloaded for the requested title, but you have selected "Pack installable archive" or "Create decrypted contents". These options are not available for titles without a ticket. Only encrypted contents have been saved.</source>
|
||||||
|
<translation>Es wurden nur verschlüsselte Inhalte gespeichert.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="321"/>
|
||||||
|
<source>Unknown Error</source>
|
||||||
|
<translation>Unbekannter Fehler</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="322"/>
|
||||||
|
<source>An Unknown Error has Occurred!</source>
|
||||||
|
<translation>Ein unbekannter Fehler ist aufgetreten.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="324"/>
|
||||||
|
<source>Please try again. If this issue persists, please open a new issue on GitHub detailing what you were trying to do when this error occurred.</source>
|
||||||
|
<translation>Versuchen Sie es erneut. Sofern das Problem bestehen bleibt, können Sie ein Issue auf GitHub öffnen, um den Fehler zu berichten.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="364"/>
|
||||||
|
<source>Open NUS script</source>
|
||||||
|
<translatorcomment>Translating the file type is pointless, since it's not an actual "script"</translatorcomment>
|
||||||
|
<translation>NUS-Script öffnen</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="364"/>
|
||||||
|
<source>NUS Scripts (*.nus *.txt)</source>
|
||||||
|
<translation>NUS Script (*.nus *.txt)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="371"/>
|
||||||
|
<location filename="../../NUSGet.py" line="386"/>
|
||||||
|
<location filename="../../NUSGet.py" line="389"/>
|
||||||
|
<location filename="../../NUSGet.py" line="397"/>
|
||||||
|
<location filename="../../NUSGet.py" line="415"/>
|
||||||
|
<location filename="../../NUSGet.py" line="422"/>
|
||||||
|
<source>Script Failure</source>
|
||||||
|
<translation>Script-Fehler</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="371"/>
|
||||||
|
<source>Failed to open the script.</source>
|
||||||
|
<translation>Konnte das NUS-Script nicht öffnen.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../modules/core.py" line="26"/>
|
||||||
|
<source>
|
||||||
|
|
||||||
|
Could not check for updates.</source>
|
||||||
|
<translation>
|
||||||
|
|
||||||
|
Konnte nicht nach Updates suchen.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../modules/core.py" line="34"/>
|
||||||
|
<source>
|
||||||
|
|
||||||
|
There's a newer version of NUSGet available!</source>
|
||||||
|
<translation>
|
||||||
|
|
||||||
|
Eine neuere Version von NUSGet ist verfügbar.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../modules/core.py" line="36"/>
|
||||||
|
<source>
|
||||||
|
|
||||||
|
You're running the latest release of NUSGet.</source>
|
||||||
|
<translatorcomment>Like previously, we're trying to refer to the user less directly (since it sounds awkard in German)</translatorcomment>
|
||||||
|
<translation>
|
||||||
|
|
||||||
|
Die neuste Version von NUSGet ist bereits aktiv.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="26"/>
|
||||||
|
<source>MainWindow</source>
|
||||||
|
<translatorcomment>This title isn't shown</translatorcomment>
|
||||||
|
<translation>Hauptmenü</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="43"/>
|
||||||
|
<source>Available Titles</source>
|
||||||
|
<translation>Verfügbare Titel</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="72"/>
|
||||||
|
<source>Wii</source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="103"/>
|
||||||
|
<source>vWii</source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="134"/>
|
||||||
|
<source>DSi</source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="174"/>
|
||||||
|
<source>Title ID</source>
|
||||||
|
<translatorcomment>We do not translate "Title ID" beyond making it grammatically correct (hence the dash), since it refers to a NUS specific component</translatorcomment>
|
||||||
|
<translation>Title-ID</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="181"/>
|
||||||
|
<source>v</source>
|
||||||
|
<translatorcomment>Since vNNNNN is a common way of referring to versions across the Wii both by Nintendo and modders, we keep it identical</translatorcomment>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="194"/>
|
||||||
|
<source>Version</source>
|
||||||
|
<translatorcomment>The same word is used in German</translatorcomment>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="201"/>
|
||||||
|
<source>Console:</source>
|
||||||
|
<translation>Konsole:</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="237"/>
|
||||||
|
<source>Start Download</source>
|
||||||
|
<translation>Herunterladen</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="250"/>
|
||||||
|
<source>Run Script</source>
|
||||||
|
<translation>Script starten</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="277"/>
|
||||||
|
<source>General Settings</source>
|
||||||
|
<translation>Einstellungen</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="308"/>
|
||||||
|
<source>Pack installable archive (WAD/TAD)</source>
|
||||||
|
<translation>Installierbar verpacken (WAD/TAD)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="323"/>
|
||||||
|
<source>File Name</source>
|
||||||
|
<translation>Dateiname</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="357"/>
|
||||||
|
<source>Keep encrypted contents</source>
|
||||||
|
<translation>Verschlüsselte Inhalte speichern</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="393"/>
|
||||||
|
<source>Create decrypted contents (*.app)</source>
|
||||||
|
<translation>Entschlüsselte Inhalte speichern (*.app)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="432"/>
|
||||||
|
<source>Use local files, if they exist</source>
|
||||||
|
<translation>Lokale Dateien nutzen, sofern verfügbar</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="477"/>
|
||||||
|
<source>Use the Wii U NUS (faster, only effects Wii/vWii)</source>
|
||||||
|
<translation>Wii U-NUS nutzen (schneller, gilt nur für Wii/vWii)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="519"/>
|
||||||
|
<source>Apply patches to IOS (Applies to WADs only)</source>
|
||||||
|
<translatorcomment>"Patch" does not have a good translation into German, and in most modding forums, it's used as is</translatorcomment>
|
||||||
|
<translation>Patches für IOS anwenden (Gilt nur für WAD)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="575"/>
|
||||||
|
<source>vWii Title Settings</source>
|
||||||
|
<translation>vWii Titel-Einstellungen</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="609"/>
|
||||||
|
<source>Re-encrypt title using the Wii Common Key</source>
|
||||||
|
<translatorcomment>Common key does not get translated</translatorcomment>
|
||||||
|
<translation>Titel mit dem Common-Key der Wii neu verschlüsseln</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="666"/>
|
||||||
|
<source><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||||
|
<html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><style type="text/css">
|
||||||
|
p, li { white-space: pre-wrap; }
|
||||||
|
hr { height: 1px; border-width: 0; }
|
||||||
|
li.unchecked::marker { content: "\2610"; }
|
||||||
|
li.checked::marker { content: "\2612"; }
|
||||||
|
</style></head><body style=" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;">
|
||||||
|
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html></source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
</TS>
|
||||||
288
resources/translations/nusget_es.ts
Normal file
288
resources/translations/nusget_es.ts
Normal file
@@ -0,0 +1,288 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!DOCTYPE TS>
|
||||||
|
<TS version="2.1" language="es_ES">
|
||||||
|
<context>
|
||||||
|
<name>MainWindow</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="72"/>
|
||||||
|
<source>Wii</source>
|
||||||
|
<translatorcomment>Does not change.</translatorcomment>
|
||||||
|
<translation type="unfinished">Wii</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="103"/>
|
||||||
|
<source>vWii</source>
|
||||||
|
<translatorcomment>Does not change.</translatorcomment>
|
||||||
|
<translation>vWii</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="134"/>
|
||||||
|
<source>DSi</source>
|
||||||
|
<translatorcomment>Does not change.</translatorcomment>
|
||||||
|
<translation>DSi</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="181"/>
|
||||||
|
<source>v</source>
|
||||||
|
<translatorcomment>Does not change.</translatorcomment>
|
||||||
|
<translation>v</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="26"/>
|
||||||
|
<source>MainWindow</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="43"/>
|
||||||
|
<source>Available Titles</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="174"/>
|
||||||
|
<source>Title ID</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="194"/>
|
||||||
|
<source>Version</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="201"/>
|
||||||
|
<source>Console:</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="237"/>
|
||||||
|
<source>Start Download</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="250"/>
|
||||||
|
<source>Run Script</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="277"/>
|
||||||
|
<source>General Settings</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="308"/>
|
||||||
|
<source>Pack installable archive (WAD/TAD)</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="323"/>
|
||||||
|
<source>File Name</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="357"/>
|
||||||
|
<source>Keep encrypted contents</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="393"/>
|
||||||
|
<source>Create decrypted contents (*.app)</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="432"/>
|
||||||
|
<source>Use local files, if they exist</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="477"/>
|
||||||
|
<source>Use the Wii U NUS (faster, only effects Wii/vWii)</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="575"/>
|
||||||
|
<source>vWii Title Settings</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="609"/>
|
||||||
|
<source>Re-encrypt title using the Wii Common Key</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="666"/>
|
||||||
|
<source><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||||
|
<html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><style type="text/css">
|
||||||
|
p, li { white-space: pre-wrap; }
|
||||||
|
hr { height: 1px; border-width: 0; }
|
||||||
|
li.unchecked::marker { content: "\2610"; }
|
||||||
|
li.checked::marker { content: "\2612"; }
|
||||||
|
</style></head><body style=" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;">
|
||||||
|
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html></source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="519"/>
|
||||||
|
<source>Apply patches to IOS (Applies to WADs only)</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="85"/>
|
||||||
|
<source>NUSGet v{nusget_version}
|
||||||
|
Developed by NinjaCheetah
|
||||||
|
Powered by libWiiPy {libwiipy_version}
|
||||||
|
DSi support provided by libTWLPy {libtwlpy_version}
|
||||||
|
|
||||||
|
Select a title from the list on the left, or enter a Title ID to begin.
|
||||||
|
|
||||||
|
Titles marked with a checkmark are free and have a ticket available, and can be decrypted and/or packed into a WAD or TAD. Titles with an X do not have a ticket, and only their encrypted contents can be saved.
|
||||||
|
|
||||||
|
Titles will be downloaded to a folder named "NUSGet" inside your downloads folder.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="184"/>
|
||||||
|
<source>NUSGet Update Available</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="185"/>
|
||||||
|
<source>There's a newer version of NUSGet available!</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="264"/>
|
||||||
|
<source>No Output Selected</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="265"/>
|
||||||
|
<source>You have not selected any format to output the data in!</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="267"/>
|
||||||
|
<source>Please select at least one option for how you would like the download to be saved.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="298"/>
|
||||||
|
<source>Invalid Title ID</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="299"/>
|
||||||
|
<source>The Title ID you have entered is not in a valid format!</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="301"/>
|
||||||
|
<source>Title IDs must be 16 digit strings of numbers and letters. Please enter a correctly formatted Title ID, or select one from the menu on the left.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="303"/>
|
||||||
|
<source>Title ID/Version Not Found</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="304"/>
|
||||||
|
<source>No title with the provided Title ID or version could be found!</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="306"/>
|
||||||
|
<source>Please make sure that you have entered a valid Title ID, or selected one from the title database, and that the provided version exists for the title you are attempting to download.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="308"/>
|
||||||
|
<source>Content Decryption Failed</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="309"/>
|
||||||
|
<source>Content decryption was not successful! Decrypted contents could not be created.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="312"/>
|
||||||
|
<source>Your TMD or Ticket may be damaged, or they may not correspond with the content being decrypted. If you have checked "Use local files, if they exist", try disabling that option before trying the download again to fix potential issues with local data.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="315"/>
|
||||||
|
<source>Ticket Not Available</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="316"/>
|
||||||
|
<source>No Ticket is Available for the Requested Title!</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="319"/>
|
||||||
|
<source>A ticket could not be downloaded for the requested title, but you have selected "Pack installable archive" or "Create decrypted contents". These options are not available for titles without a ticket. Only encrypted contents have been saved.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="321"/>
|
||||||
|
<source>Unknown Error</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="322"/>
|
||||||
|
<source>An Unknown Error has Occurred!</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="324"/>
|
||||||
|
<source>Please try again. If this issue persists, please open a new issue on GitHub detailing what you were trying to do when this error occurred.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="364"/>
|
||||||
|
<source>Open NUS script</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="364"/>
|
||||||
|
<source>NUS Scripts (*.nus *.txt)</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="371"/>
|
||||||
|
<location filename="../../NUSGet.py" line="386"/>
|
||||||
|
<location filename="../../NUSGet.py" line="389"/>
|
||||||
|
<location filename="../../NUSGet.py" line="397"/>
|
||||||
|
<location filename="../../NUSGet.py" line="415"/>
|
||||||
|
<location filename="../../NUSGet.py" line="422"/>
|
||||||
|
<source>Script Failure</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="371"/>
|
||||||
|
<source>Failed to open the script.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../modules/core.py" line="26"/>
|
||||||
|
<source>
|
||||||
|
|
||||||
|
Could not check for updates.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../modules/core.py" line="34"/>
|
||||||
|
<source>
|
||||||
|
|
||||||
|
There's a newer version of NUSGet available!</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../modules/core.py" line="36"/>
|
||||||
|
<source>
|
||||||
|
|
||||||
|
You're running the latest release of NUSGet.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
</TS>
|
||||||
284
resources/translations/nusget_fr.ts
Normal file
284
resources/translations/nusget_fr.ts
Normal file
@@ -0,0 +1,284 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!DOCTYPE TS>
|
||||||
|
<TS version="2.1" language="fr_FR">
|
||||||
|
<context>
|
||||||
|
<name>MainWindow</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="85"/>
|
||||||
|
<source>NUSGet v{nusget_version}
|
||||||
|
Developed by NinjaCheetah
|
||||||
|
Powered by libWiiPy {libwiipy_version}
|
||||||
|
DSi support provided by libTWLPy {libtwlpy_version}
|
||||||
|
|
||||||
|
Select a title from the list on the left, or enter a Title ID to begin.
|
||||||
|
|
||||||
|
Titles marked with a checkmark are free and have a ticket available, and can be decrypted and/or packed into a WAD or TAD. Titles with an X do not have a ticket, and only their encrypted contents can be saved.
|
||||||
|
|
||||||
|
Titles will be downloaded to a folder named "NUSGet" inside your downloads folder.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="184"/>
|
||||||
|
<source>NUSGet Update Available</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="185"/>
|
||||||
|
<source>There's a newer version of NUSGet available!</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="264"/>
|
||||||
|
<source>No Output Selected</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="265"/>
|
||||||
|
<source>You have not selected any format to output the data in!</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="267"/>
|
||||||
|
<source>Please select at least one option for how you would like the download to be saved.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="298"/>
|
||||||
|
<source>Invalid Title ID</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="299"/>
|
||||||
|
<source>The Title ID you have entered is not in a valid format!</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="301"/>
|
||||||
|
<source>Title IDs must be 16 digit strings of numbers and letters. Please enter a correctly formatted Title ID, or select one from the menu on the left.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="303"/>
|
||||||
|
<source>Title ID/Version Not Found</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="304"/>
|
||||||
|
<source>No title with the provided Title ID or version could be found!</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="306"/>
|
||||||
|
<source>Please make sure that you have entered a valid Title ID, or selected one from the title database, and that the provided version exists for the title you are attempting to download.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="308"/>
|
||||||
|
<source>Content Decryption Failed</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="309"/>
|
||||||
|
<source>Content decryption was not successful! Decrypted contents could not be created.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="312"/>
|
||||||
|
<source>Your TMD or Ticket may be damaged, or they may not correspond with the content being decrypted. If you have checked "Use local files, if they exist", try disabling that option before trying the download again to fix potential issues with local data.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="315"/>
|
||||||
|
<source>Ticket Not Available</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="316"/>
|
||||||
|
<source>No Ticket is Available for the Requested Title!</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="319"/>
|
||||||
|
<source>A ticket could not be downloaded for the requested title, but you have selected "Pack installable archive" or "Create decrypted contents". These options are not available for titles without a ticket. Only encrypted contents have been saved.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="321"/>
|
||||||
|
<source>Unknown Error</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="322"/>
|
||||||
|
<source>An Unknown Error has Occurred!</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="324"/>
|
||||||
|
<source>Please try again. If this issue persists, please open a new issue on GitHub detailing what you were trying to do when this error occurred.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="364"/>
|
||||||
|
<source>Open NUS script</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="364"/>
|
||||||
|
<source>NUS Scripts (*.nus *.txt)</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="371"/>
|
||||||
|
<location filename="../../NUSGet.py" line="386"/>
|
||||||
|
<location filename="../../NUSGet.py" line="389"/>
|
||||||
|
<location filename="../../NUSGet.py" line="397"/>
|
||||||
|
<location filename="../../NUSGet.py" line="415"/>
|
||||||
|
<location filename="../../NUSGet.py" line="422"/>
|
||||||
|
<source>Script Failure</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="371"/>
|
||||||
|
<source>Failed to open the script.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="26"/>
|
||||||
|
<source>MainWindow</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="43"/>
|
||||||
|
<source>Available Titles</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="72"/>
|
||||||
|
<source>Wii</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="103"/>
|
||||||
|
<source>vWii</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="134"/>
|
||||||
|
<source>DSi</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="174"/>
|
||||||
|
<source>Title ID</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="181"/>
|
||||||
|
<source>v</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="194"/>
|
||||||
|
<source>Version</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="201"/>
|
||||||
|
<source>Console:</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="237"/>
|
||||||
|
<source>Start Download</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="250"/>
|
||||||
|
<source>Run Script</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="277"/>
|
||||||
|
<source>General Settings</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="308"/>
|
||||||
|
<source>Pack installable archive (WAD/TAD)</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="323"/>
|
||||||
|
<source>File Name</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="357"/>
|
||||||
|
<source>Keep encrypted contents</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="393"/>
|
||||||
|
<source>Create decrypted contents (*.app)</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="432"/>
|
||||||
|
<source>Use local files, if they exist</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="477"/>
|
||||||
|
<source>Use the Wii U NUS (faster, only effects Wii/vWii)</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="519"/>
|
||||||
|
<source>Apply patches to IOS (Applies to WADs only)</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="575"/>
|
||||||
|
<source>vWii Title Settings</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="609"/>
|
||||||
|
<source>Re-encrypt title using the Wii Common Key</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="666"/>
|
||||||
|
<source><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||||
|
<html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><style type="text/css">
|
||||||
|
p, li { white-space: pre-wrap; }
|
||||||
|
hr { height: 1px; border-width: 0; }
|
||||||
|
li.unchecked::marker { content: "\2610"; }
|
||||||
|
li.checked::marker { content: "\2612"; }
|
||||||
|
</style></head><body style=" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;">
|
||||||
|
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html></source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../modules/core.py" line="26"/>
|
||||||
|
<source>
|
||||||
|
|
||||||
|
Could not check for updates.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../modules/core.py" line="34"/>
|
||||||
|
<source>
|
||||||
|
|
||||||
|
There's a newer version of NUSGet available!</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../modules/core.py" line="36"/>
|
||||||
|
<source>
|
||||||
|
|
||||||
|
You're running the latest release of NUSGet.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
</TS>
|
||||||
311
resources/translations/nusget_it.ts
Normal file
311
resources/translations/nusget_it.ts
Normal file
@@ -0,0 +1,311 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!DOCTYPE TS>
|
||||||
|
<TS version="2.1" language="it_IT">
|
||||||
|
<context>
|
||||||
|
<name>MainWindow</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="26"/>
|
||||||
|
<source>MainWindow</source>
|
||||||
|
<translation>Finestra principale</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="43"/>
|
||||||
|
<source>Available Titles</source>
|
||||||
|
<translation>Titoli disponibili</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="72"/>
|
||||||
|
<source>Wii</source>
|
||||||
|
<translation>Wii</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="103"/>
|
||||||
|
<source>vWii</source>
|
||||||
|
<translation>vWii</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="134"/>
|
||||||
|
<source>DSi</source>
|
||||||
|
<translation>DSi</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="174"/>
|
||||||
|
<source>Title ID</source>
|
||||||
|
<translation>ID Titolo</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="181"/>
|
||||||
|
<source>v</source>
|
||||||
|
<translation>v</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="194"/>
|
||||||
|
<source>Version</source>
|
||||||
|
<translation>Versione</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="201"/>
|
||||||
|
<source>Console:</source>
|
||||||
|
<translation>Console:</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="237"/>
|
||||||
|
<source>Start Download</source>
|
||||||
|
<translation>Avvia download</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="250"/>
|
||||||
|
<source>Run Script</source>
|
||||||
|
<translation>Avvia Script</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="277"/>
|
||||||
|
<source>General Settings</source>
|
||||||
|
<translation>Impostazioni generali</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="308"/>
|
||||||
|
<source>Pack installable archive (WAD/TAD)</source>
|
||||||
|
<translation>Archivio installabile (WAD/TAD)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="323"/>
|
||||||
|
<source>File Name</source>
|
||||||
|
<translation>Nome del file</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="357"/>
|
||||||
|
<source>Keep encrypted contents</source>
|
||||||
|
<translation>Mantieni contenuti criptati</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="393"/>
|
||||||
|
<source>Create decrypted contents (*.app)</source>
|
||||||
|
<translation>Crea contenuto decriptato (*.app)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="432"/>
|
||||||
|
<source>Use local files, if they exist</source>
|
||||||
|
<translation>Usa file locali, se esistenti</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="477"/>
|
||||||
|
<source>Use the Wii U NUS (faster, only effects Wii/vWii)</source>
|
||||||
|
<translation>Usa il NUS di Wii U (più veloce, riguarda solo Wii/vWii)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="575"/>
|
||||||
|
<source>vWii Title Settings</source>
|
||||||
|
<translation>Impostazioni titoli vWii</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="609"/>
|
||||||
|
<source>Re-encrypt title using the Wii Common Key</source>
|
||||||
|
<translation>Cripta titolo usando la Chiave Comune Wii</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="666"/>
|
||||||
|
<source><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||||
|
<html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><style type="text/css">
|
||||||
|
p, li { white-space: pre-wrap; }
|
||||||
|
hr { height: 1px; border-width: 0; }
|
||||||
|
li.unchecked::marker { content: "\2610"; }
|
||||||
|
li.checked::marker { content: "\2612"; }
|
||||||
|
</style></head><body style=" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;">
|
||||||
|
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html></source>
|
||||||
|
<translation><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||||
|
<html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><style type="text/css">
|
||||||
|
p, li { white-space: pre-wrap; }
|
||||||
|
hr { height: 1px; border-width: 0; }
|
||||||
|
li.unchecked::marker { content: "\2610"; }
|
||||||
|
li.checked::marker { content: "\2612"; }
|
||||||
|
</style></head><body style=" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;">
|
||||||
|
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||||
|
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||||
|
p, li { white-space: pre-wrap; }
|
||||||
|
</style></head><body style=" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;">
|
||||||
|
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html></source>
|
||||||
|
<translation type="vanished"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||||
|
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||||
|
p, li { white-space: pre-wrap; }
|
||||||
|
</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;">
|
||||||
|
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="264"/>
|
||||||
|
<source>No Output Selected</source>
|
||||||
|
<translation>Nessun output selezionato</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="265"/>
|
||||||
|
<source>You have not selected any format to output the data in!</source>
|
||||||
|
<translation>Non hai selezionato alcun formato in cui esportare i dati!</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="267"/>
|
||||||
|
<source>Please select at least one option for how you would like the download to be saved.</source>
|
||||||
|
<translation>Per favore scegli almeno un opzione per come vorresti che fosse salvato il download.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="298"/>
|
||||||
|
<source>Invalid Title ID</source>
|
||||||
|
<translation>ID Titolo invalido</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="299"/>
|
||||||
|
<source>The Title ID you have entered is not in a valid format!</source>
|
||||||
|
<translation>L' ID Titolo che hai inserito non è in un formato valido!</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="301"/>
|
||||||
|
<source>Title IDs must be 16 digit strings of numbers and letters. Please enter a correctly formatted Title ID, or select one from the menu on the left.</source>
|
||||||
|
<translation>Gli ID Titolo sono un codice di 16 caratteri tra numeri e lettere. Per favore inserisci in ID Titolo formattato correttamente, o scegline uno dal menù a sinistra.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="303"/>
|
||||||
|
<source>Title ID/Version Not Found</source>
|
||||||
|
<translation>ID Titolo/Versione non trovata</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="304"/>
|
||||||
|
<source>No title with the provided Title ID or version could be found!</source>
|
||||||
|
<translation>Non è stato trovato nessun titolo con l' ID Titolo o versione data!</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="306"/>
|
||||||
|
<source>Please make sure that you have entered a valid Title ID, or selected one from the title database, and that the provided version exists for the title you are attempting to download.</source>
|
||||||
|
<translation>Assicurati di aver inserito un' ID Titolo valido, o scegline uno dal database, e che la versione richiesta esista per il titolo che vuoi scaricare.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="308"/>
|
||||||
|
<source>Content Decryption Failed</source>
|
||||||
|
<translation>Decriptazione contenuti fallita</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="309"/>
|
||||||
|
<source>Content decryption was not successful! Decrypted contents could not be created.</source>
|
||||||
|
<translation>La decriptazione dei contenuti non è andata a buon fine! I contenuti decriptadi non sono stati creati.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="312"/>
|
||||||
|
<source>Your TMD or Ticket may be damaged, or they may not correspond with the content being decrypted. If you have checked "Use local files, if they exist", try disabling that option before trying the download again to fix potential issues with local data.</source>
|
||||||
|
<translation>Il tuo TMD o Ticket potrebbe essere danneggiato, o potrebbe non corrispondere col contenuto da decriptare. Se hai selezionato "Usa file locali, se esistenti", prova a disabilitare quell'opzione prima di riprovare a scaricare per aggiustare potenziali errori coi dati locali.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="315"/>
|
||||||
|
<source>Ticket Not Available</source>
|
||||||
|
<translation>Ticket non disponibile</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="316"/>
|
||||||
|
<source>No Ticket is Available for the Requested Title!</source>
|
||||||
|
<translation>Nessun ticket disponibile per il titolo richiesto!</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="319"/>
|
||||||
|
<source>A ticket could not be downloaded for the requested title, but you have selected "Pack installable archive" or "Create decrypted contents". These options are not available for titles without a ticket. Only encrypted contents have been saved.</source>
|
||||||
|
<translation>Non è stato possibile scaricare un ticket per il titolo richiesto, ma hai selezionato "Crea archivio installabile" o "Crea contenuto decriptato". Queste opzioni non sono disponibili per i titoli senza un ticket. Sono stati salvati solo i contenuti criptati.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="321"/>
|
||||||
|
<source>Unknown Error</source>
|
||||||
|
<translation>Errore sconosciuto</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="322"/>
|
||||||
|
<source>An Unknown Error has Occurred!</source>
|
||||||
|
<translation>Errore sconosciuto!</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="324"/>
|
||||||
|
<source>Please try again. If this issue persists, please open a new issue on GitHub detailing what you were trying to do when this error occurred.</source>
|
||||||
|
<translation>Per favore riprova. Se il problema persiste, apri un issue su GitHub specificando in modo dettagliato cosa volevi fare quando è comparso questo errore.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="364"/>
|
||||||
|
<source>Open NUS script</source>
|
||||||
|
<translation>Apri script NUS</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="364"/>
|
||||||
|
<source>NUS Scripts (*.nus *.txt)</source>
|
||||||
|
<translation>Scrpit NUS (*.nus *.txt)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="371"/>
|
||||||
|
<location filename="../../NUSGet.py" line="386"/>
|
||||||
|
<location filename="../../NUSGet.py" line="389"/>
|
||||||
|
<location filename="../../NUSGet.py" line="397"/>
|
||||||
|
<location filename="../../NUSGet.py" line="415"/>
|
||||||
|
<location filename="../../NUSGet.py" line="422"/>
|
||||||
|
<source>Script Failure</source>
|
||||||
|
<translation>Errore script</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="371"/>
|
||||||
|
<source>Failed to open the script.</source>
|
||||||
|
<translation>Impossibile aprire lo script.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="85"/>
|
||||||
|
<source>NUSGet v{nusget_version}
|
||||||
|
Developed by NinjaCheetah
|
||||||
|
Powered by libWiiPy {libwiipy_version}
|
||||||
|
DSi support provided by libTWLPy {libtwlpy_version}
|
||||||
|
|
||||||
|
Select a title from the list on the left, or enter a Title ID to begin.
|
||||||
|
|
||||||
|
Titles marked with a checkmark are free and have a ticket available, and can be decrypted and/or packed into a WAD or TAD. Titles with an X do not have a ticket, and only their encrypted contents can be saved.
|
||||||
|
|
||||||
|
Titles will be downloaded to a folder named "NUSGet" inside your downloads folder.</source>
|
||||||
|
<translation>NUSGet v{nusget_version}
|
||||||
|
Sviluppato da NinjaCheetah
|
||||||
|
Funzionante con libWiiPy {libwiipy_version}
|
||||||
|
|
||||||
|
Scegli un tittolo dalla lista a sinistra o inserisci un ID Titolo per iniziare.
|
||||||
|
|
||||||
|
I titoli marcati da una spunta sono disponibili e hanno un ticket libero, e possono essere decriptati/scaricati come WAD o TAD. I titoli con una X non hanno un ticket e solo il contenuto criptato può essere salvato.
|
||||||
|
|
||||||
|
I titoli verranno scaricati nella cartella "NUSGet" all'interno della cartella Download.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="519"/>
|
||||||
|
<source>Apply patches to IOS (Applies to WADs only)</source>
|
||||||
|
<translation>Applica patch agli IOS (Solo per le WAD)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="184"/>
|
||||||
|
<source>NUSGet Update Available</source>
|
||||||
|
<translation>Aggiornamento di NUSGet disponibile</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="185"/>
|
||||||
|
<source>There's a newer version of NUSGet available!</source>
|
||||||
|
<translation>Una nuova versione di NUSGet è disponibile!</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../modules/core.py" line="26"/>
|
||||||
|
<source>
|
||||||
|
|
||||||
|
Could not check for updates.</source>
|
||||||
|
<translation>Impossibile trovare eventuali aggiornamenti.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../modules/core.py" line="34"/>
|
||||||
|
<source>
|
||||||
|
|
||||||
|
There's a newer version of NUSGet available!</source>
|
||||||
|
<translation>Una nuova versione di NUSGet è disponibile!</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../modules/core.py" line="36"/>
|
||||||
|
<source>
|
||||||
|
|
||||||
|
You're running the latest release of NUSGet.</source>
|
||||||
|
<translation>Stai utilizzando l'ultima versione di NUSGet.</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
</TS>
|
||||||
305
resources/translations/nusget_nb.ts
Normal file
305
resources/translations/nusget_nb.ts
Normal file
@@ -0,0 +1,305 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!DOCTYPE TS>
|
||||||
|
<TS version="2.1" language="nb_NO">
|
||||||
|
<context>
|
||||||
|
<name>MainWindow</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="26"/>
|
||||||
|
<source>MainWindow</source>
|
||||||
|
<translation>MainWindow</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="43"/>
|
||||||
|
<source>Available Titles</source>
|
||||||
|
<translation>Tilgjengelige Titler</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="72"/>
|
||||||
|
<source>Wii</source>
|
||||||
|
<translation>Wii</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="103"/>
|
||||||
|
<source>vWii</source>
|
||||||
|
<translation>vWii</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="134"/>
|
||||||
|
<source>DSi</source>
|
||||||
|
<translation>DSi</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="174"/>
|
||||||
|
<source>Title ID</source>
|
||||||
|
<translation>Tittel ID</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="181"/>
|
||||||
|
<source>v</source>
|
||||||
|
<translation>v</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="194"/>
|
||||||
|
<source>Version</source>
|
||||||
|
<translation>Versjon</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="201"/>
|
||||||
|
<source>Console:</source>
|
||||||
|
<translation>Konsoll:</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="237"/>
|
||||||
|
<source>Start Download</source>
|
||||||
|
<translation>Start Nedlasting</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="250"/>
|
||||||
|
<source>Run Script</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="277"/>
|
||||||
|
<source>General Settings</source>
|
||||||
|
<translation>Generelle Instillinger</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="308"/>
|
||||||
|
<source>Pack installable archive (WAD/TAD)</source>
|
||||||
|
<translation>Pakke installerbart arkiv (WAD/TAD)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="323"/>
|
||||||
|
<source>File Name</source>
|
||||||
|
<translation>Filnavn</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="357"/>
|
||||||
|
<source>Keep encrypted contents</source>
|
||||||
|
<translation>Oppbevar kryptert innhold</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="393"/>
|
||||||
|
<source>Create decrypted contents (*.app)</source>
|
||||||
|
<translation>Opprette dekryptert innold (*.app)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="432"/>
|
||||||
|
<source>Use local files, if they exist</source>
|
||||||
|
<translation>Bruk lokale filer, hvis de finnes</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="477"/>
|
||||||
|
<source>Use the Wii U NUS (faster, only effects Wii/vWii)</source>
|
||||||
|
<translation>Bruk Wii U NUS (raskere, påvirker bare Wii/vWii)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="575"/>
|
||||||
|
<source>vWii Title Settings</source>
|
||||||
|
<translation>vWii Tittelinstillinger</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="609"/>
|
||||||
|
<source>Re-encrypt title using the Wii Common Key</source>
|
||||||
|
<translation>Krypter tittelen på nytt ved hjelp av Wii Common Key</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="666"/>
|
||||||
|
<source><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||||
|
<html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><style type="text/css">
|
||||||
|
p, li { white-space: pre-wrap; }
|
||||||
|
hr { height: 1px; border-width: 0; }
|
||||||
|
li.unchecked::marker { content: "\2610"; }
|
||||||
|
li.checked::marker { content: "\2612"; }
|
||||||
|
</style></head><body style=" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;">
|
||||||
|
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html></source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||||
|
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||||
|
p, li { white-space: pre-wrap; }
|
||||||
|
</style></head><body style=" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;">
|
||||||
|
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html></source>
|
||||||
|
<translation type="vanished"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||||
|
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||||
|
p, li { white-space: pre-wrap; }
|
||||||
|
</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;">
|
||||||
|
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="85"/>
|
||||||
|
<source>NUSGet v{nusget_version}
|
||||||
|
Developed by NinjaCheetah
|
||||||
|
Powered by libWiiPy {libwiipy_version}
|
||||||
|
DSi support provided by libTWLPy {libtwlpy_version}
|
||||||
|
|
||||||
|
Select a title from the list on the left, or enter a Title ID to begin.
|
||||||
|
|
||||||
|
Titles marked with a checkmark are free and have a ticket available, and can be decrypted and/or packed into a WAD or TAD. Titles with an X do not have a ticket, and only their encrypted contents can be saved.
|
||||||
|
|
||||||
|
Titles will be downloaded to a folder named "NUSGet" inside your downloads folder.</source>
|
||||||
|
<translation>NUSGet v{nusget_version}
|
||||||
|
Utviklet av NinjaCheetah
|
||||||
|
Drevet av libWiiPy {libwiipy_version}
|
||||||
|
DSi støtte levert av libTWLPy {libtwlpy_version}
|
||||||
|
|
||||||
|
Velg en tittel fra listen til venstre, eller skriv inn en Tittel ID for å begynne.
|
||||||
|
|
||||||
|
Titler merket med en hake er fri og har en billett tilgjengelig, og kan dekrypteres og/eller pakkes inn i en WAD eller TAD. Titler med en X ikke har en billett, og bare det krypterte innholdet kan lagres.
|
||||||
|
|
||||||
|
Titler er lastes ned til en mappe med navnet "NUSGet" i nedlastingsmappen din.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="264"/>
|
||||||
|
<source>No Output Selected</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="265"/>
|
||||||
|
<source>You have not selected any format to output the data in!</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="267"/>
|
||||||
|
<source>Please select at least one option for how you would like the download to be saved.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="298"/>
|
||||||
|
<source>Invalid Title ID</source>
|
||||||
|
<translation>Ugyldig Tittel ID</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="299"/>
|
||||||
|
<source>The Title ID you have entered is not in a valid format!</source>
|
||||||
|
<translation>Tittel IDen du har angitt er ikke i et gyldig format!</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="301"/>
|
||||||
|
<source>Title IDs must be 16 digit strings of numbers and letters. Please enter a correctly formatted Title ID, or select one from the menu on the left.</source>
|
||||||
|
<translation>Tittel IDer må være 16-sifrede tall og bokstav strenger. Vennligst skriv inn en korrekt formatert Tittel ID, eller velg en fra menyen til venstre.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="303"/>
|
||||||
|
<source>Title ID/Version Not Found</source>
|
||||||
|
<translation>Tittel ID/Versjon Ikke Funnet</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="304"/>
|
||||||
|
<source>No title with the provided Title ID or version could be found!</source>
|
||||||
|
<translation>Ingen tittel med oppgitt Tittel ID eller versjon ble funnet!</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="306"/>
|
||||||
|
<source>Please make sure that you have entered a valid Title ID, or selected one from the title database, and that the provided version exists for the title you are attempting to download.</source>
|
||||||
|
<translation>Vennligst kontroller at du har oppgitt en gyldig Tittel ID, eller valgt en fra titteldatabasen, og at den angitte versjonen finnes for tittelen du forsøker å laste ned.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="308"/>
|
||||||
|
<source>Content Decryption Failed</source>
|
||||||
|
<translation>Dekryptering av Innhold Mislyktes</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="309"/>
|
||||||
|
<source>Content decryption was not successful! Decrypted contents could not be created.</source>
|
||||||
|
<translation>Dekryptering av innhold var ikke vellykket! Dekryptert innhold kunne ikke opprettes.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="312"/>
|
||||||
|
<source>Your TMD or Ticket may be damaged, or they may not correspond with the content being decrypted. If you have checked "Use local files, if they exist", try disabling that option before trying the download again to fix potential issues with local data.</source>
|
||||||
|
<translation>TMDen eller Billetten kan være skadet, eller det kan hende at de ikke samsvarer med innholdet some dekrypteres. Hvis du har krysset av for "Bruk lokale filer, hvis de finnes", kan du prøve å deaktivere dette alternativet før du prøver nedlastingen på nytt for å løse eventuelle problemer med lokale data.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="315"/>
|
||||||
|
<source>Ticket Not Available</source>
|
||||||
|
<translation>Billett Ikke Tilgjengelig</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="316"/>
|
||||||
|
<source>No Ticket is Available for the Requested Title!</source>
|
||||||
|
<translation>Ingen billett er tilgjengelig for den forespurte tittelen!</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="319"/>
|
||||||
|
<source>A ticket could not be downloaded for the requested title, but you have selected "Pack installable archive" or "Create decrypted contents". These options are not available for titles without a ticket. Only encrypted contents have been saved.</source>
|
||||||
|
<translation>En billett kunne ikke lastes ned for den forespurte tittelen, men du har valgt "Pakk installerbart arkiv" eller "Opprett dekryptert innhold". Disse alternativene er ikke tilgjenelige for titler uten billett. Bare kryptert innhold har blitt lagret.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="321"/>
|
||||||
|
<source>Unknown Error</source>
|
||||||
|
<translation>Ukjent Feil</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="322"/>
|
||||||
|
<source>An Unknown Error has Occurred!</source>
|
||||||
|
<translation>En ukjent feil har oppstått!</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="324"/>
|
||||||
|
<source>Please try again. If this issue persists, please open a new issue on GitHub detailing what you were trying to do when this error occurred.</source>
|
||||||
|
<translation>Vennligst prøv igjen. Hvis dette problemet vedvarer, åpne et nytt issue på GitHub med detaljer om hva du prøvde å gjøre da denne feilen oppstod.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="364"/>
|
||||||
|
<source>Open NUS script</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="364"/>
|
||||||
|
<source>NUS Scripts (*.nus *.txt)</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="371"/>
|
||||||
|
<location filename="../../NUSGet.py" line="386"/>
|
||||||
|
<location filename="../../NUSGet.py" line="389"/>
|
||||||
|
<location filename="../../NUSGet.py" line="397"/>
|
||||||
|
<location filename="../../NUSGet.py" line="415"/>
|
||||||
|
<location filename="../../NUSGet.py" line="422"/>
|
||||||
|
<source>Script Failure</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="371"/>
|
||||||
|
<source>Failed to open the script.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="519"/>
|
||||||
|
<source>Apply patches to IOS (Applies to WADs only)</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="184"/>
|
||||||
|
<source>NUSGet Update Available</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="185"/>
|
||||||
|
<source>There's a newer version of NUSGet available!</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../modules/core.py" line="26"/>
|
||||||
|
<source>
|
||||||
|
|
||||||
|
Could not check for updates.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../modules/core.py" line="34"/>
|
||||||
|
<source>
|
||||||
|
|
||||||
|
There's a newer version of NUSGet available!</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../modules/core.py" line="36"/>
|
||||||
|
<source>
|
||||||
|
|
||||||
|
You're running the latest release of NUSGet.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
</TS>
|
||||||
305
resources/translations/nusget_no.ts
Normal file
305
resources/translations/nusget_no.ts
Normal file
@@ -0,0 +1,305 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!DOCTYPE TS>
|
||||||
|
<TS version="2.1" language="nb_NO">
|
||||||
|
<context>
|
||||||
|
<name>MainWindow</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="26"/>
|
||||||
|
<source>MainWindow</source>
|
||||||
|
<translation>MainWindow</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="43"/>
|
||||||
|
<source>Available Titles</source>
|
||||||
|
<translation>Tilgjengelige Titler</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="72"/>
|
||||||
|
<source>Wii</source>
|
||||||
|
<translation>Wii</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="103"/>
|
||||||
|
<source>vWii</source>
|
||||||
|
<translation>vWii</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="134"/>
|
||||||
|
<source>DSi</source>
|
||||||
|
<translation>DSi</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="174"/>
|
||||||
|
<source>Title ID</source>
|
||||||
|
<translation>Tittel ID</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="181"/>
|
||||||
|
<source>v</source>
|
||||||
|
<translation>v</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="194"/>
|
||||||
|
<source>Version</source>
|
||||||
|
<translation>Versjon</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="201"/>
|
||||||
|
<source>Console:</source>
|
||||||
|
<translation>Konsoll:</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="237"/>
|
||||||
|
<source>Start Download</source>
|
||||||
|
<translation>Start Nedlasting</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="250"/>
|
||||||
|
<source>Run Script</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="277"/>
|
||||||
|
<source>General Settings</source>
|
||||||
|
<translation>Generelle Instillinger</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="308"/>
|
||||||
|
<source>Pack installable archive (WAD/TAD)</source>
|
||||||
|
<translation>Pakke installerbart arkiv (WAD/TAD)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="323"/>
|
||||||
|
<source>File Name</source>
|
||||||
|
<translation>Filnavn</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="357"/>
|
||||||
|
<source>Keep encrypted contents</source>
|
||||||
|
<translation>Oppbevar kryptert innhold</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="393"/>
|
||||||
|
<source>Create decrypted contents (*.app)</source>
|
||||||
|
<translation>Opprette dekryptert innold (*.app)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="432"/>
|
||||||
|
<source>Use local files, if they exist</source>
|
||||||
|
<translation>Bruk lokale filer, hvis de finnes</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="477"/>
|
||||||
|
<source>Use the Wii U NUS (faster, only effects Wii/vWii)</source>
|
||||||
|
<translation>Bruk Wii U NUS (raskere, påvirker bare Wii/vWii)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="575"/>
|
||||||
|
<source>vWii Title Settings</source>
|
||||||
|
<translation>vWii Tittelinstillinger</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="609"/>
|
||||||
|
<source>Re-encrypt title using the Wii Common Key</source>
|
||||||
|
<translation>Krypter tittelen på nytt ved hjelp av Wii Common Key</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="666"/>
|
||||||
|
<source><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||||
|
<html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><style type="text/css">
|
||||||
|
p, li { white-space: pre-wrap; }
|
||||||
|
hr { height: 1px; border-width: 0; }
|
||||||
|
li.unchecked::marker { content: "\2610"; }
|
||||||
|
li.checked::marker { content: "\2612"; }
|
||||||
|
</style></head><body style=" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;">
|
||||||
|
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html></source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||||
|
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||||
|
p, li { white-space: pre-wrap; }
|
||||||
|
</style></head><body style=" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;">
|
||||||
|
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html></source>
|
||||||
|
<translation type="vanished"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||||
|
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||||
|
p, li { white-space: pre-wrap; }
|
||||||
|
</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;">
|
||||||
|
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="85"/>
|
||||||
|
<source>NUSGet v{nusget_version}
|
||||||
|
Developed by NinjaCheetah
|
||||||
|
Powered by libWiiPy {libwiipy_version}
|
||||||
|
DSi support provided by libTWLPy {libtwlpy_version}
|
||||||
|
|
||||||
|
Select a title from the list on the left, or enter a Title ID to begin.
|
||||||
|
|
||||||
|
Titles marked with a checkmark are free and have a ticket available, and can be decrypted and/or packed into a WAD or TAD. Titles with an X do not have a ticket, and only their encrypted contents can be saved.
|
||||||
|
|
||||||
|
Titles will be downloaded to a folder named "NUSGet" inside your downloads folder.</source>
|
||||||
|
<translation>NUSGet v{nusget_version}
|
||||||
|
Utviklet av NinjaCheetah
|
||||||
|
Drevet av libWiiPy {libwiipy_version}
|
||||||
|
DSi støtte levert av libTWLPy {libtwlpy_version}
|
||||||
|
|
||||||
|
Velg en tittel fra listen til venstre, eller skriv inn en Tittel ID for å begynne.
|
||||||
|
|
||||||
|
Titler merket med en hake er fri og har en billett tilgjengelig, og kan dekrypteres og/eller pakkes inn i en WAD eller TAD. Titler med en X ikke har en billett, og bare det krypterte innholdet kan lagres.
|
||||||
|
|
||||||
|
Titler er lastes ned til en mappe med navnet "NUSGet" i nedlastingsmappen din.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="264"/>
|
||||||
|
<source>No Output Selected</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="265"/>
|
||||||
|
<source>You have not selected any format to output the data in!</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="267"/>
|
||||||
|
<source>Please select at least one option for how you would like the download to be saved.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="298"/>
|
||||||
|
<source>Invalid Title ID</source>
|
||||||
|
<translation>Ugyldig Tittel ID</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="299"/>
|
||||||
|
<source>The Title ID you have entered is not in a valid format!</source>
|
||||||
|
<translation>Tittel IDen du har angitt er ikke i et gyldig format!</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="301"/>
|
||||||
|
<source>Title IDs must be 16 digit strings of numbers and letters. Please enter a correctly formatted Title ID, or select one from the menu on the left.</source>
|
||||||
|
<translation>Tittel IDer må være 16-sifrede tall og bokstav strenger. Vennligst skriv inn en korrekt formatert Tittel ID, eller velg en fra menyen til venstre.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="303"/>
|
||||||
|
<source>Title ID/Version Not Found</source>
|
||||||
|
<translation>Tittel ID/Versjon Ikke Funnet</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="304"/>
|
||||||
|
<source>No title with the provided Title ID or version could be found!</source>
|
||||||
|
<translation>Ingen tittel med oppgitt Tittel ID eller versjon ble funnet!</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="306"/>
|
||||||
|
<source>Please make sure that you have entered a valid Title ID, or selected one from the title database, and that the provided version exists for the title you are attempting to download.</source>
|
||||||
|
<translation>Vennligst kontroller at du har oppgitt en gyldig Tittel ID, eller valgt en fra titteldatabasen, og at den angitte versjonen finnes for tittelen du forsøker å laste ned.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="308"/>
|
||||||
|
<source>Content Decryption Failed</source>
|
||||||
|
<translation>Dekryptering av Innhold Mislyktes</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="309"/>
|
||||||
|
<source>Content decryption was not successful! Decrypted contents could not be created.</source>
|
||||||
|
<translation>Dekryptering av innhold var ikke vellykket! Dekryptert innhold kunne ikke opprettes.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="312"/>
|
||||||
|
<source>Your TMD or Ticket may be damaged, or they may not correspond with the content being decrypted. If you have checked "Use local files, if they exist", try disabling that option before trying the download again to fix potential issues with local data.</source>
|
||||||
|
<translation>TMDen eller Billetten kan være skadet, eller det kan hende at de ikke samsvarer med innholdet some dekrypteres. Hvis du har krysset av for "Bruk lokale filer, hvis de finnes", kan du prøve å deaktivere dette alternativet før du prøver nedlastingen på nytt for å løse eventuelle problemer med lokale data.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="315"/>
|
||||||
|
<source>Ticket Not Available</source>
|
||||||
|
<translation>Billett Ikke Tilgjengelig</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="316"/>
|
||||||
|
<source>No Ticket is Available for the Requested Title!</source>
|
||||||
|
<translation>Ingen billett er tilgjengelig for den forespurte tittelen!</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="319"/>
|
||||||
|
<source>A ticket could not be downloaded for the requested title, but you have selected "Pack installable archive" or "Create decrypted contents". These options are not available for titles without a ticket. Only encrypted contents have been saved.</source>
|
||||||
|
<translation>En billett kunne ikke lastes ned for den forespurte tittelen, men du har valgt "Pakk installerbart arkiv" eller "Opprett dekryptert innhold". Disse alternativene er ikke tilgjenelige for titler uten billett. Bare kryptert innhold har blitt lagret.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="321"/>
|
||||||
|
<source>Unknown Error</source>
|
||||||
|
<translation>Ukjent Feil</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="322"/>
|
||||||
|
<source>An Unknown Error has Occurred!</source>
|
||||||
|
<translation>En ukjent feil har oppstått!</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="324"/>
|
||||||
|
<source>Please try again. If this issue persists, please open a new issue on GitHub detailing what you were trying to do when this error occurred.</source>
|
||||||
|
<translation>Vennligst prøv igjen. Hvis dette problemet vedvarer, åpne et nytt issue på GitHub med detaljer om hva du prøvde å gjøre da denne feilen oppstod.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="364"/>
|
||||||
|
<source>Open NUS script</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="364"/>
|
||||||
|
<source>NUS Scripts (*.nus *.txt)</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="371"/>
|
||||||
|
<location filename="../../NUSGet.py" line="386"/>
|
||||||
|
<location filename="../../NUSGet.py" line="389"/>
|
||||||
|
<location filename="../../NUSGet.py" line="397"/>
|
||||||
|
<location filename="../../NUSGet.py" line="415"/>
|
||||||
|
<location filename="../../NUSGet.py" line="422"/>
|
||||||
|
<source>Script Failure</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="371"/>
|
||||||
|
<source>Failed to open the script.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="519"/>
|
||||||
|
<source>Apply patches to IOS (Applies to WADs only)</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="184"/>
|
||||||
|
<source>NUSGet Update Available</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="185"/>
|
||||||
|
<source>There's a newer version of NUSGet available!</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../modules/core.py" line="26"/>
|
||||||
|
<source>
|
||||||
|
|
||||||
|
Could not check for updates.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../modules/core.py" line="34"/>
|
||||||
|
<source>
|
||||||
|
|
||||||
|
There's a newer version of NUSGet available!</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../modules/core.py" line="36"/>
|
||||||
|
<source>
|
||||||
|
|
||||||
|
You're running the latest release of NUSGet.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
</TS>
|
||||||
293
resources/translations/nusget_ro.ts
Normal file
293
resources/translations/nusget_ro.ts
Normal file
@@ -0,0 +1,293 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!DOCTYPE TS>
|
||||||
|
<TS version="2.1" language="ro_RO">
|
||||||
|
<context>
|
||||||
|
<name>MainWindow</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="85"/>
|
||||||
|
<source>NUSGet v{nusget_version}
|
||||||
|
Developed by NinjaCheetah
|
||||||
|
Powered by libWiiPy {libwiipy_version}
|
||||||
|
DSi support provided by libTWLPy {libtwlpy_version}
|
||||||
|
|
||||||
|
Select a title from the list on the left, or enter a Title ID to begin.
|
||||||
|
|
||||||
|
Titles marked with a checkmark are free and have a ticket available, and can be decrypted and/or packed into a WAD or TAD. Titles with an X do not have a ticket, and only their encrypted contents can be saved.
|
||||||
|
|
||||||
|
Titles will be downloaded to a folder named "NUSGet" inside your downloads folder.</source>
|
||||||
|
<translation type="unfinished">NUSGet v{nusget_version}
|
||||||
|
Dezvoltat de NinjaCheetah
|
||||||
|
Operat de libWiiPy {libwiipy_version}
|
||||||
|
Suport pentru DSi oferit de libTWLPy {libtwlpy_version}
|
||||||
|
|
||||||
|
Selectează un titlu din lista din stânga, sau introdu un Title ID pentru a începe.
|
||||||
|
|
||||||
|
Titlurile marcate cu bifă sunt gratuite și au un tichet disponibil și pot fi decriptate și/sau incluse într-un WAD sau TAD. Titlurile cu un X nu au tichet, și pot fi salvate doar în formă encriptată.
|
||||||
|
|
||||||
|
Titlurile vor fi descărcate într-un folder numit „NUSGet” în fișierul dvs. de download.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="184"/>
|
||||||
|
<source>NUSGet Update Available</source>
|
||||||
|
<translation type="unfinished">Actualizare NUSGet disponibilă</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="185"/>
|
||||||
|
<source>There's a newer version of NUSGet available!</source>
|
||||||
|
<translation type="unfinished">O nouă versiune NUSGet este disponibilă!</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="264"/>
|
||||||
|
<source>No Output Selected</source>
|
||||||
|
<translation type="unfinished">Nu s-a selectat un output.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="265"/>
|
||||||
|
<source>You have not selected any format to output the data in!</source>
|
||||||
|
<translation type="unfinished">Nu ați selectat niciun format de ieșire.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="267"/>
|
||||||
|
<source>Please select at least one option for how you would like the download to be saved.</source>
|
||||||
|
<translation type="unfinished">Vă rugăm să selectați cel puțin o opțiune pentru modul în care doriți să salvați datele descărcate.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="298"/>
|
||||||
|
<source>Invalid Title ID</source>
|
||||||
|
<translation type="unfinished">Title ID invalid</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="299"/>
|
||||||
|
<source>The Title ID you have entered is not in a valid format!</source>
|
||||||
|
<translation type="unfinished">Title ID pe care l-ați introdus este invalid!</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="301"/>
|
||||||
|
<source>Title IDs must be 16 digit strings of numbers and letters. Please enter a correctly formatted Title ID, or select one from the menu on the left.</source>
|
||||||
|
<translation type="unfinished">Title ID-urile trebuie să conțină exact 16 cifre și/sau litere. Vă rugăm introduceți un Title ID corect, sau selectați unul din meniul din stânga.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="303"/>
|
||||||
|
<source>Title ID/Version Not Found</source>
|
||||||
|
<translation type="unfinished">Title ID/Versiunea nu a fost găsită</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="304"/>
|
||||||
|
<source>No title with the provided Title ID or version could be found!</source>
|
||||||
|
<translation type="unfinished">Niciun titlu care să corespundă cu Title ID sau cu versiunea introdusă nu a fost găsit!</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="306"/>
|
||||||
|
<source>Please make sure that you have entered a valid Title ID, or selected one from the title database, and that the provided version exists for the title you are attempting to download.</source>
|
||||||
|
<translation type="unfinished">Vă rugăm să vă asigurați că ați introdus un Title ID valid sau selectat din baza de date cu titluri, și că versiunea introdusă există pentru titlul pe care încercați să îl descărcați.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="308"/>
|
||||||
|
<source>Content Decryption Failed</source>
|
||||||
|
<translation type="unfinished">Decriptarea conținutului a eșuat.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="309"/>
|
||||||
|
<source>Content decryption was not successful! Decrypted contents could not be created.</source>
|
||||||
|
<translation type="unfinished">Decriptarea conținutului nu a reușit. Nu s-a putut crea conținutul decriptat.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="312"/>
|
||||||
|
<source>Your TMD or Ticket may be damaged, or they may not correspond with the content being decrypted. If you have checked "Use local files, if they exist", try disabling that option before trying the download again to fix potential issues with local data.</source>
|
||||||
|
<translation type="unfinished">TMD-ul sau Ticket-ul dvs. sunt corupte, sau nu corespund cu conținutul de decriptat. Dacă ați bifat „Folosiți fișiere locale, dacă există”, încercați să debifați această opțiune înainte de a descărca din nou pentru a rezolva potențiale probleme cu datele existente local.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="315"/>
|
||||||
|
<source>Ticket Not Available</source>
|
||||||
|
<translation type="unfinished">Ticket-ul nu este valabil</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="316"/>
|
||||||
|
<source>No Ticket is Available for the Requested Title!</source>
|
||||||
|
<translation type="unfinished">Niciun Ticket nu este valabil pentru titlul dorit.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="319"/>
|
||||||
|
<source>A ticket could not be downloaded for the requested title, but you have selected "Pack installable archive" or "Create decrypted contents". These options are not available for titles without a ticket. Only encrypted contents have been saved.</source>
|
||||||
|
<translation type="unfinished">Nu se poate descărca un tichet pentru titlul cerut, dar ați selectat „Împachetați arhiva instalabilă” sau „Creați conținut decriptat”. Aceste opțiuni nu sunt valabile pentru titluri fărătichet. Doar conținuturile criptate au fost salvate.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="321"/>
|
||||||
|
<source>Unknown Error</source>
|
||||||
|
<translation type="unfinished">Eroare necunoscută</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="322"/>
|
||||||
|
<source>An Unknown Error has Occurred!</source>
|
||||||
|
<translation type="unfinished">S-a produs o eroare necunoscută!</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="324"/>
|
||||||
|
<source>Please try again. If this issue persists, please open a new issue on GitHub detailing what you were trying to do when this error occurred.</source>
|
||||||
|
<translation type="unfinished">Vă rugăm încercați din nou. Dacă problema persistă, vă rugăm să deschideți un issue pe GitHub în care să explicați ce ați încercat să faceți atunci când această eroare a apărut.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="364"/>
|
||||||
|
<source>Open NUS script</source>
|
||||||
|
<translation type="unfinished">Deschideți script NUS</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="364"/>
|
||||||
|
<source>NUS Scripts (*.nus *.txt)</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="371"/>
|
||||||
|
<location filename="../../NUSGet.py" line="386"/>
|
||||||
|
<location filename="../../NUSGet.py" line="389"/>
|
||||||
|
<location filename="../../NUSGet.py" line="397"/>
|
||||||
|
<location filename="../../NUSGet.py" line="415"/>
|
||||||
|
<location filename="../../NUSGet.py" line="422"/>
|
||||||
|
<source>Script Failure</source>
|
||||||
|
<translation type="unfinished">Eșuare Script</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../NUSGet.py" line="371"/>
|
||||||
|
<source>Failed to open the script.</source>
|
||||||
|
<translation type="unfinished">Nu s-a putut deschide script-ul.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="26"/>
|
||||||
|
<source>MainWindow</source>
|
||||||
|
<translation type="unfinished">Fereastra principală</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="43"/>
|
||||||
|
<source>Available Titles</source>
|
||||||
|
<translation type="unfinished">Titluri valabile</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="72"/>
|
||||||
|
<source>Wii</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="103"/>
|
||||||
|
<source>vWii</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="134"/>
|
||||||
|
<source>DSi</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="174"/>
|
||||||
|
<source>Title ID</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="181"/>
|
||||||
|
<source>v</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="194"/>
|
||||||
|
<source>Version</source>
|
||||||
|
<translation type="unfinished">Versiune</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="201"/>
|
||||||
|
<source>Console:</source>
|
||||||
|
<translation type="unfinished">Consolă</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="237"/>
|
||||||
|
<source>Start Download</source>
|
||||||
|
<translation type="unfinished">Începeți descărcarea</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="250"/>
|
||||||
|
<source>Run Script</source>
|
||||||
|
<translation type="unfinished">Rulați script</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="277"/>
|
||||||
|
<source>General Settings</source>
|
||||||
|
<translation type="unfinished">Setări Generale</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="308"/>
|
||||||
|
<source>Pack installable archive (WAD/TAD)</source>
|
||||||
|
<translation type="unfinished">Împachetați arhiva instalabilă (WAD/TAD)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="323"/>
|
||||||
|
<source>File Name</source>
|
||||||
|
<translation type="unfinished">Nume fișier</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="357"/>
|
||||||
|
<source>Keep encrypted contents</source>
|
||||||
|
<translation type="unfinished">Păstrați conținuturile encriptate</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="393"/>
|
||||||
|
<source>Create decrypted contents (*.app)</source>
|
||||||
|
<translation type="unfinished">Creați conținuturi decriptate (*.app)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="432"/>
|
||||||
|
<source>Use local files, if they exist</source>
|
||||||
|
<translation type="unfinished">Folosiți fișiere locale, dacă există</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="477"/>
|
||||||
|
<source>Use the Wii U NUS (faster, only effects Wii/vWii)</source>
|
||||||
|
<translation type="unfinished">Folosiți Wii U NUS (mai rapid, doar pentru Wii/vWii)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="519"/>
|
||||||
|
<source>Apply patches to IOS (Applies to WADs only)</source>
|
||||||
|
<translation type="unfinished">Aplicați patch-uri pentru IOS (se aplică doar pe WAD-uri)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="575"/>
|
||||||
|
<source>vWii Title Settings</source>
|
||||||
|
<translation type="unfinished">vWII Setări titlu</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="609"/>
|
||||||
|
<source>Re-encrypt title using the Wii Common Key</source>
|
||||||
|
<translation type="unfinished">Re-encriptați titlul folosind cheia comună Wii</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../qt/ui/MainMenu.ui" line="666"/>
|
||||||
|
<source><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||||
|
<html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><style type="text/css">
|
||||||
|
p, li { white-space: pre-wrap; }
|
||||||
|
hr { height: 1px; border-width: 0; }
|
||||||
|
li.unchecked::marker { content: "\2610"; }
|
||||||
|
li.checked::marker { content: "\2612"; }
|
||||||
|
</style></head><body style=" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;">
|
||||||
|
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html></source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../modules/core.py" line="26"/>
|
||||||
|
<source>
|
||||||
|
|
||||||
|
Could not check for updates.</source>
|
||||||
|
<translation type="unfinished">Nu s-a putut verifica dacă există actualizări.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../modules/core.py" line="34"/>
|
||||||
|
<source>
|
||||||
|
|
||||||
|
There's a newer version of NUSGet available!</source>
|
||||||
|
<translation type="unfinished">O nouă versiune de NUSGet este valabilă!</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../modules/core.py" line="36"/>
|
||||||
|
<source>
|
||||||
|
|
||||||
|
You're running the latest release of NUSGet.</source>
|
||||||
|
<translation type="unfinished">Utilizați ultima versiune de NUSGet.</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
</TS>
|
||||||
30
update_translations.py
Normal file
30
update_translations.py
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
# "update_translations.py", licensed under the MIT license
|
||||||
|
# Copyright 2024 NinjaCheetah
|
||||||
|
# This script exists to work around an issue in PySide6 where the "pyside6-project lupdate" command doesn't work as
|
||||||
|
# expected, as it struggles to parse the paths in the .pyproject file. This does what it's meant to do for it.
|
||||||
|
|
||||||
|
import json
|
||||||
|
import pathlib
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
|
||||||
|
LUPDATE_CMD = "pyside6-lupdate"
|
||||||
|
|
||||||
|
|
||||||
|
pyproject_file = pathlib.Path("NUSGet.pyproject")
|
||||||
|
pyproject = json.load(open(pyproject_file, "r"))
|
||||||
|
files = []
|
||||||
|
for key in pyproject["files"]:
|
||||||
|
files.append(pathlib.Path(key))
|
||||||
|
source_files = []
|
||||||
|
ts_files = []
|
||||||
|
for file in files:
|
||||||
|
if file.suffix == ".ts":
|
||||||
|
ts_files.append(file)
|
||||||
|
elif file.suffix == ".py" or file.suffix == ".ui":
|
||||||
|
source_files.append(file)
|
||||||
|
|
||||||
|
for target in ts_files:
|
||||||
|
cmd = [LUPDATE_CMD] + [s for s in source_files] + ["-ts"]
|
||||||
|
cmd.append(target)
|
||||||
|
subprocess.run(cmd, cwd=str(pyproject_file.parent))
|
||||||
Reference in New Issue
Block a user