diff --git a/README.md b/README.md index fa3f250..be7ae92 100644 --- a/README.md +++ b/README.md @@ -7,35 +7,32 @@ I got tired of waiting for actual custom music to be added to Mega Man Maker. So ![Alt text](/nsf_changer.png?raw=true "NSF Changer window") ## Installation -You will need to install through PIP the package PySimpleGUI, requests, and packaging. You can just do "pip install -r requirements.txt". The rest of the dependencies *should* already be installed. +You will need to install through PIP the package PySimpleGUI and maybe requests. The rest of the dependencies *should* be already installed. ## Usage -To use it just launch the executable file (if available for your os) or type "python mmm-nsf-changer.py" in the terminal or commandline, and the GUI will launch. Then you choose your nsf file and where your Mega Man Maker folder is. +Please use at your own risk and make backups of the MegaManMaker folder before you use it. +To use it just launch the executable file (if available for your os) or type "python mmm-nsf-changer.py" in the terminal or commandline, and the GUI will launch. Maybe CLI support will come in the future. Then you choose your nsf file and where your Mega Man Maker folder is. Please note that support for Windows systems is not tested much since I don't use it. On windows systems the program may freeze for about 5 seconds, please DO NOT CLICK RESET ON MEGA MAKER WHILE THE TOOL IS FROZEN, IT WILL CRASH THE GAME. ## Features * Easy way to choose a NSF, NSFe, SPC, VGM, GYM, AY, HES, KSS, SAP or GBS file as a replacement for every song in the game. Yes, you heard that right: You can use SNES Music, Sega Genesis Music, and more in Mega Man Maker! * A "mute" button for replacing every song in the game with a silent song. For people that play Mega Man Maker with external music, like streamers. * Reliable way to restore the original songs. * A decent interface. -* -NEW- Support for "permanently" replacing a specific song to one of your liking, with restoring capabilities. ## Support -If you have any issues make a gitlab issue. There may be bugs. +If you have any issues, which is probable, make a gitlab issue. There may be bugs. ## Roadmap -* fix restore_ogmusic so that it doesn't replace custom music. Possible windows only behaviour, testing is needed. -* consider the posibility of adding a alternate, custom music preserving, updater for Mega Man Maker. -* improve the single-song actions to make them more persistant -* modify restore_ogmusic so it is able to restore only the last change. Maybe config files will be needed for this. -* make it so that if "you press apply music and then replace song" it checks for that and doesn't allow the "replaced song" to be reverted back to original. -* ability to preserve changes through Mega Man Maker updates, by using a config file and/or a downloaded zip of the game. -* stop using os.path in favour of pathlib -* switch to using a config file (or database) for keeping track of which tracks have been changed, that way only having one original_music folder and being able to *show* the user which song you used to replace which file. +* add selective mute, so that you mute every music except the boss music, or every song except menu music or both. +* figure out the best way to add a setting for changing each of the level editor songs, menu music, or a specific level song. Maybe an extra popup window or a check box for "replace every one" "menu" and "levelBuild" * add a way to show the available nsf files in the selected folder, like a playlist. +* add a settings file for the last folder chosen, so if there is a path try to use that so that you don't have to choose it manually +* fix slowdown on windows systems * Instead of duplicating a single file a lot of times, maybe I'll implement symlink support. +* add autoupdater?? ## Contributing You can help with the project by testing it and reporting issues, or by making pull requests. Windows testers are especially needed since I don't daily drive Windows. ## License -GNU General Public License v3.0 +For open source projects, say how it is licensed. diff --git a/bin/v1.1.1/mmm-nsf-changer.exe b/bin/v1.1.1/mmm-nsf-changer.exe deleted file mode 100755 index 9b70470..0000000 Binary files a/bin/v1.1.1/mmm-nsf-changer.exe and /dev/null differ diff --git a/bin/v1.1.2/mmm-nsf-changer.exe b/bin/v1.1.2/mmm-nsf-changer.exe deleted file mode 100755 index 31c2e50..0000000 Binary files a/bin/v1.1.2/mmm-nsf-changer.exe and /dev/null differ diff --git a/bin/v1.2/mmm-nsf-changer.zip b/bin/v1.2/mmm-nsf-changer.zip deleted file mode 100644 index a7ca3ba..0000000 Binary files a/bin/v1.2/mmm-nsf-changer.zip and /dev/null differ diff --git a/bin/v2.0/mmm-nsf-changer-v2.0.zip b/bin/v2.0/mmm-nsf-changer-v2.0.zip deleted file mode 100644 index 7b4f0fb..0000000 Binary files a/bin/v2.0/mmm-nsf-changer-v2.0.zip and /dev/null differ diff --git a/mmm-nsf-changer.py b/mmm-nsf-changer.py index 8e40d3b..a08605c 100644 --- a/mmm-nsf-changer.py +++ b/mmm-nsf-changer.py @@ -7,84 +7,19 @@ 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 update_safelist(path): -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 +#MAYBE SYMLINKS??? - -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 +#maybe add autoupdater through gitlab #add mmm_version = "1.8.5.2" @@ -99,6 +34,7 @@ def check_version(version=False): 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") @@ -110,7 +46,7 @@ def create_mute_file(base64_str): file_to_save.write(decoded_image_data) return True -def check_folder_structure(megamaker_folder, og_music=False, whitelist=[]): +def check_folder_structure(megamaker_folder, og_music=False): 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") @@ -128,77 +64,26 @@ def check_folder_structure(megamaker_folder, og_music=False, whitelist=[]): print("skipping", files_no_path) else: file_names.append(files_no_path) - if set(file_names) == set(safelist()) or set(file_names) == set(whitelist): + if set(file_names) == set(safelist()): 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): +#this needs to check if original_music exists, and if it does restore_ogmusic before moving to og music. +def move_music_to_ogmusic(path): + path = os.path.abspath(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 filecmp.cmp(os.path.join(path,"Music","MM1","Cutman.nsf"), os.path.join(path, "Music", "MM1", "Oilman.nsf"), shallow=False): + shutil.move(os.path.join(path, "Music"), os.path.join(path, "original_music")) 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)): @@ -206,6 +91,7 @@ def recreate_structure(new_nsf, original_paths_list): print("recreate structure if not os.path.exists") try: shutil.copy(new_nsf, path) + print("recreate structure shutil.copy") except: print("continuing") continue @@ -215,206 +101,96 @@ 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 + 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")) + shutil.move(os.path.join(path, "original_music", ""), os.path.join(path, "Music")) + return True + else: + print("something went wrong...") + else: + 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: +def nsf_changer (nsf_path, megamaker_folder): + original_path = check_folder_structure(megamaker_folder) 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"): + if os.path.commonpath([os.path.dirname(nsf_path), os.path.join(megamaker_folder, "Music")]) == 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) + move_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') +sg.theme('LightBlue') 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_')], + [sg.Text("Mega Man Maker NSF Music Changer | Made by Timothy GFO", justification="center")], + [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.Text(version_message, text_color=version_color)], + [sg.Text("Input NSF File:"), sg.Input(key="-IN-"),sg.FileBrowse(file_types=(("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(key="-OUT-"), sg.FolderBrowse()], + [sg.Button("Mute All")], + [sg.Exit(),sg.Button("About") , sg.Button("Replace NSF Music"), sg.Button("Restore Original Music"),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?') +app_version = "v1.1" -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: +window = sg.Window(f"MMM NSF Music Changer {app_version}", layout, grab_anywhere=True) +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?') +while disclaimer == "Yes": 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") - + 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 All": + create_mute_file(mute_nsf) + if not nsf_changer(os.path.join(os.path.dirname(__file__), "mmm_nsf_changer_mute.nsf"), values["-OUT-"]): + restore_ogmusic(values["-OUT-"]) + if not nsf_changer(os.path.join(os.path.dirname(__file__), "mmm_nsf_changer_mute.nsf"), values["-OUT-"]): + sg.popup_error("MegaMaker folder is not valid or definitions are out of date.") + if event == "Replace NSF Music": + if not nsf_changer(values["-IN-"], values["-OUT-"]): + restore_ogmusic(values["-OUT-"]) + if not nsf_changer(values["-IN-"], values["-OUT-"]): + sg.popup_error("MegaMaker folder is not valid or definitions out of date.") + if event == "Restore Original Music": + # sg.popup_error("DOESNT WORK EITHER HAHAHAHAHAHAA") + if not restore_ogmusic(values["-OUT-"]): + sg.popup_error("Unexpected folder structure or differing files") window.close() diff --git a/nsf_changer.png b/nsf_changer.png index bfdb13b..adb7382 100644 Binary files a/nsf_changer.png and b/nsf_changer.png differ diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 4171be9..0000000 --- a/requirements.txt +++ /dev/null @@ -1,7 +0,0 @@ -certifi==2023.11.17 -charset-normalizer==3.3.2 -idna==3.4 -packaging==23.2 -PySimpleGUI==4.60.5 -requests==2.31.0 -urllib3==2.1.0