Skip to content

Commit

Permalink
added metadata transplant, cleaned code (#16)
Browse files Browse the repository at this point in the history
  • Loading branch information
MiDe-S committed Apr 29, 2024
1 parent f93db44 commit e66b8b2
Show file tree
Hide file tree
Showing 9 changed files with 413 additions and 289 deletions.
509 changes: 221 additions & 288 deletions main.py

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion utils/ssbu_amiibo.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ class InvalidAmiiboDump(AmiiboBaseError):
class IncorrectGameDataIdException(Exception):
pass


class InvalidSsbuChecksum(Exception):
pass

Expand Down
16 changes: 16 additions & 0 deletions utils/virtual_amiibo_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,22 @@ def initialize_amiibo(self, mii_path: str, name: str):
self.set_mii(mii_path)
except InvalidMiiSizeError:
raise InvalidMiiSizeError

def recieve_metadata_transplant(self, donor):
"""
Takes FP medata from donor and puts it onto this file
RO areas from https://wiki.gbatemp.net/wiki/Amiibo give FP metadata needed for transplant
"""
if not self.is_initialized() or not donor.is_initialized():
raise InvalidAmiiboDump

self.dump.data = cli.amiitools_to_dump(self.dump.data)
donor.dump.data = cli.amiitools_to_dump(donor.dump.data)
self.dump.data[0:17] = donor.dump.data[0:17]
self.dump.data[52:129] = donor.dump.data[52:129]
self.dump.data[520:533] = donor.dump.data[520:533]
self.dump.data = cli.dump_to_amiitools(self.dump.data)
donor.dump.data = cli.amiitools_to_dump(donor.dump.data)

class JSONVirtualAmiiboFile(VirtualAmiiboFile):
def __init__(self, binfp, keyfp):
Expand Down
26 changes: 26 additions & 0 deletions windows/about.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import webbrowser
import PySimpleGUI as sg

def open_about_window(version_number):
mide_link = r"https://github.com/MiDe-S"
jozz_link = r"https://github.com/jozz024"
info_layout = [[sg.Text(f"Smash Amiibo Editor Version {version_number}.\n\nCreated by:", font=("Arial", 10, "bold"))],
[sg.Text("MiDe:"), sg.Text(mide_link, enable_events=True, tooltip="Click Me",
font=("Arial", 10, "underline"))],
[sg.Text("jozz:"), sg.Text(jozz_link, enable_events=True, tooltip="Click Me",
font=("Arial", 10, "underline"))],
[sg.Text("View Repo", enable_events=True, tooltip="Click Me",
font=("Arial", 10, "underline"))],
[sg.Submit("Okay")]]
info_window = sg.Window("Info", info_layout, element_justification='center')
while True:
event, values = info_window.read()
if event == mide_link:
webbrowser.open(mide_link)
elif event == jozz_link:
webbrowser.open(jozz_link)
elif event == "View Repo":
webbrowser.open(r'https://github.com/jozz024/smash-amiibo-editor')
elif event == sg.WIN_CLOSED or event == "Okay":
info_window.close()
break
File renamed without changes.
51 changes: 51 additions & 0 deletions windows/initialize.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import PySimpleGUI as sg
from utils.virtual_amiibo_file import InvalidMiiSizeError

def open_amiibo_settings_prompt():
"""
Runs a pop up window that asks user if they want to register their amiibo.
:return: Yes or No input from popup window
"""
popup = sg.PopupYesNo('This amiibo is not registered with a mii or name. \nWould you like to register this amiibo?')
return popup

def open_initialize_amiibo_window(amiibo):
# Asks the user if they want to apply a mii and name
open_settings = open_amiibo_settings_prompt()
if open_settings == "Yes":
amiibo_settings_layout = [[sg.Text("amiibo Settings Menu")],
[sg.Text("Mii File:"), sg.Button("Load Mii", key= "load-mii-key", enable_events=True)
],
[sg.Text("amiibo name:"), sg.Input(key = "amiibo-name-key", size=15, enable_events=True)],
[sg.Button("Save", key="save-amiibo-settings-key", enable_events=True), sg.Button("Cancel", key="cancel-amiibo-settings-key", enable_events = True)]]
amiibo_settings_window = sg.Window("amiibo Settings", amiibo_settings_layout)
while True:
settings_event, settings_values = amiibo_settings_window.read()
if settings_event == "load-mii-key":
# Opens a FileDialog to adk for the mii file
mii_filename = sg.filedialog.askopenfilename(filetypes=(('Mii Files', '*.bin;*.ffsd;*.cfsd'), ))
if mii_filename == "":
sg.popup("Please select a mii file!", title = "Select Mii")
if settings_event == "amiibo-name-key":
amiibo_name: str = settings_values["amiibo-name-key"]
if settings_event == "save-amiibo-settings-key":
# Passes the data to the initialize function in VirtualAmiiboFile
try:
amiibo.initialize_amiibo(mii_filename, amiibo_name)
amiibo_settings_window.close()
except InvalidMiiSizeError:
sg.popup("Mii Dump Too Large!", title='Incorrect Mii Dump!')
continue
if settings_event == "cancel-amiibo-settings-key":
# Sets the amiibo to None on cancel
amiibo = None
amiibo_settings_window.close()
if settings_event == sg.WIN_CLOSED:
# Sets the amiibo to None on cancel
amiibo = None
amiibo_settings_window.close()
break
if open_settings == "No":
amiibo = None
return amiibo
68 changes: 68 additions & 0 deletions windows/metadata_transplant.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import PySimpleGUI as sg
from tkinter import filedialog
import os

from utils.ssbu_amiibo import InvalidAmiiboDump
from utils.virtual_amiibo_file import VirtualAmiiboFile

def open_metadata_window(config):
outcome = None
recieverBin = None
recieverName = "Not seleced"
donorBin = None
DONOR_NAME_KEY = "donor_name"
RECIEVER_NAME_KEY = "reciver_name"
TRANSPLANT_SAVE_KEY = "save_location"


layout = [[sg.Text("Donor is from the figure you want to transplant to.")],
[sg.Text("Reciever has the training data you want on the figure.")],
[sg.Button("Donor"), sg.Text("Not selected", key=DONOR_NAME_KEY)],
[sg.Button("Reciever"), sg.Text("Not selected", key=RECIEVER_NAME_KEY)],
[sg.Column([[sg.FileSaveAs("Transplant Figure Metadata", target="SaveTrigger", key=TRANSPLANT_SAVE_KEY, file_types=(('Bin Files', '*.bin'),), default_extension=".bin", disabled=True)]], justification='r'), sg.Input(key="SaveTrigger", enable_events=True, visible=False)],
[sg.HorizontalSeparator()],
[sg.Text("In order to restore with powersaves, bin file name must be formatted to match that of the donor bin.")],
[sg.Text("(like AMIIBO_1a2345_2024_01_01_[])")]]
window = sg.Window("Smash Amiibo Editor", layout, element_justification='center', resizable=True)
window.finalize()

while True:
event, values = window.read()

match event:
case "Donor":
path = filedialog.askopenfilename(filetypes=(('amiibo files', '*.json;*.bin'), ))
# if cancelled don't try to open bin
if path == '':
continue
window[DONOR_NAME_KEY].update(os.path.basename(path))
donorBin = path
if recieverBin and donorBin:
window[TRANSPLANT_SAVE_KEY].update(disabled=False)
case "Reciever":
path = filedialog.askopenfilename(filetypes=(('amiibo files', '*.json;*.bin'), ))
# if cancelled don't try to open bin
if path == '':
continue
window[RECIEVER_NAME_KEY].update(os.path.basename(path))
recieverBin = path
if recieverBin and donorBin:
window[TRANSPLANT_SAVE_KEY].update(disabled=False)

case "SaveTrigger":
if values[TRANSPLANT_SAVE_KEY] == '':
continue
donor = VirtualAmiiboFile(donorBin, config.read_keys())
reciever = VirtualAmiiboFile(recieverBin, config.read_keys())
try:
reciever.recieve_metadata_transplant(donor)
reciever.save_bin(values[TRANSPLANT_SAVE_KEY])
window.close()
outcome = "OK"
break
except InvalidAmiiboDump:
sg.popup("Please initialize both bins in SSBU before transplanting")
case sg.WIN_CLOSED:
break
return outcome

File renamed without changes.
31 changes: 31 additions & 0 deletions windows/theme.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import PySimpleGUI as sg

def open_theme_window(config, show_reload_warning):
reloadwarn = None
color_list = sg.list_of_look_and_feel_values()
color_list.sort()
layout = [[sg.Text('Color Browser')],
[sg.Text("Click a color to set it as the editor's color")],
[sg.Listbox(values=color_list,
size=(20, 12), key='-LIST-', enable_events=True)],
[sg.Button('Okay'), sg.Button('Cancel')]]

color_window = sg.Window('Color Browser', layout)
while True: # Event Loop
event, values = color_window.read()
if event == 'Okay':
if len(values['-LIST-']) != 0:
reloadwarn = show_reload_warning()
if reloadwarn == 'OK':
sg.theme(values['-LIST-'][0])
config.write_color(values['-LIST-'][0])
config.save_config()
color_window.close()
break
else:
color_window.close()
break
elif event is None or event == "Cancel":
color_window.close()
break
return reloadwarn

0 comments on commit e66b8b2

Please sign in to comment.