import PySimpleGUI as sg ## pip install pysimplegui import os from glob import glob import shutil import pathlib import filecmp import webbrowser import requests import base64 import zipfile import io import threading from packaging import version ##Here goes the actual code #this checks if the folder structure is correct. It will output a list of the files that we will then use to recreate the structure with a single file def safelist(): safe_files = ['MetalMan - (GB II).nsf', 'IceMan - (GB I).nsf', 'CutMan - (GB I).nsf', 'Neptune - (GB V).nsf', 'GBVWily2.nsf', 'WoodMan - (GB II).nsf', 'Saturn - (GB V).nsf', 'Jupiter - (GB V).nsf', 'Terra - (GB V).nsf', 'Venus - (GB V).nsf', 'GBIIIWily2.nsf', 'AirMan - (GB II).nsf', 'Uranus - (GB V).nsf', 'Pluto - (GB V).nsf', 'GBVWily1.nsf', 'Mercury - (GB V).nsf', 'GBIIWily2.nsf', 'MagnetMan - (GB II).nsf', 'Mars - (GB V).nsf', 'GBIIIWily1.nsf', 'ElecMan - (GB I).nsf', 'GBIWily2.nsf', 'TopMan - (GB II).nsf', 'CrashMan - (GB II).nsf', 'GBIWily1.nsf', 'Punk - (GB III).nsf', 'HardMan - (GB II).nsf', 'NeedleMan - (GB II).nsf', 'FireMan - (GB I).nsf', 'GBIVWily1.nsf', 'GBIIWily1.nsf', 'FreezeMan.nsf', 'JunkMan.nsf', 'SlashMan.nsf', 'CloudMan.nsf', 'SpringMan.nsf', 'Wily4.nsf', 'RobotMuseum.nsf', 'Wily1.nsf', 'Intro.nsf', 'Wily3.nsf', 'ShadeMan.nsf', 'ShadeManAlt.nsf', 'TurboMan.nsf', 'BurstMan.nsf', 'Wily2.nsf', 'WilyTower2.nsf', 'HyperStormH.nsf', 'WilyTower1.nsf', 'WilyTower3.nsf', 'MegaWaterS.nsf', 'WilyTower4.nsf', 'BusterRodG.nsf', 'GravityMan.nsf', 'WaveMan.nsf', 'StoneMan.nsf', 'MM5WilyCirno.nsf', 'MM5Wily.nsf', 'StarMan.nsf', 'NapalmMan.nsf', 'CrystalMan.nsf', 'ProtoCastle.nsf', 'ChargeMan.nsf', 'GyroMan.nsf', 'FlameMan.nsf', 'MrX.nsf', 'YamatoMan.nsf', 'CentaurMan.nsf', 'WindMan.nsf', 'PlantMan.nsf', 'MM6Wily.nsf', 'KnightMan.nsf', 'BlizzardMan.nsf', 'TomahawkMan.nsf', 'MM2Wily2.nsf', 'Crashman.nsf', 'MM2Wily1.nsf', 'MM2Wily6.nsf', 'Metalman.nsf', 'Flashman.nsf', 'Bubbleman.nsf', 'Woodman.nsf', 'Heatman.nsf', 'Quickman.nsf', 'Airman.nsf', 'GameOver.nsf', 'WilyIntro3.nsf', 'StageStart.nsf', 'WilyIntro2.nsf', 'WilyIntro1.nsf', 'Victory.nsf', 'ProtoWhistle.nsf', 'Bombman.nsf', 'MM1Wily1.nsf', 'MM1Wily2.nsf', 'Fireman.nsf', 'Iceman.nsf', 'Cutman.nsf', 'Elecman.nsf', 'PUIntroStage.nsf', 'Timeman.nsf', 'Oilman.nsf', 'Gutsman.nsf', 'FrostMan.nsf', 'GrenadeMan.nsf', 'AquaMan.nsf', 'AstroMan.nsf', 'Wily4.nsf', 'TenguMan(SS).nsf', 'Wily1.nsf', 'IntroStage(Underwater).nsf', 'SwordMan.nsf', 'Wily3.nsf', 'SearchMan.nsf', 'IntroStage.nsf', 'ClownMan.nsf', 'Wily2.nsf', 'TenguMan(PSX).nsf', 'Megaman4.nsf', 'ToadMan.nsf', 'MM4Wily2.nsf', 'RingMan.nsf', 'MM4Wily1.nsf', 'DrillMan.nsf', 'BrightMan.nsf', 'DiveMan.nsf', 'SkullMan.nsf', 'DustMan.nsf', 'Cossack1.nsf', 'PharaohMan.nsf', 'Cossack2.nsf', 'MagnetMan.nsf', 'MM3Wily2.nsf', 'MM3Wily3.nsf', 'SnakeMan.nsf', 'Megaman3.nsf', 'MM3Wily1.nsf', 'GeminiMan.nsf', 'ShadowMan.nsf', 'HardMan.nsf', 'TopMan.nsf', 'NeedleMan.nsf', 'SparkMan.nsf', 'KazeYoTsutaete.nsf', 'MMB_-_King_Nix.nsf', '30XXTitleLooped.nsf', 'FakeMan.nsf', 'PlugMan.nsf', 'GalaxyMan.nsf', 'EndlessAttack.nsf', 'SplashWoman.nsf', 'Wily4.nsf', 'Wily1.nsf', 'MagmaMan.nsf', 'JewelMan.nsf', 'ConcreteMan.nsf', 'Wily3.nsf', 'TornadoMan.nsf', 'Wily2.nsf', 'HornetMan.nsf', 'StrikeMan.nsf', 'Challenges.nsf', 'Wily1Outside.nsf', 'SolarMan.nsf', 'EndlessAttack.nsf', 'Wily4.nsf', 'NitroMan.nsf', 'Wily1Inside.nsf', 'CommandoMan.nsf', 'Punk.nsf', 'Wily5.nsf', 'Wily3.nsf', 'Enker.nsf', 'Ballade.nsf', 'ChillMan.nsf', 'BladeMan.nsf', 'PumpMan.nsf', 'Wily2.nsf', 'SheepMan.nsf', 'MM4.nsf', 'MM&B.nsf', 'MM8Wily.nsf', 'Sunstar - (GB V).nsf', 'MM7WilyCapsule.nsf', 'GBIVWilyBoss.nsf', 'MM10WilyCapsule.nsf', 'MMPUWilyBoss.nsf', 'MM11WilyCapsule.nsf', 'GBIV.nsf', 'MM3.nsf', 'MM&BKingBoss.nsf', 'MM3Wily.nsf', 'MM10WilyBoss.nsf', 'MM10WilyMachine.nsf', 'MM1Wily.nsf', 'MM10.nsf', 'MM2.nsf', 'MM5.nsf', 'BassMM8.nsf', 'MMPUWilyMachine.nsf', 'MM7Wily.nsf', 'MMWilyWars.nsf', 'MM8WoodMan.nsf', 'Duo.nsf', 'MM6Wily.nsf', 'MM11.nsf', 'BassMM7.nsf', 'MM5Wily.nsf', 'MM6.nsf', 'MM8CutMan.nsf', 'BossIntro.nsf', 'MM7.nsf', 'MMPU.nsf', 'MM4Wily.nsf', 'GBI.nsf', 'GBIVBalladeBoss.nsf', 'MM1.nsf', 'MM11WilyBoss.nsf', 'GBV.nsf', 'MM11WilyMachine.nsf', 'Midboss.nsf', 'GBII.nsf', 'MM9.nsf', 'MM8.nsf', 'MM8WilyCapsule.nsf', 'MM9Wily.nsf', 'EditorB.nsf', 'Credits.nsf', 'EditorD.nsf', '30XXTitle.nsf', 'Title.nsf', 'OnlineMenu.nsf', 'Menu.nsf', 'Editor.nsf', 'EditorC.nsf', 'ChallengeCredits.nsf', 'Tutorial.nsf', 'MagicMan.nsf', 'ColdMan.nsf', 'MM&BWily1.nsf', 'MM&BKing1.nsf', 'PirateMan.nsf', 'DynamoMan.nsf', 'GroundMan.nsf', 'AstroMan.nsf', 'Intro.nsf', 'TenguMan.nsf', 'CrystalGate.nsf', 'BurnerMan.nsf', 'BounceMan.nsf', 'FuseMan.nsf', 'TorchMan.nsf', 'Challenges.nsf', 'WilyStage.nsf', 'TundraMan.nsf', 'AcidMan.nsf', 'DrLightTrial.nsf', 'BlockMan.nsf', 'BlastMan.nsf', 'ImpactMan.nsf'] return safe_files def boss_music(): boss_music = ['MM4.nsf', 'MM&B.nsf', 'MM8Wily.nsf', 'Sunstar - (GB V).nsf', 'MM7WilyCapsule.nsf', 'GBIVWilyBoss.nsf', 'MM10WilyCapsule.nsf', 'MMPUWilyBoss.nsf', 'MM11WilyCapsule.nsf', 'GBIV.nsf', 'MM3.nsf', 'MM&BKingBoss.nsf', 'MM3Wily.nsf', 'MM10WilyBoss.nsf', 'MM10WilyMachine.nsf', 'MM1Wily.nsf', 'MM10.nsf', 'MM2.nsf', 'MM5.nsf', 'BassMM8.nsf', 'MMPUWilyMachine.nsf', 'MM7Wily.nsf', 'MMWilyWars.nsf', 'MM8WoodMan.nsf', 'Duo.nsf', 'MM6Wily.nsf', 'MM11.nsf', 'BassMM7.nsf', 'MM5Wily.nsf', 'MM6.nsf', 'MM8CutMan.nsf', 'BossIntro.nsf', 'MM7.nsf', 'MMPU.nsf', 'MM4Wily.nsf', 'GBI.nsf', 'GBIVBalladeBoss.nsf', 'MM1.nsf', 'MM11WilyBoss.nsf', 'GBV.nsf', 'MM11WilyMachine.nsf', 'Midboss.nsf', 'GBII.nsf', 'MM9.nsf', 'MM8.nsf', 'MM8WilyCapsule.nsf', 'MM9Wily.nsf'] return boss_music def level_music(): level_music = ['MetalMan - (GB II).nsf', 'IceMan - (GB I).nsf', 'CutMan - (GB I).nsf', 'Neptune - (GB V).nsf', 'GBVWily2.nsf', 'WoodMan - (GB II).nsf', 'Saturn - (GB V).nsf', 'Jupiter - (GB V).nsf', 'Terra - (GB V).nsf', 'Venus - (GB V).nsf', 'GBIIIWily2.nsf', 'AirMan - (GB II).nsf', 'Uranus - (GB V).nsf', 'Pluto - (GB V).nsf', 'GBVWily1.nsf', 'Mercury - (GB V).nsf', 'GBIIWily2.nsf', 'MagnetMan - (GB II).nsf', 'Mars - (GB V).nsf', 'GBIIIWily1.nsf', 'ElecMan - (GB I).nsf', 'GBIWily2.nsf', 'TopMan - (GB II).nsf', 'CrashMan - (GB II).nsf', 'GBIWily1.nsf', 'Punk - (GB III).nsf', 'HardMan - (GB II).nsf', 'NeedleMan - (GB II).nsf', 'FireMan - (GB I).nsf', 'GBIVWily1.nsf', 'GBIIWily1.nsf', 'FreezeMan.nsf', 'JunkMan.nsf', 'SlashMan.nsf', 'CloudMan.nsf', 'SpringMan.nsf', 'Wily4.nsf', 'RobotMuseum.nsf', 'Wily1.nsf', 'Intro.nsf', 'Wily3.nsf', 'ShadeMan.nsf', 'ShadeManAlt.nsf', 'TurboMan.nsf', 'BurstMan.nsf', 'Wily2.nsf', 'WilyTower2.nsf', 'HyperStormH.nsf', 'WilyTower1.nsf', 'WilyTower3.nsf', 'MegaWaterS.nsf', 'WilyTower4.nsf', 'BusterRodG.nsf', 'GravityMan.nsf', 'WaveMan.nsf', 'StoneMan.nsf', 'MM5WilyCirno.nsf', 'MM5Wily.nsf', 'StarMan.nsf', 'NapalmMan.nsf', 'CrystalMan.nsf', 'ProtoCastle.nsf', 'ChargeMan.nsf', 'GyroMan.nsf', 'FlameMan.nsf', 'MrX.nsf', 'YamatoMan.nsf', 'CentaurMan.nsf', 'WindMan.nsf', 'PlantMan.nsf', 'MM6Wily.nsf', 'KnightMan.nsf', 'BlizzardMan.nsf', 'TomahawkMan.nsf', 'MM2Wily2.nsf', 'Crashman.nsf', 'MM2Wily1.nsf', 'MM2Wily6.nsf', 'Metalman.nsf', 'Flashman.nsf', 'Bubbleman.nsf', 'Woodman.nsf', 'Heatman.nsf', 'Quickman.nsf', 'Airman.nsf', 'Bombman.nsf', 'MM1Wily1.nsf', 'MM1Wily2.nsf', 'Fireman.nsf', 'Iceman.nsf', 'Cutman.nsf', 'Elecman.nsf', 'PUIntroStage.nsf', 'Timeman.nsf', 'Oilman.nsf', 'Gutsman.nsf', 'FrostMan.nsf', 'GrenadeMan.nsf', 'AquaMan.nsf', 'AstroMan.nsf', 'Wily4.nsf', 'TenguMan(SS).nsf', 'Wily1.nsf', 'IntroStage(Underwater).nsf', 'SwordMan.nsf', 'Wily3.nsf', 'SearchMan.nsf', 'IntroStage.nsf', 'ClownMan.nsf', 'Wily2.nsf', 'TenguMan(PSX).nsf', 'Megaman4.nsf', 'ToadMan.nsf', 'MM4Wily2.nsf', 'RingMan.nsf', 'MM4Wily1.nsf', 'DrillMan.nsf', 'BrightMan.nsf', 'DiveMan.nsf', 'SkullMan.nsf', 'DustMan.nsf', 'Cossack1.nsf', 'PharaohMan.nsf', 'Cossack2.nsf', 'MagnetMan.nsf', 'MM3Wily2.nsf', 'MM3Wily3.nsf', 'SnakeMan.nsf', 'Megaman3.nsf', 'MM3Wily1.nsf', 'GeminiMan.nsf', 'ShadowMan.nsf', 'HardMan.nsf', 'TopMan.nsf', 'NeedleMan.nsf', 'SparkMan.nsf', 'KazeYoTsutaete.nsf', 'MMB_-_King_Nix.nsf', '30XXTitleLooped.nsf', 'FakeMan.nsf', 'PlugMan.nsf', 'GalaxyMan.nsf', 'EndlessAttack.nsf', 'SplashWoman.nsf', 'Wily4.nsf', 'Wily1.nsf', 'MagmaMan.nsf', 'JewelMan.nsf', 'ConcreteMan.nsf', 'Wily3.nsf', 'TornadoMan.nsf', 'Wily2.nsf', 'HornetMan.nsf', 'StrikeMan.nsf', 'Challenges.nsf', 'Wily1Outside.nsf', 'SolarMan.nsf', 'EndlessAttack.nsf', 'Wily4.nsf', 'NitroMan.nsf', 'Wily1Inside.nsf', 'CommandoMan.nsf', 'Punk.nsf', 'Wily5.nsf', 'Wily3.nsf', 'Enker.nsf', 'Ballade.nsf', 'ChillMan.nsf', 'BladeMan.nsf', 'PumpMan.nsf', 'Wily2.nsf', 'SheepMan.nsf', 'MagicMan.nsf', 'ColdMan.nsf', 'MM&BWily1.nsf', 'MM&BKing1.nsf', 'PirateMan.nsf', 'DynamoMan.nsf', 'GroundMan.nsf', 'AstroMan.nsf', 'Intro.nsf', 'TenguMan.nsf', 'CrystalGate.nsf', 'BurnerMan.nsf', 'BounceMan.nsf', 'FuseMan.nsf', 'TorchMan.nsf', 'Challenges.nsf', 'WilyStage.nsf', 'TundraMan.nsf', 'AcidMan.nsf', 'DrLightTrial.nsf', 'BlockMan.nsf', 'BlastMan.nsf', 'ImpactMan.nsf'] return level_music def whitelist_to_blacklist(whitelist): blacklist = [] for element in safelist(): if element not in whitelist: blacklist.append(element) return blacklist # def generate_whitelist(megamaker_folder): # subfolders = os.listdir(os.path.join(megamaker_folder, "Music")) # subfolders.remove("Other") # subfolders.remove("Misc") # subfolders.remove("Boss") # filenames = [] # for folder in subfolders: # folder_filenames =os.listdir(os.path.join(megamaker_folder, "Music", folder)) # for filename in folder_filenames: # filenames.append(filename) # # print(filenames) def changed_nsf_files(megamaker_folder): megamaker_folder = os.path.abspath(megamaker_folder) music_folder = os.path.join(megamaker_folder, "original_specific_songs") file_names = [] glob_search = os.path.join(music_folder,"*","*.nsf") file_paths = (glob(glob_search)) for files in file_paths: files_no_path = os.path.basename(files) if files_no_path == 'TMP_BURNER_MAN.nsf': print("skipping",files_no_path) elif files_no_path == 'TMP_COLD_MAN.nsf': print("skipping", files_no_path) else: file_names.append(files_no_path) return file_names def get_original_songs(megamaker_folder): mmm_version = check_version(version=True) parsed_version = mmm_version.replace(".", "_") url = f"https://megamanmaker.com/downloads/MegaManMaker_v{parsed_version}.zip" request = requests.get(url) zip_file = zipfile.ZipFile(io.BytesIO(request.content)) for file in zip_file.namelist(): if file.startswith('Music/'): zip_file.extract(file, megamaker_folder) window.write_event_value('-THREAD DONE-', True) return True app_version = "v2.0" def check_if_new_version(): response = requests.get("https://gitlab.com/api/v4/projects/51771052/repository/tags") newest_version = response.json()[0]["name"] if version.parse(newest_version) == version.parse(app_version): return False elif version.parse(newest_version) > version.parse(app_version): return True #add mmm_version = "1.8.5.1" def check_version(version=False): api_version = "https://api.megamanmaker.com/version" ver = requests.get(api_version) ver_num = ver.json()["version"] if version == True: return ver_num if mmm_version == ver_num: return True else: return False def create_mute_file(base64_str): current_dir = os.path.dirname(__file__) mutefile = os.path.join(current_dir, "mmm_nsf_changer_mute.nsf") if os.path.exists(mutefile): print("the mute nsf file already exists. This is a safety measure.") else: with open(mutefile, 'wb') as file_to_save: decoded_image_data = base64.b64decode(base64_str) file_to_save.write(decoded_image_data) return True def check_folder_structure(megamaker_folder, og_music=False, whitelist=[]): megamaker_folder = os.path.abspath(megamaker_folder) subfolders = ([ f.path for f in os.scandir(megamaker_folder) if f.is_dir() ]) music_folder = os.path.join(megamaker_folder, "Music") if og_music: music_folder = os.path.join(megamaker_folder, "original_music") file_names = [] if music_folder in subfolders: glob_search = os.path.join(music_folder,"*","*.nsf") file_paths = (glob(glob_search)) for files in file_paths: files_no_path = os.path.basename(files) if files_no_path == 'TMP_BURNER_MAN.nsf': print("skipping",files_no_path) elif files_no_path == 'TMP_COLD_MAN.nsf': print("skipping", files_no_path) else: file_names.append(files_no_path) if set(file_names) == set(safelist()) or set(file_names) == set(whitelist): return file_paths else: print("Safety check failed. Either you have other files in the music folder of mega maker, you are in the wrong folder, or there has been a new update.") else: return False ##this needs an overhaul. def copy_music_to_ogmusic(path): original_filepaths = check_folder_structure(path) if original_filepaths: #if not filecmp.cmp(os.path.join(path,"Music","MM1","Cutman.nsf"), os.path.join(path, "Music", "MM1", "Oilman.nsf"), shallow=False): for filepath in original_filepaths: ogmusic_dirname = os.path.join(path, "original_music", os.path.basename(os.path.dirname(filepath))) ogmusic_filepath = os.path.join(ogmusic_dirname, os.path.basename(filepath)) if not os.path.exists(ogmusic_dirname): os.makedirs(ogmusic_dirname) if os.path.exists(ogmusic_filepath): print(os.path.basename(ogmusic_filepath), "EXISTS. SKIPPING.") else: shutil.copy(filepath, ogmusic_filepath) #shutil.copytree(os.path.join(path, "Music"), os.path.join(path, "original_music"), dirs_exist_ok=True) if not os.path.exists(os.path.join(path, "Music")): os.makedirs(os.path.join(path, "Music")) else: print("Cutman.nsf and Oilman.nsf match in Music folder.") return False def filename_to_filepath(filename, path): path = os.path.abspath(path) original_filepaths = check_folder_structure(path) if original_filepaths != False: for file_path in original_filepaths: if os.path.basename(file_path) == filename: old_song_path = file_path break return old_song_path else: return False def replace_song(new_song_path,old_song_name, megamaker_folder): path = os.path.abspath(megamaker_folder) old_song_path = filename_to_filepath(old_song_name, megamaker_folder) subfolder = os.path.basename(os.path.dirname(old_song_path)) backup_path = os.path.join(megamaker_folder, "original_specific_songs", subfolder, old_song_name) ##backup_song if old_song_name != False: os.makedirs(os.path.dirname(backup_path), exist_ok=True) if os.path.isfile(backup_path): shutil.copy(new_song_path, old_song_path) print("skipping backup file. why, it already exists!") else: try: shutil.copy(old_song_path, backup_path) shutil.copy(new_song_path, old_song_path) except FileNotFoundError: print("FILE NOT FOUND") def restore_song(old_song_name, megamaker_folder): path = os.path.abspath(megamaker_folder) old_song_path = filename_to_filepath(old_song_name, megamaker_folder) subfolder = os.path.basename(os.path.dirname(old_song_path)) backup_path = os.path.join(megamaker_folder, "original_specific_songs", subfolder, old_song_name) if old_song_name != False: try: shutil.copy(backup_path, old_song_path) except FileNotFoundError: return False def recreate_structure(new_nsf, original_paths_list): for path in original_paths_list: if not os.path.exists(os.path.dirname(path)): os.makedirs(os.path.dirname(path)) print("recreate structure if not os.path.exists") try: shutil.copy(new_nsf, path) except: print("continuing") continue #check if the contents of files in original_music != the files in music AND check if contents of input nsf == every file in music. if all of that is true replace music with original_music def restore_ogmusic(path): if os.path.exists(os.path.join(path, "original_music")): if os.path.exists(os.path.join(path, 'Music')): if check_folder_structure(path): #if check_folder_structure(path, og_music=True): #if not filecmp.cmp(os.path.join(path, "Music", "MM1", 'Cutman.nsf'), os.path.join(path, "original_music", "MM1", "Cutman.nsf"), shallow=False): #shutil.rmtree(os.path.join(path, "Music")) ogmusic = os.path.join(path, "original_music") music = os.path.join(path, "Music") shutil.copytree(ogmusic, music, dirs_exist_ok=True) shutil.rmtree(ogmusic) #files = os.listdir(ogmusic) #print(files) #for filename in files: #filepath = os.path.join(music, os.path.basename(filename)) #shutil.move(os.path.join(src, filename), os.path.join(path, "Music")) return True #else: # print("something went wrong...") #else: # print("if check_folder_structure(path, og_music=True):") # return False else: print("if check_folder_structure(path):") return False else: print("if os.path.exists(os.path.join(path, 'Music')):") return False else: print("os.path.exists(os.path.join(path, 'original_music')):") return False def nsf_changer (nsf_path, megamaker_folder, whitelist=[]): original_path = check_folder_structure(megamaker_folder, whitelist=whitelist) if whitelist: full_original_path = original_path original_path = [] for files in full_original_path: files_no_path = os.path.basename(files) if files_no_path in whitelist: original_path.append(files) #if not whitelist or files_no_path in whitelist: if original_path: try: common = os.path.commonpath([os.path.dirname(nsf_path), os.path.join(megamaker_folder, "Music")]) except ValueError: common = False if common == os.path.join(megamaker_folder, "Music"): restore_ogmusic(megamaker_folder) shutil.copy(nsf_path, os.path.join(megamaker_folder, os.path.basename(nsf_path))) nsf_path = os.path.join(megamaker_folder, os.path.basename(nsf_path)) #move_music_to_ogmusic(megamaker_folder) copy_music_to_ogmusic(megamaker_folder) recreate_structure(nsf_path, original_path) if common == os.path.join(megamaker_folder, "Music"): if os.path.dirname(nsf_path) == megamaker_folder: os.remove(nsf_path) print("nsf changer returning true") return True else: print("nsf changer returning false") return False sg.theme('Material1') icon = b"iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAArlBMVEUAAAAAAAB5eXmioqIwUYJBksNh0+Oi//MwYUFJomlx45Ki/8s4bQBJqhBx80Gi86I4aQBRogCa6wDL84JJWQCKigDr0yD/85J5QQDDcQD/ogD/26KiMADjUQD/eTD/y7qyEDDbQWH/YbL/uuuaIHnbQcPzYf/jsv9hEKKSQfOicf/Dsv8oALpBQf9Rgv+iuv8gALJBYfthov+S0/95eXmysrLr6+v///8Aaf9DkP8A2fKiAAAAOnRSTlMA////////////////////////////////////////////////////////////////////////////ncmmFQAAAK5JREFUOI21k1sSgCAIRb2rYtz/xpKnpIz1UcyUAkcEldYfpL0DwN8iGRja6g7EgLkix3Jg8ScqAyVxrOJDgIjGhHSQMQw8WwA3+4QBxFoxj8BKSmkMzMXoGZW6a4CzMw0OmJO3I6khkhVA0hBVCNoBuMrhPR4KwKNgZqSAhjZTQmEnaUQcD9Bjz+aXHT+9g3gCbV5LLf8BWw7HR3t/53e/d1bVNhkoGy911kkegQvP3acj3R2TXgAAAABJRU5ErkJggg==" gif = b"R0lGODdhQgAmAHcAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAAACwAAAAAQgAmAIAAAAAAefsCzISPqcvtD6OctNqLs95chg92YgOGT/mNExpArOqhrgzPpW3WznvSHM8AknwbocK4QGKUBybCWYFCDdMV8XhNZpfbZvf5BUjD1fFteA6GqeR2WvtWxxPmHNwux9PdevAc++cVyDYotmZYWJeCaFLGt5i3yON4NvnYwih5aFl5Sdi4ScPZJwjaeWo3qpko2ooKmYmpKutqaruaWou7S/vae4v5ySv8OxxLjFxqPJvMfKxcHN2sK/087XsNnA3r3E29HfzsjS3+rXOOnn5QAAAh+QQJCgAAACwCAAYAPgAeAIAAAAAAefsClYSPqcvtD6OctNqLcw28a9R5W0hy31FaZXoCLLWSrSuPsdm+0y2eusTD+Wqw4OwXCQaOxJ0x1wQ+hyHV9IOEKJlV243bc/IM2QerTH6iG+doYkvrFrtr+JrRli/stXr/T6cGGKaQJ2IYkxa4eDiIg7ii2Mj46LgUN/mFWUl5CSnJqfm56WkJWjpGerqq2go5CmvqSlIAACH5BAkKAAAALAIABgA+AB4AgAAAAAB5+wKthI+pF+0Lo5zTPYqzBrbtDyZdEJbfaKYYqm4s9C5xOYudVIM5c0e724MFZUNaj/XjFEPI4xKRzDQthqT1qaRmL1et0GvTTi9fMhEMdYqxVfbWc+aqzYounbfO39Po8P5NAtjWxyenB1c3B2e3qBiYeBjIKOlY1hiJUykYd2n4N+jZiegnSkmIF2o6kgpa2qrqCjgWOwtr+1r7qruZK6vZC+wYjMn7u0o8zFpsUQAAIfkECQoAAAAsAgAGAD4AHgCAAAAAAHn7AqGEb6GL7Q+jfIvNi3OrSvsPcQFIkmKJAifFpaW4ru4Ht6o9e3WV4K7M2o1uvBzQIewQLbPjJtkrNn1I6FI5LcaszpdtK4wyf99y+DrMWsA7MVbDVsZh7jTcvMbX6vzIvJ809OenJ1g42HWAeFjYF9KIVrcoFZSnxXiZOValKYdpCerZaTgqCTkZSpqKKpoK+Nkaqyr7Oso6i1u7espbGolWAAAh+QQJCgAAACwCAAgAPgAcAIAAAAAAefsCooSPCcGtD6OcqTmKs142bNl5nxKOUGkiaKp27LG+nCXPVx2nObuPvfnbBD/DzPDokiFpkd/y9ngyDCGp6JTEMqvZaJf0rSS5TC0UXPZuydPm+J1GX9htcxtlpdJB8Hm4tcbGF+gXJ0bIpYcogvcH05docwfJ6KhYSHY5uah5pYYZ2cgp6Sm3mUnaqZrKKorqehpbOUo3C2oruwpbpUvZS9tRAAA7" mute_nsf = "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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" print("Checking Version...") if check_version(): version_color = "black" version_message = f"Works with Mega Man Maker {mmm_version}" else: version_color = "red" version_message = f"Mega Man Maker has been updated to {check_version(version=True)}. \nThis tool works with {mmm_version} and may not work properly. Make an Issue at GitLab." print(" done") title = [ [sg.Push(),sg.Text("Mega Man Maker NSF Music Changer | Made by Timothy GFO", font=("Any", 12, "bold")),sg.Push()], [sg.Push(), sg.Text("YouTube", enable_events = True, key="-YT-", text_color="red"), sg.Text("GitLab",enable_events = True,key="-GIT-", text_color="purple"), sg.Text("Blog",enable_events = True,key="-SITE-", text_color="blue"), sg.Push()], [sg.Push(), sg.Text(version_message, text_color=version_color), sg.Push()], ] change_all = [ [sg.Button("Mute"), sg.Button("Apply Music"), sg.Button("Restore Music")], [sg.Radio("All", "music", default=True, key="-ALL-"), sg.Radio("Boss Music","music", key="-BOSS-"), sg.Radio("Level Music", "music", key="-LEVEL-"), sg.Checkbox("All except selected", key="-BLACKLIST-")] ] change_one = [ [sg.Text("Output NSF File:"),sg.Combo(safelist(),default_value="ClownMan.nsf", key="-DROPDOWN-"), sg.StatusBar("",size=(15,1), key="-LAST-CHANGED-")], [sg.Button("Replace Song"), sg.Button("Restore Original Song"), sg.Button("Download and Restore Music")], ] layout = [ [title], [sg.Text("Input NSF File:"), sg.Input(sg.user_settings_get_entry('-INPUT_NSF-', ''), key="-IN-"),sg.FileBrowse(file_types=(("Supported Formats",".nsf .spc .vgm .nsfe .gbs .gym .ay .hes .kss .sap"),("NSF Files", "*.nsf*"),("NSFe Files", "*.nsfe*"),("SNES Files", "*.spc*"),("Gameboy Files", "*.gbs*"), ("Sega Genesis VGM", "*.vgm*"),("Sega Genesis GYM", "*.gym*"), ("ZX Spectrum", "*.ay*"), ("TurboGrafx 16", "*.hes*"), ("MSX Home Computer", "*.kss*"), ("Atari Pokey", "*.sap*"),))], [sg.Text("MegaMaker Folder:"), sg.Input(sg.user_settings_get_entry('-MEGAMAKER_FOLDER-', ''), key="-OUT-"), sg.FolderBrowse()], [sg.TabGroup([[sg.Tab("Play Now", change_all), sg.Tab("Switch a Song", change_one)]]),], [sg.Exit(),sg.Button("About"),sg.Push(), sg.Frame('\U0001F3B5 Now Playing \U0001F3B5', [[sg.Text("Default Songs", key="-PLAYING-")]]), sg.Image(data=gif, key='_IMAGE_')], ] how_to_use = "I made this tool to be able to change the music for any Mega Man Maker level while playing the game. It works by replacing every nsf file with a custom one, but while preserving the original folders and file names.\n\nTo use it, just choose a nsf file and then tell the program where you store the *game* folder. That is where the .exe is, not the user folder.\n\nIf you find this useful, you can check out my YouTube Channel or my blog since I will keep making tools like this. Also, if you find any bugs or errors remember to notify me at GitLab by making an Issue." window = sg.Window(f"MMM NSF Music Changer {app_version}", layout) #disclaimer = sg.popup_yes_no('NSF Changer, by Timothy GFO', 'This program is not complete, there WILL be bugs. Use at your own risk.', 'Do you want to continue?') if check_if_new_version(): sg.popup(f"There is a new update for MMM NSF Changer. Get it at the GitLab repo.") running = False while True: event,values = window.read(timeout=50) window.set_icon(icon) window.refresh() if event in (sg.WINDOW_CLOSED,"Exit"): try: sg.user_settings_set_entry('-INPUT_NSF-', values['-IN-']) sg.user_settings_set_entry('-MEGAMAKER_FOLDER-', values['-OUT-']) except TypeError: pass break window.Element('_IMAGE_').UpdateAnimation(gif, time_between_frames=100) if running: if event == "-THREAD DONE-": running = False sg.PopupAnimated(None) else: window.refresh() sg.popup_animated(sg.DEFAULT_BASE64_LOADING_GIF, message='Loading', time_between_frames=100, location=window.current_location()) else: if event == "-YT-": webbrowser.open("https://youtube.com/gamefeveronline") if event == "-SITE-": webbrowser.open("https://gamefeveronline.gitlab.io") if event == "-GIT-": webbrowser.open("https://gitlab.com/gamefeveronline") if event == "About": sg.popup(how_to_use) if event == "Mute": if values["-ALL-"] != True: if values["-BOSS-"] == True: if values["-BLACKLIST-"] == True: whitelist = whitelist_to_blacklist(boss_music()) else: whitelist = boss_music() elif values["-LEVEL-"] == True: if values["-BLACKLIST-"] == True: whitelist = whitelist_to_blacklist(level_music()) else: whitelist = level_music() else: whitelist = [] create_mute_file(mute_nsf) if not nsf_changer(os.path.join(os.path.dirname(__file__), "mmm_nsf_changer_mute.nsf"), values["-OUT-"], whitelist=whitelist): restore_ogmusic(values["-OUT-"]) if not nsf_changer(os.path.join(os.path.dirname(__file__), "mmm_nsf_changer_mute.nsf"), values["-OUT-"], whitelist=whitelist): sg.popup_error("MegaMaker folder is not valid or definitions are out of date.") window["-PLAYING-"].update(f"MUTED") if event == "Replace Song": if values["-DROPDOWN-"] == "": sg.popup_error('Please select which Output NSF File to replace. If not, use "Replace *All* NSF Music".') else: replace_song(values["-IN-"], values["-DROPDOWN-"], values["-OUT-"]) window["-LAST-CHANGED-"].update(values["-DROPDOWN-"]) if event == "Restore Original Song": if values["-DROPDOWN-"] == "": sg.popup_error('Please select which Output NSF File to replace. If not, use "Replace *All* NSF Music".') else: if restore_song(values["-DROPDOWN-"], values["-OUT-"]) == False: sg.popup_error("The selected song has not been changed, cannot restore.") else: window["-LAST-CHANGED-"].update("") if event == "Apply Music": if values["-ALL-"] != True: if values["-BOSS-"] == True: if values["-BLACKLIST-"] == True: whitelist = whitelist_to_blacklist(boss_music()) else: whitelist = boss_music() elif values["-LEVEL-"] == True: if values["-BLACKLIST-"] == True: whitelist = whitelist_to_blacklist(level_music()) else: whitelist = level_music() else: whitelist = [] if not nsf_changer(values["-IN-"], values["-OUT-"], whitelist=whitelist): restore_ogmusic(values["-OUT-"]) if not nsf_changer(values["-IN-"], values["-OUT-"], whitelist=whitelist): sg.popup_error("MegaMaker folder is not valid or definitions out of date.") window["-PLAYING-"].update(os.path.basename(values["-IN-"])) if event == "Restore Music": # Needs testing # sg.popup_error("DOESNT WORK EITHER HAHAHAHAHAHAA") if not restore_ogmusic(values["-OUT-"]): sg.popup_error("Already Restored or wrong Mega Man Maker folder.") window["-PLAYING-"].update("Default Songs") if event == "Download and Restore Music": sg.popup_yes_no("WARNING: This will erase all custom songs.\nDo you want to continue?", location=window.current_location()) window["-LAST-CHANGED-"].update("") threading.Thread(target=get_original_songs, args=(values["-OUT-"], ), daemon=True).start() running = True #if not restore_ogmusic(values["-OUT-"]): # sg.popup_error("Unexpected folder structure or differing files") window.close()