mirror of
https://github.com/UberGuidoZ/Flipper.git
synced 2025-01-30 17:40:12 +00:00
amiibo update
This commit is contained in:
parent
f321f082bb
commit
916b7b167a
Binary file not shown.
24
NFC/Amiibo/amiibo to flip/README.md
Normal file
24
NFC/Amiibo/amiibo to flip/README.md
Normal file
@ -0,0 +1,24 @@
|
||||
# AmiiboFlipperConverter https://github.com/Lucaslhm/AmiiboFlipperConverter
|
||||
Converts Amiibo .bins to a flipper compatible format
|
||||
|
||||
Simply run `amiiboconvert.py` from the root directory to generate all amiibos within `raw_amiibos` to `nfcs`
|
||||
|
||||
You can target a specific file by appending a path to the end of the call as such that `amiiboconvert.py *path to file*`
|
||||
|
||||
You can target a directory full of amiibos by passing a path such that `amiiboconvert.py *path to directory*`
|
||||
|
||||
You can also use the amiibos i've generated already.
|
||||
|
||||
|
||||
The original code was created in the Flipper Discord by Friendartiste
|
||||
|
||||
The code was modified to run itteratively by Lamp
|
||||
|
||||
I, VapidAnt, have modified the code to work in a variety of situations with a recursive function and have uploaded to github
|
||||
I believe this will make it easy to modify the code in the future and track changes over time.
|
||||
|
||||
If you have problems, please make an issue or ping me in the flipper discord.
|
||||
|
||||
Feel free to itterate off this and make pull requests.
|
||||
|
||||
Happy Flipping!
|
223
NFC/Amiibo/amiibo to flip/amiiboconvert.py
Normal file
223
NFC/Amiibo/amiibo to flip/amiiboconvert.py
Normal file
@ -0,0 +1,223 @@
|
||||
"""
|
||||
amiiboconvert.py
|
||||
3/12/2022
|
||||
Modified Amiibo Flipper Conversion Code
|
||||
|
||||
Original Code by Friendartiste
|
||||
Modified by Lamp
|
||||
Modified again by VapidAnt
|
||||
Modified and commented by bjschafer
|
||||
|
||||
Execute with python amiiboconvert -h to see options
|
||||
"""
|
||||
import argparse
|
||||
import logging
|
||||
import os
|
||||
import pathlib
|
||||
from typing import Tuple
|
||||
|
||||
|
||||
def write_output(name: str, assemble: str, out_dir: str):
|
||||
"""
|
||||
Handles writing the converted file
|
||||
:param name: The base filename - e.g. for Foo.bin, Foo
|
||||
:param assemble: The converted flipper-compatible contents
|
||||
:param out_dir: The directory to place Foo.nfc in
|
||||
"""
|
||||
with open(os.path.join(out_dir, f"{name}.nfc"), "wt") as f:
|
||||
f.write(assemble)
|
||||
|
||||
|
||||
def convert(contents: bytes) -> Tuple[str, int]:
|
||||
"""
|
||||
Convert from bytes into the Page-based format expected by flipper
|
||||
|
||||
Each "Page" is 4 bytes hex, notated like:
|
||||
Page 0: DE AD BE EF
|
||||
|
||||
To process, we grab one byte at a time, turn it into a hex string, and store it in `page`.
|
||||
When page is "full" (has 4 bytes in it), we flush it to the buffer.
|
||||
|
||||
When all's said and done, buffer contains text ready for writing to the end of a .nfc file.
|
||||
|
||||
Also tracks and returns running page number, since that's also needed.
|
||||
:param contents: byte array we're reading, from a .bin file
|
||||
:return: The full string of Pages, suitable for writing to a file
|
||||
"""
|
||||
buffer = []
|
||||
page_count = 0
|
||||
|
||||
page = []
|
||||
for i in range(len(contents) - 1):
|
||||
byte = contents[i : i + 1].hex()
|
||||
page.append(byte)
|
||||
|
||||
if len(page) == 4:
|
||||
buffer.append(f"Page {page_count}: {' '.join(page).upper()}")
|
||||
page = []
|
||||
page_count += 1
|
||||
|
||||
# we may have an unfilled page. This needs to be filled out and appended
|
||||
logging.debug(f"We have an unfilled final page: {page} with length {len(page)}")
|
||||
if len(page) > 0:
|
||||
# pad with zeroes
|
||||
for i in range(len(page) - 1, 3):
|
||||
page.append("00")
|
||||
buffer.append(f"Page {page_count}: {' '.join(page).upper()}")
|
||||
page_count += 1
|
||||
return "\n".join(buffer), page_count
|
||||
|
||||
|
||||
def get_uid(contents: bytes) -> str:
|
||||
"""
|
||||
the UID appears to be made up of the first 3 bytes, a byte is skipped, and then the next 4 bytes
|
||||
:param contents: The bytes object we're operating on
|
||||
:return: something like `23 20 41 6D 69 69 62 6F`
|
||||
"""
|
||||
page = []
|
||||
for i in range(3):
|
||||
byte = contents[i : i + 1].hex()
|
||||
page.append(byte)
|
||||
for i in range(4, 8):
|
||||
byte = contents[i : i + 1].hex()
|
||||
page.append(byte)
|
||||
|
||||
return " ".join(page).upper()
|
||||
|
||||
|
||||
def assemble_code(contents: {hex}) -> str:
|
||||
"""
|
||||
Convert from .bin files to Flipper text-like .nfc files
|
||||
|
||||
:param contents: File contents upon which .hex() can be called
|
||||
:return: A string to be written to a file
|
||||
"""
|
||||
conversion, page_count = convert(contents)
|
||||
|
||||
return f"""Filetype: Flipper NFC device
|
||||
Version: 2
|
||||
# Nfc device type can be UID, Mifare Ultralight, Bank card
|
||||
Device type: NTAG215
|
||||
# UID, ATQA and SAK are common for all formats
|
||||
UID: {get_uid(contents)}
|
||||
ATQA: 44 00
|
||||
SAK: 00
|
||||
# Mifare Ultralight specific data
|
||||
Signature: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
Mifare version: 00 04 04 02 01 00 11 03
|
||||
Counter 0: 0
|
||||
Tearing 0: 00
|
||||
Counter 1: 0
|
||||
Tearing 1: 00
|
||||
Counter 2: 0
|
||||
Tearing 2: 00
|
||||
Pages total: {page_count}
|
||||
{conversion}
|
||||
"""
|
||||
|
||||
|
||||
def convert_file(input_path: str, output_path: str):
|
||||
"""
|
||||
Handles reading, converting, and writing a single file
|
||||
:param input_path: The full path to the .bin file
|
||||
:param output_path: The base directory to output to
|
||||
"""
|
||||
input_extension = os.path.splitext(input_path)[1]
|
||||
if input_extension == ".bin":
|
||||
logging.info(f"Writing: {input_path}")
|
||||
with open(input_path, "rb") as file:
|
||||
contents = file.read()
|
||||
name = os.path.split(input_path)[1]
|
||||
write_output(name.split(".bin")[0], assemble_code(contents), output_path)
|
||||
|
||||
elif input_extension == ".nfc":
|
||||
logging.warning(f"Seems like {input_path} may already be Flipper-compatible!")
|
||||
else:
|
||||
logging.info(f"{input_path} doesn't seem like a relevant file, skipping")
|
||||
|
||||
|
||||
def process(path: str, output_path: str):
|
||||
"""
|
||||
Process an input file, or walk through an input directory and process every matching .bin file therein
|
||||
:param path: Path to a single file or a directory containing one or more .bin files
|
||||
:param output_path: The base directory to output to
|
||||
"""
|
||||
if os.path.isfile(path):
|
||||
convert_file(path, output_path)
|
||||
else:
|
||||
for filename in os.listdir(path):
|
||||
new_path = os.path.join(path, filename)
|
||||
logging.debug(f"Current file: {filename}; Current path: {new_path}")
|
||||
|
||||
if os.path.isfile(path):
|
||||
convert_file(path, output_path)
|
||||
else:
|
||||
logging.debug(f"Recursing into: {new_path}")
|
||||
process(new_path, output_path)
|
||||
|
||||
|
||||
def get_args():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
"-i",
|
||||
"--input-path",
|
||||
required=True,
|
||||
type=pathlib.Path,
|
||||
help="Single file or directory tree to convert",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-o",
|
||||
"--output-path",
|
||||
required=False,
|
||||
type=pathlib.Path,
|
||||
help="Directory to store output in. Will be created if it doesn't exist. If not specified, the output will be "
|
||||
"stored in the same location as the original, with a '.nfc' extension.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-v",
|
||||
"--verbose",
|
||||
action="count",
|
||||
default=0,
|
||||
help="Show extra info: pass -v to see what's going on, pass -vv to get useful debug info",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
if args.verbose >= 2:
|
||||
# set debug
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
elif args.verbose >= 1:
|
||||
# set info
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logging.debug(f"Parsed args into {args}")
|
||||
return args
|
||||
|
||||
|
||||
def main():
|
||||
args = get_args()
|
||||
|
||||
# single file mode
|
||||
if os.path.isfile(args.input_path):
|
||||
if not args.output_path:
|
||||
args.output_path = os.path.split(args.input_path)[0]
|
||||
# recursive directory mode
|
||||
elif os.path.isdir(args.input_path):
|
||||
if not args.output_path:
|
||||
logging.exception(
|
||||
ValueError(
|
||||
f"{args.input_path} is a directory, but no output path given."
|
||||
)
|
||||
)
|
||||
elif not os.path.exists(args.input_path):
|
||||
logging.exception(
|
||||
FileNotFoundError(f"{args.input_path} doesn't actually exist")
|
||||
)
|
||||
|
||||
logging.debug(f"Going to create output directory {args.output_path}")
|
||||
os.makedirs(args.output_path, exist_ok=True)
|
||||
|
||||
logging.debug(f"input: {args.input_path}, output: {args.output_path}")
|
||||
process(args.input_path, args.output_path)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
print("----Good Execution----")
|
BIN
NFC/Amiibo/amiibos/Amiibo_Files.zip
Normal file
BIN
NFC/Amiibo/amiibos/Amiibo_Files.zip
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user