mirror of
https://github.com/Melon-Bread/gnu-slash-dot-files
synced 2024-11-25 00:38:23 -05:00
Added pip upgrade script
This commit is contained in:
parent
192f681fdb
commit
74e11bf38d
BIN
.bin/4nxci
Executable file
BIN
.bin/4nxci
Executable file
Binary file not shown.
165
.bin/NSP_NX.py
Executable file
165
.bin/NSP_NX.py
Executable file
@ -0,0 +1,165 @@
|
||||
# This script depends on PyUSB. You can get it with pip install pyusb.
|
||||
# You will also need libusb installed
|
||||
|
||||
# My sincere apologies for this process being overly complicated. Apparently Python and Windows
|
||||
# aren't very friendly :(
|
||||
# Windows Instructions:
|
||||
# 1. Download Zadig from https://zadig.akeo.ie/.
|
||||
# 2. With your switch plugged in and on the Tinfoil USB install menu,
|
||||
# choose "List All Devices" under the options menu in Zadig, and select libnx USB comms.
|
||||
# 3. Choose libusbK from the driver list and click the "Replace Driver" button.
|
||||
# 4. Run this script
|
||||
|
||||
# macOS Instructions:
|
||||
# 1. Install Homebrew https://brew.sh
|
||||
# 2. Install Python 3
|
||||
# sudo mkdir /usr/local/Frameworks
|
||||
# sudo chown $(whoami) /usr/local/Frameworks
|
||||
# brew install python
|
||||
# 3. Install PyUSB
|
||||
# pip3 install pyusb
|
||||
# 4. Install libusb
|
||||
# brew install libusb
|
||||
# 5. Plug in your Switch and go to Tinfoil > Title Management > USB Install NSP
|
||||
# 6. Run this script
|
||||
# python3 usb_install_pc.py <path/to/nsp_folder>
|
||||
|
||||
import usb.core
|
||||
import usb.util
|
||||
import struct
|
||||
import sys
|
||||
from binascii import hexlify as hx, unhexlify as uhx
|
||||
from pathlib import Path
|
||||
|
||||
CMD_ID_EXIT = 0
|
||||
CMD_ID_FILE_RANGE = 1
|
||||
CMD_ID_FILE_RANGE_PADDED = 2
|
||||
|
||||
CMD_TYPE_RESPONSE = 1
|
||||
|
||||
BUFFER_SEGMENT_DATA_SIZE = 0x100000
|
||||
PADDING_SIZE = 0x1000
|
||||
|
||||
def send_response_header(out_ep, cmd_id, data_size):
|
||||
out_ep.write(b'TUC0') # Tinfoil USB Command 0
|
||||
out_ep.write(struct.pack('<B', CMD_TYPE_RESPONSE))
|
||||
out_ep.write(b'\x00' * 3)
|
||||
out_ep.write(struct.pack('<I', cmd_id))
|
||||
out_ep.write(struct.pack('<Q', data_size))
|
||||
out_ep.write(b'\x00' * 0xC)
|
||||
|
||||
def file_range_cmd(nsp_dir, in_ep, out_ep, data_size, padding=False):
|
||||
file_range_header = in_ep.read(0x20)
|
||||
|
||||
range_size = struct.unpack('<Q', file_range_header[:8])[0]
|
||||
range_offset = struct.unpack('<Q', file_range_header[8:16])[0]
|
||||
nsp_name_len = struct.unpack('<Q', file_range_header[16:24])[0]
|
||||
#in_ep.read(0x8) # Reserved
|
||||
nsp_name = bytes(in_ep.read(nsp_name_len)).decode('utf-8')
|
||||
|
||||
print('Range Size: {}, Range Offset: {}, Name len: {}, Name: {}'.format(range_size, range_offset, nsp_name_len, nsp_name))
|
||||
cmd_id = CMD_ID_FILE_RANGE
|
||||
if padding:
|
||||
cmd_id = CMD_ID_FILE_RANGE_PADDED
|
||||
send_response_header(out_ep, cmd_id, range_size)
|
||||
|
||||
with open(nsp_name, 'rb') as f:
|
||||
f.seek(range_offset)
|
||||
|
||||
curr_off = 0x0
|
||||
end_off = range_size
|
||||
read_size = BUFFER_SEGMENT_DATA_SIZE
|
||||
if (padding):
|
||||
read_size -= PADDING_SIZE
|
||||
|
||||
while curr_off < end_off:
|
||||
if curr_off + read_size >= end_off:
|
||||
read_size = end_off - curr_off
|
||||
|
||||
buf = f.read(read_size)
|
||||
if (padding):
|
||||
buf = b'\x00' * PADDING_SIZE + buf
|
||||
out_ep.write(data=buf, timeout=0)
|
||||
curr_off += read_size
|
||||
|
||||
def poll_commands(nsp_dir, in_ep, out_ep):
|
||||
while True:
|
||||
cmd_header = bytes(in_ep.read(0x20, timeout=0))
|
||||
magic = cmd_header[:4]
|
||||
print('Magic: {}'.format(magic), flush=True)
|
||||
|
||||
if magic != b'TUC0': # Tinfoil USB Command 0
|
||||
continue
|
||||
|
||||
cmd_type = struct.unpack('<B', cmd_header[4:5])[0]
|
||||
cmd_id = struct.unpack('<I', cmd_header[8:12])[0]
|
||||
data_size = struct.unpack('<Q', cmd_header[12:20])[0]
|
||||
|
||||
print('Cmd Type: {}, Command id: {}, Data size: {}'.format(cmd_type, cmd_id, data_size), flush=True)
|
||||
|
||||
if cmd_id == CMD_ID_EXIT:
|
||||
print('Exiting...')
|
||||
break
|
||||
elif cmd_id == CMD_ID_FILE_RANGE:
|
||||
file_range_cmd(nsp_dir, in_ep, out_ep, data_size)
|
||||
elif cmd_id == CMD_ID_FILE_RANGE_PADDED:
|
||||
file_range_cmd(nsp_dir, in_ep, out_ep, data_size, padding=True)
|
||||
|
||||
def send_nsp_list(nsp_dir, out_ep):
|
||||
nsp_path_list = list()
|
||||
nsp_path_list_len = 0
|
||||
|
||||
# Add all files with the extension .nsp in the provided dir
|
||||
for nsp_path in [f for f in nsp_dir.iterdir() if f.is_file() and f.suffix == '.nsp']:
|
||||
nsp_path_list.append(nsp_path.__str__() + '\n')
|
||||
nsp_path_list_len += len(nsp_path.__str__()) + 1
|
||||
|
||||
print('Sending header...')
|
||||
|
||||
out_ep.write(b'TUL0') # Tinfoil USB List 0
|
||||
out_ep.write(struct.pack('<I', nsp_path_list_len))
|
||||
out_ep.write(b'\x00' * 0x8) # Padding
|
||||
|
||||
print('Sending NSP list: {}'.format(nsp_path_list))
|
||||
|
||||
for nsp_path in nsp_path_list:
|
||||
out_ep.write(nsp_path)
|
||||
|
||||
def print_usage():
|
||||
print("""\
|
||||
usb_install_pc.py
|
||||
|
||||
Used for the installation of NSPs over USB.
|
||||
|
||||
Usage: usb_install_pc.py <nsp folder>""")
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) != 2:
|
||||
print_usage()
|
||||
sys.exit(1)
|
||||
|
||||
nsp_dir = Path(sys.argv[1])
|
||||
|
||||
if not nsp_dir.is_dir():
|
||||
raise ValueError('1st argument must be a directory')
|
||||
|
||||
# Find the switch
|
||||
dev = usb.core.find(idVendor=0x057E, idProduct=0x3000)
|
||||
|
||||
if dev is None:
|
||||
raise ValueError('Switch is not found!')
|
||||
|
||||
dev.reset()
|
||||
dev.set_configuration()
|
||||
cfg = dev.get_active_configuration()
|
||||
|
||||
is_out_ep = lambda ep: usb.util.endpoint_direction(ep.bEndpointAddress) == usb.util.ENDPOINT_OUT
|
||||
is_in_ep = lambda ep: usb.util.endpoint_direction(ep.bEndpointAddress) == usb.util.ENDPOINT_IN
|
||||
out_ep = usb.util.find_descriptor(cfg[(0,0)], custom_match=is_out_ep)
|
||||
in_ep = usb.util.find_descriptor(cfg[(0,0)], custom_match=is_in_ep)
|
||||
|
||||
assert out_ep is not None
|
||||
assert in_ep is not None
|
||||
|
||||
send_nsp_list(nsp_dir, out_ep)
|
||||
poll_commands(nsp_dir, in_ep, out_ep)
|
48
.bin/NX2OGG.py
Executable file
48
.bin/NX2OGG.py
Executable file
@ -0,0 +1,48 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Converts .lopus to .ogg via vgmstream & ffmpeg
|
||||
"""
|
||||
|
||||
__author__ = "Melon Bread"
|
||||
__version__ = "0.5.0"
|
||||
__license__ = "MIT"
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
|
||||
def main(args):
|
||||
file = args.input[:-6]
|
||||
|
||||
try:
|
||||
print("Converting .lpous to .wav via vgmstream-cli...")
|
||||
subprocess.Popen(['vgmstream-cli', '-o',
|
||||
'{}.wav'.format(file), args.input]).wait()
|
||||
pass
|
||||
except Exception as e:
|
||||
print("ERROR: Please make sure 'vgmstream-cli' is in the PATH!")
|
||||
raise
|
||||
|
||||
try:
|
||||
print("Converting .wav to .ogg via ffmpeg...")
|
||||
subprocess.Popen(['ffmpeg', '-i', '{}.wav'.format(file), '-acodec',
|
||||
'libvorbis', '{}.ogg'.format(file)]).wait()
|
||||
pass
|
||||
except Exception as e:
|
||||
print("ERROR: Please make sure 'ffmpeg' is in the PATH!")
|
||||
raise
|
||||
|
||||
print("Removing .wav file...")
|
||||
os.remove("{}.wav".format(file))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
""" This is executed when run from the command line """
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
parser.add_argument('-i', '--input', metavar='STRING', required=True,
|
||||
help='.lopus file your want to convert to .ogg')
|
||||
|
||||
args = parser.parse_args()
|
||||
main(args)
|
4
.bin/Pipgrade.sh
Normal file
4
.bin/Pipgrade.sh
Normal file
@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
echo 'Updating all user installed pip packages...'
|
||||
pip list --outdated --format=freeze | grep -v '^\-e' | cut -d = -f 1 | xargs -n1 pip install --user -U
|
1
.bin/pico8
Symbolic link
1
.bin/pico8
Symbolic link
@ -0,0 +1 @@
|
||||
/home/melon/Games/Linux/pico-8/pico8
|
Loading…
Reference in New Issue
Block a user