Repository: stuff-by-3-random-dudes/UWUVCI-AIO-WPF Branch: master Commit: 767dcb338c0b Files: 125 Total size: 5.2 MB Directory structure: gitextract_nzcsa59w/ ├── .gitattributes ├── .gitignore ├── AnalysisReport.sarif ├── LICENSE ├── README.md ├── UWUVCI AIO WPF/ │ ├── App.config │ ├── App.xaml │ ├── App.xaml.cs │ ├── AssemblyInfo1.cs │ ├── Classes/ │ │ ├── BootImage.cs │ │ ├── DeflickerDitheringRemover.cs │ │ ├── Dol.cs │ │ ├── GameConfig.cs │ │ ├── GameCubeISO.cs │ │ ├── Injection.cs │ │ ├── KeyFile.cs │ │ ├── MenuIconImage - Kopieren.cs │ │ ├── MenuIconImage.cs │ │ └── ToolCheck.cs │ ├── FodyWeavers.xml │ ├── FodyWeavers.xsd │ ├── Font/ │ │ └── font.otf │ ├── Helpers/ │ │ ├── ConsoleLoggerWriter.cs │ │ ├── FileUtils.cs │ │ ├── JsonSettingsManager.cs │ │ ├── Logger.cs │ │ └── MacLinuxHelper.cs │ ├── ILLink/ │ │ └── ILLink.Descriptors.LibraryBuild.xml │ ├── Models/ │ │ ├── BaseModel.cs │ │ ├── DolSection.cs │ │ ├── GctCode.cs │ │ ├── JsonAppSettings.cs │ │ ├── MainViewModel.cs │ │ ├── N64Conf.cs │ │ ├── PNGTGA.cs │ │ ├── TKeys.cs │ │ └── ToolStep.cs │ ├── Properties/ │ │ ├── AssemblyInfo.cs │ │ ├── Resources.Designer.cs │ │ ├── Resources.resx │ │ ├── Settings.Designer.cs │ │ └── Settings.settings │ ├── Settings.cs │ ├── UI/ │ │ ├── Done.xaml │ │ ├── Done.xaml.cs │ │ ├── Frames/ │ │ │ ├── InjectFrame.xaml │ │ │ ├── InjectFrame.xaml.cs │ │ │ ├── InjectFrames/ │ │ │ │ ├── Bases/ │ │ │ │ │ ├── BaseContainerFrame.xaml │ │ │ │ │ ├── BaseContainerFrame.xaml.cs │ │ │ │ │ ├── CustomBaseFrame.xaml │ │ │ │ │ ├── CustomBaseFrame.xaml.cs │ │ │ │ │ ├── NonCustomBaseFrame.xaml │ │ │ │ │ └── NonCustomBaseFrame.xaml.cs │ │ │ │ └── Configurations/ │ │ │ │ ├── BrightnessValidationRule.cs │ │ │ │ ├── GBA.xaml │ │ │ │ ├── GBA.xaml.cs │ │ │ │ ├── GCConfig.xaml │ │ │ │ ├── GCConfig.xaml.cs │ │ │ │ ├── InverseBootConverter.cs │ │ │ │ ├── N64Config.xaml │ │ │ │ ├── N64Config.xaml.cs │ │ │ │ ├── OtherConfigs.xaml │ │ │ │ ├── OtherConfigs.xaml.cs │ │ │ │ ├── PixelArtScalerValidationRule.cs │ │ │ │ ├── TurboGrafX.xaml │ │ │ │ ├── TurboGrafX.xaml.cs │ │ │ │ ├── WiiConfig.xaml │ │ │ │ └── WiiConfig.xaml.cs │ │ │ ├── KeyFrame/ │ │ │ │ ├── TKFrame.xaml │ │ │ │ └── TKFrame.xaml.cs │ │ │ ├── Path/ │ │ │ │ ├── Paths.xaml │ │ │ │ └── Paths.xaml.cs │ │ │ ├── SettingsFrame.xaml │ │ │ ├── SettingsFrame.xaml.cs │ │ │ ├── StartFrame.xaml │ │ │ └── StartFrame.xaml.cs │ │ └── Windows/ │ │ ├── BaseGameWindow.xaml │ │ ├── BaseGameWindow.xaml.cs │ │ ├── CloseWindow.xaml │ │ ├── CloseWindow.xaml.cs │ │ ├── Custom Message - Kopieren.xaml │ │ ├── Custom Message - Kopieren.xaml.cs │ │ ├── Custom Message.xaml │ │ ├── Custom Message.xaml.cs │ │ ├── DownloadWait - Kopieren.xaml │ │ ├── DownloadWait - Kopieren.xaml.cs │ │ ├── DownloadWait.xaml │ │ ├── DownloadWait.xaml.cs │ │ ├── EnterKey.xaml │ │ ├── EnterKey.xaml.cs │ │ ├── GuideWindow.xaml │ │ ├── GuideWindow.xaml.cs │ │ ├── IMG_Message - Kopieren - Kopieren - Kopieren.xaml │ │ ├── IMG_Message - Kopieren - Kopieren - Kopieren.xaml.cs │ │ ├── IMG_Message - Kopieren - Kopieren.xaml │ │ ├── IMG_Message - Kopieren - Kopieren.xaml.cs │ │ ├── IMG_Message - Kopieren.xaml │ │ ├── IMG_Message - Kopieren.xaml.cs │ │ ├── IMG_Message.xaml │ │ ├── IMG_Message.xaml.cs │ │ ├── ImageCreator - Kopieren - Kopieren (2).xaml │ │ ├── ImageCreator - Kopieren - Kopieren (2).xaml.cs │ │ ├── ImageCreator - Kopieren - Kopieren.xaml │ │ ├── ImageCreator - Kopieren - Kopieren.xaml.cs │ │ ├── ImageCreator - Kopieren.xaml │ │ ├── ImageCreator - Kopieren.xaml.cs │ │ ├── ImageCreator.xaml │ │ ├── ImageCreator.xaml.cs │ │ ├── IntroductionWindow.xaml │ │ ├── IntroductionWindow.xaml.cs │ │ ├── MacLinuxWindow.xaml │ │ ├── MacLinuxWindow.xaml.cs │ │ ├── MenuWindow.xaml │ │ ├── MenuWindow.xaml.cs │ │ ├── TitleKeys - Kopieren.xaml │ │ ├── TitleKeys - Kopieren.xaml.cs │ │ ├── TitleKeys.xaml │ │ └── TitleKeys.xaml.cs │ ├── UWUVCI AIO WPF.csproj │ ├── app.manifest │ ├── packages.config │ └── uwuvci_installer_creator/ │ ├── app/ │ │ └── Readme.txt │ └── install_script.iss ├── UWUVCI AIO WPF.sln └── upgrade-assistant.clef ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitattributes ================================================ ############################################################################### # Set default behavior to automatically normalize line endings. ############################################################################### * text=auto ############################################################################### # Set default behavior for command prompt diff. # # This is need for earlier builds of msysgit that does not have it on by # default for csharp files. # Note: This is only used by command line ############################################################################### #*.cs diff=csharp ############################################################################### # Set the merge driver for project and solution files # # Merging from the command prompt will add diff markers to the files if there # are conflicts (Merging from VS is not affected by the settings below, in VS # the diff markers are never inserted). Diff markers may cause the following # file extensions to fail to load in VS. An alternative would be to treat # these files as binary and thus will always conflict and require user # intervention with every merge. To do so, just uncomment the entries below ############################################################################### #*.sln merge=binary #*.csproj merge=binary #*.vbproj merge=binary #*.vcxproj merge=binary #*.vcproj merge=binary #*.dbproj merge=binary #*.fsproj merge=binary #*.lsproj merge=binary #*.wixproj merge=binary #*.modelproj merge=binary #*.sqlproj merge=binary #*.wwaproj merge=binary ############################################################################### # behavior for image files # # image files are treated as binary by default. ############################################################################### #*.jpg binary #*.png binary #*.gif binary ############################################################################### # diff behavior for common document formats # # Convert binary document formats to text before diffing them. This feature # is only available from the command line. Turn it on by uncommenting the # entries below. ############################################################################### #*.doc diff=astextplain #*.DOC diff=astextplain #*.docx diff=astextplain #*.DOCX diff=astextplain #*.dot diff=astextplain #*.DOT diff=astextplain #*.pdf diff=astextplain #*.PDF diff=astextplain #*.rtf diff=astextplain #*.RTF diff=astextplain ================================================ FILE: .gitignore ================================================ ## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. ## ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore # User-specific files *.rsuser *.suo *.user *.userosscache *.sln.docstates # User-specific files (MonoDevelop/Xamarin Studio) *.userprefs # Build results [Dd]ebug/ [Dd]ebugPublic/ [Rr]elease/ [Rr]eleases/ x64/ x86/ [Aa][Rr][Mm]/ [Aa][Rr][Mm]64/ bld/ [Bb]in/ [Oo]bj/ [Ll]og/ # Visual Studio 2015/2017 cache/options directory .vs/ # Uncomment if you have tasks that create the project's static files in wwwroot #wwwroot/ # Visual Studio 2017 auto generated files Generated\ Files/ # MSTest test Results [Tt]est[Rr]esult*/ [Bb]uild[Ll]og.* # NUNIT *.VisualState.xml TestResult.xml # Build Results of an ATL Project [Dd]ebugPS/ [Rr]eleasePS/ dlldata.c # Benchmark Results BenchmarkDotNet.Artifacts/ # .NET Core project.lock.json project.fragment.lock.json artifacts/ # StyleCop StyleCopReport.xml # Files built by Visual Studio *_i.c *_p.c *_h.h *.ilk *.meta *.obj *.iobj *.pch *.pdb *.ipdb *.pgc *.pgd *.rsp *.sbr *.tlb *.tli *.tlh *.tmp *.tmp_proj *_wpftmp.csproj *.log *.vspscc *.vssscc .builds *.pidb *.svclog *.scc # Chutzpah Test files _Chutzpah* # Visual C++ cache files ipch/ *.aps *.ncb *.opendb *.opensdf *.sdf *.cachefile *.VC.db *.VC.VC.opendb # Visual Studio profiler *.psess *.vsp *.vspx *.sap # Visual Studio Trace Files *.e2e # TFS 2012 Local Workspace $tf/ # Guidance Automation Toolkit *.gpState # ReSharper is a .NET coding add-in _ReSharper*/ *.[Rr]e[Ss]harper *.DotSettings.user # JustCode is a .NET coding add-in .JustCode # TeamCity is a build add-in _TeamCity* # DotCover is a Code Coverage Tool *.dotCover # AxoCover is a Code Coverage Tool .axoCover/* !.axoCover/settings.json # Visual Studio code coverage results *.coverage *.coveragexml # NCrunch _NCrunch_* .*crunch*.local.xml nCrunchTemp_* # MightyMoose *.mm.* AutoTest.Net/ # Web workbench (sass) .sass-cache/ # Installshield output folder [Ee]xpress/ # DocProject is a documentation generator add-in DocProject/buildhelp/ DocProject/Help/*.HxT DocProject/Help/*.HxC DocProject/Help/*.hhc DocProject/Help/*.hhk DocProject/Help/*.hhp DocProject/Help/Html2 DocProject/Help/html # Click-Once directory publish/ # Publish Web Output *.[Pp]ublish.xml *.azurePubxml # Note: Comment the next line if you want to checkin your web deploy settings, # but database connection strings (with potential passwords) will be unencrypted *.pubxml *.publishproj # Microsoft Azure Web App publish settings. Comment the next line if you want to # checkin your Azure Web App publish settings, but sensitive information contained # in these scripts will be unencrypted PublishScripts/ # NuGet Packages *.nupkg # The packages folder can be ignored because of Package Restore **/[Pp]ackages/* # except build/, which is used as an MSBuild target. !**/[Pp]ackages/build/ # Uncomment if necessary however generally it will be regenerated when needed #!**/[Pp]ackages/repositories.config # NuGet v3's project.json files produces more ignorable files *.nuget.props *.nuget.targets # Microsoft Azure Build Output csx/ *.build.csdef # Microsoft Azure Emulator ecf/ rcf/ # Windows Store app package directories and files AppPackages/ BundleArtifacts/ Package.StoreAssociation.xml _pkginfo.txt *.appx # Visual Studio cache files # files ending in .cache can be ignored *.[Cc]ache # but keep track of directories ending in .cache !?*.[Cc]ache/ # Others ClientBin/ ~$* *~ *.dbmdl *.dbproj.schemaview *.jfm *.pfx *.publishsettings orleans.codegen.cs # Including strong name files can present a security risk # (https://github.com/github/gitignore/pull/2483#issue-259490424) #*.snk # Since there are multiple workflows, uncomment next line to ignore bower_components # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) #bower_components/ # RIA/Silverlight projects Generated_Code/ # Backup & report files from converting an old project file # to a newer Visual Studio version. Backup files are not needed, # because we have git ;-) _UpgradeReport_Files/ Backup*/ UpgradeLog*.XML UpgradeLog*.htm ServiceFabricBackup/ *.rptproj.bak # SQL Server files *.mdf *.ldf *.ndf # Business Intelligence projects *.rdl.data *.bim.layout *.bim_*.settings *.rptproj.rsuser *- Backup*.rdl # Microsoft Fakes FakesAssemblies/ # GhostDoc plugin setting file *.GhostDoc.xml # Node.js Tools for Visual Studio .ntvs_analysis.dat node_modules/ # Visual Studio 6 build log *.plg # Visual Studio 6 workspace options file *.opt # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) *.vbw # Visual Studio LightSwitch build output **/*.HTMLClient/GeneratedArtifacts **/*.DesktopClient/GeneratedArtifacts **/*.DesktopClient/ModelManifest.xml **/*.Server/GeneratedArtifacts **/*.Server/ModelManifest.xml _Pvt_Extensions # Paket dependency manager .paket/paket.exe paket-files/ # FAKE - F# Make .fake/ # JetBrains Rider .idea/ *.sln.iml # CodeRush personal settings .cr/personal # Python Tools for Visual Studio (PTVS) __pycache__/ *.pyc # Cake - Uncomment if you are using it # tools/** # !tools/packages.config # Tabs Studio *.tss # Telerik's JustMock configuration file *.jmconfig # BizTalk build output *.btp.cs *.btm.cs *.odx.cs *.xsd.cs # OpenCover UI analysis results OpenCover/ # Azure Stream Analytics local run output ASALocalRun/ # MSBuild Binary and Structured Log *.binlog # NVidia Nsight GPU debugger configuration file *.nvuser # MFractors (Xamarin productivity tool) working folder .mfractor/ # Local History for Visual Studio .localhistory/ # BeatPulse healthcheck temp database healthchecksdb ================================================ FILE: AnalysisReport.sarif ================================================ { "$schema": "https://schemastore.azurewebsites.net/schemas/json/sarif-2.1.0-rtm.5.json", "version": "2.1.0", "runs": [ { "tool": { "driver": { "name": "Dependency Analysis", "semanticVersion": "0.4.336902", "informationUri": "https://docs.microsoft.com/en-us/dotnet/core/porting/upgrade-assistant-overview", "rules": [ { "id": "UA106", "name": "PackageToBeAdded", "fullDescription": { "text": "Packages that need to be added in order to upgrade the project to chosen TFM" }, "helpUri": "https://docs.microsoft.com/en-us/dotnet/core/porting/upgrade-assistant-overview" } ] } }, "results": [ { "ruleId": "UA106", "message": { "text": "Package Microsoft.DotNet.UpgradeAssistant.Extensions.Default.Analyzers, Version=0.4.336902 needs to be added." }, "locations": [ { "physicalLocation": { "artifactLocation": { "uri": "file:///C:/Users/zesty.fernandez/Documents/GitHub/UWUVCI-AIO-WPF/UWUVCI%20AIO%20WPF/UWUVCI%20AIO%20WPF.csproj" }, "region": {} } } ] }, { "ruleId": "UA106", "message": { "text": "Package Microsoft.Windows.Compatibility, Version=6.0.0 needs to be added." }, "locations": [ { "physicalLocation": { "artifactLocation": { "uri": "file:///C:/Users/zesty.fernandez/Documents/GitHub/UWUVCI-AIO-WPF/UWUVCI%20AIO%20WPF/UWUVCI%20AIO%20WPF.csproj" }, "region": {} } } ] } ], "columnKind": "utf16CodeUnits" }, { "tool": { "driver": { "name": "API Upgradability", "semanticVersion": "0.4.336902", "informationUri": "https://docs.microsoft.com/en-us/dotnet/core/porting/upgrade-assistant-overview" } }, "results": [], "columnKind": "utf16CodeUnits" } ] } ================================================ FILE: LICENSE ================================================ GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . ================================================ FILE: README.md ================================================ # UWUVCI-AIO-WPF Wii U All-in-One Injector. ## Systems Supported * DS * GBA * N64 * Snes * Nes * Turbo Grafx * MSX * Wii * GCN ## Questions and Concerns Check out our discord: * https://discord.gg/mPZpqJJVmZ Check out the official video guide: * https://www.youtube.com/watch?v=1vzD_R-xPx4&list=PLbQMtrmXFIxQ1hpvu9m1th41vsaqnZ2Id ## This repo is no longer in active development * The latest version of this writing is 3.N * Any future updates will be community-driven * Repo is still being managed, so feel free to fork/PR ================================================ FILE: UWUVCI AIO WPF/App.config ================================================ 
================================================ FILE: UWUVCI AIO WPF/App.xaml ================================================  pack://application:,,,/Font/#FOT-RodinNTLG Pro B ================================================ FILE: UWUVCI AIO WPF/App.xaml.cs ================================================ using System; using System.Diagnostics; using System.IO; using System.Timers; using System.Windows; using System.Windows.Controls; using UWUVCI_AIO_WPF.UI.Windows; using UWUVCI_AIO_WPF.Helpers; using GameBaseClassLibrary; namespace UWUVCI_AIO_WPF { public partial class App : Application { Timer t = new Timer(5000); private StartupEventArgs _startupArgs; private static string AppDataPath = Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "UWUVCI-V3"); private void Application_Startup(object sender, StartupEventArgs e) { // Ensure the settings directory exists before attempting to load settings if (!Directory.Exists(AppDataPath)) Directory.CreateDirectory(AppDataPath); // Redirect Console.WriteLine to the logger at the very beginning Console.SetOut(new ConsoleLoggerWriter()); // Check if running from OneDrive if (IsRunningFromOneDrive()) { MessageBox.Show("UWUVCI AIO cannot be run from a OneDrive folder due to compatibility issues. \n\n" + "Please move it to another location (e.g., C:\\Programs or C:\\Users\\YourName\\UWUVCI_AIO) before launching.", "Error: OneDrive Detected", MessageBoxButton.OK, MessageBoxImage.Error); Environment.Exit(1); // Terminate the application } // Add global event handlers for drag-and-drop EventManager.RegisterClassHandler(typeof(TextBox), UIElement.PreviewDragOverEvent, new DragEventHandler(GlobalTextBox_PreviewDragOver)); EventManager.RegisterClassHandler(typeof(TextBox), UIElement.PreviewDropEvent, new DragEventHandler(GlobalTextBox_PreviewDrop)); if (File.Exists("tools.json")) File.Delete("tools.json"); _startupArgs = e; JsonSettingsManager.LoadSettings(); if (!JsonSettingsManager.Settings.IsFirstLaunch) { LaunchMainApplication(e); } else { if (MacLinuxHelper.IsRunningUnderWineOrSimilar()) { MessageBox.Show("UWUVCI cannot tell if you went through the tutorial or not. We will assume you did, but if you didn't, in the main application click the gear icon, and then click the button that says 'Show Tutorial Screens'.", "UWUVCI Tutorial..?", MessageBoxButton.OK, MessageBoxImage.Question); JsonSettingsManager.Settings.IsFirstLaunch = false; JsonSettingsManager.SaveSettings(); LaunchMainApplication(e); } else { new IntroductionWindow().ShowDialog(); } } if (JsonSettingsManager.Settings.ShowZestyFork) { var result = MessageBox.Show("There is a more updated fork that is recommended to use going forward. Press 'Yes' to check it out now. If not, you can always find it under the Settings (gear icon).", "ZestyTS's UWUVCI V3", MessageBoxButton.YesNo,MessageBoxImage.Exclamation); if (result == MessageBoxResult.Yes) { Process.Start("https://zestyts.itch.io/uwuvci-v3"); } JsonSettingsManager.Settings.ShowZestyFork = false; JsonSettingsManager.SaveSettings(); } } private static void GlobalTextBox_PreviewDragOver(object sender, DragEventArgs e) { e.Effects = e.Data.GetDataPresent(DataFormats.FileDrop) ? DragDropEffects.Copy : DragDropEffects.None; e.Handled = true; } private bool IsRunningFromOneDrive() { string exePath = Process.GetCurrentProcess().MainModule.FileName; return exePath.ToLower().Contains("onedrive"); } private static void GlobalTextBox_PreviewDrop(object sender, DragEventArgs e) { if (e.Data.GetDataPresent(DataFormats.FileDrop)) { string[] files = (string[])e.Data.GetData(DataFormats.FileDrop); if (files != null && files.Length > 0) { TextBox txtBox = sender as TextBox; if (txtBox != null) { // Assign to ViewModel properties dynamically if (Current.MainWindow is MainWindow mainWindow && mainWindow.Content is Grid grid && grid.DataContext is MainViewModel mvm) { if (mvm.GameConfiguration.Console == GameConsoles.WII || mvm.GameConfiguration.Console == GameConsoles.GCN) return; string filePath = files[0]; // Temporarily make writable to allow drop txtBox.IsReadOnly = false; txtBox.Text = filePath; txtBox.IsReadOnly = true; switch (txtBox.Name) { case "rp": // Special handling for ROM Path mvm.RomSet = true; mvm.RomPath = filePath; if (mvm.BaseDownloaded) { mvm.CanInject = true; } // Call the correct `getBootIMG*()` method dynamically switch (mvm.GameConfiguration.Console) { case GameConsoles.NDS: mvm.getBootIMGNDS(mvm.RomPath); break; case GameConsoles.NES: mvm.getBootIMGNES(mvm.RomPath); break; case GameConsoles.SNES: mvm.getBootIMGSNES(mvm.RomPath); break; case GameConsoles.MSX: mvm.getBootIMGMSX(mvm.RomPath); break; case GameConsoles.N64: mvm.getBootIMGN64(mvm.RomPath); break; case GameConsoles.GBA: var fileExtension = Path.GetExtension(filePath).ToLower(); if (fileExtension != ".gb" && fileExtension != ".gbc") mvm.getBootIMGGBA(mvm.RomPath); break; case GameConsoles.TG16: mvm.getBootIMGTG(mvm.RomPath); break; default: Console.WriteLine("Unsupported console type: " + mvm.GameConfiguration.Console); break; } break; case "ic": mvm.GameConfiguration.TGAIco.ImgPath = filePath; break; case "tv": mvm.GameConfiguration.TGATv.ImgPath = filePath; break; case "drc": mvm.GameConfiguration.TGADrc.ImgPath = filePath; break; case "log": mvm.GameConfiguration.TGALog.ImgPath = filePath; break; case "ini": mvm.GameConfiguration.N64Stuff.INIPath = filePath; break; case "sound": mvm.BootSound = filePath; break; } } } } } } public void LaunchMainApplication() { LaunchMainApplication(_startupArgs); } private void LaunchMainApplication(StartupEventArgs e) { if (Directory.Exists(@"custom") && File.Exists(@"custom\main.dol")) { if (!Directory.Exists(@"bin\Tools")) Directory.CreateDirectory(@"bin\Tools"); File.Copy(@"custom\main.dol", @"bin\Tools\nintendont.dol", true); File.Copy(@"custom\main.dol", @"bin\Tools\nintendont_force.dol", true); } bool check = true; bool bypass = false; if (e.Args.Length >= 1) foreach (var s in e.Args) { if (s == "--skip") check = false; if (s == "--spacebypass") bypass = true; } Process[] pname = Process.GetProcessesByName("UWUVCI AIO"); if (pname.Length > 1 && check) { t.Elapsed += KillProg; t.Start(); Custom_Message cm = new Custom_Message("Another Instance Running", " You already got another instance of UWUVCI AIO running. \n This instance will terminate in 5 seconds. "); cm.ShowDialog(); KillProg(null, null); } else { MainWindow wnd = new MainWindow(); double height = SystemParameters.PrimaryScreenHeight; double width = SystemParameters.PrimaryScreenWidth; if (width < 1150 || height < 700) { t.Elapsed += KillProg; t.Start(); Custom_Message cm = new Custom_Message("Resolution not supported", "Your screen resolution is not supported, please use a resolution of at least 1152x864\nIf your resolution is higher than this, then it's because of your zoom level, either way, please change your display settings.\nThis instance will terminate in 5 seconds."); cm.ShowDialog(); KillProg(null, null); } if (bypass) wnd.allowBypass(); if (e.Args.Length >= 1 && e.Args[0] == "--debug") wnd.setDebug(bypass); wnd.Show(); } } private void KillProg(object sender, ElapsedEventArgs e) { t.Stop(); Environment.Exit(1); } } } ================================================ FILE: UWUVCI AIO WPF/AssemblyInfo1.cs ================================================  ================================================ FILE: UWUVCI AIO WPF/Classes/BootImage.cs ================================================ using System; using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Text; using System.Globalization; using System.Reflection; namespace UWUVCI_AIO_WPF.Classes { public class BootImage : IDisposable { private bool disposed = false; private Bitmap _frame; private Bitmap _titleScreen; private Font font; public string _imageVar; public Rectangle _rectangleGBA = new Rectangle(132, 260, 399, 266); public Rectangle _rectangleGBC = new Rectangle(183, 260, 296, 266); public Rectangle _rectangleH4V3 = new Rectangle(131, 249, 400, 300); public Rectangle _rectangleWII = new Rectangle(224, 200, 832, 333); public Bitmap Frame { set { _frame?.Dispose(); _frame = value; } get { return _frame; } } public Bitmap TitleScreen { set { _titleScreen?.Dispose(); _titleScreen = value; } get { return _titleScreen; } } public string NameLine1; public string NameLine2; public int Released; public int Players; public bool Longname; public BootImage() { NameLine1 = null; NameLine2 = null; Released = 0; Players = 0; Longname = false; } ~BootImage() { Dispose(false); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (!disposed) { if (disposing) { _frame?.Dispose(); _titleScreen?.Dispose(); } disposed = true; } } private bool ContainsJapanese(string text) { if (string.IsNullOrEmpty(text)) return false; foreach (char c in text) { if (char.GetUnicodeCategory(c) == UnicodeCategory.OtherLetter) // this covers Hiragana, Katakana, and Kanji return true; } return false; } private Font GetFont() { try { var privateFonts = new PrivateFontCollection(); privateFonts.AddFontFile(@"bin\Tools\font.otf"); return new Font(privateFonts.Families[0], 10.0F, FontStyle.Regular, GraphicsUnit.Point); } catch { return new Font("Trebuchet MS", 10.0F, FontStyle.Bold, GraphicsUnit.Point); } } private Rectangle GetRectangleForConsole(string console) { _imageVar = "_rectangle" + console; try { var fieldInfo = GetType().GetField(_imageVar, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); return fieldInfo != null ? (Rectangle)fieldInfo.GetValue(this) : _rectangleH4V3; } catch { return _rectangleH4V3; } } private void DrawText(Graphics g, string text, Font font, Rectangle rectangle, Pen shadow, Pen outline, Brush brush) { using (var path = new GraphicsPath()) { path.AddString(text, font.FontFamily, (int)FontStyle.Regular, g.DpiY * 25.0F / 72.0F, rectangle, new StringFormat()); g.DrawPath(shadow, path); g.DrawPath(outline, path); g.FillPath(brush, path); } } public Bitmap Create(string console) { Bitmap img = new Bitmap(1280, 720); Graphics g = Graphics.FromImage(img); g.PixelOffsetMode = PixelOffsetMode.Half; g.SmoothingMode = SmoothingMode.AntiAlias; g.CompositingMode = CompositingMode.SourceOver; g.CompositingQuality = CompositingQuality.HighQuality; g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit; g.Clear(Color.White); try { PrivateFontCollection privateFonts = new PrivateFontCollection(); privateFonts.AddFontFile(@"bin\Tools\font.otf"); font = new Font(privateFonts.Families[0], 10.0F, FontStyle.Regular, GraphicsUnit.Point); } catch (Exception) { font = new Font("Trebuchet MS", 10.0F, FontStyle.Bold, GraphicsUnit.Point); } SolidBrush brush = new SolidBrush(Color.FromArgb(32, 32, 32)); Pen outline = new Pen(Color.FromArgb(222, 222, 222), 4.0F); Pen shadow = new Pen(Color.FromArgb(190, 190, 190), 6.0F); StringFormat format = new StringFormat(); _imageVar = "_rectangle" + console; Rectangle rectangle; try { FieldInfo fieldInfo = GetType().GetField(_imageVar, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); rectangle = fieldInfo != null ? (Rectangle)fieldInfo.GetValue(this) : _rectangleH4V3; } catch { //if rectangle isn't able to get set then H4V3 should be used. rectangle = _rectangleH4V3; } if (TitleScreen != null) g.DrawImage(TitleScreen, rectangle); else g.FillRectangle(new SolidBrush(Color.Black), rectangle); if (Frame != null) g.DrawImage(Frame, new Rectangle(0, 0, 1280, 720)); var isNotEnglish = false; if (!string.IsNullOrEmpty(NameLine1) || !string.IsNullOrEmpty(NameLine2)) { if (ContainsJapanese(NameLine1) || ContainsJapanese(NameLine2)) isNotEnglish = true; Pen outlineBold = new Pen(Color.FromArgb(222, 222, 222), 5.0F); Pen shadowBold = new Pen(Color.FromArgb(190, 190, 190), 7.0F); Rectangle rectangleNL1 = Longname ? new Rectangle(578, 313, 640, 50) : new Rectangle(578, 340, 640, 50); Rectangle rectangleNL2 = new Rectangle(578, 368, 640, 50); GraphicsPath nl1 = new GraphicsPath(); GraphicsPath nl2 = new GraphicsPath(); if (Longname) { nl1.AddString(NameLine1, font.FontFamily, (int)(FontStyle.Bold), g.DpiY * 37.0F / 72.0F, rectangleNL1, format); g.DrawPath(shadowBold, nl1); g.DrawPath(outlineBold, nl1); g.FillPath(brush, nl1); nl2.AddString(NameLine2, font.FontFamily, (int)(FontStyle.Bold), g.DpiY * 37.0F / 72.0F, rectangleNL2, format); g.DrawPath(shadowBold, nl2); g.DrawPath(outlineBold, nl2); g.FillPath(brush, nl2); } else { nl1.AddString(NameLine1, font.FontFamily, (int)(FontStyle.Bold), g.DpiY * 37.0F / 72.0F, rectangleNL1, format); g.DrawPath(shadowBold, nl1); g.DrawPath(outlineBold, nl1); g.FillPath(brush, nl1); } } if (Released > 0) { GraphicsPath r = new GraphicsPath(); var releasedString = "Released: " + Released.ToString(); if (isNotEnglish) releasedString = Released.ToString() + "年発売"; r.AddString(releasedString, font.FontFamily, (int)(FontStyle.Regular), g.DpiY * 25.0F / 72.0F, new Rectangle(586, 450, 600, 40), format); g.DrawPath(shadow, r); g.DrawPath(outline, r); g.FillPath(brush, r); } if (Players > 0) { string pStr = Players >= 4 ? "1-4" : (Players == 1 ? "1" : "1-" + Players.ToString()); if (isNotEnglish) pStr = "プレイ人数 " + pStr + "人"; else pStr = "Players: " + pStr; GraphicsPath p = new GraphicsPath(); p.AddString(pStr, font.FontFamily, (int)(FontStyle.Regular), g.DpiY * 25.0F / 72.0F, new Rectangle(586, 496, 600, 40), format); g.DrawPath(shadow, p); g.DrawPath(outline, p); g.FillPath(brush, p); } return img; } } } ================================================ FILE: UWUVCI AIO WPF/Classes/DeflickerDitheringRemover.cs ================================================ using System; using System.IO; using System.Windows; using UWUVCI_AIO_WPF.Helpers; public static class DeflickerDitheringRemover { private static readonly byte[] DeflickerPattern = { 0x2C, 0x03, 0x00, 0x00, 0x41, 0x82, 0x00, 0xF8, 0x89, 0x04, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x89, 0x44, 0x00, 0x01, 0x38, 0x60, 0x00, 0x00, 0x51, 0x00, 0x07, 0x3E, 0x88, 0xE4, 0x00, 0x06, 0x51, 0x40, 0x26, 0x36, 0x89, 0x04, 0x00, 0x0C, 0x50, 0xE3, 0x07, 0x3E, 0x38, 0xE0, 0x00, 0x00, 0x51, 0x07, 0x07, 0x3E, 0x89, 0x44, 0x00, 0x0D, 0x89, 0x64, 0x00, 0x07, 0x39, 0x00, 0x00, 0x00, 0x51, 0x47, 0x26, 0x36, 0x89, 0x44, 0x00, 0x02, 0x89, 0x24, 0x00, 0x12, 0x51, 0x63, 0x26, 0x36, 0x51, 0x40, 0x45, 0x2E, 0x89, 0x44, 0x00, 0x0E, 0x51, 0x28, 0x07, 0x3E, 0x89, 0x24, 0x00, 0x13, 0x51, 0x47, 0x45, 0x2E, 0x89, 0x44, 0x00, 0x03, 0x51, 0x28, 0x26, 0x36, 0x89, 0x24, 0x00, 0x14, 0x51, 0x40, 0x64, 0x26, 0x89, 0x44, 0x00, 0x0F, 0x51, 0x28, 0x45, 0x2E, 0x89, 0x24, 0x00, 0x15, 0x51, 0x47, 0x64, 0x26, 0x89, 0x44, 0x00, 0x04, 0x89, 0x64, 0x00, 0x08, 0x51, 0x28, 0x64, 0x26, 0x51, 0x40, 0x83, 0x1E, 0x89, 0x44, 0x00, 0x10, 0x89, 0x24, 0x00, 0x16, 0x51, 0x63, 0x45, 0x2E, 0x89, 0x64, 0x00, 0x09, 0x51, 0x47, 0x83, 0x1E, 0x89, 0x44, 0x00, 0x05, 0x51, 0x28, 0x83, 0x1E, 0x89, 0x24, 0x00, 0x11, 0x51, 0x63, 0x64, 0x26, 0x89, 0x64, 0x00, 0x0A, 0x51, 0x40, 0xA2, 0x16, 0x89, 0x44, 0x00, 0x0B, 0x51, 0x27, 0xA2, 0x16, 0x88, 0x84, 0x00, 0x17, 0x39, 0x20, 0x00, 0x01, 0x51, 0x63, 0x83, 0x1E, 0x51, 0x43, 0xA2, 0x16, 0x50, 0x88, 0xA2, 0x16, 0x51, 0x20, 0xC0, 0x0E, 0x39, 0x40, 0x00, 0x02, 0x39, 0x20, 0x00, 0x03, 0x38, 0x80, 0x00, 0x04, 0x51, 0x43, 0xC0, 0x0E, 0x51, 0x27, 0xC0, 0x0E, 0x50, 0x88, 0xC0, 0x0E, 0x48, 0x00, 0x00, 0x24, 0x3D, 0x00, 0x01, 0x66, 0x3C, 0x60, 0x02, 0x66, 0x3C, 0xE0, 0x03, 0x66, 0x3C, 0x80, 0x04, 0x66, 0x38, 0x08, 0x66, 0x66, 0x38, 0x63, 0x66, 0x66, 0x38, 0xE7, 0x66, 0x66, 0x39, 0x04, 0x66, 0x66, 0x3D, 0x20, 0xCC, 0x01, 0x39, 0x40, 0x00, 0x61, 0x99, 0x49, 0x80, 0x00, 0x2C, 0x05, 0x00, 0x00, 0x38, 0x80, 0x00, 0x53, 0x39, 0x60, 0x00, 0x00, 0x90, 0x09, 0x80, 0x00, 0x38, 0x00, 0x00, 0x54, 0x39, 0x80, 0x00, 0x00, 0x50, 0x8B, 0xC0, 0x0E, 0x99, 0x49, 0x80, 0x00, 0x50, 0x0C, 0xC0, 0x0E, 0x90, 0x69, 0x80, 0x00, 0x99, 0x49, 0x80, 0x00, 0x90, 0xE9, 0x80, 0x00, 0x99, 0x49, 0x80, 0x00, 0x91, 0x09, 0x80, 0x00, 0x41, 0x82, 0x00, 0x40 }; private static readonly byte[] DeflickerReplacement = { 0x48, 0x00, 0x00, 0x40 }; private static readonly byte[] DitheringPattern = { 0x3C, 0x80, 0xCC, 0x01, 0x38, 0xA0, 0x00, 0x61, 0x38, 0x00, 0x00, 0x00, 0x80, 0xC7, 0x02, 0x20, 0x50, 0x66, 0x17, 0x7A, 0x98, 0xA4, 0x80, 0x00, 0x90, 0xC4, 0x80, 0x00, 0x90, 0xC7, 0x02, 0x20, 0xB0, 0x07, 0x00, 0x02, 0x4E, 0x80, 0x00, 0x20 }; private static readonly byte[] DitheringReplacement = { 0x48, 0x00, 0x00, 0x28 }; private static readonly byte[] VFilterPattern = { 0x08, 0x08, 0x0A, 0x0C, 0x0A, 0x08, 0x08 }; private static readonly byte[] VFilterReplacement = { 0x04, 0x04, 0x10, 0x10, 0x10, 0x04, 0x04 }; public static void ProcessFile(string inputFilePath, string outputFilePath, bool applyDeflicker, bool applyDithering, bool applyVFilter) { if (string.IsNullOrEmpty(inputFilePath)) { Logger.Log($"Invalid input file path: {nameof(inputFilePath)}"); throw new ArgumentException("Invalid input file path", nameof(inputFilePath)); } if (string.IsNullOrEmpty(outputFilePath)) { Logger.Log($"Invalid input file path: {nameof(outputFilePath)}"); throw new ArgumentException("Invalid output file path", nameof(outputFilePath)); } byte[] fileBuffer = File.ReadAllBytes(inputFilePath); if (applyDeflicker) ApplyDeflickerPatch(fileBuffer); if (applyDithering) ApplyDitheringPatch(fileBuffer); if (applyVFilter) ApplyVFilterPatch(fileBuffer); File.WriteAllBytes(outputFilePath, fileBuffer); } private static void ApplyDeflickerPatch(byte[] buffer) { int deflickerPatternLength = DeflickerPattern.Length; // This is 252 bytes int replacementLength = DeflickerReplacement.Length; // This is 4 bytes for (int i = 0; i <= buffer.Length - deflickerPatternLength; i++) if (IsMatch(buffer, i, DeflickerPattern)) { int replacePosition = i + deflickerPatternLength - replacementLength; // Replace the last 4 bytes of the matched pattern Array.Copy(DeflickerReplacement, 0, buffer, replacePosition, replacementLength); break; // Stop after the first match } } private static void ApplyDitheringPatch(byte[] buffer) { for (int i = 8; i <= buffer.Length - DitheringPattern.Length; i++) if (IsMatch(buffer, i, DitheringPattern)) { // Replace the 4 bytes preceding the pattern Array.Copy(DitheringReplacement, 0, buffer, i - 4, DitheringReplacement.Length); break; } } private static void ApplyVFilterPatch(byte[] buffer) { for (int i = 0; i <= buffer.Length - VFilterPattern.Length; i++) if (IsMatch(buffer, i, VFilterPattern)) { // Replace the pattern directly Array.Copy(VFilterReplacement, 0, buffer, i, VFilterReplacement.Length); } } private static bool IsMatch(byte[] buffer, int position, byte[] pattern) { for (int i = 0; i < pattern.Length; i++) if (buffer[position + i] != pattern[i]) return false; return true; } // This is dev code to quickly check to see how the applying went. public static bool AreFilesDifferent(string filePath1, string filePath2) { byte[] file1 = File.ReadAllBytes(filePath1); byte[] file2 = File.ReadAllBytes(filePath2); if (file1.Length != file2.Length) return true; for (int i = 0; i < file1.Length; i++) if (file1[i] != file2[i]) { MessageBox.Show($"Files are different starting at byte position: {i}"); MessageBox.Show($"Original Byte: {file1[i]:X2}"); MessageBox.Show($"Modified Byte: {file2[i]:X2}"); return true; } return false; } } ================================================ FILE: UWUVCI AIO WPF/Classes/Dol.cs ================================================ using System; using System.Collections.Generic; using System.IO; using System.Linq; using UWUVCI_AIO_WPF.Models; using UWUVCI_AIO_WPF.Helpers; namespace UWUVCI_AIO_WPF.Classes { public class Dol { public void ApplyMultipleFilesToDol(IEnumerable filePaths, string dolFilePath) { try { Logger.Log($"Starting to process {filePaths.Count()} files for DOL patching."); var allCodes = new List(); // Load codes from all provided files foreach (var filePath in filePaths) { Logger.Log($"Processing file: {filePath}"); var codes = GctCode.LoadFromFile(filePath); Logger.Log($"Parsed {codes.Count} codes from {filePath}."); allCodes.AddRange(codes); } // Validate combined codes if (!ValidateCodes(allCodes, dolFilePath)) { Logger.Log("Validation failed for the provided codes. Aborting patching."); return; } Logger.Log($"Combined total of {allCodes.Count} codes from all files."); // Patch the DOL file PatchDolFile(dolFilePath, allCodes); // Inject the codehandler InjectCodehandler(dolFilePath, "path/to/codehandler.bin"); // Adjust the path if needed Logger.Log("All files applied and patched successfully."); } catch (Exception ex) { Logger.Log($"Error applying files to DOL: {ex.Message}"); } } public void PatchDolFile(string dolFilePath, List gctCodes) { try { Logger.Log($"Patching DOL file {dolFilePath} with GCT codes."); if (!File.Exists(dolFilePath)) { Logger.Log($"DOL file '{dolFilePath}' not found."); throw new FileNotFoundException($"DOL file '{dolFilePath}' not found."); } var sections = DolSection.ReadDolHeader(dolFilePath); byte[] dolData = File.ReadAllBytes(dolFilePath); foreach (var code in gctCodes) { int offset = MemoryToDolOffset(code.Address, sections); if (offset >= 0 && offset < dolData.Length - 4) // Ensure offset is within bounds { byte[] valueBytes = BitConverter.GetBytes(code.Value); if (BitConverter.IsLittleEndian) Array.Reverse(valueBytes); // Convert to big-endian Array.Copy(valueBytes, 0, dolData, offset, 4); } else { Logger.Log($"Address {code.Address:X8} is out of bounds for the DOL file."); } } string outputPath = Path.Combine(Path.GetDirectoryName(dolFilePath), "patched_dol.dol"); File.WriteAllBytes(outputPath, dolData); Logger.Log($"Patched DOL saved to: {outputPath}"); } catch (Exception ex) { Logger.Log($"Error patching DOL file: {ex.Message}"); throw; } } private bool ValidateCodes(List codes, string dolFilePath) { Logger.Log("Validating codes before patching..."); var sections = DolSection.ReadDolHeader(dolFilePath); foreach (var code in codes) { bool valid = sections.Any(section => code.Address >= section.MemoryAddress && code.Address < section.MemoryAddress + section.Size); if (!valid) { Logger.Log($"Invalid code: Address {code.Address:X8} is not within any DOL section."); return false; } } Logger.Log("All codes are valid."); return true; } public int MemoryToDolOffset(uint memoryAddress, List sections) { if (sections == null || sections.Count == 0) { Logger.Log("Sections list is null or empty."); throw new ArgumentException("Sections list cannot be null or empty."); } foreach (var section in sections) { if (memoryAddress >= section.MemoryAddress && memoryAddress < section.MemoryAddress + section.Size) { return (int)(section.FileOffset + (memoryAddress - section.MemoryAddress)); } } Logger.Log($"Memory address {memoryAddress:X} not found in any section."); return -1; // Address not found } public void InjectCodehandler(string dolFilePath, string codehandlerPath) { try { Logger.Log($"Starting codehandler injection for {dolFilePath}."); if (!File.Exists(dolFilePath) || !File.Exists(codehandlerPath)) { Logger.Log("DOL file or codehandler file not found."); throw new FileNotFoundException("DOL file or codehandler file not found."); } byte[] dolData = File.ReadAllBytes(dolFilePath); byte[] codehandlerData = File.ReadAllBytes(codehandlerPath); int injectionOffset = FindFreeSpace(dolData, codehandlerData.Length); if (injectionOffset < 0) { Logger.Log("No free space available for codehandler injection."); throw new Exception("No free space available for codehandler injection."); } Array.Copy(codehandlerData, 0, dolData, injectionOffset, codehandlerData.Length); // Update entry point in DOL PatchDolEntryPoint(dolData, injectionOffset); string outputPath = Path.Combine(Path.GetDirectoryName(dolFilePath), "patched_dol.dol"); File.WriteAllBytes(outputPath, dolData); Logger.Log($"Codehandler injected successfully. Patched DOL saved to: {outputPath}"); } catch (Exception ex) { Logger.Log($"Error during codehandler injection: {ex.Message}"); throw; } } private void PatchDolEntryPoint(byte[] dolData, int injectionOffset) { uint newEntryPoint = (uint)(0x80000000 + injectionOffset); // Convert offset to memory address Array.Copy(BitConverter.GetBytes(newEntryPoint), 0, dolData, 0xE0, 4); // Replace entry point Logger.Log($"Updated DOL entry point to: {newEntryPoint:X}"); } private int FindFreeSpace(byte[] fileData, int requiredSize) { Logger.Log($"Searching for {requiredSize} bytes of free space in the file."); for (int i = 0; i < fileData.Length - requiredSize; i++) { bool isFree = true; for (int j = 0; j < requiredSize; j++) { if (fileData[i + j] != 0x00) { isFree = false; break; } } if (isFree) { Logger.Log($"Found free space at offset {i}."); return i; } } Logger.Log("No free space found in the file."); return -1; // No free space found } } } ================================================ FILE: UWUVCI AIO WPF/Classes/GameConfig.cs ================================================ using GameBaseClassLibrary; using System; using UWUVCI_AIO_WPF.Models; namespace UWUVCI_AIO_WPF { [Serializable] public class GameConfig { public GameConfig Clone() { return MemberwiseClone() as GameConfig; } public GameConsoles Console { get; set; } public GameBases BaseRom { get; set; } private string cBasePath; public string CBasePath { get { return cBasePath; } set { cBasePath = value; } } public byte[] bootsound; public string extension = ""; public bool fourbythree = false; public bool disgamepad = false; public bool donttrim = false; public bool lr = false; public bool motepass = false; public bool jppatch = false; public bool pokepatch = false; public bool tgcd = false; public int Index; public bool pixelperfect = false; public string GameName { get; set; } public bool vm = false; public bool vmtopal = false; public bool rf = false; public bool rfus = false; public bool rfjp = false; public PNGTGA TGAIco { get; set; } = new PNGTGA(); public PNGTGA TGADrc { get; set; } = new PNGTGA(); public PNGTGA TGATv { get; set; } = new PNGTGA(); public PNGTGA TGALog { get; set; } = new PNGTGA(); public N64Conf N64Stuff { get; set; } = new N64Conf(); public N64Conf GBAStuff { get; set; } = new N64Conf(); } } ================================================ FILE: UWUVCI AIO WPF/Classes/GameCubeISO.cs ================================================ using System; using System.Collections.Generic; using System.IO; namespace UWUVCI_AIO_WPF.Classes { public class GameCubeISO { private TOCManager TOCManager { get; set; } = new TOCManager(); public string IsoPath { get; private set; } public string ExtractedPath { get; private set; } public GameCubeISO(string isoPath) { if (string.IsNullOrWhiteSpace(isoPath) || !File.Exists(isoPath)) throw new FileNotFoundException("ISO file not found."); IsoPath = isoPath; } /// /// Extracts the ISO into a directory. /// public void Extract(string outputPath) { if (string.IsNullOrWhiteSpace(outputPath)) throw new ArgumentException("Output path cannot be empty."); ExtractedPath = outputPath; Directory.CreateDirectory(ExtractedPath); // Path to the TOC file string tocPath = Path.Combine(ExtractedPath, "&&systemdata", "Game.toc"); if (!File.Exists(tocPath)) throw new FileNotFoundException("Game.toc not found in the extracted directory."); Console.WriteLine("Parsing TOC..."); ParseTOCFromFile(tocPath); if (TOCManager.TOCEntries.Count == 0) throw new InvalidOperationException("No valid entries found in the TOC."); Console.WriteLine($"Found {TOCManager.TOCEntries.Count} entries in the TOC."); using var fs = new FileStream(IsoPath, FileMode.Open, FileAccess.Read); using var reader = new BinaryReader(fs); Console.WriteLine("Extracting files..."); TOCManager.ExtractFiles(reader, ExtractedPath); Console.WriteLine($"Extraction complete: {ExtractedPath}"); } /// /// Rebuilds the ISO from the extracted directory. /// public void Rebuild(string extractedPath, string outputIsoPath) { if (!Directory.Exists(extractedPath)) throw new DirectoryNotFoundException($"Extracted directory not found: {extractedPath}"); // Paths for essential system files string systemDataPath = Path.Combine(extractedPath, "&&systemdata"); if (!Directory.Exists(systemDataPath)) throw new DirectoryNotFoundException($"System data directory not found: {systemDataPath}"); string hdrFilePath = Path.Combine(systemDataPath, "ISO.hdr"); string dolFilePath = Path.Combine(systemDataPath, "Start.dol"); string apploaderFilePath = Path.Combine(systemDataPath, "AppLoader.ldr"); string tocFilePath = Path.Combine(systemDataPath, "Game.toc"); if (!File.Exists(hdrFilePath) || !File.Exists(dolFilePath) || !File.Exists(apploaderFilePath) || !File.Exists(tocFilePath)) throw new FileNotFoundException("One or more essential system files are missing."); Console.WriteLine("Rebuilding ISO..."); using var writer = new BinaryWriter(File.Create(outputIsoPath)); // Write the ISO header Console.WriteLine("Writing ISO header..."); WriteSystemFile(writer, hdrFilePath); // Write the DOL file Console.WriteLine("Writing Start.dol..."); WriteSystemFile(writer, dolFilePath); // Write the Apploader Console.WriteLine("Writing AppLoader.ldr..."); WriteSystemFile(writer, apploaderFilePath); // Parse the TOC Console.WriteLine("Parsing TOC..."); List tocEntries = ParseTOCFromFile(tocFilePath); // Write game files Console.WriteLine("Writing game files..."); foreach (var entry in tocEntries) { // Directories are skipped if (entry.IsDirectory) continue; string filePath = Path.Combine(extractedPath, entry.Name.Replace('/', Path.DirectorySeparatorChar)); if (!File.Exists(filePath)) throw new FileNotFoundException($"File not found: {filePath}"); WriteGameFile(writer, filePath, entry.Position); } Console.WriteLine($"Rebuild complete. ISO saved to: {outputIsoPath}"); } /// /// Parses the TOC file to determine the list of files and directories in the ISO. /// private List ParseTOCFromFile(string tocPath) { var tocEntries = new List(); using var reader = new BinaryReader(File.OpenRead(tocPath)); while (reader.BaseStream.Position < reader.BaseStream.Length) { uint fileOffset = reader.ReadUInt32(); // File position in ISO uint fileSize = reader.ReadUInt32(); // File size byte flags = reader.ReadByte(); // Flags (e.g., directory or file) reader.BaseStream.Seek(3, SeekOrigin.Current); // Skip padding uint nameOffset = reader.ReadUInt32(); // Offset to the name in the string table // Resolve file name long currentPos = reader.BaseStream.Position; reader.BaseStream.Seek(nameOffset, SeekOrigin.Begin); string name = ReadNullTerminatedString(reader); reader.BaseStream.Seek(currentPos, SeekOrigin.Begin); tocEntries.Add(new TOCItem { Position = (int)fileOffset, Length = (int)fileSize, IsDirectory = (flags & 0x02) != 0, Name = name }); } return tocEntries; } /// /// Writes system files (e.g., ISO.hdr, Start.dol) to the ISO. /// private void WriteSystemFile(BinaryWriter writer, string filePath) { byte[] data = File.ReadAllBytes(filePath); writer.Write(data); // Align to 0x8000-byte boundaries long padding = AlignToBlock(data.Length, 0x8000) - data.Length; writer.Write(new byte[padding]); } /// /// Writes game files based on their TOC entries. /// private void WriteGameFile(BinaryWriter writer, string filePath, long position) { byte[] data = File.ReadAllBytes(filePath); // Seek to the correct position in the ISO writer.Seek((int)position, SeekOrigin.Begin); writer.Write(data); // Add padding to align to the next block if needed long padding = AlignToBlock(data.Length, 0x8000) - data.Length; writer.Write(new byte[padding]); } /// /// Aligns a value to the next 0x8000-byte boundary. /// private long AlignToBlock(long value, int blockSize) { return (value + blockSize - 1) / blockSize * blockSize; } /// /// Reads a null-terminated string from the binary stream. /// private string ReadNullTerminatedString(BinaryReader reader) { var bytes = new List(); byte b; while ((b = reader.ReadByte()) != 0) bytes.Add(b); return System.Text.Encoding.ASCII.GetString(bytes.ToArray()); } } public class TOCManager { public List TOCEntries { get; private set; } = new List(); public void ExtractFiles(BinaryReader reader, string outputDirectory) { foreach (var entry in TOCEntries) { var outputPath = Path.Combine(outputDirectory, entry.Name); // Create directories for output if (entry.IsDirectory) { Directory.CreateDirectory(outputPath); continue; } // Ensure the parent directory exists Directory.CreateDirectory(Path.GetDirectoryName(outputPath) ?? string.Empty); // Seek to the file's position in the ISO reader.BaseStream.Seek(entry.Position, SeekOrigin.Begin); // Extract file in chunks using var outputFile = new FileStream(outputPath, FileMode.Create, FileAccess.Write); long remaining = entry.Length; const int bufferSize = 0x8000; // 32KB chunks byte[] buffer = new byte[bufferSize]; while (remaining > 0) { int bytesToRead = (int)Math.Min(bufferSize, remaining); int bytesRead = reader.Read(buffer, 0, bytesToRead); outputFile.Write(buffer, 0, bytesRead); remaining -= bytesRead; } } } } public class TOCItem { public int Position { get; set; } public int Length { get; set; } public bool IsDirectory { get; set; } public string Name { get; set; } } } ================================================ FILE: UWUVCI AIO WPF/Classes/Injection.cs ================================================ using GameBaseClassLibrary; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.IO.Compression; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Windows; using System.Windows.Threading; using System.Xml; using UWUVCI_AIO_WPF.Classes; using UWUVCI_AIO_WPF.UI.Windows; using Newtonsoft.Json; using MessageBox = System.Windows.MessageBox; using UWUVCI_AIO_WPF.Models; using WiiUDownloaderLibrary.Models; using WiiUDownloaderLibrary; using Newtonsoft.Json.Linq; using UWUVCI_AIO_WPF.Helpers; using System.Diagnostics.Eventing.Reader; namespace UWUVCI_AIO_WPF { public static class StringExtensions { public static string ToHex(this string input) { StringBuilder sb = new StringBuilder(); foreach (char c in input) sb.AppendFormat("{0:X2}", (int)c); return sb.ToString().Trim(); } } internal static class Injection { [DllImport("User32.dll")] static extern int SetForegroundWindow(IntPtr point); [DllImport("user32.dll")] public static extern int SendMessage( int hWnd, // handle to destination window uint Msg, // message long wParam, // first message parameter long lParam // second message parameter ); [return: MarshalAs(UnmanagedType.Bool)] [DllImport("user32.dll", SetLastError = true)] static extern bool PostMessage(IntPtr hWnd, int Msg, System.Windows.Forms.Keys wParam, int lParam); private static int WM_KEYUP = 0x101; private static readonly string tempPath = Path.Combine(Directory.GetCurrentDirectory(), "bin", "temp"); private static readonly string baseRomPath = Path.Combine(tempPath, "baserom"); private static readonly string imgPath = Path.Combine(tempPath, "img"); private static readonly string toolsPath = Path.Combine(Directory.GetCurrentDirectory(), "bin", "Tools"); static string code = null; static MainViewModel mvvm; private static bool IsNativeWindows = !MacLinuxHelper.IsRunningUnderWineOrSimilar(); /* * GameConsole: Can either be NDS, N64, GBA, NES, SNES or TG16 * baseRom = Name of the BaseRom, which is the folder name too (example: Super Metroid EU will be saved at the BaseRom path under the folder SMetroidEU, so the BaseRom is in this case SMetroidEU). * customBasePath = Path to the custom Base. Is null if no custom base is used. * injectRomPath = Path to the Rom to be injected into the Base Game. * bootImages = String array containing the paths for * bootTvTex: PNG or TGA (PNG gets converted to TGA using UPNG). Needs to be in the dimensions 1280x720 and have a bit depth of 24. If null, the original BootImage will be used. * bootDrcTex: PNG or TGA (PNG gets converted to TGA using UPNG). Needs to be in the dimensions 854x480 and have a bit depth of 24. If null, the original BootImage will be used. * iconTex: PNG or TGA (PNG gets converted to TGA using UPNG). Needs to be in the dimensions 128x128 and have a bit depth of 32. If null, the original BootImage will be used. * bootLogoTex: PNG or TGA (PNG gets converted to TGA using UPNG). Needs to be in the dimensions 170x42 and have a bit depth of 32. If null, the original BootImage will be used. * gameName = The name of the final game to be entered into the .xml files. * iniPath = Only used for N64. Path to the INI configuration. If "blank", a blank ini will be used. * darkRemoval = Only used for N64. Indicates whether the dark filter should be removed. */ static List fiind(this byte[] buffer, byte[] pattern, int startIndex) { List positions = new List(); int i = Array.IndexOf(buffer, pattern[0], startIndex); while (i >= 0 && i <= buffer.Length - pattern.Length) { byte[] segment = new byte[pattern.Length]; Buffer.BlockCopy(buffer, i, segment, 0, pattern.Length); if (segment.SequenceEqual(pattern)) positions.Add(i); i = Array.IndexOf(buffer, pattern[0], i + 1); } return positions; } static void PokePatch(string rom) { byte[] search = { 0xD0, 0x88, 0x8D, 0x83, 0x42 }; byte[] test; test = new byte[new FileInfo(rom).Length]; using (var fs = new FileStream(rom, FileMode.Open, FileAccess.ReadWrite)) { try { fs.Read(test, 0, test.Length - 1); var l = fiind(test, search, 0); byte[] check = new byte[4]; fs.Seek(l[0] + 5, SeekOrigin.Begin); fs.Read(check, 0, 4); fs.Seek(0, SeekOrigin.Begin); if (check[3] != 0x24) { fs.Seek(l[0] + 5, SeekOrigin.Begin); fs.Write(new byte[] { 0x00, 0x00, 0x00, 0x00 }, 0, 4); } else { fs.Seek(l[0] + 5, SeekOrigin.Begin); fs.Write(new byte[] { 0x00, 0x00, 0x00 }, 0, 3); } check = new byte[4]; fs.Seek(l[1] + 5, SeekOrigin.Begin); fs.Read(check, 0, 4); fs.Seek(0, SeekOrigin.Begin); if (check[3] != 0x24) { fs.Seek(l[1] + 5, SeekOrigin.Begin); fs.Write(new byte[] { 0x00, 0x00, 0x00, 0x00 }, 0, 4); } else { fs.Seek(l[1] + 5, SeekOrigin.Begin); fs.Write(new byte[] { 0x00, 0x00, 0x00 }, 0, 3); } } catch (Exception) { } fs.Close(); } } private static string FormatBytes(long bytes) { string[] Suffix = { "B", "KB", "MB", "GB", "TB" }; int i; double dblSByte = bytes; for (i = 0; i < Suffix.Length && bytes >= 1024; i++, bytes /= 1024) { dblSByte = bytes / 1024.0; } return string.Format("{0:0.##} {1}", dblSByte, Suffix[i]); } [STAThread] public static bool Inject(GameConfig Configuration, string RomPath, MainViewModel mvm, bool force) { mvm.failed = false; DispatcherTimer timer = new DispatcherTimer(); timer.Interval = TimeSpan.FromSeconds(1); timer.Tick += tick; Clean(); long freeSpaceInBytes = 0; if (!mvm.saveworkaround) { try { long gamesize = new FileInfo(RomPath).Length; var drive = new DriveInfo(tempPath); done = true; freeSpaceInBytes = drive.AvailableFreeSpace; } catch (Exception) { mvm.saveworkaround = true; } } mvvm = mvm; Directory.CreateDirectory(tempPath); mvm.msg = "Checking Tools..."; mvm.InjcttoolCheck(); mvm.Progress = 5; mvm.msg = "Copying Base..."; try { if (!mvm.saveworkaround && (Configuration.Console == GameConsoles.WII || Configuration.Console == GameConsoles.GCN)) { long neededspace = mvm.GC ? 10000000000 : 15000000000; if (freeSpaceInBytes < neededspace) throw new Exception("12G"); } if (Configuration.BaseRom == null || Configuration.BaseRom.Name == null) { throw new Exception("BASE"); } if (Configuration.BaseRom.Name != "Custom") { //Normal Base functionality here CopyBase($"{Configuration.BaseRom.Name.Replace(":", "")} [{Configuration.BaseRom.Region}]", null); } else { //Custom Base Functionality here CopyBase($"Custom", Configuration.CBasePath); } if (!Directory.Exists(Path.Combine(baseRomPath, "code")) || !Directory.Exists(Path.Combine(baseRomPath, "content")) || !Directory.Exists(Path.Combine(baseRomPath, "meta"))) { throw new Exception("MISSINGF"); } mvm.Progress = 10; mvm.msg = "Injecting ROM..."; RunSpecificInjection(Configuration, (mvm.GC ? GameConsoles.GCN : Configuration.Console), RomPath, force, mvm); mvm.msg = "Editing XML..."; EditXML(Configuration.GameName, mvm.Index, code); mvm.Progress = 90; mvm.msg = "Changing Images..."; Images(Configuration); if (File.Exists(mvm.BootSound)) { mvm.Progress = 95; mvm.msg = "Adding BootSound..."; bootsound(mvm.BootSound); } mvm.Progress = 100; code = null; return true; } catch (Exception e) { mvm.Progress = 100; code = null; if (e.Message == "Failed this shit") { Clean(); return false; } var errorMessage = "Injection Failed due to unknown circumstances. Accent marks in the install path for UWUVCI or in the rom path is known to cause issues. Please contact us on the UWUVCI discord if you need any assistance."; if (e.Message == "MISSINGF") errorMessage = "Injection Failed because there are base files missing. \nPlease redownload the base, or redump if you used a custom base!"; else if (e.Message.Contains("Images")) errorMessage = "Injection Failed due to wrong BitDepth, please check if your Files are in a different bitdepth than 32bit or 24bit\n\nIf the image/s that's being used is automatically grabbed for you, then don't use them." + "\nFAQ: #28"; else if (e.Message.Contains("Size")) errorMessage = "Injection Failed due to Image Issues.Please check if your Images are made using following Information:\n\niconTex: \nDimensions: 128x128\nBitDepth: 32\n\nbootDrcTex: \nDimensions: 854x480\nBitDepth: 24\n\nbootTvTex: \nDimensions: 1280x720\nBitDepth: 24\n\nbootLogoTex: \nDimensions: 170x42\nBitDepth: 32"; else if (e.Message.Contains("retro")) errorMessage = "The ROM you want to Inject is to big for selected Base!\nPlease try again with different Base"; else if (e.Message.Contains("BASE")) errorMessage = "If you import a config you NEED to reselect a base"; else if (e.Message.Contains("WII")) errorMessage = $"{e.Message.Replace("Wii", "")}\nPlease make sure that your ROM isn't flawed and that you have atleast 12 GB of free Storage left."; else if (e.Message.Contains("12G")) errorMessage = $"Please make sure to have atleast {FormatBytes(15000000000)} of storage left on the drive where you stored the Injector."; else if (e.Message.Contains("nkit")) errorMessage = $"There is an issue with your NKIT.\nPlease try the original ISO, or redump your game and try again with that dump."; else if (e.Message.Contains("meta.xml")) errorMessage = "Looks to be your meta.xml file isn't missing from your directory. If you downloaded your base, redownload it, if it's a custom base then the folder selected might be wrong or the layout is messed up."; else if (e.Message.Contains("pre.iso")) errorMessage = "Looks to be that there is something about your game that UWUVCI doesn't like, you are most likely injecting with a wbfs or nkit.iso file, this file has data trimmed." + "\nFAQ: #17, #27, #29"; else if (e.Message.Contains("temp\\temp") || e.Message.Contains("temp/temp")) errorMessage = "The images are most likely the culprit, try changing them around." + "\nFAQ: #28"; if (MacLinuxHelper.IsRunningInVirtualMachine() || MacLinuxHelper.IsRunningUnderWineOrSimilar()) errorMessage += "\n\nYou look to be running this under some form of emulation instead of a native Windows OS. There are external tools that UWUVCI uses which are not managed by the UWUVCI team. These external tools may be causing you issues and we will not be able to resolve your issues."; MessageBox.Show(errorMessage + "\n\nDon't forget that there's an FAQ in the ReadMe.txt file and on the UWUVCI Discord\n\nError Message:\n" + e.Message, "Injection Failed", MessageBoxButton.OK, MessageBoxImage.Error); Logger.Log(e.Message); Clean(); return false; } finally { mvm.Index = -1; mvm.LR = false; mvm.msg = ""; } } private static bool done = false; private static void tick(object sender, EventArgs e) { if (!done) mvvm.failed = true; throw new Exception("Failed this shit"); } public static void SendKey(IntPtr hWnd, System.Windows.Forms.Keys key) { PostMessage(hWnd, WM_KEYUP, key, 0); } static void bootsound(string sound) { string btsndPath = Path.Combine(baseRomPath, "meta", "bootSound.btsnd"); FileInfo soundFile = new FileInfo(sound); if (soundFile.Extension.Contains("mp3") || soundFile.Extension.Contains("wav")) { // Convert input file to 6 second .wav using (Process sox = new Process()) { sox.StartInfo.UseShellExecute = false; sox.StartInfo.CreateNoWindow = true; sox.StartInfo.FileName = Path.Combine(toolsPath, "sox.exe"); sox.StartInfo.Arguments = $"\"{sound}\" -b 16 \"{Path.Combine(tempPath, "bootSound.wav")}\" channels 2 rate 48k trim 0 6"; sox.Start(); sox.WaitForExit(); } //convert to btsnd wav2btsnd(Path.Combine(tempPath, "bootSound.wav"), btsndPath); File.Delete(Path.Combine(tempPath, "bootSound.wav")); } else { //Copy BootSound to location File.Delete(btsndPath); File.Copy(sound, btsndPath); } } private static void wav2btsnd(string inputWav, string outputBtsnd) { // credits to the original creator of wav2btsnd for the general logic byte[] buffer = File.ReadAllBytes(inputWav); using FileStream output = new FileStream(outputBtsnd, FileMode.OpenOrCreate); using BinaryWriter writer = new BinaryWriter(output); writer.Write(new byte[] { 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0 }); for (int i = 0x2C; i < buffer.Length; i += 2) writer.Write(new[] { buffer[i + 1], buffer[i] }); } static void timer_Tick(object sender, EventArgs e) { if (mvvm.Progress < 50) mvvm.Progress += 1; } private static void RunSpecificInjection(GameConfig cfg, GameConsoles console, string RomPath, bool force, MainViewModel mvm) { switch (console) { case GameConsoles.NDS: NDS(RomPath); break; case GameConsoles.N64: N64(RomPath, cfg.N64Stuff); break; case GameConsoles.GBA: GBA(RomPath, cfg.GBAStuff); break; case GameConsoles.NES: NESSNES(RomPath); break; case GameConsoles.SNES: NESSNES(RemoveHeader(RomPath)); break; case GameConsoles.TG16: TG16(RomPath); break; case GameConsoles.MSX: MSX(RomPath); break; case GameConsoles.WII: if (RomPath.ToLower().EndsWith(".dol")) WiiHomebrew(RomPath, mvm); else if (RomPath.ToLower().EndsWith(".wad")) WiiForwarder(RomPath, mvm); else WII(RomPath, mvm); break; case GameConsoles.GCN: GC(RomPath, mvm, force); break; } } private static string ByteArrayToString(byte[] arr) { ASCIIEncoding enc = new ASCIIEncoding(); return enc.GetString(arr); } private static void WiiForwarder(string romPath, MainViewModel mvm) { string savedir = Directory.GetCurrentDirectory(); mvvm.msg = "Extracting Forwarder Base..."; if (Directory.Exists(Path.Combine(tempPath, "TempBase"))) Directory.Delete(Path.Combine(tempPath, "TempBase"), true); Directory.CreateDirectory(Path.Combine(tempPath, "TempBase")); var zipLocation = Path.Combine(toolsPath, "BASE.zip"); ZipFile.ExtractToDirectory(zipLocation, Path.Combine(tempPath)); DirectoryCopy(Path.Combine(tempPath, "BASE"), Path.Combine(tempPath, "TempBase"), true); mvvm.Progress = 20; mvvm.msg = "Setting up Forwarder..."; byte[] test = new byte[4]; using (FileStream fs = new FileStream(romPath, FileMode.Open)) { fs.Seek(0xC20, SeekOrigin.Begin); fs.Read(test, 0, 4); fs.Close(); } string[] id = { ByteArrayToString(test) }; File.WriteAllLines(Path.Combine(tempPath, "TempBase", "files", "title.txt"), id); mvm.Progress = 30; mvm.msg = "Copying Forwarder..."; File.Copy(Path.Combine(toolsPath, "forwarder.dol"), Path.Combine(tempPath, "TempBase", "sys", "main.dol")); mvm.Progress = 40; mvvm.msg = "Creating Injectable file..."; SharedWitAndNFS2ISO2NFS(savedir, mvm, "WiiForwarder"); } private static void SharedWitAndNFS2ISO2NFS(string savedir, MainViewModel mvm, string functionName) { if (IsNativeWindows) { using (Process wit = new Process()) { if (!mvm.debug) wit.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; wit.StartInfo.FileName = Path.Combine(toolsPath, "wit.exe"); wit.StartInfo.Arguments = $"copy \"{Path.Combine(tempPath, "TempBase")}\" --DEST \"{Path.Combine(tempPath, "game.iso")}\" -ovv --links --iso"; wit.Start(); wit.WaitForExit(); } //Thread.Sleep(6000); if (!File.Exists(Path.Combine(tempPath, "game.iso"))) { Console.Clear(); throw new Exception("Wii: An error occured while Creating the ISO"); } mvvm.Progress = 50; mvm.msg = "Replacing TIK and TMD..."; using Process extract = new Process(); if (!mvm.debug) extract.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; extract.StartInfo.FileName = Path.Combine(toolsPath, "wit.exe"); extract.StartInfo.Arguments = $"extract \"{Path.Combine(tempPath, "game.iso")}\" --psel data --files +tmd.bin --files +ticket.bin --DEST \"{Path.Combine(tempPath, "TIKTMD")}\" -vv1"; extract.Start(); extract.WaitForExit(); } else { string[] args = { $"copy \"{Path.Combine(tempPath, "TempBase")}\" --DEST \"{Path.Combine(tempPath, "game.iso")}\" -ovv --links --iso", $"extract \"{Path.Combine(tempPath, "game.iso")}\" --psel data --files +tmd.bin --files +ticket.bin --DEST \"{Path.Combine(tempPath, "TIKTMD")}\" -vv1" }; foreach (var arg in args) MacLinuxHelper.WriteFailedStepToJson(functionName, "wit", arg, string.Empty); MacLinuxHelper.DisplayMessageBoxAboutTheHelper(); } if (functionName == "GCN") { //GET ROMCODE and change it mvm.msg = "Trying to save rom code..."; //READ FIRST 4 BYTES byte[] chars = new byte[4]; FileStream fstrm = new FileStream(Path.Combine(tempPath, "game.iso"), FileMode.Open); fstrm.Read(chars, 0, 4); fstrm.Close(); string procod = ByteArrayToString(chars); string metaXml = Path.Combine(baseRomPath, "meta", "meta.xml"); XmlDocument doc = new XmlDocument(); doc.Load(metaXml); doc.SelectSingleNode("menu/reserved_flag2").InnerText = procod.ToHex(); doc.Save(metaXml); mvvm.Progress = 55; } Directory.Delete(Path.Combine(tempPath, "TempBase"), true); foreach (string sFile in Directory.GetFiles(Path.Combine(baseRomPath, "code"), "rvlt.*")) File.Delete(sFile); File.Copy(Path.Combine(tempPath, "TIKTMD", "tmd.bin"), Path.Combine(baseRomPath, "code", "rvlt.tmd")); File.Copy(Path.Combine(tempPath, "TIKTMD", "ticket.bin"), Path.Combine(baseRomPath, "code", "rvlt.tik")); Directory.Delete(Path.Combine(tempPath, "TIKTMD"), true); mvm.Progress = 60; mvm.msg = "Injecting ROM..."; foreach (string sFile in Directory.GetFiles(Path.Combine(baseRomPath, "content"), "*.nfs")) File.Delete(sFile); File.Move(Path.Combine(tempPath, "game.iso"), Path.Combine(baseRomPath, "content", "game.iso")); File.Copy(Path.Combine(toolsPath, "nfs2iso2nfs.exe"), Path.Combine(baseRomPath, "content", "nfs2iso2nfs.exe")); Directory.SetCurrentDirectory(Path.Combine(baseRomPath, "content")); using (Process iso2nfs = new Process()) { if (!mvm.debug) iso2nfs.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; iso2nfs.StartInfo.FileName = "nfs2iso2nfs.exe"; if (functionName != "GCN") { string pass = "-passthrough "; string extra = ""; if (mvm.passtrough != true) pass = ""; if (mvm.Index == 2) extra = "-horizontal "; if (mvm.Index == 3) extra = "-wiimote "; if (mvm.Index == 4) extra = "-instantcc "; if (mvm.Index == 5) extra = "-nocc "; if (mvm.LR) extra += "-lrpatch "; iso2nfs.StartInfo.Arguments = $"-enc -homebrew {extra}{pass}-iso game.iso"; } else iso2nfs.StartInfo.Arguments = $"-enc -homebrew -passthrough -iso game.iso"; iso2nfs.Start(); iso2nfs.WaitForExit(); File.Delete("nfs2iso2nfs.exe"); File.Delete("game.iso"); } Directory.SetCurrentDirectory(savedir); mvm.Progress = 80; } private static void WiiHomebrew(string romPath, MainViewModel mvm) { string savedir = Directory.GetCurrentDirectory(); mvvm.msg = "Extracting Homebrew Base..."; if (Directory.Exists(Path.Combine(tempPath, "TempBase"))) Directory.Delete(Path.Combine(tempPath, "TempBase"), true); Directory.CreateDirectory(Path.Combine(tempPath, "TempBase")); ZipFile.ExtractToDirectory(Path.Combine(toolsPath, "BASE.zip"), Path.Combine(tempPath)); DirectoryCopy(Path.Combine(tempPath, "BASE"), Path.Combine(tempPath, "TempBase"), true); mvvm.Progress = 20; mvvm.msg = "Injecting DOL..."; File.Copy(romPath, Path.Combine(tempPath, "TempBase", "sys", "main.dol")); mvm.Progress = 30; mvvm.msg = "Creating Injectable file..."; SharedWitAndNFS2ISO2NFS(savedir, mvm, "WiiHomebrew"); } private static void PatchDol(string consoleName, string mainDolPath, MainViewModel mvm) { var filePaths = mvm.gctPath.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); var convertedGctFiles = new List(); foreach (var path in filePaths) { string convertedPath = path; if (Path.GetExtension(path).Equals(".txt", StringComparison.OrdinalIgnoreCase)) { try { var (codes, gameId) = GctCode.ParseOcarinaOrDolphinTxtFile(path); convertedPath = Path.ChangeExtension(path, ".gct"); GctCode.WriteGctFile(convertedPath, codes, gameId); Logger.Log($"Converted {path} → {convertedPath} (Game ID: {gameId ?? "None"})"); } catch (Exception ex) { Logger.Log($"ERROR: Failed to convert {path} - {ex.Message}"); continue; } } convertedGctFiles.Add(convertedPath); } if (convertedGctFiles.Count == 0) { Logger.Log("ERROR: No valid GCT files available for patching."); return; } if (consoleName == "Wii") { var stringBuilder = new StringBuilder(); foreach (var gctFile in convertedGctFiles) stringBuilder.Append($" --add-section \"{gctFile}\""); var witArgs = $"patch \"{mainDolPath}\"" + stringBuilder.ToString(); if (IsNativeWindows) { using var unpack = new Process(); unpack.StartInfo.FileName = Path.Combine(toolsPath, "wstrt.exe"); unpack.StartInfo.Arguments = witArgs; unpack.Start(); unpack.WaitForExit(); } else { MacLinuxHelper.PrepareAndInformUserOnUWUVCIHelper(consoleName, "wstrt", witArgs, toolsPath); } } else { var dol = new Dol(); var allCodes = new List(); foreach (var filePath in convertedGctFiles) allCodes.AddRange(GctCode.LoadFromFile(filePath)); dol.PatchDolFile(mainDolPath, allCodes); } } private static void GctPatch(MainViewModel mvm, string consoleName, string isoPath) { if (string.IsNullOrEmpty(mvm.GctPath)) return; ; var extraction = Path.Combine(tempPath, "temp"); mvm.msg = "Patching main.dol with gct file"; mvm.Progress = 27; File.Delete(isoPath); ; var mainDolPath = Directory.GetFiles(extraction, "main.dol", SearchOption.AllDirectories).FirstOrDefault(); PatchDol(consoleName, mainDolPath, mvm); } private static void WII(string romPath, MainViewModel mvm) { var witArgs = ""; var dolPatch = mvm.RemoveDeflicker || mvm.RemoveDithering || mvm.HalfVFilter; string savedir = Directory.GetCurrentDirectory(); if (new FileInfo(romPath).Extension.Contains("iso")) { mvm.msg = "Copying ROM..."; File.Copy(romPath, Path.Combine(tempPath, "pre.iso")); mvm.Progress = 15; } else if (mvm.NKITFLAG || romPath.Contains("nkit") || new FileInfo(romPath).Extension.Contains("wbfs")) { witArgs = $"copy --source \"{romPath}\" --dest \"{Path.Combine(tempPath, "pre.iso")}\" -I"; if (IsNativeWindows) { if (mvm.NKITFLAG || romPath.Contains("nkit")) mvm.msg = "Converting NKIT to ISO"; else mvm.msg = "Converting WBFS to ISO..."; using Process toiso = new Process(); if (!mvm.debug) toiso.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; toiso.StartInfo.FileName = Path.Combine(toolsPath, "wit.exe"); toiso.StartInfo.Arguments = witArgs; toiso.Start(); toiso.WaitForExit(); } else MacLinuxHelper.PrepareAndInformUserOnUWUVCIHelper("Wii", "wit", witArgs, toolsPath); if (!new FileInfo(romPath).Extension.Contains("wbfs")) if (!File.Exists(Path.Combine(toolsPath, "pre.iso"))) throw new Exception("nkit"); mvm.Progress = 15; } //GET ROMCODE and change it mvm.msg = "Trying to change the Manual..."; //READ FIRST 4 BYTES byte[] chars = new byte[4]; FileStream fstrm = new FileStream(Path.Combine(tempPath, "pre.iso"), FileMode.Open); fstrm.Read(chars, 0, 4); fstrm.Close(); string procod = ByteArrayToString(chars); string neededformanual = procod.ToHex(); string metaXml = Path.Combine(baseRomPath, "meta", "meta.xml"); XmlDocument doc = new XmlDocument(); doc.Load(metaXml); doc.SelectSingleNode("menu/reserved_flag2").InnerText = neededformanual; doc.Save(metaXml); //edit emta.xml mvm.Progress = 25; if (mvm.regionfrii) { using FileStream fs = new FileStream(Path.Combine(tempPath, "pre.iso"), FileMode.Open); fs.Seek(0x4E003, SeekOrigin.Begin); if (mvm.regionfriius) { fs.Write(new byte[] { 0x01 }, 0, 1); fs.Seek(0x4E010, SeekOrigin.Begin); fs.Write(new byte[] { 0x80, 0x06, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 }, 0, 16); } else if (mvm.regionfriijp) { fs.Write(new byte[] { 0x00 }, 0, 1); fs.Seek(0x4E010, SeekOrigin.Begin); fs.Write(new byte[] { 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 }, 0, 16); } else { fs.Write(new byte[] { 0x02 }, 0, 1); fs.Seek(0x4E010, SeekOrigin.Begin); fs.Write(new byte[] { 0x80, 0x80, 0x80, 0x00, 0x03, 0x03, 0x04, 0x03, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 }, 0, 16); } fs.Close(); } var preIso = Path.Combine(tempPath, "pre.iso"); if (mvm.donttrim) { witArgs = $"extract \"{preIso}\" --DEST \"{Path.Combine(tempPath, "TEMP")}\" --psel data -vv1"; mvm.msg = "Prepping ROM..."; } else { witArgs = $"extract \"{preIso}\" --DEST \"{Path.Combine(tempPath, "TEMP")}\" --psel WHOLE -vv1"; mvm.msg = "Trimming ROM..."; } if (IsNativeWindows) { using Process trimm = new Process(); if (!mvm.debug) trimm.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; trimm.StartInfo.FileName = Path.Combine(toolsPath, "wit.exe"); trimm.StartInfo.Arguments = witArgs; trimm.Start(); trimm.WaitForExit(); mvm.Progress = 30; } else MacLinuxHelper.PrepareAndInformUserOnUWUVCIHelper("Wii", "wit", witArgs, toolsPath); GctPatch(mvm, "Wii", Path.Combine(tempPath, "pre.iso")); if (dolPatch) { mvm.msg = "Patching main.dol file"; mvm.Progress = 33; var extractionFolder = Path.Combine(tempPath, "TEMP"); var mainDolPath = Directory.GetFiles(extractionFolder, "main.dol", SearchOption.AllDirectories).FirstOrDefault(); var output = Path.Combine(Path.GetDirectoryName(mainDolPath), "patched.dol"); DeflickerDitheringRemover.ProcessFile(mainDolPath, output, mvm.RemoveDeflicker, mvm.RemoveDithering, mvm.HalfVFilter); File.Delete(mainDolPath); File.Move(output, mainDolPath); } if (mvm.Index == 4) { mvvm.msg = "Patching ROM (Force CC)..."; Console.WriteLine("Patching the ROM to force Classic Controller input"); using Process tik = new Process(); tik.StartInfo.FileName = Path.Combine(toolsPath, "GetExtTypePatcher.exe"); tik.StartInfo.Arguments = $"\"{Path.Combine(tempPath, "TEMP", "DATA", "sys", "main.dol")}\" -nc"; tik.StartInfo.UseShellExecute = false; tik.StartInfo.CreateNoWindow = true; tik.StartInfo.RedirectStandardOutput = true; tik.StartInfo.RedirectStandardInput = true; tik.Start(); Thread.Sleep(2000); tik.StandardInput.WriteLine(); tik.WaitForExit(); mvm.Progress = 35; } if (mvm.Patch) { mvm.msg = "Video Patching ROM..."; using Process vmc = new Process(); File.Copy(Path.Combine(toolsPath, "wii-vmc.exe"), Path.Combine(tempPath, "TEMP", "DATA", "sys", "wii-vmc.exe")); Directory.SetCurrentDirectory(Path.Combine(tempPath, "TEMP", "DATA", "sys")); vmc.StartInfo.FileName = "wii-vmc.exe"; vmc.StartInfo.Arguments = "main.dol"; vmc.StartInfo.UseShellExecute = false; vmc.StartInfo.CreateNoWindow = true; vmc.StartInfo.RedirectStandardOutput = true; vmc.StartInfo.RedirectStandardInput = true; vmc.Start(); Thread.Sleep(1000); vmc.StandardInput.WriteLine("a"); Thread.Sleep(2000); if (mvm.toPal) vmc.StandardInput.WriteLine("1"); else vmc.StandardInput.WriteLine("2"); Thread.Sleep(2000); vmc.StandardInput.WriteLine(); vmc.WaitForExit(); File.Delete("wii-vmc.exe"); Directory.SetCurrentDirectory(savedir); mvm.Progress = 40; } var tempFolder = Path.Combine(tempPath, "TEMP"); if (mvm.donttrim) { mvm.msg = "Creating ISO from patched ROM..."; witArgs = $"copy \"{tempFolder}\" --DEST \"{Path.Combine(tempPath, "game.iso")}\" -ovv --psel WHOLE --iso"; } else { mvm.msg = "Creating ISO from trimmed ROM..."; witArgs = $"copy \"{tempFolder}\" --DEST \"{Path.Combine(tempPath, "game.iso")}\" -ovv --links --iso"; } if (IsNativeWindows) { using Process repack = new Process(); if (!mvm.debug) repack.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; repack.StartInfo.FileName = Path.Combine(toolsPath, "wit.exe"); repack.StartInfo.Arguments = witArgs; repack.Start(); repack.WaitForExit(); } else MacLinuxHelper.PrepareAndInformUserOnUWUVCIHelper("Wii", "wit", witArgs, toolsPath); Directory.Delete(Path.Combine(tempPath, "TEMP"), true); File.Delete(Path.Combine(tempPath, "pre.iso")); mvm.Progress = 50; mvm.msg = "Replacing TIK and TMD..."; var gameIso = Path.Combine(tempPath, "game.iso"); witArgs = $"extract \"{gameIso}\" --psel data --files +tmd.bin --files +ticket.bin --DEST \"{Path.Combine(tempPath, "TIKTMD")}\" -vv1"; if (IsNativeWindows) { using Process extract = new Process(); if (!mvm.debug) extract.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; extract.StartInfo.FileName = Path.Combine(toolsPath, "wit.exe"); extract.StartInfo.Arguments = witArgs; extract.Start(); extract.WaitForExit(); } else MacLinuxHelper.PrepareAndInformUserOnUWUVCIHelper("Wii", "wit", witArgs, toolsPath); foreach (string sFile in Directory.GetFiles(Path.Combine(baseRomPath, "code"), "rvlt.*")) File.Delete(sFile); File.Copy(Path.Combine(tempPath, "TIKTMD", "tmd.bin"), Path.Combine(baseRomPath, "code", "rvlt.tmd")); File.Copy(Path.Combine(tempPath, "TIKTMD", "ticket.bin"), Path.Combine(baseRomPath, "code", "rvlt.tik")); Directory.Delete(Path.Combine(tempPath, "TIKTMD"), true); mvm.Progress = 60; mvm.msg = "Injecting ROM..."; foreach (string sFile in Directory.GetFiles(Path.Combine(baseRomPath, "content"), "*.nfs")) File.Delete(sFile); File.Move(Path.Combine(tempPath, "game.iso"), Path.Combine(baseRomPath, "content", "game.iso")); File.Copy(Path.Combine(toolsPath, "nfs2iso2nfs.exe"), Path.Combine(baseRomPath, "content", "nfs2iso2nfs.exe")); Directory.SetCurrentDirectory(Path.Combine(baseRomPath, "content")); using (Process iso2nfs = new Process()) { if (!mvm.debug) iso2nfs.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; iso2nfs.StartInfo.FileName = "nfs2iso2nfs.exe"; string extra = ""; if (mvm.Index == 2) { extra = "-horizontal "; } if (mvm.Index == 3) { extra = "-wiimote "; } if (mvm.Index == 4) { extra = "-instantcc "; } if (mvm.Index == 5) { extra = "-nocc "; } if (mvm.LR) { extra += "-lrpatch "; } iso2nfs.StartInfo.Arguments = $"-enc {extra}-iso game.iso"; iso2nfs.Start(); iso2nfs.WaitForExit(); File.Delete("nfs2iso2nfs.exe"); File.Delete("game.iso"); } Directory.SetCurrentDirectory(savedir); mvm.Progress = 80; } private static void ConvertToIso(string sourcePath, string outputFileName, bool debugMode) { using Process process = new Process(); if (!debugMode) process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; process.StartInfo.FileName = Path.Combine(toolsPath, "ConvertToIso.exe"); process.StartInfo.Arguments = $"\"{sourcePath}\""; process.Start(); process.WaitForExit(); string isoPath = Path.Combine(toolsPath, outputFileName); if (!File.Exists(isoPath)) throw new Exception("ISO conversion failed."); File.Move(isoPath, Path.Combine(tempPath, "TempBase", "files", "game.iso")); } // Function to handle NKit conversion private static void ConvertToNKit(string sourcePath, string outputFileName, bool debugMode) { using Process process = new Process(); if (!debugMode) process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; process.StartInfo.FileName = Path.Combine(toolsPath, "ConvertToNKit.exe"); process.StartInfo.Arguments = $"\"{sourcePath}\""; process.Start(); process.WaitForExit(); string nkitIsoPath = Path.Combine(toolsPath, outputFileName); if (!File.Exists(nkitIsoPath)) throw new Exception("NKit conversion failed."); File.Move(nkitIsoPath, Path.Combine(tempPath, "TempBase", "files", outputFileName)); } private static void GC(string romPath, MainViewModel mvm, bool force) { string savedir = Directory.GetCurrentDirectory(); mvvm.msg = "Extracting Nintendont Base..."; if (Directory.Exists(Path.Combine(tempPath, "TempBase"))) Directory.Delete(Path.Combine(tempPath, "TempBase"), true); Directory.CreateDirectory(Path.Combine(tempPath, "TempBase")); ZipFile.ExtractToDirectory(Path.Combine(toolsPath, "BASE.zip"), Path.Combine(tempPath)); DirectoryCopy(Path.Combine(tempPath, "BASE"), Path.Combine(tempPath, "TempBase"), true); mvvm.Progress = 20; mvvm.msg = "Applying Nintendont"; if (force) { mvvm.msg += " force 4:3..."; File.Copy(Path.Combine(toolsPath, "nintendont_force.dol"), Path.Combine(tempPath, "TempBase", "sys", "main.dol")); } else { mvvm.msg += "..."; File.Copy(Path.Combine(toolsPath, "nintendont.dol"), Path.Combine(tempPath, "TempBase", "sys", "main.dol")); } mvm.Progress = 40; mvvm.msg = "Injecting GameCube Game into NintendontBase..."; if (mvm.donttrim) { if (romPath.ToLower().Contains("nkit.iso")) { using (Process wit = new Process()) { if (!mvm.debug) { wit.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; } wit.StartInfo.FileName = Path.Combine(toolsPath, "ConvertToIso.exe"); wit.StartInfo.Arguments = $"\"{romPath}\""; wit.Start(); wit.WaitForExit(); if (!File.Exists(Path.Combine(toolsPath, "out.iso"))) { throw new Exception("nkit"); } File.Move(Path.Combine(toolsPath, "out.iso"), Path.Combine(tempPath, "TempBase", "files", "game.iso")); } } else { if (romPath.ToLower().Contains("gcz")) { //Convert to nkit.iso using (Process wit = new Process()) { if (!mvm.debug) { wit.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; } wit.StartInfo.FileName = Path.Combine(toolsPath, "ConvertToIso.exe"); wit.StartInfo.Arguments = $"\"{romPath}\""; wit.Start(); wit.WaitForExit(); if (!File.Exists(Path.Combine(toolsPath, "out.iso"))) { throw new Exception("nkit"); } File.Move(Path.Combine(toolsPath, "out.iso"), Path.Combine(tempPath, "TempBase", "files", "game.iso")); } } else { File.Copy(romPath, Path.Combine(tempPath, "TempBase", "files", "game.iso")); } } } else { if (romPath.ToLower().Contains("iso") || romPath.ToLower().Contains("gcm")) { //convert to nkit using (Process wit = new Process()) { if (!mvm.debug) { wit.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; } wit.StartInfo.FileName = Path.Combine(toolsPath, "ConvertToNKit.exe"); wit.StartInfo.Arguments = $"\"{romPath}\""; wit.Start(); wit.WaitForExit(); if (!File.Exists(Path.Combine(toolsPath, "out.nkit.iso"))) { throw new Exception("nkit"); } File.Move(Path.Combine(toolsPath, "out.nkit.iso"), Path.Combine(tempPath, "TempBase", "files", "game.iso")); } } else { if (romPath.ToLower().Contains("gcz")) { //Convert to nkit.iso using (Process wit = new Process()) { if (!mvm.debug) { wit.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; } wit.StartInfo.FileName = Path.Combine(toolsPath, "ConvertToNKit.exe"); wit.StartInfo.Arguments = $"\"{romPath}\""; wit.Start(); wit.WaitForExit(); if (!File.Exists(Path.Combine(toolsPath, "out.nkit.iso"))) { throw new Exception("nkit"); } File.Move(Path.Combine(toolsPath, "out.nkit.iso"), Path.Combine(tempPath, "TempBase", "files", "game.iso")); } } else { File.Copy(romPath, Path.Combine(tempPath, "TempBase", "files", "game.iso")); } } } if (mvm.gc2rom != "" && File.Exists(mvm.gc2rom)) { if (mvm.donttrim) { if (mvm.gc2rom.Contains("nkit")) { using (Process wit = new Process()) { if (!mvm.debug) { wit.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; } wit.StartInfo.FileName = Path.Combine(toolsPath, "ConvertToIso.exe"); wit.StartInfo.Arguments = $"\"{mvm.gc2rom}\""; wit.Start(); wit.WaitForExit(); if (!File.Exists(Path.Combine(toolsPath, "out(Disc 1).iso"))) { throw new Exception("nkit"); } File.Move(Path.Combine(toolsPath, "out(Disc 1).iso"), Path.Combine(tempPath, "TempBase", "files", "disc2.iso")); } } else { File.Copy(mvm.gc2rom, Path.Combine(tempPath, "TempBase", "files", "disc2.iso")); } } else{ if (mvm.gc2rom.ToLower().Contains("iso") || mvm.gc2rom.ToLower().Contains("gcm")) { //convert to nkit using (Process wit = new Process()) { if (!mvm.debug) { wit.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; } wit.StartInfo.FileName = Path.Combine(toolsPath, "ConvertToNKit.exe"); wit.StartInfo.Arguments = $"\"{mvm.gc2rom}\""; wit.Start(); wit.WaitForExit(); if (!File.Exists(Path.Combine(toolsPath, "out(Disc 1).nkit.iso"))) { throw new Exception("nkit"); } File.Move(Path.Combine(toolsPath, "out(Disc 1).nkit.iso"), Path.Combine(tempPath, "TempBase", "files", "disc2.iso")); } } else { if (romPath.ToLower().Contains("gcz")) { //Convert to nkit.iso using (Process wit = new Process()) { if (!mvm.debug) { wit.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; } wit.StartInfo.FileName = Path.Combine(toolsPath, "ConvertToNKit.exe"); wit.StartInfo.Arguments = $"\"{romPath}\""; wit.Start(); wit.WaitForExit(); if (!File.Exists(Path.Combine(toolsPath, "out(Disc 1).nkit.iso"))) { throw new Exception("nkit"); } File.Move(Path.Combine(toolsPath, "out(Disc 1).nkit.iso"), Path.Combine(tempPath, "TempBase", "files", "disc2.iso")); } } else { File.Copy(romPath, Path.Combine(tempPath, "TempBase", "files", "disc2.iso")); } } } } var args = $"copy \"{Path.Combine(tempPath, "TempBase")}\" --DEST \"{Path.Combine(tempPath, "game.iso")}\" -ovv --links --iso"; if (IsNativeWindows) { using (Process wit = new Process()) { if (!mvm.debug) { wit.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; } wit.StartInfo.FileName = Path.Combine(toolsPath, "wit.exe"); wit.StartInfo.Arguments = args; wit.Start(); wit.WaitForExit(); } } else { MacLinuxHelper.WriteFailedStepToJson("GCN","wit", args, string.Empty); MacLinuxHelper.DisplayMessageBoxAboutTheHelper(); } //Thread.Sleep(6000); if (!File.Exists(Path.Combine(tempPath, "game.iso"))) { Console.Clear(); throw new Exception("WII: An error occured while Creating the ISO"); } //Directory.Delete(Path.Combine(tempPath, "TempBase"), true); romPath = Path.Combine(tempPath, "game.iso"); mvvm.Progress = 50; //GET ROMCODE and change it mvm.msg = "Trying to save rom code..."; //READ FIRST 4 BYTES byte[] chars = new byte[4]; FileStream fstrm = new FileStream(Path.Combine(tempPath, "TempBase", "files", "game.iso"), FileMode.Open); fstrm.Read(chars, 0, 4); fstrm.Close(); string procod = ByteArrayToString(chars); string metaXml = Path.Combine(baseRomPath, "meta", "meta.xml"); XmlDocument doc = new XmlDocument(); doc.Load(metaXml); doc.SelectSingleNode("menu/reserved_flag2").InnerText = procod.ToHex(); doc.Save(metaXml); //edit emta.xml Directory.Delete(Path.Combine(tempPath, "TempBase"), true); mvvm.Progress = 55; mvm.msg = "Replacing TIK and TMD..."; args = $"extract \"{Path.Combine(tempPath, "game.iso")}\" --psel data --files +tmd.bin --files +ticket.bin --DEST \"{Path.Combine(tempPath, "TIKTMD")}\" -vv1"; if (IsNativeWindows) { using (Process extract = new Process()) { if (!mvm.debug) { extract.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; } extract.StartInfo.FileName = Path.Combine(toolsPath, "wit.exe"); extract.StartInfo.Arguments = args; extract.Start(); extract.WaitForExit(); } } else { MacLinuxHelper.WriteFailedStepToJson("GCN", "wit", args, string.Empty); MacLinuxHelper.DisplayMessageBoxAboutTheHelper(); } foreach (string sFile in Directory.GetFiles(Path.Combine(baseRomPath, "code"), "rvlt.*")) { File.Delete(sFile); } File.Copy(Path.Combine(tempPath, "TIKTMD", "tmd.bin"), Path.Combine(baseRomPath, "code", "rvlt.tmd")); File.Copy(Path.Combine(tempPath, "TIKTMD", "ticket.bin"), Path.Combine(baseRomPath, "code", "rvlt.tik")); Directory.Delete(Path.Combine(tempPath, "TIKTMD"), true); mvm.Progress = 60; mvm.msg = "Injecting ROM..."; foreach (string sFile in Directory.GetFiles(Path.Combine(baseRomPath, "content"), "*.nfs")) { File.Delete(sFile); } File.Move(Path.Combine(tempPath, "game.iso"), Path.Combine(baseRomPath, "content", "game.iso")); File.Copy(Path.Combine(toolsPath, "nfs2iso2nfs.exe"), Path.Combine(baseRomPath, "content", "nfs2iso2nfs.exe")); Directory.SetCurrentDirectory(Path.Combine(baseRomPath, "content")); using (Process iso2nfs = new Process()) { if (!mvm.debug) { iso2nfs.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; } iso2nfs.StartInfo.FileName = "nfs2iso2nfs.exe"; iso2nfs.StartInfo.Arguments = $"-enc -homebrew -passthrough -iso game.iso"; iso2nfs.Start(); iso2nfs.WaitForExit(); File.Delete("nfs2iso2nfs.exe"); File.Delete("game.iso"); } Directory.SetCurrentDirectory(savedir); mvm.Progress = 80; } private static void Zesty_GC(string romPath, MainViewModel mvm, bool force) { string savedir = Directory.GetCurrentDirectory(); mvvm.msg = "Extracting Nintendont Base..."; if (Directory.Exists(Path.Combine(tempPath, "TempBase"))) Directory.Delete(Path.Combine(tempPath, "TempBase"), true); Directory.CreateDirectory(Path.Combine(tempPath, "TempBase")); ZipFile.ExtractToDirectory(Path.Combine(toolsPath, "BASE.zip"), Path.Combine(tempPath)); DirectoryCopy(Path.Combine(tempPath, "BASE"), Path.Combine(tempPath, "TempBase"), true); mvvm.Progress = 20; mvvm.msg = "Applying Nintendont"; if (force) { mvvm.msg += " force 4:3..."; File.Copy(Path.Combine(toolsPath, "nintendont_force.dol"), Path.Combine(tempPath, "TempBase", "sys", "main.dol")); } else { mvvm.msg += "..."; File.Copy(Path.Combine(toolsPath, "nintendont.dol"), Path.Combine(tempPath, "TempBase", "sys", "main.dol")); } mvm.Progress = 25; mvvm.msg = "Injecting GameCube Game into NintendontBase..."; var isoPath = Path.Combine(tempPath, "TempBase", "files"); if (mvm.donttrim) { if (romPath.ToLower().Contains("nkit.iso") || romPath.ToLower().Contains("gcz")) ConvertToIso(romPath, "out.iso", mvm.debug); else File.Copy(romPath, Path.Combine(tempPath, "TempBase", "files", "game.iso")); } else { if (romPath.ToLower().Contains("iso") || romPath.ToLower().Contains("gcm") || romPath.ToLower().Contains("gcz")) ConvertToNKit(romPath, "out.nkit.iso", mvm.debug); else File.Copy(romPath, Path.Combine(tempPath, "TempBase", "files", "game.iso")); } // Handle the second game (disc2.iso) if (!string.IsNullOrEmpty(mvm.gc2rom) && File.Exists(mvm.gc2rom)) { if (mvm.donttrim) { if (mvm.gc2rom.Contains("nkit")) ConvertToIso(mvm.gc2rom, "out(Disc 1).iso", mvm.debug); else File.Copy(mvm.gc2rom, Path.Combine(tempPath, "TempBase", "files", "disc2.iso")); } else { if (mvm.gc2rom.ToLower().Contains("iso") || mvm.gc2rom.ToLower().Contains("gcm") || romPath.ToLower().Contains("gcz")) ConvertToNKit(mvm.gc2rom, "out(Disc 1).nkit.iso", mvm.debug); else File.Copy(romPath, Path.Combine(tempPath, "TempBase", "files", "disc2.iso")); } } SharedWitAndNFS2ISO2NFS(savedir, mvm, "GCN"); } public static void MSX(string injectRomPath) { mvvm.msg = "Reading Header from Base..."; byte[] test = new byte[0x580B3]; using (var fs = new FileStream(Path.Combine(baseRomPath, "content" , "msx", "msx.pkg"), FileMode.Open, FileAccess.ReadWrite)) { fs.Read(test, 0, 0x580B3); fs.Close(); File.Delete(Path.Combine(baseRomPath, "content", "msx", "msx.pkg")); } mvvm.Progress = 20; mvvm.msg = "Creating new PKG with read Header..."; using (var fs = new FileStream(Path.Combine(baseRomPath, "content", "msx", "msx.pkg"), FileMode.OpenOrCreate, FileAccess.ReadWrite)) { fs.Write(test, 0, 0x580B3); fs.Close(); } mvvm.Progress = 30; mvvm.msg = "Reading ROM content..."; using (var fs = new FileStream(injectRomPath, FileMode.OpenOrCreate, FileAccess.ReadWrite)) { test = new byte[fs.Length]; fs.Read(test, 0, test.Length - 1); } mvvm.Progress = 50; mvvm.msg = "Injecting ROM into new PKG..."; using (var fs = new FileStream(Path.Combine(baseRomPath, "content", "msx", "msx.pkg"), FileMode.Append)) { fs.Write(test, 0, test.Length); } mvvm.Progress = 80; } public static void DeleteDirectory(string path) { foreach (string directory in Directory.GetDirectories(path)) DeleteDirectory(directory); try { Thread.Sleep(0); Directory.Delete(path, true); } catch (IOException) { Directory.Delete(path, true); } catch (UnauthorizedAccessException) { Directory.Delete(path, true); } } public static void Clean() { if (Directory.Exists(tempPath)) DeleteDirectory(tempPath); } [STAThread] public static void Loadiine(string gameName, string gameConsole) { if (gameName == null || gameName == string.Empty) gameName = "NoName"; gameName = gameName.Replace("|", " "); Regex reg = new Regex("[^a-zA-Z0-9 é -]"); //string outputPath = Path.Combine(JsonSettingsManager.Settings.InjectionPath, gameName); string outputPath = Path.Combine(JsonSettingsManager.Settings.OutPath, $"[LOADIINE][{gameConsole}] {reg.Replace(gameName,"")} [{mvvm.prodcode}]"); mvvm.foldername = $"[LOADIINE][{gameConsole}] {reg.Replace(gameName, "")} [{mvvm.prodcode}]"; int i = 0; while (Directory.Exists(outputPath)) { outputPath = Path.Combine(JsonSettingsManager.Settings.OutPath, $"[LOADIINE][{gameConsole}] {reg.Replace(gameName, "")} [{mvvm.prodcode}]_{i}"); mvvm.foldername = $"[LOADIINE][{gameConsole}] {reg.Replace(gameName, "")} [{mvvm.prodcode}]_{i}"; i++; } DirectoryCopy(baseRomPath,outputPath, true); Custom_Message cm = new Custom_Message("Injection Complete", $"To Open the Location of the Inject press Open Folder.\nIf you want the inject to be put on your SD now, press Copy to SD.", JsonSettingsManager.Settings.OutPath); try { cm.Owner = mvvm.mw; }catch(Exception ) { } cm.ShowDialog(); Clean(); } [STAThread] public static void Packing(string gameName, string gameConsole, MainViewModel mvm) { mvm.msg = "Checking Tools..."; mvm.InjcttoolCheck(); mvm.Progress = 20; mvm.msg = "Creating Outputfolder..."; Regex reg = new Regex("[^a-zA-Z0-9 -]"); if (gameName == null || gameName == string.Empty) gameName = "NoName"; //string outputPath = Path.Combine(JsonSettingsManager.Settings.InjectionPath, gameName); string outputPath = Path.Combine(JsonSettingsManager.Settings.OutPath, $"[WUP][{gameConsole}] {reg.Replace(gameName,"").Replace("|", " ")}"); outputPath = outputPath.Replace("|", " "); mvvm.foldername = $"[WUP][{gameConsole}] {reg.Replace(gameName, "").Replace("|"," ")}"; int i = 0; while (Directory.Exists(outputPath)) { outputPath = Path.Combine(JsonSettingsManager.Settings.OutPath, $"[WUP][{gameConsole}] {reg.Replace(gameName,"").Replace("|", " ")}_{i}"); mvvm.foldername = $"[WUP][{gameConsole}] {reg.Replace(gameName, "").Replace("|", " ")}_{i}"; i++; } var oldpath = Directory.GetCurrentDirectory(); mvm.Progress = 40; mvm.msg = "Packing..."; try { Directory.Delete(Environment.GetEnvironmentVariable("LocalAppData") + @"\temp\.net\CNUSPACKER", true); } catch { } try { var cmdLine = $"-in \"{baseRomPath}\" -out \"{outputPath}\" -encryptKeyWith {JsonSettingsManager.Settings.Ckey}"; var regex = new Regex(@"(\"".+?\"")|(\S+)", RegexOptions.Compiled); var args = new List(); foreach (Match match in regex.Matches(cmdLine)) args.Add(match.Value.Trim('\"')); CNUSPACKER.Program.Main(args.ToArray()); Directory.SetCurrentDirectory(oldpath); } catch(Exception ex ) { Logger.Log(ex.Message); throw ex; } mvm.Progress = 90; mvm.msg = "Cleaning..."; Clean(); mvm.Progress = 100; mvm.msg = ""; } public static void Download(MainViewModel mvm) { var curdir = Directory.GetCurrentDirectory(); mvm.InjcttoolCheck(); GameBases b = mvm.getBasefromName(mvm.SelectedBaseAsString); //GetKeyOfBase TKeys key = mvm.getTkey(b); if (mvm.GameConfiguration.Console == GameConsoles.WII || mvm.GameConfiguration.Console == GameConsoles.GCN) { if (Directory.Exists(tempPath)) Directory.Delete(tempPath, true); Directory.CreateDirectory(tempPath); // Call the download method with progress reporting var downloader = new Downloader(null, null); downloader.DownloadAsync(new TitleData(b.Tid, key.Tkey), Path.Combine(tempPath, "download")).GetAwaiter().GetResult(); CSharpDecrypt.CSharpDecrypt.Decrypt(new string[] { JsonSettingsManager.Settings.Ckey, Path.Combine(tempPath, "download", b.Tid), Path.Combine(JsonSettingsManager.Settings.BasePath, $"{b.Name.Replace(":", "")} [{b.Region}]") }); mvm.Progress = 99; foreach (string sFile in Directory.GetFiles(Path.Combine(JsonSettingsManager.Settings.BasePath, $"{b.Name.Replace(":", "")} [{b.Region}]", "content"), "*.nfs")) File.Delete(sFile); mvm.Progress = 100; } else { if (Directory.Exists(tempPath)) Directory.Delete(tempPath, true); Directory.CreateDirectory(tempPath); // Call the download method with progress reporting var downloader = new Downloader(null, null); downloader.DownloadAsync(new TitleData(b.Tid, key.Tkey), Path.Combine(tempPath, "download")).GetAwaiter().GetResult(); mvm.Progress = 75; CSharpDecrypt.CSharpDecrypt.Decrypt(new string[] { JsonSettingsManager.Settings.Ckey, Path.Combine(tempPath, "download", b.Tid), Path.Combine(JsonSettingsManager.Settings.BasePath, $"{b.Name.Replace(":", "")} [{b.Region}]") }); mvm.Progress = 100; } Directory.SetCurrentDirectory(curdir); } public static string ExtractBase(string path, GameConsoles console) { if(!Directory.Exists(Path.Combine(JsonSettingsManager.Settings.BasePath, "CustomBases"))) Directory.CreateDirectory(Path.Combine(JsonSettingsManager.Settings.BasePath, "CustomBases")); string outputPath = Path.Combine(JsonSettingsManager.Settings.BasePath, "CustomBases", $"[{console}] Custom"); int i = 0; while (Directory.Exists(outputPath)) { outputPath = Path.Combine(JsonSettingsManager.Settings.BasePath, $"[{console}] Custom_{i}"); i++; } CSharpDecrypt.CSharpDecrypt.Decrypt(new string[] { JsonSettingsManager.Settings.Ckey, path, outputPath }); return outputPath; } // This function changes TitleID, ProductCode and GameName in app.xml (ID) and meta.xml (ID, ProductCode, Name) private static void EditXML(string gameNameOr, int index, string code) { string gameName = string.Empty; if(gameNameOr != null || !string.IsNullOrWhiteSpace(gameNameOr)) { gameName = gameNameOr; if (gameName.Contains('|')) { var split = gameName.Split('|'); gameName = split[0] + "," + split[1]; } } string metaXml = Path.Combine(baseRomPath, "meta", "meta.xml"); string appXml = Path.Combine(baseRomPath, "code", "app.xml"); Random random = new Random(); string ID = $"{random.Next(0x3000, 0x10000):X4}{random.Next(0x3000, 0x10000):X4}"; string ID2 = $"{random.Next(0x3000, 0x10000):X4}"; mvvm.prodcode = ID2; XmlDocument doc = new XmlDocument(); try { doc.Load(metaXml); if (gameName != null && gameName != string.Empty) { doc.SelectSingleNode("menu/longname_ja").InnerText = gameName.Replace(",", "\n" ); doc.SelectSingleNode("menu/longname_en").InnerText = gameName.Replace(",", "\n"); doc.SelectSingleNode("menu/longname_fr").InnerText = gameName.Replace(",", "\n"); doc.SelectSingleNode("menu/longname_de").InnerText = gameName.Replace(",", "\n"); doc.SelectSingleNode("menu/longname_it").InnerText = gameName.Replace(",", "\n"); doc.SelectSingleNode("menu/longname_es").InnerText = gameName.Replace(",", "\n"); doc.SelectSingleNode("menu/longname_zhs").InnerText = gameName.Replace(",", "\n"); doc.SelectSingleNode("menu/longname_ko").InnerText = gameName.Replace(",", "\n"); doc.SelectSingleNode("menu/longname_nl").InnerText = gameName.Replace(",", "\n"); doc.SelectSingleNode("menu/longname_pt").InnerText = gameName.Replace(",", "\n"); doc.SelectSingleNode("menu/longname_ru").InnerText = gameName.Replace(",", "\n"); doc.SelectSingleNode("menu/longname_zht").InnerText = gameName.Replace(",", "\n"); } /* if(code != null) { doc.SelectSingleNode("menu/product_code").InnerText = $"WUP-N-{code}"; } else {*/ doc.SelectSingleNode("menu/product_code").InnerText = $"WUP-N-{ID2}"; //} if (index > 0) { doc.SelectSingleNode("menu/drc_use").InnerText = "65537"; } doc.SelectSingleNode("menu/title_id").InnerText = $"00050002{ID}"; doc.SelectSingleNode("menu/group_id").InnerText = $"0000{ID2}"; if (gameName != null && gameName != string.Empty) { doc.SelectSingleNode("menu/shortname_ja").InnerText = gameName.Split(',')[0]; doc.SelectSingleNode("menu/shortname_fr").InnerText = gameName.Split(',')[0]; doc.SelectSingleNode("menu/shortname_de").InnerText = gameName.Split(',')[0]; doc.SelectSingleNode("menu/shortname_en").InnerText = gameName.Split(',')[0]; doc.SelectSingleNode("menu/shortname_it").InnerText = gameName.Split(',')[0]; doc.SelectSingleNode("menu/shortname_es").InnerText = gameName.Split(',')[0]; doc.SelectSingleNode("menu/shortname_zhs").InnerText = gameName.Split(',')[0]; doc.SelectSingleNode("menu/shortname_ko").InnerText = gameName.Split(',')[0]; doc.SelectSingleNode("menu/shortname_nl").InnerText = gameName.Split(',')[0]; doc.SelectSingleNode("menu/shortname_pt").InnerText = gameName.Split(',')[0]; doc.SelectSingleNode("menu/shortname_ru").InnerText = gameName.Split(',')[0]; doc.SelectSingleNode("menu/shortname_zht").InnerText = gameName.Split(',')[0]; } doc.Save(metaXml); } catch (NullReferenceException) { } try { doc.Load(appXml); doc.SelectSingleNode("app/title_id").InnerText = $"00050002{ID}"; //doc.SelectSingleNode("app/title_id").InnerText = $"0005000247414645"; doc.SelectSingleNode("app/group_id").InnerText = $"0000{ID2}"; doc.Save(appXml); } catch (NullReferenceException) { } } //This function copies the custom or normal Base to the working directory private static void CopyBase(string baserom, string customPath) { if (Directory.Exists(baseRomPath)) // sanity check Directory.Delete(baseRomPath, true); if (baserom == "Custom") DirectoryCopy(customPath, baseRomPath, true); else DirectoryCopy(Path.Combine(JsonSettingsManager.Settings.BasePath, baserom), baseRomPath, true); } private static void TG16(string injectRomPath) { //checking if folder if (Directory.Exists(injectRomPath)) { DirectoryCopy(injectRomPath, "test", true); //TurboGrafCD using (Process TurboInject = new Process()) { mvvm.msg = "Creating TurboCD Pkg..."; TurboInject.StartInfo.UseShellExecute = false; TurboInject.StartInfo.CreateNoWindow = true; TurboInject.StartInfo.FileName = Path.Combine(toolsPath, "BuildTurboCDPcePkg.exe"); TurboInject.StartInfo.Arguments = $"test"; TurboInject.Start(); TurboInject.WaitForExit(); mvvm.Progress = 70; } Directory.Delete("test", true); } else { //creating pkg file including the TG16 rom using Process TurboInject = new Process(); mvvm.msg = "Creating Turbo16 Pkg..."; TurboInject.StartInfo.UseShellExecute = false; TurboInject.StartInfo.CreateNoWindow = true; TurboInject.StartInfo.FileName = Path.Combine(toolsPath, "BuildPcePkg.exe"); TurboInject.StartInfo.Arguments = $"\"{injectRomPath}\""; TurboInject.Start(); TurboInject.WaitForExit(); mvvm.Progress = 70; } mvvm.msg = "Injecting ROM..."; //replacing tg16 rom File.Delete(Path.Combine(baseRomPath, "content", "pceemu", "pce.pkg")); File.Copy("pce.pkg", Path.Combine(baseRomPath, "content", "pceemu", "pce.pkg")); File.Delete("pce.pkg"); mvvm.Progress = 80; } private static void NESSNES(string injectRomPath) { string rpxFile = Directory.GetFiles(Path.Combine(baseRomPath, "code"), "*.rpx")[0]; //To get the RPX path where the NES/SNES rom needs to be Injected in mvvm.msg = "Decompressing RPX..."; RPXCompOrDecomp(rpxFile, false); //Decompresses the RPX to be able to write the game into it mvvm.Progress = 20; if (mvvm.pixelperfect) { using Process retroinject = new Process(); mvvm.msg = "Applying Pixel Perfect Patches..."; retroinject.StartInfo.UseShellExecute = false; retroinject.StartInfo.CreateNoWindow = true; retroinject.StartInfo.RedirectStandardOutput = true; retroinject.StartInfo.RedirectStandardError = true; retroinject.StartInfo.FileName = Path.Combine(toolsPath, "ChangeAspectRatio.exe"); retroinject.StartInfo.Arguments = $"\"{rpxFile}\""; retroinject.Start(); retroinject.WaitForExit(); mvvm.Progress = 30; } using (Process retroinject = new Process()) { mvvm.msg = "Injecting ROM..."; retroinject.StartInfo.UseShellExecute = false; retroinject.StartInfo.CreateNoWindow = true; retroinject.StartInfo.RedirectStandardOutput = true; retroinject.StartInfo.RedirectStandardError = true; retroinject.StartInfo.FileName = Path.Combine(toolsPath, "retroinject.exe"); retroinject.StartInfo.Arguments = $"\"{rpxFile}\" \"{injectRomPath}\" \"{rpxFile}\""; retroinject.Start(); retroinject.WaitForExit(); mvvm.Progress = 70; var s = retroinject.StandardOutput.ReadToEnd(); var e = retroinject.StandardError.ReadToEnd(); if (e.Contains("is too large") || s.Contains("is too large")) { mvvm.Progress = 100; throw new Exception("retro"); } } mvvm.msg = "Compressing RPX..."; RPXCompOrDecomp(rpxFile, true); //Compresses the RPX mvvm.Progress = 80; } private static void GBA(string injectRomPath, N64Conf config) { bool delete = false; if (!new FileInfo(injectRomPath).Extension.Contains("gba")) { mvvm.msg = "Injecting GB/GBC ROM into goomba..."; // Concatenate goomba.gba and the ROM into goombamenu.gba string goombaGbaPath = Path.Combine(toolsPath, "goomba.gba"); string goombaMenuPath = Path.Combine(toolsPath, "goombamenu.gba"); // Read both files and concatenate them using (FileStream output = new FileStream(goombaMenuPath, FileMode.Create)) { // Copy goomba.gba into goombamenu.gba using (FileStream goombaGbaStream = new FileStream(goombaGbaPath, FileMode.Open)) goombaGbaStream.CopyTo(output); // Append the injectRomPath (GB/GBC ROM) to goombamenu.gba using FileStream injectRomStream = new FileStream(injectRomPath, FileMode.Open); injectRomStream.CopyTo(output); } mvvm.Progress = 20; mvvm.msg = "Padding goomba ROM..."; // Padding to 32MB (33554432 bytes) byte[] rom = new byte[33554432]; FileStream fs = new FileStream(goombaMenuPath, FileMode.Open); fs.Read(rom, 0, (int)fs.Length); fs.Close(); // Write the padded ROM to goombaPadded.gba string goombaPaddedPath = Path.Combine(toolsPath, "goombaPadded.gba"); File.WriteAllBytes(goombaPaddedPath, rom); injectRomPath = goombaPaddedPath; // Set the injectRomPath to the padded ROM delete = true; mvvm.Progress = 40; } if (mvvm.PokePatch) { mvvm.msg = "Applying PokePatch"; File.Copy(injectRomPath, Path.Combine(tempPath, "rom.gba")); injectRomPath = Path.Combine(tempPath, "rom.gba"); PokePatch(injectRomPath); delete = true; mvvm.PokePatch = false; mvvm.Progress = 50; } using (Process psb = new Process()) { mvvm.msg = "Injecting ROM..."; psb.StartInfo.UseShellExecute = false; psb.StartInfo.CreateNoWindow = true; psb.StartInfo.FileName = Path.Combine(toolsPath, "psb.exe"); psb.StartInfo.Arguments = $"\"{Path.Combine(baseRomPath, "content", "alldata.psb.m")}\" \"{injectRomPath}\" \"{Path.Combine(baseRomPath, "content", "alldata.psb.m")}\""; //psb.StartInfo.RedirectStandardError = true; //psb.StartInfo.RedirectStandardOutput = true; psb.Start(); //var error = psb.StandardError.ReadToEndAsync(); //var output = psb.StandardOutput.ReadToEndAsync(); psb.WaitForExit(); //if (!string.IsNullOrEmpty(error.Result)) //throw new Exception(error.Result + "\nFile:" + new StackFrame(0, true).GetFileName() + "\nLine: " + new StackFrame(0, true).GetFileLineNumber()); mvvm.Progress = 50; } if (config.DarkFilter == false) { var mArchiveExePath = Path.Combine(toolsPath, "MArchiveBatchTool.exe"); var allDataPath = Path.Combine(baseRomPath, "content", "alldata.psb.m"); // Step 1: Extract all data (longer wait time) RunProcess(mArchiveExePath, $"archive extract \"{allDataPath}\" --codec zlib --seed MX8wgGEJ2+M47 --keyLength 80", true); mvvm.Progress += 5; var lastModDirect = new DirectoryInfo(Path.Combine(baseRomPath, "content", "alldata.psb.m_extracted")) .GetDirectories() .OrderByDescending(d => d.LastWriteTimeUtc) .LastOrDefault(); var titleprofPsbM = Path.Combine(lastModDirect.FullName, "config", "title_prof.psb.m"); // Step 2: Unpack title_prof.psb.m RunProcess(mArchiveExePath, $"m unpack \"{titleprofPsbM}\" zlib MX8wgGEJ2+M47 80", true); mvvm.Progress += 5; var titleprofPsb = Path.Combine(lastModDirect.FullName, "config", "title_prof.psb"); // Step 3: Deserialize title_prof.psb RunProcess(mArchiveExePath, $"psb deserialize \"{titleprofPsb}\"", true); mvvm.Progress += 5; var titleprofPsbJson = Path.Combine(lastModDirect.FullName, "config", "title_prof.psb.json"); var titleprofPsbJson_Modified = Path.Combine(lastModDirect.FullName, "config", "modified_title_prof.psb.json"); // Step 4: Modify the JSON using (StreamReader sr = File.OpenText(titleprofPsbJson)) { var json = sr.ReadToEnd(); dynamic jsonObj = JsonConvert.DeserializeObject(json); jsonObj["root"]["m2epi"]["brightness"] = 1; json = JsonConvert.SerializeObject(jsonObj, Newtonsoft.Json.Formatting.Indented); File.WriteAllText(titleprofPsbJson_Modified, json); sr.Close(); } File.Delete(titleprofPsbJson); File.Move(titleprofPsbJson_Modified, titleprofPsbJson); // Step 5: Serialize the JSON back to PSB RunProcess(mArchiveExePath, $"psb serialize \"{titleprofPsbJson}\"", true); mvvm.Progress += 5; // Step 6: Pack the modified PSB back to a file RunProcess(mArchiveExePath, $"m pack \"{titleprofPsb}\" zlib MX8wgGEJ2+M47 80", true); mvvm.Progress += 5; File.Delete(titleprofPsbJson); // Step 7: Rebuild the archive (longer wait time) RunProcess(mArchiveExePath, $"archive build --codec zlib --seed MX8wgGEJ2+M47 --keyLength 80 \"{Path.Combine(baseRomPath, "content", "alldata.psb.m_extracted")}\" \"{Path.Combine(baseRomPath, "content", "alldata")}\"", true); mvvm.Progress += 15; // Clean up extracted data Directory.Delete(Path.Combine(baseRomPath, "content", "alldata.psb.m_extracted"), true); File.Delete(Path.Combine(baseRomPath, "content", "alldata.psb")); } if (delete) { File.Delete(injectRomPath); if (File.Exists(Path.Combine(toolsPath, "goombamenu.gba"))) File.Delete(Path.Combine(toolsPath, "goombamenu.gba")); } } // Stupid me complaining, function to create and run the process private static void RunProcess(string fileName, string arguments, bool indefiniteWait = false, int waitTime = 3000) { using var process = new Process(); var startInfo = new ProcessStartInfo { UseShellExecute = false, CreateNoWindow = true, Arguments = arguments, FileName = fileName }; process.StartInfo = startInfo; process.Start(); if (indefiniteWait) process.WaitForExit(); else process.WaitForExit(waitTime); } private static void NDS(string injectRomPath) { try { string romName = GetRomNameFromZip(); mvvm.msg = "Removing BaseRom..."; ReplaceRomWithInjected(romName, injectRomPath); if (mvvm.DSLayout) { mvvm.msg = "Adding additional DS layout screens..."; using (var zip = ZipFile.Open(Path.Combine(toolsPath, "DSLayoutScreens.zip"), ZipArchiveMode.Read)) zip.ExtractToDirectory(Path.Combine(tempPath, "DSLayoutScreens")); // Yes this is a typo but it's becuase I fucked up when I uploaded the original file. DirectoryCopy(Path.Combine(tempPath, "DSLayoutScreens", (mvvm.STLayout ? "Phatnom Hourglass" : "All")), baseRomPath, true); } if (mvvm.RendererScale || mvvm.Brightness != 80 || mvvm.PixelArtUpscaler != 0) { mvvm.msg = "Updating configuration_cafe.json..."; UpdateConfigurationCafeJson(); } RecompressRom(romName); mvvm.Progress = 80; } catch (Exception ex) { // Log the error Console.WriteLine($"An error occurred in NDS method: {ex.Message}"); throw; } } private static void UpdateConfigurationCafeJson() { var configurationCafe = Path.Combine(baseRomPath, "content", "0010", "configuration_cafe.json"); // Load the JSON file string jsonContent = File.ReadAllText(configurationCafe); // Parse the JSON content var jsonObject = JObject.Parse(jsonContent); // Update the values jsonObject["configuration"]["3DRendering"]["RenderScale"] = (mvvm.RendererScale ? 0 : 1); jsonObject["configuration"]["Display"]["Brightness"] = mvvm.Brightness; jsonObject["configuration"]["Display"]["PixelArtUpscaler"] = mvvm.PixelArtUpscaler; // Write the updated JSON back to the file File.WriteAllText(configurationCafe, jsonObject.ToString()); } private static string GetRomNameFromZip() { mvvm.msg = "Getting BaseRom Name..."; string zipLocation = Path.Combine(baseRomPath, "content", "0010", "rom.zip"); string romName = string.Empty; using (var zip = ZipFile.Open(zipLocation, ZipArchiveMode.Read)) { var entry = zip.Entries.FirstOrDefault(file => file.Name.Contains("WUP")); if (entry != null) romName = entry.Name; } mvvm.Progress = 15; if (string.IsNullOrEmpty(romName)) throw new InvalidOperationException("ROM name not found in the zip archive."); return romName; } private static void ReplaceRomWithInjected(string romName, string injectRomPath) { string romPath = Path.Combine(Directory.GetCurrentDirectory(), romName); if (File.Exists(romPath)) File.Delete(romPath); string zipLocation = Path.Combine(baseRomPath, "content", "0010", "rom.zip"); if (File.Exists(zipLocation)) File.Delete(zipLocation); File.Copy(injectRomPath, romPath); } private static void RecompressRom(string romName) { string zipLocation = Path.Combine(baseRomPath, "content", "0010", "rom.zip"); string romPath = Path.Combine(Directory.GetCurrentDirectory(), romName); using (var stream = new FileStream(zipLocation, FileMode.Create)) using (var archive = new ZipArchive(stream, ZipArchiveMode.Create)) archive.CreateEntryFromFile(romPath, Path.GetFileName(romPath)); File.Delete(romPath); } private static void N64(string injectRomPath, N64Conf config) { try { InjectRom(injectRomPath); if (config.WideScreen || config.DarkFilter) ApplyCustomSettings(config); ApplyIniSettings(config); mvvm.Progress = 80; } catch (Exception ex) { // Log the error Console.WriteLine($"An error occurred in N64 method: {ex.Message}"); throw; } } private static void InjectRom(string injectRomPath) { string mainRomPath = Directory.GetFiles(Path.Combine(baseRomPath, "content", "rom"))[0]; using Process n64convert = new Process(); mvvm.msg = "Injecting ROM..."; n64convert.StartInfo.UseShellExecute = false; n64convert.StartInfo.CreateNoWindow = true; n64convert.StartInfo.FileName = Path.Combine(toolsPath, "N64Converter.exe"); n64convert.StartInfo.Arguments = $"\"{injectRomPath}\" \"{mainRomPath}\""; n64convert.Start(); n64convert.WaitForExit(); mvvm.Progress = 60; } private static void ApplyCustomSettings(N64Conf config) { string frameLayoutPath = Path.Combine(baseRomPath, "content", "FrameLayout.arc"); using (var fileStream = File.Open(frameLayoutPath, FileMode.Open)) { // I would love to modularize this code, but idfk how it works exactly uint offset = 0; uint size = 0; byte[] offsetB = new byte[4]; byte[] sizeB = new byte[4]; byte[] nameB = new byte[0x18]; var header = new byte[4]; byte[] oneOut = BitConverter.GetBytes((float)1); byte[] zeroOut = BitConverter.GetBytes((float)0); byte darkFilter = (byte)(config.DarkFilter ? 0 : 1); byte[] wideScreen = config.WideScreen ? new byte[] { 0x44, 0xF0, 0, 0 } : new byte[] { 0x44, 0xB4, 0, 0 }; fileStream.Read(header, 0, 4); if (header.SequenceEqual(new byte[] { (byte)'S', (byte)'A', (byte)'R', (byte)'C' })) { fileStream.Position = 0x0C; fileStream.Read(offsetB, 0, 4); offset = BitConverter.ToUInt32(offsetB.Reverse().ToArray(), 0); fileStream.Position = 0x38; fileStream.Read(offsetB, 0, 4); offset += BitConverter.ToUInt32(offsetB.Reverse().ToArray(), 0); fileStream.Position = offset; fileStream.Read(header, 0, 4); if (header.SequenceEqual(new byte[] { (byte)'F', (byte)'L', (byte)'Y', (byte)'T' })) { fileStream.Position = offset + 0x04; fileStream.Read(offsetB, 0, 4); offset += BitConverter.ToUInt32(offsetB.Skip(2).Reverse().ToArray(), 0); fileStream.Position = offset; while (offset < fileStream.Length) { fileStream.Read(header, 0, 4); fileStream.Read(sizeB, 0, 4); size = BitConverter.ToUInt32(sizeB.Reverse().ToArray(), 0); fileStream.Read(nameB, 0, 0x18); string name = Encoding.ASCII.GetString(nameB.TakeWhile(b => b != 0).ToArray()); if (name == "frame") WriteFrameData(fileStream, offset, zeroOut, oneOut, wideScreen); else if (name == "frame_mask") WriteDarkFilterData(fileStream, offset, darkFilter); else if (name == "power_save_bg") break; // End the loop as the required modifications are done offset += size; fileStream.Position = offset; } } } } mvvm.Progress = 70; } private static void WriteFrameData(FileStream fileStream, uint offset, byte[] zeroOut, byte[] oneOut, byte[] wideScreen) { fileStream.Position = offset + 0x2C; fileStream.Write(zeroOut, 0, zeroOut.Length); fileStream.Position = offset + 0x30; // TranslationX fileStream.Write(zeroOut, 0, zeroOut.Length); fileStream.Position = offset + 0x44; // ScaleX fileStream.Write(oneOut, 0, oneOut.Length); fileStream.Position = offset + 0x48; // ScaleY fileStream.Write(oneOut, 0, oneOut.Length); fileStream.Position = offset + 0x4C; // Widescreen fileStream.Write(wideScreen, 0, wideScreen.Length); } private static void WriteDarkFilterData(FileStream fileStream, uint offset, byte darkFilter) { fileStream.Position = offset + 0x08; // Dark filter fileStream.WriteByte(darkFilter); } private static void ApplyIniSettings(N64Conf config) { mvvm.msg = "Copying INI..."; string mainRomPath = Directory.GetFiles(Path.Combine(baseRomPath, "content", "rom"))[0]; string mainIni = Path.Combine(baseRomPath, "content", "config", $"{Path.GetFileName(mainRomPath)}.ini"); if (config.INIBin == null) { if (config.INIPath == null) { File.Delete(mainIni); File.Copy(Path.Combine(toolsPath, "blank.ini"), mainIni); } else { File.Delete(mainIni); File.Copy(config.INIPath, mainIni); } } else { ReadFileFromBin(config.INIBin, "custom.ini"); File.Delete(mainIni); File.Move("custom.ini", mainIni); } } private static void RPXCompOrDecomp(string rpxpath, bool comp) { var prefix = comp ? "-c" : "-d"; using Process rpxtool = new Process(); rpxtool.StartInfo.UseShellExecute = false; rpxtool.StartInfo.CreateNoWindow = true; rpxtool.StartInfo.FileName = Path.Combine(toolsPath, "wiiurpxtool.exe"); rpxtool.StartInfo.Arguments = $"{prefix} \"{rpxpath}\""; rpxtool.Start(); rpxtool.WaitForExit(); } private static void ReadFileFromBin(byte[] bin, string output) { File.WriteAllBytes(output, bin); } private static void Images(GameConfig config) { bool usetemp = false; bool readbin = false; try { //is an image embedded? yes => export them and check for issues //no => using path if (Directory.Exists(imgPath)) // sanity check Directory.Delete(imgPath, true); Directory.CreateDirectory(imgPath); //ICON List Images = new List(); if (config.TGAIco.ImgBin == null) { //use path if (config.TGAIco.ImgPath != null) { Images.Add(true); CopyAndConvertImage(config.TGAIco.ImgPath, Path.Combine(imgPath), false, 128, 128, 32, "iconTex.tga"); } else { if (File.Exists(Path.Combine(toolsPath, "iconTex.tga"))) { CopyAndConvertImage(Path.Combine(toolsPath, "iconTex.tga"), Path.Combine(imgPath), false, 128, 128, 32, "iconTex.tga"); Images.Add(true); } else Images.Add(false); } } else { ReadFileFromBin(config.TGAIco.ImgBin, $"iconTex.{config.TGAIco.extension}"); CopyAndConvertImage($"iconTex.{config.TGAIco.extension}", Path.Combine(imgPath), true, 128, 128, 32, "iconTex.tga"); Images.Add(true); } if (config.TGATv.ImgBin == null) { //use path if (config.TGATv.ImgPath != null) { Images.Add(true); CopyAndConvertImage(config.TGATv.ImgPath, Path.Combine(imgPath), false, 1280, 720, 24, "bootTvTex.tga"); config.TGATv.ImgPath = Path.Combine(imgPath, "bootTvTex.tga"); } else { if (File.Exists(Path.Combine(toolsPath, "bootTvTex.png"))) { CopyAndConvertImage(Path.Combine(toolsPath, "bootTvTex.png"), Path.Combine(imgPath), false, 1280, 720, 24, "bootTvTex.tga"); usetemp = true; Images.Add(true); } else { Images.Add(false); } } } else { ReadFileFromBin(config.TGATv.ImgBin, $"bootTvTex.{config.TGATv.extension}"); CopyAndConvertImage($"bootTvTex.{config.TGATv.extension}", Path.Combine(imgPath), true, 1280, 720, 24, "bootTvTex.tga"); config.TGATv.ImgPath = Path.Combine(imgPath, "bootTvTex.tga"); Images.Add(true); readbin = true; } //Drc if (config.TGADrc.ImgBin == null) { //use path if (config.TGADrc.ImgPath != null) { Images.Add(true); CopyAndConvertImage(config.TGADrc.ImgPath, Path.Combine(imgPath), false, 854, 480, 24, "bootDrcTex.tga"); } else { if (Images[1]) { using Process conv = new Process(); if (!mvvm.debug) { conv.StartInfo.UseShellExecute = false; conv.StartInfo.CreateNoWindow = true; } if (usetemp) File.Copy(Path.Combine(toolsPath, "bootTvTex.png"), Path.Combine(tempPath, "bootDrcTex.png")); else { conv.StartInfo.FileName = Path.Combine(toolsPath, "tga2png.exe"); if (!readbin) conv.StartInfo.Arguments = $"-i \"{config.TGATv.ImgPath}\" -o \"{Path.Combine(tempPath)}\""; else { if (config.TGATv.extension.Contains("tga")) { ReadFileFromBin(config.TGATv.ImgBin, $"bootTvTex.{config.TGATv.extension}"); conv.StartInfo.Arguments = $"-i \"bootTvTex.{config.TGATv.extension}\" -o \"{Path.Combine(tempPath)}\""; } else ReadFileFromBin(config.TGATv.ImgBin, Path.Combine(tempPath, "bootTvTex.png")); } if (!readbin || config.TGATv.extension.Contains("tga")) { conv.Start(); conv.WaitForExit(); } File.Copy(Path.Combine(tempPath, "bootTvTex.png"), Path.Combine(tempPath, "bootDrcTex.png")); if (File.Exists(Path.Combine(tempPath, "bootTvTex.png"))) File.Delete(Path.Combine(tempPath, "bootTvTex.png")); if (File.Exists($"bootTvTex.{config.TGATv.extension}")) File.Delete($"bootTvTex.{config.TGATv.extension}"); } CopyAndConvertImage(Path.Combine(tempPath, "bootDrcTex.png"), Path.Combine(imgPath), false, 854, 480, 24, "bootDrcTex.tga"); Images.Add(true); } else Images.Add(false); } } else { ReadFileFromBin(config.TGADrc.ImgBin, $"bootDrcTex.{config.TGADrc.extension}"); CopyAndConvertImage($"bootDrcTex.{config.TGADrc.extension}", Path.Combine(imgPath), true, 854, 480, 24, "bootDrcTex.tga"); Images.Add(true); } //tv //logo if (config.TGALog.ImgBin == null) //use path if (config.TGALog.ImgPath != null) { Images.Add(true); CopyAndConvertImage(config.TGALog.ImgPath, Path.Combine(imgPath), false, 170, 42, 32, "bootLogoTex.tga"); } else Images.Add(false); else { ReadFileFromBin(config.TGALog.ImgBin, $"bootLogoTex.{config.TGALog.extension}"); CopyAndConvertImage($"bootLogoTex.{config.TGALog.extension}", Path.Combine(imgPath), true, 170, 42, 32, "bootLogoTex.tga"); Images.Add(true); } //Fixing Images + Injecting them if (Images[0] || Images[1] || Images[2] || Images[3]) { using (Process checkIfIssue = new Process()) { checkIfIssue.StartInfo.UseShellExecute = false; checkIfIssue.StartInfo.CreateNoWindow = false; checkIfIssue.StartInfo.RedirectStandardOutput = true; checkIfIssue.StartInfo.RedirectStandardError = true; checkIfIssue.StartInfo.FileName = $"{Path.Combine(toolsPath, "tga_verify.exe")}"; Console.WriteLine(Directory.GetCurrentDirectory()); checkIfIssue.StartInfo.Arguments = $"\"{imgPath}\""; checkIfIssue.Start(); checkIfIssue.WaitForExit(); var s = checkIfIssue.StandardOutput.ReadToEnd(); if (s.Contains("width") || s.Contains("height") || s.Contains("depth")) throw new Exception("Size"); var e = checkIfIssue.StandardError.ReadToEnd(); if (e.Contains("width") || e.Contains("height") || e.Contains("depth")) throw new Exception("Size"); if (e.Contains("TRUEVISION") || s.Contains("TRUEVISION")) { checkIfIssue.StartInfo.UseShellExecute = false; checkIfIssue.StartInfo.CreateNoWindow = false; checkIfIssue.StartInfo.RedirectStandardOutput = true; checkIfIssue.StartInfo.RedirectStandardError = true; checkIfIssue.StartInfo.FileName = $"{Path.Combine(toolsPath, "tga_verify.exe")}"; Console.WriteLine(Directory.GetCurrentDirectory()); checkIfIssue.StartInfo.Arguments = $"--fixup \"{imgPath}\""; checkIfIssue.Start(); checkIfIssue.WaitForExit(); } // Console.ReadLine(); } if (Images[1]) { File.Delete(Path.Combine(baseRomPath, "meta", "bootTvTex.tga")); File.Move(Path.Combine(imgPath, "bootTvTex.tga"), Path.Combine(baseRomPath, "meta", "bootTvTex.tga")); } if (Images[2]) { File.Delete(Path.Combine(baseRomPath, "meta", "bootDrcTex.tga")); File.Move(Path.Combine(imgPath, "bootDrcTex.tga"), Path.Combine(baseRomPath, "meta", "bootDrcTex.tga")); } if (Images[0]) { File.Delete(Path.Combine(baseRomPath, "meta", "iconTex.tga")); File.Move(Path.Combine(imgPath, "iconTex.tga"), Path.Combine(baseRomPath, "meta", "iconTex.tga")); } if (Images[3]) { File.Delete(Path.Combine(baseRomPath, "meta", "bootLogoTex.tga")); File.Move(Path.Combine(imgPath, "bootLogoTex.tga"), Path.Combine(baseRomPath, "meta", "bootLogoTex.tga")); } } } catch (Exception e) { Logger.Log(e.Message); if (e.Message.Contains("Size")) throw e; throw new Exception("Images"); } } private static void PrepareImageDirectory() { if (Directory.Exists(imgPath)) Directory.Delete(imgPath, true); Directory.CreateDirectory(imgPath); } private static bool HandleImage(PNGTGA imgConfig, string fileName, string outputDir, int width, int height, int bitDepth) { if (imgConfig.ImgBin == null) { if (!string.IsNullOrEmpty(imgConfig.ImgPath)) { CopyAndConvertImage(imgConfig.ImgPath, outputDir, false, width, height, bitDepth, $"{fileName}.tga"); return true; } else if (File.Exists(Path.Combine(toolsPath, $"{fileName}.tga"))) { CopyAndConvertImage(Path.Combine(toolsPath, $"{fileName}.tga"), outputDir, false, width, height, bitDepth, $"{fileName}.tga"); return true; } } else { ReadFileFromBin(imgConfig.ImgBin, $"{fileName}.{imgConfig.extension}"); CopyAndConvertImage($"{fileName}.{imgConfig.extension}", outputDir, true, width, height, bitDepth, $"{fileName}.tga"); return true; } // When tf would this ever return false? return false; } private static bool HandleDrcImage(GameConfig config, bool hasTvImage) { if (config.TGADrc.ImgBin == null) { if (!string.IsNullOrEmpty(config.TGADrc.ImgPath)) { CopyAndConvertImage(config.TGADrc.ImgPath, imgPath, false, 854, 480, 24, "bootDrcTex.tga"); return true; } else if (hasTvImage) { ConvertTvImageToDrc(config); return true; } } else { ReadFileFromBin(config.TGADrc.ImgBin, $"bootDrcTex.{config.TGADrc.extension}"); CopyAndConvertImage($"bootDrcTex.{config.TGADrc.extension}", imgPath, true, 854, 480, 24, "bootDrcTex.tga"); return true; } return false; } private static void ConvertTvImageToDrc(GameConfig config) { string tempFilePath = Path.Combine(tempPath, "bootDrcTex.png"); if (config.TGATv.extension.Contains("tga")) using (var process = new Process()) { if (!mvvm.debug) { process.StartInfo.UseShellExecute = false; process.StartInfo.CreateNoWindow = true; } ReadFileFromBin(config.TGATv.ImgBin, $"bootTvTex.{config.TGATv.extension}"); process.StartInfo.Arguments = $"-i \"bootTvTex.{config.TGATv.extension}\" -o \"{tempFilePath}\""; process.Start(); process.WaitForExit(); } else ReadFileFromBin(config.TGATv.ImgBin, Path.Combine(tempPath, "bootTvTex.png")); CopyAndConvertImage(tempFilePath, imgPath, false, 854, 480, 24, "bootDrcTex.tga"); } private static void VerifyAndInjectImages(bool hasIconImage, bool hasTvImage, bool hasDrcImage, bool hasLogoImage) { using (Process checkIfIssue = new Process()) { checkIfIssue.StartInfo.UseShellExecute = false; checkIfIssue.StartInfo.CreateNoWindow = true; checkIfIssue.StartInfo.RedirectStandardOutput = true; checkIfIssue.StartInfo.RedirectStandardError = true; checkIfIssue.StartInfo.FileName = $"{Path.Combine(toolsPath, "tga_verify.exe")}"; checkIfIssue.StartInfo.Arguments = $"\"{imgPath}\""; checkIfIssue.Start(); checkIfIssue.WaitForExit(); string output = checkIfIssue.StandardOutput.ReadToEnd(); string error = checkIfIssue.StandardError.ReadToEnd(); if (output.Contains("width") || output.Contains("height") || output.Contains("depth") || error.Contains("width") || error.Contains("height") || error.Contains("depth")) { throw new Exception("Size"); } if (output.Contains("TRUEVISION") || error.Contains("TRUEVISION")) { checkIfIssue.StartInfo.Arguments = $"--fixup \"{imgPath}\""; checkIfIssue.Start(); checkIfIssue.WaitForExit(); } } MoveProcessedImages(hasIconImage, hasTvImage, hasDrcImage, hasLogoImage); } private static void MoveProcessedImages(bool hasIconImage, bool hasTvImage, bool hasDrcImage, bool hasLogoImage) { if (hasTvImage) { string destPath = Path.Combine(baseRomPath, "meta", "bootTvTex.tga"); if (File.Exists(destPath)) File.Delete(destPath); File.Move(Path.Combine(imgPath, "bootTvTex.tga"), destPath); } if (hasDrcImage) { string destPath = Path.Combine(baseRomPath, "meta", "bootDrcTex.tga"); if (File.Exists(destPath)) File.Delete(destPath); File.Move(Path.Combine(imgPath, "bootDrcTex.tga"), destPath); } if (hasIconImage) { string destPath = Path.Combine(baseRomPath, "meta", "iconTex.tga"); if (File.Exists(destPath)) File.Delete(destPath); File.Move(Path.Combine(imgPath, "iconTex.tga"), destPath); } if (hasLogoImage) { string destPath = Path.Combine(baseRomPath, "meta", "bootLogoTex.tga"); if (File.Exists(destPath)) File.Delete(destPath); File.Move(Path.Combine(imgPath, "bootLogoTex.tga"), destPath); } } private static void CopyAndConvertImage(string inputPath, string outputPath, bool delete, int widht, int height, int bit, string newname) { if (inputPath.EndsWith(".tga")) File.Copy(inputPath, Path.Combine(outputPath,newname)); else { using (Process png2tga = new Process()) { png2tga.StartInfo.UseShellExecute = false; png2tga.StartInfo.CreateNoWindow = true; var extension = new FileInfo(inputPath).Extension; if (extension.Contains("png")) png2tga.StartInfo.FileName = Path.Combine(toolsPath, "png2tga.exe"); else if (extension.Contains("jpg") || extension.Contains("jpeg")) png2tga.StartInfo.FileName = Path.Combine(toolsPath, "jpg2tga.exe"); else if (extension.Contains("bmp")) png2tga.StartInfo.FileName = Path.Combine(toolsPath, "bmp2tga.exe"); png2tga.StartInfo.Arguments = $"-i \"{inputPath}\" -o \"{outputPath}\" --width={widht} --height={height} --tga-bpp={bit} --tga-compression=none"; png2tga.Start(); png2tga.WaitForExit(); } string name = Path.GetFileNameWithoutExtension(inputPath); if(File.Exists(Path.Combine(outputPath , name + ".tga"))) File.Move(Path.Combine(outputPath, name + ".tga"), Path.Combine(outputPath, newname)); } if (delete) File.Delete(inputPath); } private static string RemoveHeader(string filePath) { // logic taken from snesROMUtil using FileStream inStream = new FileStream(filePath, FileMode.Open); byte[] header = new byte[512]; inStream.Read(header, 0, 512); string string1 = BitConverter.ToString(header, 8, 3); string string2 = Encoding.ASCII.GetString(header, 0, 11); string string3 = BitConverter.ToString(header, 30, 16); if (string1 != "AA-BB-04" && string2 != "GAME DOCTOR" && string3 != "00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00") return filePath; string newFilePath = Path.Combine(tempPath, Path.GetFileName(filePath)); using (FileStream outStream = new FileStream(newFilePath, FileMode.OpenOrCreate)) { inStream.CopyTo(outStream); } return newFilePath; } public static void DirectoryCopy(string sourceDirName, string destDirName, bool copySubDirs) { // Get the subdirectories for the specified directory. DirectoryInfo dir = new DirectoryInfo(sourceDirName); if (!dir.Exists) { Logger.Log($"Source directory does not exist or could not be found: {sourceDirName}"); throw new DirectoryNotFoundException($"Source directory does not exist or could not be found: {sourceDirName}"); } // If the destination directory doesn't exist, create it. if (!Directory.Exists(destDirName)) Directory.CreateDirectory(destDirName); // Get the files in the directory and copy them to the new location. foreach (FileInfo file in dir.EnumerateFiles()) file.CopyTo(Path.Combine(destDirName, file.Name), true); // If copying subdirectories, copy them and their contents to new location. if (copySubDirs) foreach (DirectoryInfo subdir in dir.EnumerateDirectories()) DirectoryCopy(subdir.FullName, Path.Combine(destDirName, subdir.Name), copySubDirs); } } } ================================================ FILE: UWUVCI AIO WPF/Classes/KeyFile.cs ================================================ using GameBaseClassLibrary; using System; using System.Collections.Generic; using System.IO; using System.IO.Compression; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; using UWUVCI_AIO_WPF.Models; namespace UWUVCI_AIO_WPF.Classes { class KeyFile { public static List ReadBasesFromKeyFile(string keyPath) { List result = new List(); try { FileInfo fileInfo = new FileInfo(keyPath); if (fileInfo.Extension.Contains("vck")) { using (FileStream inputConfigStream = new FileStream(keyPath, FileMode.Open, FileAccess.Read)) using (GZipStream decompressedConfigStream = new GZipStream(inputConfigStream, CompressionMode.Decompress)) { IFormatter formatter = new BinaryFormatter(); result = (List)formatter.Deserialize(decompressedConfigStream); } } } catch (Exception ex) { // Handle or log the error appropriately Console.WriteLine($"An error occurred while reading the key file: {ex.Message}"); } return result; } public static void ExportFile(List keys, GameConsoles console) { try { string folderPath = Path.Combine("bin", "keys"); CheckAndFixFolder(folderPath); string filePath = Path.Combine(folderPath, $"{console.ToString().ToLower()}.vck"); using (FileStream createConfigStream = new FileStream(filePath, FileMode.Create, FileAccess.Write)) using (GZipStream compressedStream = new GZipStream(createConfigStream, CompressionMode.Compress)) { IFormatter formatter = new BinaryFormatter(); formatter.Serialize(compressedStream, keys); } } catch (Exception ex) { // Handle or log the error appropriately Console.WriteLine($"An error occurred while exporting the key file: {ex.Message}"); } } private static void CheckAndFixFolder(string folderPath) { if (!Directory.Exists(folderPath)) Directory.CreateDirectory(folderPath); } } } ================================================ FILE: UWUVCI AIO WPF/Classes/MenuIconImage - Kopieren.cs ================================================ using System; using System.Drawing; using System.Drawing.Drawing2D; using System.Windows.Forms; using System.Drawing.Text; namespace UWUVCI_AIO_WPF.Classes { public class BootLogoImage : IDisposable { private bool disposed = false; private Bitmap _frame; private Bitmap _titleScreen; private static readonly string FontPath = @"bin\Tools\font2.ttf"; private static readonly PrivateFontCollection PrivateFonts = new PrivateFontCollection(); static BootLogoImage() { PrivateFonts.AddFontFile(FontPath); } public Bitmap Frame { get => _frame; set { _frame?.Dispose(); _frame = value; } } public Bitmap TitleScreen { get => _titleScreen; set { _titleScreen?.Dispose(); _titleScreen = value; } } public BootLogoImage() { _frame = null; _titleScreen = null; } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (!disposed) { if (disposing) { _frame?.Dispose(); _titleScreen?.Dispose(); } disposed = true; } } public Bitmap Create(string text, float fontsize) { Bitmap img = new Bitmap(170, 42); using (Graphics g = Graphics.FromImage(img)) { StringFormat format1 = new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center }; g.PixelOffsetMode = PixelOffsetMode.Half; g.SmoothingMode = SmoothingMode.AntiAlias; g.CompositingMode = CompositingMode.SourceOver; g.CompositingQuality = CompositingQuality.HighQuality; g.Clear(Color.FromArgb(30, 30, 30)); g.DrawImage(Frame, 0, 0, 170, 42); Rectangle rectangletxt = new Rectangle(18, 5, 134, 32); Font font = new Font(PrivateFonts.Families[0], fontsize, FontStyle.Bold, GraphicsUnit.Pixel); TextRenderer.DrawText(g, text, font, rectangletxt, Color.FromArgb(180, 180, 180), Color.White, TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter | TextFormatFlags.GlyphOverhangPadding); } return img; } } } ================================================ FILE: UWUVCI AIO WPF/Classes/MenuIconImage.cs ================================================ using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Drawing2D; namespace UWUVCI_AIO_WPF.Classes { public class MenuIconImage : IDisposable { private bool disposed = false; private Bitmap _frame; private Bitmap _titleScreen; private static readonly Dictionary ConsoleRectangles = new Dictionary { { "GBA", new Rectangle(3, 17, 122, 81) }, { "H4V3", new Rectangle(3, 9, 122, 92) }, { "WII", new Rectangle(0, 23, 128, 94) } }; public Bitmap Frame { get => _frame; set { _frame?.Dispose(); _frame = value; } } public Bitmap TitleScreen { get => _titleScreen; set { _titleScreen?.Dispose(); _titleScreen = value; } } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (disposed) return; if (disposing) { _frame?.Dispose(); _titleScreen?.Dispose(); } disposed = true; } public Bitmap Create(string console) { Bitmap img = new Bitmap(128, 128); using (Graphics g = Graphics.FromImage(img)) { g.PixelOffsetMode = PixelOffsetMode.Half; g.SmoothingMode = SmoothingMode.AntiAlias; g.CompositingMode = CompositingMode.SourceOver; g.CompositingQuality = CompositingQuality.HighQuality; g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; g.Clear(Color.FromArgb(30, 30, 30)); Rectangle rectangle = ConsoleRectangles.ContainsKey(console) ? ConsoleRectangles[console] : ConsoleRectangles["H4V3"]; if (TitleScreen != null) g.DrawImage(TitleScreen, rectangle); else g.FillRectangle(Brushes.Black, rectangle); if (Frame == null) { using (GraphicsPath vc = new GraphicsPath()) { Font font = new Font("Arial", 10.0F, FontStyle.Regular, GraphicsUnit.Point); StringFormat format = new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center }; vc.AddString("Virtual Console", font.FontFamily, (int)(FontStyle.Bold | FontStyle.Italic), g.DpiY * 9.2F / 72.0F, new Rectangle(0, 101, 128, 27), format); g.DrawPath(Pens.Black, vc); g.FillPath(new SolidBrush(Color.FromArgb(147, 149, 152)), vc); } } else { g.DrawImage(Frame, new Rectangle(0, 0, 128, 128)); } } return img; } } } ================================================ FILE: UWUVCI AIO WPF/Classes/ToolCheck.cs ================================================ using System; using System.Collections.Generic; using System.IO; using System.IO.Compression; using System.Net; using System.Security.Cryptography; using System.Threading; namespace UWUVCI_AIO_WPF.Classes { class ToolCheck { static string FolderName = "bin\\Tools"; public static string backupulr = @"https://github.com/Hotbrawl20/UWUVCI-Tools/raw/master/"; public static string[] ToolNames = { "N64Converter.exe", "png2tga.exe", "psb.exe", "RetroInject.exe", "tga_verify.exe", "wiiurpxtool.exe", "INICreator.exe", "blank.ini", "FreeImage.dll", "BuildPcePkg.exe", "BuildTurboCdPcePkg.exe", "goomba.gba", "nfs2iso2nfs.exe", "nintendont.dol", "nintendont_force.dol", "GetExtTypePatcher.exe", "wit.exe", "wstrt.exe", "cygwin1.dll", "cygz.dll", "cyggcc_s-1.dll", "NintendontConfig.exe", "BASE.zip", "tga2png.exe", "iconTex.tga", "wii-vmc.exe", "bootTvTex.png", "ConvertToISO.exe", "NKit.dll", "SharpCompress.dll", "NKit.dll.config", "sox.exe", "jpg2tga.exe", "bmp2tga.exe", "ConvertToNKit.exe", "wglp.exe", "font.otf", "ChangeAspectRatio.exe", "font2.ttf", "forwarder.dol", "gba1.zip", "gba2.zip", "c2w_patcher.exe", "DSLayoutScreens.zip", "cygcrypto-1.1.dll", "cygncursesw-10.dll" }; public static bool DoesToolsFolderExist() { try { return Directory.Exists(FolderName); } catch { return false; } } public static bool IsToolRight(string name) { bool ret = false; var md5 = ""; try { using (WebClient client = new WebClient()) { client.DownloadFile(backupulr + name + ".md5", name + ".md5"); } using StreamReader sr = new StreamReader(name + ".md5"); md5 = sr.ReadLine(); } catch (Exception ex) { Console.WriteLine($"Error downloading MD5 file for {name}: {ex.Message}"); return false; // Early return if MD5 file cannot be downloaded } ret = CalculateMD5(name) == md5; File.Delete(name + ".md5"); return ret; } public static string CalculateMD5(string filename) { using var md5 = MD5.Create(); using var stream = File.OpenRead(filename); string ret = BitConverter.ToString(md5.ComputeHash(stream)).Replace("-", "").ToLower(); stream.Close(); return ret; } public static List CheckForMissingTools() { List missingTools = new List(); foreach (string toolName in ToolNames) { string path = Path.Combine(FolderName, toolName); // Check if the tool exists and has the right MD5 hash if (!DoesToolExist(path)) missingTools.Add(new MissingTool(toolName, path)); } return missingTools; } private static bool DoesToolExist(string path, int retryCount = 0) { const int MaxRetries = 3; // Define a maximum number of retries if (!File.Exists(path)) return false; if (path.ToLower().Contains("gba1.zip") || path.ToLower().Contains("gba2.zip")) { if (!File.Exists(Path.Combine(FolderName, "MArchiveBatchTool.exe")) || !File.Exists(Path.Combine(FolderName, "ucrtbase.dll"))) { try { ZipFile.ExtractToDirectory(path, FolderName); } catch (Exception) { if (retryCount < MaxRetries) { Thread.Sleep(200); return DoesToolExist(path, retryCount + 1); // Recursively retry } else { Console.WriteLine($"Failed to extract {path} after {MaxRetries} attempts."); return false; } } } } return true; } } public class MissingTool { public string Name { get; set; } public string Path { get; set; } public MissingTool(string n, string p) { Name = n; FileInfo f = new FileInfo(p); Path = f.FullName; } } } ================================================ FILE: UWUVCI AIO WPF/FodyWeavers.xml ================================================  ================================================ FILE: UWUVCI AIO WPF/FodyWeavers.xsd ================================================  A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks A list of assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks. A list of runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks A list of runtime assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks. Obsolete, use UnmanagedWinX86Assemblies instead A list of unmanaged X86 (32 bit) assembly names to include, delimited with line breaks. Obsolete, use UnmanagedWinX64Assemblies instead. A list of unmanaged X64 (64 bit) assembly names to include, delimited with line breaks. A list of unmanaged Arm64 (64 bit) assembly names to include, delimited with line breaks. The order of preloaded assemblies, delimited with line breaks. This will copy embedded files to disk before loading them into memory. This is helpful for some scenarios that expected an assembly to be loaded from a physical file. Controls if .pdbs for reference assemblies are also embedded. Controls if runtime assemblies are also embedded. Controls whether the runtime assemblies are embedded with their full path or only with their assembly name. Embedded assemblies are compressed by default, and uncompressed when they are loaded. You can turn compression off with this option. As part of Costura, embedded assemblies are no longer included as part of the build. This cleanup can be turned off. The attach method no longer subscribes to the `AppDomain.AssemblyResolve` (.NET 4.x) and `AssemblyLoadContext.Resolving` (.NET 6.0+) events. Costura by default will load as part of the module initialization. This flag disables that behavior. Make sure you call CosturaUtility.Initialize() somewhere in your code. Costura will by default use assemblies with a name like 'resources.dll' as a satellite resource and prepend the output path. This flag disables that behavior. A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with | A list of assembly names to include from the default action of "embed all Copy Local references", delimited with |. A list of runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with | A list of runtime assembly names to include from the default action of "embed all Copy Local references", delimited with |. Obsolete, use UnmanagedWinX86Assemblies instead A list of unmanaged X86 (32 bit) assembly names to include, delimited with |. Obsolete, use UnmanagedWinX64Assemblies instead A list of unmanaged X64 (64 bit) assembly names to include, delimited with |. A list of unmanaged Arm64 (64 bit) assembly names to include, delimited with |. The order of preloaded assemblies, delimited with |. 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. A comma-separated list of error codes that can be safely ignored in assembly verification. 'false' to turn off automatic generation of the XML Schema file. ================================================ FILE: UWUVCI AIO WPF/Helpers/ConsoleLoggerWriter.cs ================================================ using System; using System.IO; using System.Text; namespace UWUVCI_AIO_WPF.Helpers { public class ConsoleLoggerWriter : TextWriter { private TextWriter originalConsoleOut; // Keep track of the original console output public ConsoleLoggerWriter() { originalConsoleOut = Console.Out; // Save the original Console output } public override Encoding Encoding => originalConsoleOut.Encoding; // Maintain the same encoding public override void WriteLine(string message) { // Write to the original Console output originalConsoleOut.WriteLine(message); // Log the message Logger.Log(message); } public override void WriteLine(string format, params object[] arg) { string formattedMessage = string.Format(format, arg); // Write to the original Console output originalConsoleOut.WriteLine(formattedMessage); // Log the formatted message Logger.Log(formattedMessage); } } } ================================================ FILE: UWUVCI AIO WPF/Helpers/FileUtils.cs ================================================ namespace UWUVCI_AIO_WPF.Helpers { public static class FileUtils { public static int FindFreeSpace(byte[] fileData, int requiredSize) { Logger.Log($"Searching for {requiredSize} bytes of free space in the file."); for (int i = 0; i < fileData.Length - requiredSize; i++) { bool isFree = true; for (int j = 0; j < requiredSize; j++) { if (fileData[i + j] != 0x00) { isFree = false; break; } } if (isFree) { Logger.Log($"Found free space at offset {i}."); return i; } } Logger.Log("No free space found in the file."); return -1; // No free space found } } } ================================================ FILE: UWUVCI AIO WPF/Helpers/JsonSettingsManager.cs ================================================ using System; using System.IO; using Newtonsoft.Json; using UWUVCI_AIO_WPF.Models; namespace UWUVCI_AIO_WPF.Helpers { public class JsonSettingsManager { private static string AppDataPath = Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "UWUVCI-V3"); private static string SettingsFile = Path.Combine(AppDataPath, "settings.json"); public static JsonAppSettings Settings { get; private set; } = new JsonAppSettings(); // Load settings with exception handling for invalid or missing files public static void LoadSettings() { try { if (File.Exists(SettingsFile)) { var json = File.ReadAllText(SettingsFile); Settings = JsonConvert.DeserializeObject(json) ?? new JsonAppSettings(); Console.WriteLine("Settings loaded successfully."); } else { Console.WriteLine("Settings file not found. Creating default settings."); SaveSettings(); // Create a new file with default values } } catch (JsonException ex) { // Handle JSON parsing errors, e.g., malformed or corrupted file Console.WriteLine($"Error parsing settings file: {ex.Message}. Reverting to default settings."); Settings = new JsonAppSettings(); // Reset to default settings SaveSettings(); // Save default settings to create a valid file } catch (Exception ex) { // Catch other exceptions (e.g., file I/O issues) Console.WriteLine($"Error loading settings: {ex.Message}. Reverting to default settings."); Settings = new JsonAppSettings(); // Reset to default SaveSettings(); } } // Save settings with retry mechanism in case of temporary file access issues public static void SaveSettings() { // Check if the settings file is writable if (!IsFileWritable(SettingsFile)) { Console.WriteLine("Settings file is not writable. Unable to save settings."); return; // Exit early if the file is not writable } int retryCount = 0; const int maxRetry = 3; const int delayBetweenRetries = 1000; // 1 second while (retryCount < maxRetry) { try { if (!Directory.Exists(AppDataPath)) Directory.CreateDirectory(AppDataPath); var json = JsonConvert.SerializeObject(Settings, Formatting.Indented); File.WriteAllText(SettingsFile, json); Console.WriteLine("Settings saved successfully."); break; // Success, exit loop } catch (IOException ex) { retryCount++; Console.WriteLine($"Error saving settings (attempt {retryCount}/{maxRetry}): {ex.Message}"); if (retryCount < maxRetry) System.Threading.Thread.Sleep(delayBetweenRetries); // Wait before retrying else Console.WriteLine("Failed to save settings after multiple attempts."); } catch (Exception ex) { Console.WriteLine($"Unexpected error saving settings: {ex.Message}"); break; // If it's not an IO exception, don't retry } } } // Utility to check if the file is writable public static bool IsFileWritable(string path) { try { using FileStream fs = File.Open(path, FileMode.OpenOrCreate, FileAccess.ReadWrite); return true; } catch (IOException) { return false; } } } } ================================================ FILE: UWUVCI AIO WPF/Helpers/Logger.cs ================================================ using System; using System.IO; namespace UWUVCI_AIO_WPF.Helpers { public static class Logger { private static readonly string logDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "UWUVCI-V3", "Logs"); private static readonly string logFilePath; static Logger() { try { // Ensure log directory exists if (!Directory.Exists(logDirectory)) Directory.CreateDirectory(logDirectory); // Create a new log file with timestamp string timestamp = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss"); logFilePath = Path.Combine(logDirectory, $"log_{timestamp}.txt"); // Optional: Clean up old logs (e.g., older than 7 days) CleanupOldLogs(7); } catch (Exception ex) { Console.WriteLine($"Logger initialization failed: {ex.Message}"); } } public static void Log(string message) { try { using StreamWriter sw = new StreamWriter(logFilePath, true); sw.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss} - {message}"); } catch (Exception) { // If logging fails, there's nothing more to do } } private static void CleanupOldLogs(int daysToKeep) { try { var logFiles = Directory.GetFiles(logDirectory, "log_*.txt"); foreach (var file in logFiles) { FileInfo fi = new FileInfo(file); if (fi.CreationTime < DateTime.Now.AddDays(-daysToKeep)) { fi.Delete(); } } } catch (Exception ex) { Console.WriteLine($"Failed to clean up old logs: {ex.Message}"); } } } } ================================================ FILE: UWUVCI AIO WPF/Helpers/MacLinuxHelper.cs ================================================ using Microsoft.Win32; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Management; using System.Windows; using UWUVCI_AIO_WPF.Models; namespace UWUVCI_AIO_WPF.Helpers { public class MacLinuxHelper { private static readonly string[] UWUVCIHelperMessage = { "Don't panic! I see you're trying to run UWUCVI V3 on something that isn't Windows. Sadly, some external tool seems to not be compatible, but that's where I, ZestyTS, comes in!" + "\n\nGo to the folder where UWUVCI is, you should see a folder called 'macOS' or 'linux' please go into the one meant for your system. In either folder you'll see a file called 'UWUVCI-V3-Helper' run that file." + "\nDon't use Wine or any form of virtualization, that is a console app that you can run natively. Since it's a console app, make sure to run it via the terminal!" + "\n\nOnce that program finishes running, it'll tell you, to click the 'OK' button on this MessageBox. The console app has it's own ReadMe, so make sure to check it out!" + "\nIf it's not clear, clicking 'OK' will continue with the Inject and clicking 'Cancel' will cancel out of the inject.", "UWUVCI V3 Helper Program Required To Continue!" }; public static void WriteFailedStepToJson(string functionName, string toolName, string arguments, string currentDirectory) { // Get the base directory where the application is running string basePath = AppDomain.CurrentDomain.BaseDirectory; string toolsJsonPath = Path.Combine(basePath, "tools.json"); var step = new ToolStep { ToolName = toolName, Arguments = arguments, CurrentDirectory = currentDirectory, Function = functionName }; List steps; if (File.Exists(toolsJsonPath)) steps = JsonConvert.DeserializeObject>(File.ReadAllText(toolsJsonPath)) ?? new List(); else steps = new List(); steps.Add(step); File.WriteAllText(toolsJsonPath, JsonConvert.SerializeObject(steps)); } public static void DisplayMessageBoxAboutTheHelper() { var result = MessageBox.Show(UWUVCIHelperMessage[0], UWUVCIHelperMessage[1], MessageBoxButton.OKCancel, MessageBoxImage.Exclamation); if (result != MessageBoxResult.OK) { string basePath = AppDomain.CurrentDomain.BaseDirectory; string toolsJsonPath = Path.Combine(basePath, "tools.json"); if (File.Exists(toolsJsonPath)) File.Delete(toolsJsonPath); MessageBox.Show("You have requested to cancel out of the inject.", "Cancel"); Logger.Log("User canceled Injection early"); throw new Exception("User canceled Injection early"); } } public static void PrepareAndInformUserOnUWUVCIHelper(string functionName, string toolName, string arguments, string realPath = "") { WriteFailedStepToJson(functionName, toolName, arguments, realPath); DisplayMessageBoxAboutTheHelper(); } public static bool IsRunningUnderWineOrSimilar() { try { // Check for Wine using (RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software\Wine")) { if (key != null) return true; } string winePrefix = Environment.GetEnvironmentVariable("WINEPREFIX"); if (!string.IsNullOrEmpty(winePrefix)) return true; // Check for Proton string protonPrefix = Environment.GetEnvironmentVariable("STEAM_COMPAT_DATA_PATH"); if (!string.IsNullOrEmpty(protonPrefix)) return true; // Check for CrossOver string crossoverPrefix = Environment.GetEnvironmentVariable("CROSSOVER_PREFIX"); if (!string.IsNullOrEmpty(crossoverPrefix)) return true; // Check for BoxedWine string boxedWinePrefix = Environment.GetEnvironmentVariable("BOXEDWINE_PATH"); if (!string.IsNullOrEmpty(boxedWinePrefix)) return true; // Check for Lutris string lutrisRuntime = Environment.GetEnvironmentVariable("LUTRIS_GAME_UUID"); if (!string.IsNullOrEmpty(lutrisRuntime)) return true; // Check for PlayOnLinux string playOnLinux = Environment.GetEnvironmentVariable("PLAYONLINUX"); if (!string.IsNullOrEmpty(playOnLinux)) return true; // Check for DXVK string dxvk = Environment.GetEnvironmentVariable("DXVK_LOG_LEVEL"); if (!string.IsNullOrEmpty(dxvk)) return true; // Check for ReactOS if (Environment.OSVersion.Platform == PlatformID.Win32NT && Environment.OSVersion.VersionString.Contains("ReactOS")) return true; // Check for Winetricks string winetricks = Environment.GetEnvironmentVariable("WINETRICKS"); if (!string.IsNullOrEmpty(winetricks)) return true; // Check for Cedega (WineX) string cedega = Environment.GetEnvironmentVariable("CEDEGA_PATH"); if (!string.IsNullOrEmpty(cedega)) return true; // Check for common Wine/Proton files string[] wineFiles = { "/usr/bin/wine", "/usr/local/bin/wine", "/usr/bin/proton", "/usr/local/bin/proton" }; if (wineFiles.Any(File.Exists)) return true; } catch (Exception ex) { Console.WriteLine($"Exception while checking for Wine or similar: {ex.Message}"); } return false; } public static bool IsRunningInVirtualMachine() { try { using (ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_BIOS")) foreach (var _ in from ManagementObject bios in searcher.Get() let manufacturer = bios["Manufacturer"]?.ToString() ?? string.Empty where manufacturer.Contains("VMware") || manufacturer.Contains("VirtualBox") || manufacturer.Contains("Parallels") || manufacturer.Contains("Xen") || manufacturer.Contains("KVM") || manufacturer.Contains("Bhyve") select new { }) return true; /* using (ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_ComputerSystem")) foreach (var (manufacturer, model) in from ManagementObject cs in searcher.Get() let manufacturer = cs["Manufacturer"]?.ToString() ?? string.Empty let model = cs["Model"]?.ToString() ?? string.Empty select (manufacturer, model)) { if (manufacturer.Contains("Microsoft Corporation") && model.Contains("Virtual Machine")) return true; if (manufacturer.Contains("QEMU") || manufacturer.Contains("Bochs") || manufacturer.Contains("OpenStack")) return true; } */ string[] virtualizationIndicators = { "Parallels", "VMware", "VirtualBox", "QEMU", "Hyper-V", "Xen", "KVM", "Bhyve", "Bochs", "OpenStack", "ProxMox", "Virtuozzo" }; foreach (string indicator in virtualizationIndicators) if (Environment.OSVersion.VersionString.Contains(indicator)) return true; // Check for common VM files string[] vmFiles = { "/usr/bin/vmware", "/usr/bin/virtualbox", "/usr/bin/qemu", "/usr/bin/kvm", "/usr/bin/hyperv" }; if (vmFiles.Any(File.Exists)) return true; // Check for Docker string dockerEnv = Environment.GetEnvironmentVariable("DOCKER_ENV"); if (!string.IsNullOrEmpty(dockerEnv) || File.Exists("/.dockerenv")) return true; // Check for common VM processes string[] vmProcesses = { "vmware", "virtualbox", "qemu", "kvm", "hyperv" }; foreach (var processName in vmProcesses) if (Process.GetProcessesByName(processName).Length > 0) return true; } catch (Exception ex) { Console.WriteLine($"Exception while checking for virtual machine: {ex.Message}"); } return false; } } } ================================================ FILE: UWUVCI AIO WPF/ILLink/ILLink.Descriptors.LibraryBuild.xml ================================================  ================================================ FILE: UWUVCI AIO WPF/Models/BaseModel.cs ================================================ using System; using System.ComponentModel; using System.Runtime.CompilerServices; namespace UWUVCI_AIO_WPF { [Serializable] public class BaseModel : INotifyPropertyChanged { // Declare the PropertyChanged event public event PropertyChangedEventHandler PropertyChanged; // OnPropertyChanged will raise the PropertyChanged event passing the // source property that is being updated. protected void OnPropertyChanged([CallerMemberName]string propertyName = "") { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } } ================================================ FILE: UWUVCI AIO WPF/Models/DolSection.cs ================================================ using System.Collections.Generic; using System.IO; namespace UWUVCI_AIO_WPF.Models { public class DolSection { public uint MemoryAddress { get; set; } public uint FileOffset { get; set; } public uint Size { get; set; } public static List ReadDolHeader(string dolFilePath) { var sections = new List(); if (!File.Exists(dolFilePath)) throw new FileNotFoundException($"The file '{dolFilePath}' was not found."); using (FileStream fs = new FileStream(dolFilePath, FileMode.Open, FileAccess.Read)) using (BinaryReader br = new BinaryReader(fs)) { if (fs.Length < 0x100) // Minimum header size throw new InvalidDataException("The file is too small to be a valid DOL file."); fs.Seek(0x00, SeekOrigin.Begin); // Start of DOL file header for (int i = 0; i < 7; i++) // Text sections { uint offset = br.ReadUInt32(); uint addr = br.ReadUInt32(); uint size = br.ReadUInt32(); if (size > 0) sections.Add(new DolSection { FileOffset = offset, MemoryAddress = addr, Size = size }); } for (int i = 0; i < 11; i++) // Data sections { uint offset = br.ReadUInt32(); uint addr = br.ReadUInt32(); uint size = br.ReadUInt32(); if (size > 0) sections.Add(new DolSection { FileOffset = offset, MemoryAddress = addr, Size = size }); } } return sections; } } } ================================================ FILE: UWUVCI AIO WPF/Models/GctCode.cs ================================================ using System; using System.Collections.Generic; using System.IO; using System.Text; using System.Text.RegularExpressions; using UWUVCI_AIO_WPF.Helpers; namespace UWUVCI_AIO_WPF.Models { public class GctCode { public uint Address { get; set; } public uint Value { get; set; } public GctCode(uint address, uint value) { Address = address; Value = value; } // Unified loader for GCT and TXT files public static List LoadFromFile(string filePath) { string extension = Path.GetExtension(filePath).ToLower(); return extension switch { ".gct" => ParseGctFile(filePath), ".txt" => ParseOcarinaOrDolphinTxtFile(filePath).Item1, _ => throw new NotSupportedException($"Unsupported file format: {extension}") }; } // Parse binary GCT files public static List ParseGctFile(string gctFilePath) { var codes = new List(); byte[] gctData = File.ReadAllBytes(gctFilePath); for (int i = 0; i < gctData.Length - 8; i += 8) { uint address = BitConverter.ToUInt32(gctData, i); uint value = BitConverter.ToUInt32(gctData, i + 4); // Check for terminator if (address == 0xF0000000 && value == 0x00000000) break; codes.Add(new GctCode(address, value)); } Logger.Log($"Parsed {codes.Count} codes from GCT file."); return codes; } // Parse textual codelists from Ocarina Manager or Dolphin Emulator public static (List, string) ParseOcarinaOrDolphinTxtFile(string txtFilePath) { var codes = new List(); string[] lines = File.ReadAllLines(txtFilePath); string gameId = null; string currentCodeName = null; bool insideGeckoSection = false; var codeLines = new List(); foreach (var line in lines) { string trimmedLine = line.Trim(); // Ignore empty lines or comments if (string.IsNullOrEmpty(trimmedLine) || trimmedLine.StartsWith("#")) continue; // Detect Game ID (Ocarina) if (trimmedLine.StartsWith("[") && trimmedLine.EndsWith("]")) { if (!trimmedLine.Equals("[Gecko]", StringComparison.OrdinalIgnoreCase)) { gameId = trimmedLine.Trim('[', ']'); Logger.Log($"Detected Game ID: {gameId}"); } continue; } // Detect start of Gecko section (Dolphin) if (trimmedLine.Equals("[Gecko]", StringComparison.OrdinalIgnoreCase)) { insideGeckoSection = true; continue; } // Detect new cheat code section if (trimmedLine.StartsWith("$")) { // Process previous block if any if (codeLines.Count > 0) { codes.AddRange(ParseCodeBlock(currentCodeName, codeLines)); codeLines.Clear(); } currentCodeName = trimmedLine.Substring(1).Trim(); Logger.Log($"Detected Code Name: {currentCodeName}"); continue; } // Validate and collect cheat codes if (Regex.IsMatch(trimmedLine, @"^[0-9A-Fa-f]{8}\s+[0-9A-Fa-f]{8}$")) { codeLines.Add(trimmedLine); } else if (insideGeckoSection) { Logger.Log($"WARNING: Ignoring unrecognized line in Gecko section: {trimmedLine}"); } else { Logger.Log($"ERROR: Unrecognized line format in {txtFilePath}: {trimmedLine}"); throw new InvalidDataException($"Invalid format in {txtFilePath}: {trimmedLine}"); } } // Process last block if (codeLines.Count > 0) codes.AddRange(ParseCodeBlock(currentCodeName, codeLines)); if (codes.Count == 0) throw new InvalidDataException($"No valid cheat codes found in {txtFilePath}"); return (codes, gameId); } // Helper method to parse a block of code lines into GctCode objects private static List ParseCodeBlock(string codeName, List codeLines) { var parsedCodes = new List(); foreach (var line in codeLines) { var parts = line.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries); if (parts.Length != 2) { Logger.Log($"Invalid code line: {line}"); throw new InvalidDataException($"Invalid code line: {line}"); } uint address = Convert.ToUInt32(parts[0], 16); uint value = Convert.ToUInt32(parts[1], 16); parsedCodes.Add(new GctCode(address, value)); } Logger.Log($"Parsed {parsedCodes.Count} codes for {codeName}."); return parsedCodes; } // Convert a list of GctCode to a GCT binary file public static void WriteGctFile(string gctFilePath, List codes, string gameId = null) { if (codes == null || codes.Count == 0) { Logger.Log($"ERROR: No cheat codes available to write to {gctFilePath}"); throw new InvalidDataException($"Cannot create {gctFilePath}: No valid codes found."); } using var fs = new FileStream(gctFilePath, FileMode.Create, FileAccess.Write); Logger.Log($"Writing {codes.Count} cheat codes to {gctFilePath}"); // Optionally write Game ID if provided if (!string.IsNullOrEmpty(gameId)) { byte[] gameIdBytes = Encoding.ASCII.GetBytes(gameId.PadRight(8, '\0')); // Ensure 8 bytes fs.Write(gameIdBytes, 0, 8); } foreach (var code in codes) { byte[] addressBytes = BitConverter.GetBytes(code.Address); byte[] valueBytes = BitConverter.GetBytes(code.Value); if (BitConverter.IsLittleEndian) { Array.Reverse(addressBytes); Array.Reverse(valueBytes); } fs.Write(addressBytes, 0, 4); fs.Write(valueBytes, 0, 4); } // Write GCT terminator fs.Write(BitConverter.GetBytes(0xF0000000), 0, 4); fs.Write(BitConverter.GetBytes(0x00000000), 0, 4); Logger.Log($"GCT file successfully written to {gctFilePath}"); } } } ================================================ FILE: UWUVCI AIO WPF/Models/JsonAppSettings.cs ================================================ namespace UWUVCI_AIO_WPF.Models { public class JsonAppSettings { public bool PathsSet { get; set; } = false; public string BasePath { get; set; } = ""; public string OutPath { get; set; } = ""; public string Ckey { get; set; } = ""; public bool SetBaseOnce { get; set; } = false; public bool SetOutOnce { get; set; } = false; public bool UpgradeRequired { get; set; } = true; public string SysKey { get; set; } = ""; public string SysKey1 { get; set; } = ""; public bool dont { get; set; } = false; public bool ndsw { get; set; } = false; public bool snesw { get; set; } = false; public bool gczw { get; set; } = false; public string Ancast { get; set; } = ""; public bool IsFirstLaunch { get; set; } = true; public bool ShowZestyFork { get; set; } = true; } } ================================================ FILE: UWUVCI AIO WPF/Models/MainViewModel.cs ================================================ using GameBaseClassLibrary; using System; using System.Collections.Generic; using System.IO; using System.IO.Compression; using System.Linq; using System.Net; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; using System.Text; using System.Threading.Tasks; using System.Windows.Controls; using System.Windows.Forms; using UWUVCI_AIO_WPF.Classes; using UWUVCI_AIO_WPF.Models; using UWUVCI_AIO_WPF.UI.Frames.InjectFrames.Bases; using UWUVCI_AIO_WPF.UI.Frames.InjectFrames.Configurations; using UWUVCI_AIO_WPF.UI.Windows; using System.Threading; using System.Windows.Threading; using System.Diagnostics; using Microsoft.WindowsAPICodePack.Dialogs; using System.Text.RegularExpressions; using NAudio.Wave; using System.Timers; using NAudio.Utils; using System.Security.Cryptography; using UWUVCI_AIO_WPF.Helpers; namespace UWUVCI_AIO_WPF { public class MainViewModel : BaseModel { public bool saveworkaround = false; private bool Injected2 = false; public bool injected2 { get { return Injected2; } set { Injected2 = value; OnPropertyChanged(); } } public string prodcode = ""; //public GameConfig GameConfiguration { get; set; } private GameConfig gameConfiguration = new GameConfig(); public bool addi = false; public GameConfig GameConfiguration { get { return gameConfiguration; } set { gameConfiguration = value; OnPropertyChanged(); } } private string romPath; public bool regionfrii = false; public bool regionfriius = false; public bool regionfriijp = false; public string RomPath { get { return romPath; } set { romPath = value; OnPropertyChanged(); } } public bool jppatch = false; public bool pixelperfect = false; private GameBases gbTemp; public GameBases GbTemp { get { return gbTemp; } set { gbTemp = value; } } private string selectedBaseAsString; public string SelectedBaseAsString { get { return selectedBaseAsString; } set { selectedBaseAsString = value; } } private List lGameBasesString = new List(); public List LGameBasesString { get { return lGameBasesString; } set { lGameBasesString = value; OnPropertyChanged(); } } private bool pathsSet { get; set; } = false; public bool PathsSet { get { return pathsSet; } set { pathsSet = value; OnPropertyChanged(); } } private string baseStore; public string BaseStore { get { return baseStore; } set { baseStore = value; OnPropertyChanged(); } } private string injectStore; public string InjectStore { get { return injectStore; } set { injectStore = value; OnPropertyChanged(); } } private bool injected = false; public bool Injected { get { return injected; } set { injected = value; OnPropertyChanged(); } } private Page thing; public Page Thing { get { return thing; } set { thing = value; } } public int OldIndex { get; set; } public bool RomSet { get; set; } private List lBases = new List(); public List LBases { get { return lBases; } set { lBases = value; OnPropertyChanged(); } } private int progress = 0; public int Progress { get { return progress; } set { progress = value; OnPropertyChanged(); } } public BaseContainerFrame bcf = null; #region TKLIST private List lNDS = new List(); public List LNDS { get { return lNDS; } set { lNDS = value; OnPropertyChanged(); } } private List lN64 = new List(); public List LN64 { get { return lN64; } set { lN64 = value; OnPropertyChanged(); } } private List lNES = new List(); public List LNES { get { return lNES; } set { lNES = value; OnPropertyChanged(); } } private List lGBA = new List(); public List LGBA { get { return lGBA; } set { lGBA = value; OnPropertyChanged(); } } private List lSNES = new List(); public List LSNES { get { return lSNES; } set { lSNES = value; OnPropertyChanged(); } } private List lTG16 = new List(); public string ReadCkeyFromOtp() { string ret = ""; using (var dialog = new System.Windows.Forms.OpenFileDialog()) { dialog.Filter = "OTP.bin | otp.bin"; DialogResult res = dialog.ShowDialog(); if (res == DialogResult.OK) { var filepath = dialog.FileName; using (var fs = new FileStream(filepath, FileMode.Open, FileAccess.Read)) { byte[] test = new byte[16]; fs.Seek(0xE0, SeekOrigin.Begin); fs.Read(test, 0, 16); fs.Close(); foreach (var b in test) { ret += string.Format("{0:X2}", b); } } } } return ret; } public List LTG16 { get { return lTG16; } set { lTG16 = value; OnPropertyChanged(); } } private List lMSX = new List(); public List LMSX { get { return lMSX; } set { lMSX = value; OnPropertyChanged(); } } public void RemoveCreatedIMG() { if (Directory.Exists(@"bin\createdIMG")) Directory.Delete(@"bin\createdIMG", true); } private List lWii = new List(); public void IsIsoNkit() { using var fs = new FileStream(RomPath, FileMode.Open, FileAccess.Read); byte[] procode = new byte[4]; fs.Seek(0x200, SeekOrigin.Begin); fs.Read(procode, 0, 4); var s = ByteArrayToString(procode); fs.Close(); NKITFLAG = s.ToLower().Contains("nkit"); } public bool CheckTime(DateTime creationTime) { DateTime curr = DateTime.Now; // Calculate the time difference and return true if within 62 minutes, false otherwise return (curr - creationTime).TotalMinutes >= 0 && (curr - creationTime).TotalMinutes <= 62; } public List LWII { get { return lWii; } set { lWii = value; OnPropertyChanged(); } } private List ltemp = new List(); public List Ltemp { get { return ltemp; } set { ltemp = value; OnPropertyChanged(); } } #endregion public bool BaseDownloaded { get; set; } = false; private bool removeDeflicker = false; public bool RemoveDeflicker { get { return removeDeflicker; } set { removeDeflicker = value; OnPropertyChanged(); } } private bool rendererScale = false; private int brightness = 80; private int pixelArtUpscaler = 0; private bool dsLayout = false; private bool stLayout = false; public bool RendererScale { get { return rendererScale; } set { rendererScale = value; OnPropertyChanged(); } } public bool DSLayout { get { return dsLayout; } set { dsLayout = value; OnPropertyChanged(); } } public bool STLayout { get { return stLayout; } set { stLayout = value; OnPropertyChanged(); } } public int Brightness { get { return brightness; } set { brightness = value; OnPropertyChanged(); } } public int PixelArtUpscaler { get { return pixelArtUpscaler; } set { pixelArtUpscaler = value; OnPropertyChanged(); } } private bool removeDithering = false; public bool RemoveDithering { get { return removeDithering; } set { removeDithering = value; OnPropertyChanged(); } } private bool halfVFilter = false; public bool HalfVFilter { get { return halfVFilter; } set { halfVFilter = value; OnPropertyChanged(); } } private bool canInject = false; public bool CanInject { get { return canInject; } set { canInject = value; OnPropertyChanged(); } } private string cBasePath; public string CBasePath { get { return cBasePath; } set { cBasePath = value; OnPropertyChanged(); } } public int Index = -1; public bool LR = false; public bool GC = false; public bool debug = false; public string doing = ""; public bool Patch = false; public bool toPal = false; public string GctPath = ""; private string Msg; private string Gc2rom = ""; public string gctPath { get { return GctPath; } set { GctPath = value; OnPropertyChanged(); } } public string gc2rom { get { return Gc2rom; } set { Gc2rom = value; OnPropertyChanged(); } } public string foldername = ""; public string msg { get { return Msg; } set { Msg = value; OnPropertyChanged(); } } private string bootsound; public string BootSound { get { return bootsound; } set { bootsound = value; OnPropertyChanged(); } } public System.Windows.Controls.ListViewItem curr = null; private bool ckeys; public bool Ckeys { get { return ckeys; } set { ckeys = value; OnPropertyChanged(); } } public bool NKITFLAG { get; set; } = false; public MainWindow mw; private CustomBaseFrame cb = null; DispatcherTimer timer = new DispatcherTimer(); public bool PokePatch = false; public void Update(bool button) { if (CheckForInternetConnection()) { System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly(); FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(assembly.Location); string version = fvi.FileVersion; if (button) { var client = new Octokit.GitHubClient(new Octokit.ProductHeaderValue("UWUVCI-AIO-WPF")); var releases = Task.Run(() => client.Repository.Release.GetAll("stuff-by-3-random-dudes", "UWUVCI-AIO-WPF")).GetAwaiter().GetResult(); int comparison; try { var latestString = Regex.Replace(releases[0].TagName, "[^0-9.]", ""); var latestLength = latestString.Split('.').Length; var localLength = version.Split('.').Length; for (var i = 0; i < localLength - latestLength; i++) latestString += ".0"; var latestVersion = new Version(latestString); var localVersion = new Version(version); comparison = localVersion.CompareTo(latestVersion); } catch { //Someone messed up versioning, so eff it just don't even bother then return; } //You idiot, when tf did you flip this back? if (comparison < 0) { var cm = new Custom_Message("Update Available!", "You can get it from: https://github.com/stuff-by-3-random-dudes/UWUVCI-AIO-WPF/releases/latest"); try { cm.Owner = mw; } catch (Exception) { } cm.ShowDialog(); } else { var cm = new Custom_Message("No Update Available", "This is currently the latest version."); try { cm.Owner = mw; } catch (Exception) { } cm.ShowDialog(); } } } } private int GetNewVersion() { try { WebRequest request; //get download link from uwuvciapi request = WebRequest.Create("https://uwuvciapi.azurewebsites.net/GetVersionNum"); var response = request.GetResponse(); using Stream dataStream = response.GetResponseStream(); // Open the stream using a StreamReader for easy access. StreamReader reader = new StreamReader(dataStream); // Read the content. string responseFromServer = reader.ReadToEnd(); // Display the content. return Convert.ToInt32(responseFromServer); } catch (Exception) { return 100000; } } public bool ConfirmRiffWave(string path) { using var reader = new BinaryReader(File.OpenRead(path)); reader.BaseStream.Position = 0x00; long WAVHeader1 = reader.ReadInt32(); reader.BaseStream.Position = 0x08; long WAVHeader2 = reader.ReadInt32(); return WAVHeader1 == 1179011410 & WAVHeader2 == 1163280727; } public void OpenDialog(string title, string msg) { Custom_Message cm = new Custom_Message(title, msg); try { cm.Owner = mw; } catch (Exception) { } cm.ShowDialog(); } public MainViewModel() { if (!Environment.Is64BitOperatingSystem) { List Tools = ToolCheck.ToolNames.ToList(); Tools.Add("NUSPacker.jar"); ToolCheck.ToolNames = Tools.ToArray(); } // Clean up unnecessary folders CleanUpFolders(); // Ensure settings paths are initialized properly InitializePaths(); JsonSettingsManager.SaveSettings(); ArePathsSet(); Update(false); toolCheck(); BaseCheck(); GameConfiguration = new GameConfig(); if (!ValidatePathsStillExist() && JsonSettingsManager.Settings.SetBaseOnce && JsonSettingsManager.Settings.SetOutOnce) { Custom_Message cm = new Custom_Message("Issue", " One of your added Paths seems to not exist anymore. \n The Tool is now using it's default Paths \n Please check the paths in the Path menu! "); try { cm.Owner = mw; } catch (Exception) { } cm.ShowDialog(); } UpdatePathSet(); GetAllBases(); } private void CleanUpFolders() { if (Directory.Exists(@"bases")) Directory.Delete(@"bases", true); if (Directory.Exists(@"temp")) Directory.Delete(@"temp", true); if (Directory.Exists(@"keys")) { if (Directory.Exists(@"bin\keys")) Directory.Delete(@"bin\keys", true); Injection.DirectoryCopy("keys", "bin/keys", true); Directory.Delete("keys", true); } if (!Directory.Exists("InjectedGames")) Directory.CreateDirectory("InjectedGames"); if (!Directory.Exists("SourceFiles")) Directory.CreateDirectory("SourceFiles"); if (!Directory.Exists("bin\\BaseGames")) Directory.CreateDirectory("bin\\BaseGames"); } private void InitializePaths() { if (string.IsNullOrEmpty(JsonSettingsManager.Settings.OutPath)) JsonSettingsManager.Settings.OutPath = Path.Combine(Directory.GetCurrentDirectory(), "InjectedGames"); if (string.IsNullOrEmpty(JsonSettingsManager.Settings.BasePath)) JsonSettingsManager.Settings.BasePath = Path.Combine(Directory.GetCurrentDirectory(), "bin", "BaseGames"); } public string turbocd() { string ret = string.Empty; Custom_Message cm = new Custom_Message("Information", " Please put a TurboGrafX CD ROM into a folder and select said folder. \n\n The Folder should at least contain: \n EXACTLY ONE *.hcd file \n One or more *.ogg files \n One or More *.bin files \n\n Not doing so will result in a faulty Inject. You have been warned! "); try { cm.Owner = mw; } catch (Exception) { } cm.ShowDialog(); using (var dialog = new CommonOpenFileDialog()) { dialog.IsFolderPicker = true; CommonFileDialogResult result = dialog.ShowDialog(); if (result == CommonFileDialogResult.Ok) { try { if (DirectoryIsEmpty(dialog.FileName)) { cm = new Custom_Message("Issue", " The folder is Empty. Please choose another folder "); try { cm.Owner = mw; } catch (Exception) { } cm.ShowDialog(); } else { if (Directory.GetDirectories(dialog.FileName).Length > 0) { cm = new Custom_Message("Issue", " This folder mustn't contain any subfolders. "); try { cm.Owner = mw; } catch (Exception) { } cm.ShowDialog(); } else { //WUP if (Directory.GetFiles(dialog.FileName, "*.hcd").Length == 1 && Directory.GetFiles(dialog.FileName, "*.ogg").Length > 0 && Directory.GetFiles(dialog.FileName, "*.bin").Length > 0) ret = dialog.FileName; else { cm = new Custom_Message("Issue", " This Folder does not contain needed minimum of Files "); try { cm.Owner = mw; } catch (Exception) { } cm.ShowDialog(); } } } } catch (Exception) { } } } return ret; } public GameConfig saveconf = null; public void resetCBASE() { cb?.Reset(); } public void removeCBASE() { cb = null; } public void setThing(Page T) { Thing = T; } public void SetCBASE(CustomBaseFrame cbs) { cb = cbs; } public void setMW(MainWindow mwi) { mw = mwi; } public bool cd = false; public void ExportFile() { string drcp = null; string tvcp = null; string iccp = null; string lgcp = null; string incp = null; if (GameConfiguration.TGADrc.ImgPath != null || GameConfiguration.TGADrc.ImgPath == "") drcp = string.Copy(GameConfiguration.TGADrc.ImgPath); if (GameConfiguration.TGATv.ImgPath != null || GameConfiguration.TGATv.ImgPath == "") tvcp = string.Copy(GameConfiguration.TGATv.ImgPath); if (GameConfiguration.TGAIco.ImgPath != null || GameConfiguration.TGAIco.ImgPath == "") iccp = string.Copy(GameConfiguration.TGAIco.ImgPath); if (GameConfiguration.TGALog.ImgPath != null || GameConfiguration.TGALog.ImgPath == "") lgcp = string.Copy(GameConfiguration.TGALog.ImgPath); GameConfiguration.pixelperfect = pixelperfect; GameConfiguration.lr = LR; GameConfiguration.pokepatch = PokePatch; GameConfiguration.tgcd = cd; GameConfiguration.donttrim = donttrim; GameConfiguration.motepass = passtrough; GameConfiguration.jppatch = jppatch; GameConfiguration.vm = Patch; GameConfiguration.vmtopal = toPal; GameConfiguration.rf = regionfrii; GameConfiguration.rfjp = regionfriijp; GameConfiguration.rfus = regionfriius; if (Index != -1) { GameConfiguration.disgamepad = false; } else { GameConfiguration.disgamepad = true; } GameConfiguration.fourbythree = cd; if (GameConfiguration.N64Stuff.INIPath != null || GameConfiguration.N64Stuff.INIPath == "") incp = string.Copy(GameConfiguration.N64Stuff.INIPath); ReadBootSoundIntoConfig(); ReadImagesIntoConfig(); if (GameConfiguration.Console == GameConsoles.N64) { ReadIniIntoConfig(); } GameConfig backup = GameConfiguration; if (test == GameConsoles.GCN) backup.Console = GameConsoles.GCN; if (GameConfiguration.TGADrc.ImgBin != null && GameConfiguration.TGADrc.ImgBin.Length > 0) backup.TGADrc.ImgPath = "Added via Config"; if (GameConfiguration.TGATv.ImgBin != null && GameConfiguration.TGATv.ImgBin.Length > 0) backup.TGATv.ImgPath = "Added via Config"; if (GameConfiguration.TGALog.ImgBin != null && GameConfiguration.TGALog.ImgBin.Length > 0) backup.TGALog.ImgPath = "Added via Config"; if (GameConfiguration.TGAIco.ImgBin != null && GameConfiguration.TGAIco.ImgBin.Length > 0) backup.TGAIco.ImgPath = "Added via Config"; if (GameConfiguration.N64Stuff.INIBin != null && GameConfiguration.N64Stuff.INIBin.Length > 0) backup.N64Stuff.INIPath = "Added via Config"; if (GameConfiguration.GameName == "" || GameConfiguration.GameName == null) backup.GameName = "NoName"; GameConfiguration.Index = Index; CheckAndFixConfigFolder(); var sanitizedGameName = backup.GameName; Array.ForEach(Path.GetInvalidFileNameChars(), c => sanitizedGameName = sanitizedGameName.Replace(c.ToString(), string.Empty)); string outputPath = $@"configs\[{backup.Console}]{sanitizedGameName}.uwuvci"; int i = 1; while (File.Exists(outputPath)) { outputPath = $@"configs\[{backup.Console}]{sanitizedGameName}_{i}.uwuvci"; i++; } Stream createConfigStream = new FileStream(outputPath, FileMode.Create, FileAccess.Write); GZipStream compressedStream = new GZipStream(createConfigStream, CompressionMode.Compress); IFormatter formatter = new BinaryFormatter(); formatter.Serialize(compressedStream, backup); compressedStream.Close(); createConfigStream.Close(); Custom_Message cm = new Custom_Message("Export success", " The Config was successfully exported.\n Click the Open Folder Button to open the Location where the Config is stored. ", Path.Combine(Directory.GetCurrentDirectory(), outputPath)); try { cm.Owner = mw; } catch (Exception) { } cm.ShowDialog(); GameConfiguration.TGADrc.ImgPath = drcp; GameConfiguration.TGATv.ImgPath = tvcp; GameConfiguration.TGAIco.ImgPath = iccp; GameConfiguration.TGALog.ImgPath = lgcp; GameConfiguration.TGADrc.ImgBin = null; GameConfiguration.TGATv.ImgBin = null; GameConfiguration.TGAIco.ImgBin = null; GameConfiguration.TGALog.ImgBin = null; if (incp != null) { GameConfiguration.N64Stuff.INIBin = null; GameConfiguration.N64Stuff.INIPath = incp; } /*if (GameConfiguration.Console == GameConsoles.N64) { (thing as N64Config).reset(); } else if (gameConfiguration.Console == GameConsoles.TG16) { (thing as TurboGrafX).reset(); } else if (gameConfiguration.Console == GameConsoles.WII && test != GameConsoles.GCN) { (thing as WiiConfig).reset(); } else if (test == GameConsoles.GCN) { (thing as GCConfig).reset(); } else { try { (thing as OtherConfigs).reset(); } catch (Exception e) { (thing as GCConfig).reset(); } }*/ } public void ImportConfig(string configPath) { FileInfo fn = new FileInfo(configPath); if (Directory.Exists(@"bin\cfgBoot")) { Directory.Delete(@"bin\cfgBoot", true); } if (fn.Extension.Contains("uwuvci")) { FileStream inputConfigStream = new FileStream(configPath, FileMode.Open, FileAccess.Read); GZipStream decompressedConfigStream = new GZipStream(inputConfigStream, CompressionMode.Decompress); IFormatter formatter = new BinaryFormatter(); GameConfiguration = (GameConfig)formatter.Deserialize(decompressedConfigStream); pixelperfect = GameConfiguration.pixelperfect; LR = GameConfiguration.lr; cd = GameConfiguration.tgcd; PokePatch = GameConfiguration.pokepatch; passtrough = GameConfiguration.motepass; jppatch = GameConfiguration.jppatch; Patch = GameConfiguration.vm; toPal = GameConfiguration.vmtopal; regionfrii = GameConfiguration.rf; regionfriijp = GameConfiguration.rfjp; regionfriius = GameConfiguration.rfus; } if (GameConfiguration.Console == GameConsoles.N64) { (thing as N64Config).getInfoFromConfig(); } else if (gameConfiguration.Console == GameConsoles.TG16) { (thing as TurboGrafX).getInfoFromConfig(); } else if (gameConfiguration.Console == GameConsoles.WII && test != GameConsoles.GCN) { (thing as WiiConfig).getInfoFromConfig(); } else if (test == GameConsoles.GCN) { (thing as GCConfig).getInfoFromConfig(); } else if (gameConfiguration.Console == GameConsoles.GBA) { (thing as GBA).getInfoFromConfig(); } else { try { (thing as OtherConfigs).getInfoFromConfig(); } catch (Exception) { (thing as GCConfig).getInfoFromConfig(); } } } public void ReadBootSoundIntoConfig() { ReadFileAsBin(GameConfiguration, bootsound, 6); } public void ReadImagesIntoConfig() { ReadFileAsBin(GameConfiguration, GameConfiguration.TGAIco.ImgPath, 1); ReadFileAsBin(GameConfiguration, GameConfiguration.TGADrc.ImgPath, 2); ReadFileAsBin(GameConfiguration, GameConfiguration.TGATv.ImgPath, 3); ReadFileAsBin(GameConfiguration, GameConfiguration.TGALog.ImgPath, 4); } public void ReadIniIntoConfig() { ReadFileAsBin(GameConfiguration, GameConfiguration.N64Stuff.INIPath, 5); } private void ReadFileAsBin(GameConfig file, string FilePath, int scase) { if (FilePath != null) { try { var filedata = new FileStream(FilePath, FileMode.Open); var len = (int)filedata.Length; switch (scase) { case 1: file.TGAIco.ImgBin = new byte[len]; filedata.Read(file.TGAIco.ImgBin, 0, len); break; case 2: file.TGADrc.ImgBin = new byte[len]; filedata.Read(file.TGADrc.ImgBin, 0, len); break; case 3: file.TGATv.ImgBin = new byte[len]; filedata.Read(file.TGATv.ImgBin, 0, len); break; case 4: file.TGALog.ImgBin = new byte[len]; filedata.Read(file.TGALog.ImgBin, 0, len); break; case 5: file.N64Stuff.INIBin = new byte[len]; filedata.Read(file.N64Stuff.INIBin, 0, len); break; case 6: file.bootsound = new byte[len]; filedata.Read(file.bootsound, 0, len); file.extension = new FileInfo(FilePath).Extension.Replace(".", ""); break; } filedata.Close(); } catch (Exception) { switch (scase) { case 1: file.TGAIco.ImgBin = null; break; case 2: file.TGADrc.ImgBin = null; break; case 3: file.TGATv.ImgBin = null; break; case 4: file.TGALog.ImgBin = null; break; case 5: file.N64Stuff.INIBin = null; break; } } } } public bool donttrim = false; private static void CheckAndFixConfigFolder() { if (!Directory.Exists(@"configs")) Directory.CreateDirectory(@"configs"); } public void Pack(bool loadiine) { string consoleName = GameConfiguration.Console.ToString(); if (GC) consoleName = GameConsoles.GCN.ToString(); ValidatePathsStillExist(); if (loadiine) Injection.Loadiine(GameConfiguration.GameName, consoleName); else { if (gameConfiguration.GameName != null) { Regex reg = new Regex("[^a-zA-Z0-9 é -]"); gameConfiguration.GameName = gameConfiguration.GameName.Replace("|", " "); gameConfiguration.GameName = reg.Replace(gameConfiguration.GameName, ""); } Task.Run(() => { Injection.Packing(GameConfiguration.GameName, consoleName, this); }); DownloadWait dw = new DownloadWait("Packing Inject - Please Wait", "", this); try { dw.changeOwner(mw); } catch (Exception) { } dw.ShowDialog(); Progress = 0; string extra = ""; string names = "Copy to SD"; if (GameConfiguration.Console == GameConsoles.WII) extra = "\n Some games cannot reboot into the WiiU Menu. Shut down via the GamePad. \n If Stuck in a BlackScreen, you need to unplug your WiiU."; if (GameConfiguration.Console == GameConsoles.WII && romPath.ToLower().Contains(".wad")) extra += "\n Make sure that the chosen WAD is installed in your vWii!"; if (GC) { extra = "\n Make sure to have Nintendon't + config on your SD.\n You can add them by pressing the \"SD Setup\" button or using the \"Start Nintendont Config Tool\" button under Settings. "; names = "SD Setup"; } gc2rom = ""; Custom_Message cm = new Custom_Message("Injection Complete", $" You need CFW (ex: haxchi, mocha, tiramisu, or aroma) to run and install this inject! \n It's recommended to install onto USB to avoid brick risks.{extra}\n To Open the Location of the Inject press Open Folder.\n If you want the inject to be put on your SD now, press {names}. ", JsonSettingsManager.Settings.OutPath); try { cm.Owner = mw; } catch (Exception) { } cm.ShowDialog(); } LGameBasesString.Clear(); CanInject = false; RomSet = false; RomPath = null; Injected = false; GameConfiguration.CBasePath = null; GC = false; bootsound = ""; NKITFLAG = false; CBasePath = null; prodcode = ""; ClearImage(); foldername = ""; mw.ListView_Click(mw.listCONS, null); } private void ClearImage() { switch (GameConfiguration.Console) { case GameConsoles.NDS: (thing as OtherConfigs).icoIMG.Visibility = System.Windows.Visibility.Hidden; (thing as OtherConfigs).tvIMG.Visibility = System.Windows.Visibility.Hidden; (thing as OtherConfigs).drcIMG.Visibility = System.Windows.Visibility.Hidden; (thing as OtherConfigs).logIMG.Visibility = System.Windows.Visibility.Hidden; (thing as OtherConfigs).Injection.IsEnabled = false; break; case GameConsoles.GBA: (thing as GBA).icoIMG.Visibility = System.Windows.Visibility.Hidden; (thing as GBA).tvIMG.Visibility = System.Windows.Visibility.Hidden; (thing as GBA).drcIMG.Visibility = System.Windows.Visibility.Hidden; (thing as GBA).logIMG.Visibility = System.Windows.Visibility.Hidden; (thing as GBA).Injection.IsEnabled = false; break; case GameConsoles.N64: (thing as N64Config).icoIMG.Visibility = System.Windows.Visibility.Hidden; (thing as N64Config).tvIMG.Visibility = System.Windows.Visibility.Hidden; (thing as N64Config).drcIMG.Visibility = System.Windows.Visibility.Hidden; (thing as N64Config).logIMG.Visibility = System.Windows.Visibility.Hidden; (thing as N64Config).Injection.IsEnabled = false; break; case GameConsoles.NES: (thing as OtherConfigs).icoIMG.Visibility = System.Windows.Visibility.Hidden; (thing as OtherConfigs).tvIMG.Visibility = System.Windows.Visibility.Hidden; (thing as OtherConfigs).drcIMG.Visibility = System.Windows.Visibility.Hidden; (thing as OtherConfigs).logIMG.Visibility = System.Windows.Visibility.Hidden; (thing as OtherConfigs).Injection.IsEnabled = false; break; case GameConsoles.SNES: (thing as OtherConfigs).icoIMG.Visibility = System.Windows.Visibility.Hidden; (thing as OtherConfigs).tvIMG.Visibility = System.Windows.Visibility.Hidden; (thing as OtherConfigs).drcIMG.Visibility = System.Windows.Visibility.Hidden; (thing as OtherConfigs).logIMG.Visibility = System.Windows.Visibility.Hidden; (thing as OtherConfigs).Injection.IsEnabled = false; break; case GameConsoles.TG16: (thing as TurboGrafX).icoIMG.Visibility = System.Windows.Visibility.Hidden; (thing as TurboGrafX).tvIMG.Visibility = System.Windows.Visibility.Hidden; (thing as TurboGrafX).drcIMG.Visibility = System.Windows.Visibility.Hidden; (thing as TurboGrafX).logIMG.Visibility = System.Windows.Visibility.Hidden; (thing as TurboGrafX).Injection.IsEnabled = false; break; case GameConsoles.MSX: (thing as OtherConfigs).icoIMG.Visibility = System.Windows.Visibility.Hidden; (thing as OtherConfigs).tvIMG.Visibility = System.Windows.Visibility.Hidden; (thing as OtherConfigs).drcIMG.Visibility = System.Windows.Visibility.Hidden; (thing as OtherConfigs).logIMG.Visibility = System.Windows.Visibility.Hidden; (thing as OtherConfigs).Injection.IsEnabled = false; break; case GameConsoles.WII: if (test == GameConsoles.GCN) { (thing as GCConfig).icoIMG.Visibility = System.Windows.Visibility.Hidden; (thing as GCConfig).tvIMG.Visibility = System.Windows.Visibility.Hidden; (thing as GCConfig).drcIMG.Visibility = System.Windows.Visibility.Hidden; (thing as GCConfig).logIMG.Visibility = System.Windows.Visibility.Hidden; (thing as GCConfig).Injection.IsEnabled = false; } else { (thing as WiiConfig).icoIMG.Visibility = System.Windows.Visibility.Hidden; (thing as WiiConfig).tvIMG.Visibility = System.Windows.Visibility.Hidden; (thing as WiiConfig).drcIMG.Visibility = System.Windows.Visibility.Hidden; (thing as WiiConfig).logIMG.Visibility = System.Windows.Visibility.Hidden; (thing as WiiConfig).Injection.IsEnabled = false; } break; } } DownloadWait Injectwait; public void runInjectThread(bool force) { timer.Interval = TimeSpan.FromSeconds(1); timer.Tick += timer_Tick2; timer.Start(); var thread = new Thread(() => { Injectwait = new DownloadWait("Injecting Game - Please Wait", "", this); try { Injectwait.changeOwner(mw); } catch (Exception) { } Injectwait.Topmost = true; Injectwait.ShowDialog(); }); thread.SetApartmentState(ApartmentState.STA); thread.Start(); } public bool failed = false; public void Inject(bool force) { ValidatePathsStillExist(); /* var task = new Task(() => runInjectThread(true)); task.Start();*/ Task.Run(() => { if (Injection.Inject(GameConfiguration, RomPath, this, force)) { Injected = true; injected2 = true; if (GameConfiguration.Console == GameConsoles.WII || GameConfiguration.Console == GameConsoles.GCN) injected2 = false; } else { Injected = false; injected2 = false; } }); DownloadWait dw = new DownloadWait("Injecting Game - Please Wait", "", this); try { dw.changeOwner(mw); } catch (Exception) { } dw.ShowDialog(); Progress = 0; if (Injected) { Custom_Message cm = new Custom_Message("Finished Injection Part", " Injection Finished, please choose how you want to export the Inject next. "); try { cm.Owner = mw; } catch (Exception) { } cm.ShowDialog(); } else { if (failed) { MessageBox.Show("In here"); mw.allowBypass(); if (debug) { mw.setDebug(true); } Inject(force); } } } private void BaseCheck() { if (Directory.Exists(@"bin\bases")) { var test = GetMissingVCBs(); if (test.Count > 0) { if (CheckForInternetConnection()) { Progress = 0; Task.Run(() => { double stuff = 100 / test.Count; foreach (string s in test) { DownloadBase(s, this); Progress += Convert.ToInt32(stuff); } Progress = 100; }); DownloadWait dw = new DownloadWait("Downloading needed Data - Please Wait", "", this); try { dw.changeOwner(mw); } catch (Exception) { } dw.ShowDialog(); BaseCheck(); } else { Custom_Message dw = new Custom_Message("No Internet connection", " You have files missing, which need to be downloaded but you dont have an Internet Connection. \n The Program will now terminate "); try { dw.Owner = mw; } catch (Exception) { } dw.ShowDialog(); Environment.Exit(1); } } } else { if (CheckForInternetConnection()) { Directory.CreateDirectory(@"bin\bases"); var test = GetMissingVCBs(); Progress = 0; Task.Run(() => { double stuff = 100 / test.Count; foreach (string s in test) { DownloadBase(s, this); Progress += Convert.ToInt32(stuff); } Progress = 100; }); DownloadWait dw = new DownloadWait("Downloading needed Data - Please Wait", "", this); try { dw.changeOwner(mw); } catch (Exception) { } dw.ShowDialog(); Progress = 0; BaseCheck(); } else { Custom_Message dw = new Custom_Message("No Internet connection", " You have files missing, which need to be downloaded but you dont have an Internet Connection. \n The Program will now terminate "); try { dw.Owner = mw; } catch (Exception) { } dw.ShowDialog(); Environment.Exit(1); } } } public void UpdateTools() { if (CheckForInternetConnection()) { string[] bases = ToolCheck.ToolNames; Task.Run(() => { Progress = 0; double l = 100 / bases.Length; foreach (string s in bases) { DeleteTool(s); DownloadTool(s, this); Progress += Convert.ToInt32(l); } Progress = 100; }); DownloadWait dw = new DownloadWait("Updating Tools - Please Wait", "", this); try { dw.changeOwner(mw); } catch (Exception) { } dw.ShowDialog(); toolCheck(); Custom_Message cm = new Custom_Message("Finished Update", " Finished Updating Tools! Restarting UWUVCI AIO "); try { cm.Owner = mw; } catch (Exception) { } cm.ShowDialog(); Process p = new Process(); p.StartInfo.FileName = System.Windows.Application.ResourceAssembly.Location; if (debug) { if (saveworkaround) { p.StartInfo.Arguments = "--debug --skip --spacebypass"; } else { p.StartInfo.Arguments = "--debug --skip"; } } else { if (saveworkaround) { p.StartInfo.Arguments = "--skip --spacebypass"; } else { p.StartInfo.Arguments = "--skip"; } } p.Start(); Environment.Exit(0); } } public void ResetTKQuest() { Custom_Message cm = new Custom_Message("Resetting TitleKeys", " This Option will reset all entered TitleKeys meaning you will need to reenter them again! \n Do you still wish to continue?"); try { cm.Owner = mw; } catch (Exception) { } cm.ShowDialog(); cm.Close(); } public void ResetTitleKeys() { File.Delete("bin/keys/gba.vck"); File.Delete("bin/keys/nds.vck"); File.Delete("bin/keys/nes.vck"); File.Delete("bin/keys/n64.vck"); File.Delete("bin/keys/msx.vck"); File.Delete("bin/keys/tg16.vck"); File.Delete("bin/keys/snes.vck"); File.Delete("bin/keys/wii.vck"); Custom_Message cm = new Custom_Message("Reset Successful", " The TitleKeys are now reset. \n The Program will now restart."); try { cm.Owner = mw; } catch (Exception) { } cm.ShowDialog(); mw.Close(); Process p = new Process(); p.StartInfo.FileName = System.Windows.Application.ResourceAssembly.Location; if (debug) { p.StartInfo.Arguments = "--debug --skip"; } else { p.StartInfo.Arguments = "--skip"; } p.Start(); Environment.Exit(0); } public void UpdateBases() { if (CheckForInternetConnection()) { string[] bases = { "bases.vcbnds", "bases.vcbn64", "bases.vcbgba", "bases.vcbsnes", "bases.vcbnes", "bases.vcbtg16", "bases.vcbmsx", "bases.vcbwii" }; Task.Run(() => { Progress = 0; double l = 100 / bases.Length; foreach (string s in bases) { DeleteBase(s); DownloadBase(s, this); GameConsoles g = new GameConsoles(); if (s.Contains("nds")) g = GameConsoles.NDS; if (s.Contains("nes")) g = GameConsoles.NES; if (s.Contains("snes")) g = GameConsoles.SNES; if (s.Contains("n64")) g = GameConsoles.N64; if (s.Contains("gba")) g = GameConsoles.GBA; if (s.Contains("tg16")) g = GameConsoles.TG16; if (s.Contains("msx")) g = GameConsoles.MSX; if (s.Contains("wii")) g = GameConsoles.WII; UpdateKeyFile(VCBTool.ReadBasesFromVCB($@"bin/bases/{s}"), g); Progress += Convert.ToInt32(l); } Progress = 100; }); DownloadWait dw = new DownloadWait("Updating Base Files - Please Wait", "", this); try { dw.changeOwner(mw); } catch (Exception) { } dw.ShowDialog(); Custom_Message cm = new Custom_Message("Finished Updating", " Finished Updating Bases! Restarting UWUVCI AIO "); try { cm.Owner = mw; } catch (Exception) { } cm.ShowDialog(); Process p = new Process(); p.StartInfo.FileName = System.Windows.Application.ResourceAssembly.Location; if (debug) { p.StartInfo.Arguments = "--debug --skip"; } else { p.StartInfo.Arguments = "--skip"; } p.Start(); Environment.Exit(0); } } public static int GetDeterministicHashCode(string str) { unchecked { int hash1 = (5381 << 16) + 5381; int hash2 = hash1; for (int i = 0; i < str.Length; i += 2) { hash1 = ((hash1 << 5) + hash1) ^ str[i]; if (i == str.Length - 1) break; hash2 = ((hash2 << 5) + hash2) ^ str[i + 1]; } return hash1 + (hash2 * 1566083941); } } public bool checkSysKey(string key) { if (key.GetHashCode() == -589797700 || GetDeterministicHashCode(key) == -589797700) { JsonSettingsManager.Settings.SysKey = key; JsonSettingsManager.SaveSettings(); return true; } return false; } public bool SysKey1set() { return checkSysKey1(JsonSettingsManager.Settings.SysKey1); } public bool checkSysKey1(string key) { if (key.GetHashCode() == -1230232583 || (GetDeterministicHashCode(key) == -1230232583)) { JsonSettingsManager.Settings.SysKey1 = key; JsonSettingsManager.SaveSettings(); return true; } return false; } public bool SysKeyset() { return checkSysKey(JsonSettingsManager.Settings.SysKey); } public bool GetConsoleOfConfig(string configPath, GameConsoles console) { FileInfo fn = new FileInfo(configPath); if (fn.Extension.Contains("uwuvci")) { FileStream inputConfigStream = new FileStream(configPath, FileMode.Open, FileAccess.Read); GZipStream decompressedConfigStream = new GZipStream(inputConfigStream, CompressionMode.Decompress); IFormatter formatter = new BinaryFormatter(); GameConfig check = (GameConfig)formatter.Deserialize(decompressedConfigStream); if (check.Console == console) return true; } return false; } public void selectConfig(GameConsoles console) { string ret = string.Empty; using (var dialog = new System.Windows.Forms.OpenFileDialog()) { dialog.InitialDirectory = Path.Combine(Directory.GetCurrentDirectory(), "configs"); dialog.Filter = "UWUVCI Config (*.uwuvci) | *.uwuvci"; DialogResult res = dialog.ShowDialog(); if (res == DialogResult.OK) { ret = dialog.FileName; if (GetConsoleOfConfig(ret, console)) { ImportConfig(ret); Custom_Message cm = new Custom_Message("Import Complete", " Importing of Config completed. \n Please reselect a Base!"); try { cm.Owner = mw; } catch (Exception) { } cm.ShowDialog(); } else { Custom_Message cm = new Custom_Message("Import Failed", $" The config you are trying to import is not made for {console.ToString()} Injections. \n Please choose a config made for these kind of Injections or choose a different kind of Injection"); try { cm.Owner = mw; } catch (Exception) { } cm.ShowDialog(); } } } } private bool RemoteFileExists(string url) { try { HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest; request.Method = "HEAD"; HttpWebResponse response = request.GetResponse() as HttpWebResponse; response.Close(); return (response.StatusCode == HttpStatusCode.OK); } catch { return false; } } public string GetFilePath(bool ROM, bool INI) { Custom_Message cm; string ret = string.Empty; if (ROM && !INI) { switch (GameConfiguration.Console) { case GameConsoles.NDS: cm = new Custom_Message("Information", " You can only inject NDS ROMs that are not DSi Enhanced (example for not working: Pokémon Black & White) \n\n If attempting to inject a DSi Enhanced ROM, we will not give you any support with fixing said injection. "); try { cm.Owner = mw; } catch (Exception) { } if (!JsonSettingsManager.Settings.ndsw) { cm.ShowDialog(); } break; case GameConsoles.SNES: cm = new Custom_Message("Information", " You can only inject SNES ROMs that are not using any Co-Processors (example for not working: Star Fox) \n\n If attempting to inject a ROM in need of a Co-Processor, we will not give you any support with fixing said injection. "); try { cm.Owner = mw; } catch (Exception) { } if (!JsonSettingsManager.Settings.snesw) { cm.ShowDialog(); } break; } } using (var dialog = new System.Windows.Forms.OpenFileDialog()) { if (ROM) { if (INI) { dialog.Filter = "BootSound Files (*.mp3; *.wav; *.btsnd) | *.mp3;*.wav;*.btsnd"; } else if (GC) { dialog.Filter = "GCN ROM (*.iso; *.gcm) | *.iso; *.gcm"; } else { switch (GameConfiguration.Console) { case GameConsoles.NDS: dialog.Filter = "Nintendo DS ROM (*.nds; *.srl) | *.nds;*.srl"; break; case GameConsoles.N64: dialog.Filter = "Nintendo 64 ROM (*.n64; *.v64; *.z64) | *.n64;*.v64;*.z64"; break; case GameConsoles.GBA: dialog.Filter = "GameBoy Series ROM (*.gba;*.gbc;*.gb) | *.gba;*.gbc;*.gb"; break; case GameConsoles.NES: dialog.Filter = "Nintendo Entertainment System ROM (*.nes) | *.nes"; break; case GameConsoles.SNES: dialog.Filter = "Super Nintendo Entertainment System ROM (*.sfc; *.smc) | *.sfc;*.smc"; break; case GameConsoles.TG16: dialog.Filter = "TurboGrafX-16 ROM (*.pce) | *.pce"; break; case GameConsoles.MSX: dialog.Filter = "MSX/MSX2 ROM (*.ROM) | *.ROM"; break; case GameConsoles.WII: if (test == GameConsoles.GCN) dialog.Filter = "GC ROM (*.iso; *.gcm; *.nkit.iso; *.nkit.gcz) | *.iso; *.gcm; *.nkit.iso; *.nkit.gcz"; else dialog.Filter = "All Supported Types (*.*) | *.iso; *.wbfs; *.nkit.gcz; *.nkit.iso; *.dol; *.wad|Wii ROM (*.iso; *.wbfs; *.nkit.gcz; *.nkit.iso) | *.iso; *.wbfs; *.nkit.gcz; *.nkit.iso|Wii Homebrew (*.dol) | *.dol|Wii Channel (*.wad) | *.wad"; // dialog.Filter = "Wii ROM (*.iso; *.wbfs; *.nkit.gcz; *.nkit.iso) | *.iso; *.wbfs; *.nkit.gcz; *.nkit.iso|Wii Homebrew (*.dol) | *.dol|Wii Channel (*.wad) | *.wad"; break; case GameConsoles.GCN: dialog.Filter = "GC ROM (*.iso; *.gcm; *.nkit.iso; *.nkit.gcz) | *.iso; *.gcm; *.nkit.iso; *.nkit.gcz"; break; } } } else if (!INI) dialog.Filter = "Images (*.png; *.jpg; *.bmp; *.tga; *jpeg) | *.png;*.jpg;*.bmp;*.tga;*jpeg"; else if (INI) dialog.Filter = "N64 VC Configuration (*.ini) | *.ini"; if (Directory.Exists("SourceFiles")) dialog.InitialDirectory = "SourceFiles"; DialogResult res = dialog.ShowDialog(); if (res == DialogResult.OK) { if (dialog.FileName.ToLower().Contains(".gcz")) { Custom_Message cm1 = new Custom_Message("Information", " Using a GameCube GCZ Nkit for a Wii Inject or vice versa will break things. \n You will not be able to grab the BootImages or GameName using this type of ROM. "); try { cm1.Owner = mw; } catch (Exception) { } if (!JsonSettingsManager.Settings.gczw) cm1.ShowDialog(); } ret = dialog.FileName; } else if (dialog.Filter.Contains("BootImages") || dialog.Filter.Contains("BootSound") || dialog.Filter.Contains("GCT")) ret = ""; } return ret; } public GameConsoles test; private static void CopyBase(string console) { File.Copy(console, $@"bin\bases\{console}"); File.Delete(console); } private static void DeleteTool(string tool) { try { File.Delete($@"bin\Tools\{tool}"); } catch { //why does that try break everything? wtf } } private static void DeleteBase(string console) { File.Delete($@"bin\bases\{console}"); } public static List GetMissingVCBs() { List ret = new List(); string path = @"bin\bases\bases.vcb"; if (!File.Exists(path + "nds")) ret.Add(path + "nds"); if (!File.Exists(path + "nes")) ret.Add(path + "nes"); if (!File.Exists(path + "n64")) ret.Add(path + "n64"); if (!File.Exists(path + "snes")) ret.Add(path + "snes"); if (!File.Exists(path + "gba")) ret.Add(path + "gba"); if (!File.Exists(path + "tg16")) ret.Add(path + "tg16"); if (!File.Exists(path + "msx")) ret.Add(path + "msx"); if (!File.Exists(path + "wii")) ret.Add(path + "wii"); return ret; } public static void DownloadBase(string name, MainViewModel mvm) { string olddir = Directory.GetCurrentDirectory(); try { string basePath = $@"bin\bases\"; Directory.SetCurrentDirectory(basePath); using var client = new WebClient(); var fixname = name.Split('\\'); if (MacLinuxHelper.IsRunningInVirtualMachine() || MacLinuxHelper.IsRunningUnderWineOrSimilar()) name = "Net6/" + name; client.DownloadFile(getDownloadLink(name, false), fixname[fixname.Length - 1]); } catch (Exception e) { Console.WriteLine(e.Message); Custom_Message cm = new Custom_Message("Error 005: \"Unable to Download VCB Base\"", " There was an Error downloading the VCB Base File. \n The Programm will now terminate."); try { cm.Owner = mvm.mw; } catch (Exception) { } cm.ShowDialog(); Environment.Exit(1); } Directory.SetCurrentDirectory(olddir); } public static void DownloadTool(string name, MainViewModel mvm) { string olddir = Directory.GetCurrentDirectory(); try { if (Directory.GetCurrentDirectory().Contains("bin") && Directory.GetCurrentDirectory().Contains("Tools")) olddir = Directory.GetCurrentDirectory().Replace("bin\\Tools", ""); else { string basePath = $@"bin\Tools\"; Directory.SetCurrentDirectory(basePath); } do { if (File.Exists(name)) File.Delete(name); using var client = new WebClient(); client.DownloadFile(getDownloadLink(name, true), name); } while (!ToolCheck.IsToolRight(name)); } catch (Exception e) { Console.WriteLine(e.Message); Custom_Message cm = new Custom_Message("Error 006: \"Unable to Download Tool\"", " There was an Error downloading the Tool. \n The Programm will now terminate."); try { cm.Owner = mvm.mw; } catch (Exception) { } cm.ShowDialog(); Environment.Exit(1); } Directory.SetCurrentDirectory(olddir); } private static string getDownloadLink(string toolname, bool tool) { try { bool ok = false; try { using (WebClient client = new WebClient()) { string result = client.DownloadString("https://uwuvciapi.azurewebsites.net/api/values"); } ok = true; } catch (WebException) { } if (ok) { WebRequest request; //get download link from uwuvciapi request = WebRequest.Create("https://uwuvciapi.azurewebsites.net/GetToolLink?" + (tool ? "tool=" : "vcb=") + toolname); var response = request.GetResponse(); using Stream dataStream = response.GetResponseStream(); // Open the stream using a StreamReader for easy access. StreamReader reader = new StreamReader(dataStream); // Read the content. string responseFromServer = reader.ReadToEnd(); // Display the content. if (responseFromServer == "") if (tool) return $"{ToolCheck.backupulr}{toolname}"; else return $@"https://github.com/Hotbrawl20/UWUVCI-VCB/raw/master/" + toolname; return responseFromServer; } else { if (tool) return $"{ToolCheck.backupulr}{toolname}"; else return $@"https://github.com/Hotbrawl20/UWUVCI-VCB/raw/master/" + toolname.Replace("bin\\bases\\", ""); } } catch (Exception) { if (tool) return $"{ToolCheck.backupulr}{toolname}"; else return $@"https://github.com/Hotbrawl20/UWUVCI-VCB/raw/master/" + toolname.Replace("bin\\bases\\", ""); } } public void InjcttoolCheck() { if (ToolCheck.DoesToolsFolderExist()) { List missingTools = new List(); missingTools = ToolCheck.CheckForMissingTools(); if (missingTools.Count > 0) { foreach (MissingTool m in missingTools) DownloadTool(m.Name, this); InjcttoolCheck(); } } else { Directory.CreateDirectory($@"{Directory.GetCurrentDirectory()}bin\\Tools"); InjcttoolCheck(); } } private void ThreadDownload(List missingTools) { var thread = new Thread(() => { double l = 100 / missingTools.Count; foreach (MissingTool m in missingTools) { if (m.Name == "blank.ini") { StreamWriter sw = new StreamWriter(Path.Combine(Directory.GetCurrentDirectory(), "bin", "Tools", "blank.ini")); sw.Close(); } else DownloadTool(m.Name, this); Progress += Convert.ToInt32(l); } Progress = 100; }); thread.SetApartmentState(ApartmentState.STA); thread.Start(); } private void timer_Tick2(object sender, EventArgs e) { if (Progress == 100) { Injectwait.Close(); timer.Stop(); Progress = 0; } } private void toolCheck(int currentRetry = 0) { int maxRetries = 3; if (ToolCheck.DoesToolsFolderExist()) { List missingTools = ToolCheck.CheckForMissingTools(); if (missingTools.Count > 0) { Logger.Log("Missing tools detected."); if (CheckForInternetConnection()) { Task.Run(() => ThreadDownload(missingTools)); ShowDownloadWaitDialog(); // Retry logic after downloading if (currentRetry < maxRetries) toolCheck(currentRetry + 1); else { Logger.Log($"Failed to download {missingTools} after retries."); ShowMessage("Error", "Tool download failed after multiple attempts."); } } else { ShowMessage("No Internet connection", "You have files missing, which need to be downloaded but there is no Internet Connection. The program will now terminate."); Environment.Exit(1); } } } else { try { Directory.CreateDirectory("bin/Tools"); Logger.Log("Created Tools folder."); toolCheck(); // Retry once after creating the directory } catch (Exception ex) { ShowMessage("Error", $"Failed to create tools directory: {ex.Message}"); Logger.Log($"Failed to create Tools folder: {ex.Message}"); } } } private void ShowDownloadWaitDialog() { DownloadWait dw = new DownloadWait("Downloading Tools - Please Wait", "", this); try { dw.changeOwner(mw); } catch (Exception) { Logger.Log("Failed to set DownloadWait owner."); } dw.ShowDialog(); Thread.Sleep(200); // Pause after showing dialog } private void ShowMessage(string title, string message) { Custom_Message cm = new Custom_Message(title, message); try { cm.Owner = mw; } catch (Exception) { } cm.ShowDialog(); } public void UpdatePathSet() { PathsSet = JsonSettingsManager.Settings.PathsSet; if (BaseStore != JsonSettingsManager.Settings.BasePath) BaseStore = JsonSettingsManager.Settings.BasePath; if (InjectStore != JsonSettingsManager.Settings.BasePath) InjectStore = JsonSettingsManager.Settings.OutPath; } public bool ValidatePathsStillExist() { string basePath = JsonSettingsManager.Settings.BasePath; string outPath = JsonSettingsManager.Settings.OutPath; bool baseExists = EnsureDirectoryExists(ref basePath, "bin/BaseGames"); bool injectExists = EnsureDirectoryExists(ref outPath, "InjectedGames"); if (baseExists && injectExists) { JsonSettingsManager.Settings.BasePath = basePath; JsonSettingsManager.Settings.OutPath = outPath; JsonSettingsManager.Settings.PathsSet = true; JsonSettingsManager.SaveSettings(); return true; } return false; } private bool EnsureDirectoryExists(ref string path, string defaultSubDir) { if (Directory.Exists(path)) return true; string fullPath = Path.Combine(Directory.GetCurrentDirectory(), defaultSubDir); Directory.CreateDirectory(fullPath); path = fullPath; return false; } public void GetBases(GameConsoles console) { string baseFilePath = $@"bin/bases/bases.vcb{console.ToString().ToLower()}"; var tempBases = VCBTool.ReadBasesFromVCB(baseFilePath); LBases.Clear(); LBases.Add(new GameBases { Name = "Custom", Region = Regions.EU }); LBases.AddRange(tempBases); LGameBasesString.Clear(); LGameBasesString.AddRange(LBases.Select(b => b.Name == "Custom" ? b.Name : $"{b.Name} {b.Region}")); } public GameBases getBasefromName(string name) { string nameWithoutRegion = name.Substring(0, name.Length - 3); string region = name.Substring(name.Length - 2); return LNDS.Concat(LN64).Concat(LNES).Concat(LSNES).Concat(LGBA).Concat(LTG16).Concat(LMSX).Concat(LWII) .FirstOrDefault(b => b.Name == nameWithoutRegion && b.Region.ToString() == region); } private void GetAllBases() { LN64.Clear(); LNDS.Clear(); LNES.Clear(); LSNES.Clear(); LGBA.Clear(); LTG16.Clear(); LMSX.Clear(); LWII.Clear(); lNDS = VCBTool.ReadBasesFromVCB($@"bin/bases/bases.vcbnds"); lNES = VCBTool.ReadBasesFromVCB($@"bin/bases/bases.vcbnes"); lSNES = VCBTool.ReadBasesFromVCB($@"bin/bases/bases.vcbsnes"); lN64 = VCBTool.ReadBasesFromVCB($@"bin/bases/bases.vcbn64"); lGBA = VCBTool.ReadBasesFromVCB($@"bin/bases/bases.vcbgba"); lTG16 = VCBTool.ReadBasesFromVCB($@"bin/bases/bases.vcbtg16"); lMSX = VCBTool.ReadBasesFromVCB($@"bin/bases/bases.vcbmsx"); lWii = VCBTool.ReadBasesFromVCB($@"bin/bases/bases.vcbwii"); CreateSettingIfNotExist(lNDS, GameConsoles.NDS); CreateSettingIfNotExist(lNES, GameConsoles.NES); CreateSettingIfNotExist(lSNES, GameConsoles.SNES); CreateSettingIfNotExist(lGBA, GameConsoles.GBA); CreateSettingIfNotExist(lN64, GameConsoles.N64); CreateSettingIfNotExist(lTG16, GameConsoles.TG16); CreateSettingIfNotExist(lMSX, GameConsoles.MSX); CreateSettingIfNotExist(lWii, GameConsoles.WII); } private void CreateSettingIfNotExist(List basesList, GameConsoles console) { string keyFilePath = $@"bin\keys\{console.ToString().ToLower()}.vck"; if (!File.Exists(keyFilePath)) { var keyList = basesList.Select(baseGame => new TKeys { Base = baseGame }).ToList(); KeyFile.ExportFile(keyList, console); } else FixupKeys(basesList, console); } private void FixupKeys(List basesList, GameConsoles console) { string keyFilePath = $@"bin\keys\{console.ToString().ToLower()}.vck"; var savedKeys = KeyFile.ReadBasesFromKeyFile(keyFilePath); var updatedKeys = savedKeys.Concat( basesList.Where(baseGame => !savedKeys.Any(savedKey => savedKey.Base.Name == baseGame.Name && savedKey.Base.Region == baseGame.Region)) .Select(baseGame => new TKeys { Base = baseGame }) ).ToList(); File.Delete(keyFilePath); KeyFile.ExportFile(updatedKeys, console); } private void UpdateKeyFile(List basesList, GameConsoles console) { string keyFilePath = $@"bin\keys\{console.ToString().ToLower()}.vck"; if (File.Exists(keyFilePath)) { var savedKeys = KeyFile.ReadBasesFromKeyFile(keyFilePath); var updatedKeys = basesList.Select(baseGame => { var existingKey = savedKeys.FirstOrDefault(savedKey => savedKey.Base.Name == baseGame.Name && savedKey.Base.Region == baseGame.Region); return existingKey ?? new TKeys { Base = baseGame, Tkey = null }; }).ToList(); File.Delete(keyFilePath); KeyFile.ExportFile(updatedKeys, console); } } public void getTempList(GameConsoles console) { Ltemp = console switch { GameConsoles.NDS => LNDS, GameConsoles.N64 => LN64, GameConsoles.GBA => LGBA, GameConsoles.NES => LNES, GameConsoles.SNES => LSNES, GameConsoles.TG16 => LTG16, GameConsoles.MSX => LMSX, GameConsoles.WII => LWII, _ => throw new ArgumentOutOfRangeException(nameof(console), console, null) }; } public void EnterKey(bool ck) { EnterKey ek = new EnterKey(ck); try { ek.Owner = mw; } catch (Exception) { } ek.ShowDialog(); } public bool checkcKey(string key) { string lowerKey = key.ToLower(); int keyHash = lowerKey.GetHashCode(); if (keyHash == 1274359530 || GetDeterministicHashCode(lowerKey) == -485504051) { JsonSettingsManager.Settings.Ckey = lowerKey; ckeys = true; JsonSettingsManager.SaveSettings(); return true; } ckeys = false; return false; } public bool isCkeySet() { string lowerCKey = JsonSettingsManager.Settings.Ckey.ToLower(); ckeys = lowerCKey.GetHashCode() == 1274359530 || GetDeterministicHashCode(lowerCKey) == -485504051; return ckeys; } public bool checkKey(string key) { string lowerKey = key.ToLower(); if (GbTemp.KeyHash == lowerKey.GetHashCode() || GbTemp.KeyHash == GetDeterministicHashCode(lowerKey)) { string consoleName = GetConsoleOfBase(gbTemp).ToString().ToLower(); string keyFilePath = $@"bin\keys\{consoleName}.vck"; UpdateKeyInFile(lowerKey, keyFilePath, GbTemp, GetConsoleOfBase(gbTemp)); return true; } return false; } public void UpdateKeyInFile(string key, string file, GameBases baseGame, GameConsoles console) { if (File.Exists(file)) { var keyEntries = KeyFile.ReadBasesFromKeyFile(file); foreach (var entry in keyEntries) if (entry.Base.Name == baseGame.Name && entry.Base.Region == baseGame.Region) entry.Tkey = key; File.Delete(file); KeyFile.ExportFile(keyEntries, console); } } public bool isKeySet(GameBases baseGame) { var keyEntries = KeyFile.ReadBasesFromKeyFile($@"bin\keys\{GetConsoleOfBase(baseGame).ToString().ToLower()}.vck"); return keyEntries.Any(entry => entry.Base.Name == baseGame.Name && entry.Base.Region == baseGame.Region && entry.Tkey != null); } public void ImageWarning() { Custom_Message cm = new Custom_Message("Image Warning", " Images need to either be in a Bit Depth of 32bit or 24bit. \n If using Tools like paint.net do not choose the Auto function."); try { cm.Owner = mw; } catch (Exception) { } cm.ShowDialog(); } public bool choosefolder = false; public bool CBaseConvertInfo() { Custom_Message cm = new Custom_Message("NUS Custom Base", " You seem to have added a NUS format Custom Base. \n Do you want it to be converted to be used with the Injector?"); try { cm.Owner = mw; } catch (Exception) { } cm.ShowDialog(); if (choosefolder) { choosefolder = false; return true; } return false; } public TKeys getTkey(GameBases baseGame) { var keyEntries = KeyFile.ReadBasesFromKeyFile($@"bin\keys\{GetConsoleOfBase(baseGame).ToString().ToLower()}.vck"); return keyEntries.FirstOrDefault(entry => entry.Base.Name == baseGame.Name && entry.Base.Region == baseGame.Region && entry.Tkey != null); } public void Download() { ValidatePathsStillExist(); if (CheckForInternetConnection()) { DownloadWait dw; if (GameConfiguration.Console == GameConsoles.WII || GameConfiguration.Console == GameConsoles.GCN) { double speed = TestDownloadSpeed(); // in MB/s TimeSpan estimatedTime = CalculateEstimatedTime(speed); // Start the actual download Task.Run(() => { Injection.Download(this); }); // Display the waiting dialog with the estimated time dw = new DownloadWait("Downloading Base - Please Wait", estimatedTime, this); } else { Task.Run(() => { Injection.Download(this); }); dw = new DownloadWait("Downloading Base - Please Wait", "", this); } try { dw.changeOwner(mw); } catch (Exception) { } dw.ShowDialog(); Progress = 0; } } private double TestDownloadSpeed() { Stopwatch sw = Stopwatch.StartNew(); //Using this file as a test file, it's about 16MB which should be small enough to not impact anything. string url = "https://github.com/NicoAICP/UWUVCI-Tools/raw/master/gba2.zip"; byte[] data; try { using var webClient = new WebClient(); data = webClient.DownloadData(url); } catch { return 0; } sw.Stop(); double timeTaken = sw.Elapsed.TotalSeconds; double sizeOfData = data.Length / (1024.0 * 1024.0); // size in MB return sizeOfData / timeTaken; // returns speed in MB/s } private TimeSpan CalculateEstimatedTime(double speedInMBps) { const double fileSize = 8.5 * 1024; // file size in MB if (speedInMBps <= 0) return TimeSpan.MaxValue; double estimatedTimeInSec = fileSize / speedInMBps; return TimeSpan.FromSeconds(estimatedTimeInSec); } public GameConsoles GetConsoleOfBase(GameBases gb) { var consoleMappings = new Dictionary> { { GameConsoles.NDS, lNDS }, { GameConsoles.N64, lN64 }, { GameConsoles.NES, lNES }, { GameConsoles.SNES, lSNES }, { GameConsoles.GBA, lGBA }, { GameConsoles.TG16, lTG16 }, { GameConsoles.MSX, lMSX }, { GameConsoles.WII, lWii } }; foreach (var mapping in consoleMappings) if (mapping.Value.Any(b => b.Name == gb.Name && b.Region == gb.Region)) return mapping.Key; Logger.Log($"Console of base is not one of the listed ones to work with UWUVCI, what did you do? Name: {gb.Name}, Region: {gb.Region}"); throw new Exception("Console of base is not one of the listed ones to work with UWUVCI, what you do?"); } public List getInfoOfBase(GameBases gb) { string basePath = $@"{JsonSettingsManager.Settings.BasePath}\{gb.Name.Replace(":", "")} [{gb.Region}]"; return new List { Directory.Exists(basePath), isKeySet(gb), isCkeySet() }; } public void SetInjectPath() { SetFolderPath( folderPath => JsonSettingsManager.Settings.OutPath = folderPath, JsonSettingsManager.Settings.SetOutOnce, "Inject Folder"); } private void SetFolderPath(Action setPathAction, bool setOnceFlag, string folderDescription) { using (var dialog = new CommonOpenFileDialog { IsFolderPicker = true }) { if (dialog.ShowDialog() == CommonFileDialogResult.Ok) try { if (DirectoryIsEmpty(dialog.FileName)) { setPathAction(dialog.FileName); setOnceFlag = true; JsonSettingsManager.SaveSettings(); UpdatePathSet(); } else PromptUserForFolderSelection(dialog.FileName, setPathAction, setOnceFlag, folderDescription); } catch (Exception e) { HandleError(e); } } ArePathsSet(); } private void PromptUserForFolderSelection(string folderPath, Action setPathAction, bool setOnceFlag, string folderDescription) { Custom_Message cm = new Custom_Message("Information", $" Folder contains Files or Subfolders, do you really want to use this folder as the {folderDescription}? "); try { cm.Owner = mw; } catch (Exception) { } cm.ShowDialog(); if (choosefolder) { choosefolder = false; setPathAction(folderPath); setOnceFlag = true; JsonSettingsManager.SaveSettings(); UpdatePathSet(); } else { SetFolderPath(setPathAction, setOnceFlag, folderDescription); } } private void HandleError(Exception e) { Console.WriteLine(e.Message); Custom_Message cm = new Custom_Message("Error", " An Error occured, please try again! "); try { cm.Owner = mw; } catch (Exception) { } cm.ShowDialog(); } public void SetBasePath() { SetFolderPath( folderPath => JsonSettingsManager.Settings.BasePath = folderPath, JsonSettingsManager.Settings.SetBaseOnce, "Bases Folder"); } public void ArePathsSet() { if (ValidatePathsStillExist()) { JsonSettingsManager.Settings.PathsSet = true; JsonSettingsManager.SaveSettings(); } UpdatePathSet(); } public bool DirectoryIsEmpty(string path) { return !Directory.EnumerateFileSystemEntries(path).Any(); } public void getBootIMGGBA(string rom) { try { string repoid = ""; string SystemType = "gba/"; using (var fs = new FileStream(rom, FileMode.Open, FileAccess.Read)) { byte[] procode = new byte[4]; fs.Seek(0xAC, SeekOrigin.Begin); fs.Read(procode, 0, 4); repoid = ByteArrayToString(procode); Regex rgx = new Regex("[^a-zA-Z0-9 -]"); repoid = rgx.Replace(repoid, ""); Console.WriteLine("prodcode before scramble: " + repoid); fs.Close(); Console.WriteLine("prodcode after scramble: " + repoid); } List repoids = new List { SystemType + repoid, SystemType + repoid.Substring(0, 3) + "E", SystemType + repoid.Substring(0, 3) + "P", SystemType + repoid.Substring(0, 3) + "J" }; FetchAndProcessRepoImages(SystemType, repoid, repoids, GameConsoles.GBA); } catch (Exception e) { var cm = new Custom_Message("Missing Required Header Data", "Rom has missing some binary in the header used to determine the name, fetching images and other configuration files will not be possible.\nError Message: " + e.Message); try { cm.Owner = mw; } catch (Exception) { } cm.ShowDialog(); } } public void getBootIMGSNES(string rom) { try { string SystemType = "snes/"; var repoid = GetFakeSNESProdcode(rom); List repoids = new List { SystemType + repoid }; FetchAndProcessRepoImages(SystemType, repoid, repoids, GameConsoles.SNES); } catch (Exception e) { var cm = new Custom_Message("Missing Required Header Data", "Rom has missing some binary in the header used to determine the name, fetching images and other configuration files will not be possible.\nError Message: " + e.Message); try { cm.Owner = mw; } catch (Exception) { } cm.ShowDialog(); } } public void getBootIMGMSX(string rom) { try { string SystemType = "msx/"; var repoid = GetFakeMSXTGProdcode(rom, true); List repoids = new List { SystemType + repoid }; FetchAndProcessRepoImages(SystemType, repoid, repoids, GameConsoles.MSX); } catch (Exception e) { var cm = new Custom_Message("Missing Required Header Data", "Rom has missing some binary in the header used to determine the name, fetching images and other configuration files will not be possible.\nError Message: " + e.Message); try { cm.Owner = mw; } catch (Exception) { } cm.ShowDialog(); } } public void getBootIMGTG(string rom) { try { string SystemType = "tg16/"; var repoid = GetFakeMSXTGProdcode(rom, false); List repoids = new List { SystemType + repoid }; FetchAndProcessRepoImages(SystemType, repoid, repoids, GameConsoles.TG16); } catch (Exception e) { var cm = new Custom_Message("Missing Required Header Data", "Rom has missing some binary in the header used to determine the name, fetching images and other configuration files will not be possible.\nError Message: " + e.Message); try { cm.Owner = mw; } catch (Exception) { } cm.ShowDialog(); } } private string GetFakeMSXTGProdcode(string v, bool msx) { Regex rgx = new Regex("[^a-zA-Z0-9 -]"); Regex rgx2 = new Regex("[^0-9]"); byte[] procode = new byte[0x210]; using var md5 = MD5.Create(); using (var fs = new FileStream(v, FileMode.Open, FileAccess.Read)) { fs.Read(procode, 0, 0x210); fs.Close(); } string hash = GetMd5Hash(md5, procode); //var number = /*hash.GetHashCode();*/ gamename.GetHashCode(); if (msx) Console.Write("MSX"); else Console.Write("TG16"); Console.WriteLine(" PRODCODE:"); Console.WriteLine("File Name: " + new FileInfo(v).Name); Console.WriteLine("MD5 of Code Snippet: " + hash); string hashonlynumbers = rgx2.Replace(hash, ""); do { if (hashonlynumbers.Length < 10) hashonlynumbers += 0; } while (hashonlynumbers.Length < 10); string first10 = new string(new char[] { hashonlynumbers[0], hashonlynumbers[1], hashonlynumbers[2], hashonlynumbers[3], hashonlynumbers[4], hashonlynumbers[5], hashonlynumbers[6], hashonlynumbers[7], hashonlynumbers[8] }); string prodcode = getCodeOfNumbers(Convert.ToInt32(first10)); if (msx) prodcode += "SX"; else prodcode += "TG"; //Console.WriteLine("NumberHash of GameName: "+ number); Console.WriteLine("Fake ProdCode: " + prodcode); Console.WriteLine("---------------------------------------------------"); return prodcode; } private string GetFakeSNESProdcode(string path) { Regex rgx = new Regex("[^a-zA-Z0-9 -]"); Regex rgx2 = new Regex("[^0-9]"); using var md5 = MD5.Create(); var name = new byte[] { }; using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read)) { byte[] procode = new byte[4]; fs.Seek(0x7FB2, SeekOrigin.Begin); fs.Read(procode, 0, 4); string repoid = ByteArrayToString(procode); repoid = rgx.Replace(repoid, ""); if (repoid.Length < 4) { fs.Seek(0xFFC0, SeekOrigin.Begin); procode = new byte[21]; fs.Read(procode, 0, 21); name = procode; repoid = ByteArrayToString(procode); repoid = rgx.Replace(repoid, ""); } if (repoid.Length < 4) { fs.Seek(0x7FC0, SeekOrigin.Begin); procode = new byte[21]; fs.Read(procode, 0, 21); name = procode; } } string gamenameo = ByteArrayToString(name); string gamename = rgx.Replace(gamenameo, ""); string hash = GetMd5Hash(md5, gamename); //var number = /*hash.GetHashCode();*/ gamename.GetHashCode(); Console.WriteLine("SNES PRODCODE:"); Console.WriteLine("GameName: " + gamename); Console.WriteLine("MD5 of Name: " + hash); string hashonlynumbers = rgx2.Replace(hash, ""); do { if (hashonlynumbers.Length < 10) hashonlynumbers += 0; } while (hashonlynumbers.Length < 10); string first10 = new string(new char[] { hashonlynumbers[0], hashonlynumbers[1], hashonlynumbers[2], hashonlynumbers[3], hashonlynumbers[4], hashonlynumbers[5], hashonlynumbers[6], hashonlynumbers[7], hashonlynumbers[8] }); //Console.WriteLine("NumberHash of GameName: "+ number); Console.WriteLine("Fake ProdCode: " + getCodeOfNumbers(Convert.ToInt32(first10))); Console.WriteLine("---------------------------------------------------"); return getCodeOfNumbers(Convert.ToInt32(first10)); // Console.WriteLine(md5.ComputeHash(name)); // Console.WriteLine("NumberCode: "+hash.GetHashCode()); } private string GetFakeNESProdcode(string path) { Regex rgx = new Regex("[^a-zA-Z0-9 -]"); Regex rgx2 = new Regex("[^0-9]"); byte[] procode = new byte[0xB0]; using var md5 = MD5.Create(); using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read)) { fs.Seek(0x8000, SeekOrigin.Begin); fs.Read(procode, 0, 0xB0); fs.Close(); } string hash = GetMd5Hash(md5, procode); //var number = /*hash.GetHashCode();*/ gamename.GetHashCode(); Console.WriteLine("NES PRODCODE:"); Console.WriteLine("File Name: " + new FileInfo(path).Name); Console.WriteLine("MD5 of Code Snippet: " + hash); string hashonlynumbers = rgx2.Replace(hash, ""); do { if (hashonlynumbers.Length < 10) hashonlynumbers += 0; } while (hashonlynumbers.Length < 10); string first10 = new string(new char[] { hashonlynumbers[0], hashonlynumbers[1], hashonlynumbers[2], hashonlynumbers[3], hashonlynumbers[4], hashonlynumbers[5], hashonlynumbers[6], hashonlynumbers[7], hashonlynumbers[8] }); //Console.WriteLine("NumberHash of GameName: "+ number); Console.WriteLine("Fake ProdCode: " + getCodeOfNumbers(Convert.ToInt32(first10))); Console.WriteLine("---------------------------------------------------"); return getCodeOfNumbers(Convert.ToInt32(first10)); } private void FetchAndProcessRepoImages(string systemType, string repoid, List repoids, GameConsoles console) { if (CheckForInternetConnectionWOWarning()) { GetRepoImages(systemType, repoid, repoids); checkForAdditionalFiles(console, repoids); } } public void getBootIMGNES(string rom) { try { string SystemType = "nes/"; string repoid = GetFakeNESProdcode(rom); List repoids = new List { SystemType + repoid }; FetchAndProcessRepoImages(SystemType, repoid, repoids, GameConsoles.NES); } catch (Exception e) { var cm = new Custom_Message("Missing Required Header Data", "Rom has missing some binary in the header used to determine the name, fetching images and other configuration files will not be possible.\nError Message: " + e.Message); try { cm.Owner = mw; } catch (Exception) { } cm.ShowDialog(); } } public void getBootIMGNDS(string rom) { try { string repoid = ""; string SystemType = "nds/"; using (var fs = new FileStream(rom, FileMode.Open, FileAccess.Read)) { byte[] procode = new byte[4]; fs.Seek(0xC, SeekOrigin.Begin); fs.Read(procode, 0, 4); repoid = ByteArrayToString(procode); Regex rgx = new Regex("[^a-zA-Z0-9 -]"); repoid = rgx.Replace(repoid, ""); Console.WriteLine("prodcode before scramble: " + repoid); fs.Close(); Console.WriteLine("prodcode after scramble: " + repoid); } List repoids = new List { SystemType + repoid, SystemType + repoid.Substring(0, 3) + "E", SystemType + repoid.Substring(0, 3) + "P", SystemType + repoid.Substring(0, 3) + "J" }; FetchAndProcessRepoImages(SystemType, repoid, repoids, GameConsoles.NDS); } catch (Exception e) { var cm = new Custom_Message("Missing Required Header Data", "Rom has missing some binary in the header used to determine the name, fetching images and other configuration files will not be possible.\nError Message: " + e.Message); try { cm.Owner = mw; } catch (Exception) { } cm.ShowDialog(); } } public void getBootIMGN64(string rom) { try { string repoid = ""; string SystemType = "n64/"; List repoids = new List(); using var fs = new FileStream(rom, FileMode.Open, FileAccess.Read); byte[] procode = new byte[6]; fs.Seek(0x3A, SeekOrigin.Begin); fs.Read(procode, 0, 6); repoid = ByteArrayToString(procode); Regex rgx = new Regex("[^a-zA-Z0-9 -]"); repoid = rgx.Replace(repoid, ""); Console.WriteLine("prodcode before scramble: " + repoid); fs.Close(); Console.WriteLine("prodcode after scramble: " + repoid); repoids.Add(SystemType + repoid); repoids.Add(SystemType + new string(new char[] { repoid[0], repoid[2], repoid[1], repoid[3] })); FetchAndProcessRepoImages(SystemType, repoid, repoids, GameConsoles.N64); } catch (Exception e) { var cm = new Custom_Message("Missing Required Header Data", "Rom has missing some binary in the header used to determine the name, fetching images and other configuration files will not be possible.\nError Message: " + e.Message); try { cm.Owner = mw; } catch (Exception) { } cm.ShowDialog(); } } static string GetMd5Hash(MD5 md5Hash, byte[] input) { // Compute the hash from the byte array input. byte[] hashData = md5Hash.ComputeHash(input); // Convert the byte array to a hexadecimal string. return ConvertByteArrayToHexString(hashData); } static string GetMd5Hash(MD5 md5Hash, string input) { // Compute the hash from the string input. byte[] hashData = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input)); // Convert the byte array to a hexadecimal string. return ConvertByteArrayToHexString(hashData); } private static string ConvertByteArrayToHexString(byte[] data) { StringBuilder hexString = new StringBuilder(data.Length * 2); // Loop through each byte of the hashed data // and format each one as a hexadecimal string. foreach (byte b in data) hexString.Append(b.ToString("x2")); return hexString.ToString(); } static string getCodeOfNumbers(int number) { string ts = number.ToString(); int n1 = Convert.ToInt32(ts[0] + ts[1]); int n2 = Convert.ToInt32(ts[2] + ts[3]); int n3 = Convert.ToInt32(ts[4] + ts[5]); int n4; try { n4 = Convert.ToInt32(ts[6] + ts[7]); } catch (Exception) { n4 = Convert.ToInt32(ts[6]); } char[] letters = new char[] { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' }; while (n1 > 23) { n1 -= 23; } while (n2 > 23) { n2 -= 23; } while (n3 > 23) { n3 -= 23; } while (n4 > 23) { n4 -= 23; } var toret = new char[] { letters[n1], letters[n2], letters[n3], letters[n4] }; return new string(toret).ToUpper(); } private string ByteArrayToString(byte[] arr) { return new ASCIIEncoding().GetString(arr); } public string getInternalWIIGCNName(string OpenGame, bool gc) { string ret = ""; try { string TempString = ""; string SystemType = (gc ? "gcn" : "wii") + "/"; var repoid = ""; char TempChar; //WBFS Check List repoids = new List(); using (var reader = new BinaryReader(File.OpenRead(OpenGame))) { reader.BaseStream.Position = 0x00; if (new FileInfo(OpenGame).Extension.Contains("wbfs")) //Performs actions if the header indicates a WBFS file { reader.BaseStream.Position = 0x200; reader.BaseStream.Position = 0x218; reader.BaseStream.Position = 0x220; while ((TempChar = reader.ReadChar()) != 0) ret += TempChar; reader.BaseStream.Position = 0x200; while ((TempChar = reader.ReadChar()) != 0) TempString += TempChar; repoid = TempString; } else { reader.BaseStream.Position = 0x18; reader.BaseStream.Position = 0x20; while ((TempChar = reader.ReadChar()) != 0) ret += TempChar; reader.BaseStream.Position = 0x00; while ((TempChar = reader.ReadChar()) != 0) TempString += TempChar; repoid = TempString; } } repoids.Add(SystemType + repoid); repoids.Add(SystemType + repoid.Substring(0, 3) + "E" + repoid.Substring(4, 2)); repoids.Add(SystemType + repoid.Substring(0, 3) + "P" + repoid.Substring(4, 2)); repoids.Add(SystemType + repoid.Substring(0, 3) + "J" + repoid.Substring(4, 2)); FetchAndProcessRepoImages(SystemType, repoid, repoids, gc ? GameConsoles.GCN : GameConsoles.WII); } catch (Exception) { Custom_Message cm = new Custom_Message("Unknown ROM", " It seems that you inserted an unknown ROM as a Wii or GameCube game. \n It is not recommended continuing with said ROM!"); try { cm.Owner = mw; } catch (Exception) { } cm.ShowDialog(); } return ret; } public bool CheckForInternetConnection() { try { using (var client = new WebClient()) { client.Proxy = null; client.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.BypassCache); client.DownloadString("http://google.com/generate_204"); } return true; } catch (WebException) { ShowNoInternetConnectionMessage(); Environment.Exit(1); return false; } catch (Exception ex) { // Optionally log the unexpected exception Console.WriteLine($"Unexpected error: {ex.Message}"); ShowNoInternetConnectionMessage(); Environment.Exit(1); return false; } } private void ShowNoInternetConnectionMessage() { var cm = new Custom_Message("No Internet Connection", "To download tools, bases, or required files, you need to be connected to the Internet. The program will now terminate."); try { cm.Owner = mw; } catch (Exception ex) { // Optionally log the exception if setting the owner fails Console.WriteLine($"Failed to set message owner: {ex.Message}"); } cm.ShowDialog(); } public bool CheckForInternetConnectionWOWarning() { try { using var client = new WebClient(); client.Proxy = null; client.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.BypassCache); client.DownloadString("http://google.com/generate_204"); return true; } catch (WebException) { return false; } catch (Exception ex) { // Optionally log the unexpected exception Console.WriteLine($"Unexpected error: {ex.Message}"); return false; } } /// /// Checks for additional files like INI and BootSound for the given console and repository IDs. /// /// The game console type. /// List of repository IDs to check for additional files. private void checkForAdditionalFiles(GameConsoles console, List repoids) { string repoPath = Path.Combine(Directory.GetCurrentDirectory(), "bin", "repo"); if (!Directory.Exists(repoPath)) Directory.CreateDirectory(repoPath); string linkbase = "https://raw.githubusercontent.com/UWUVCI-PRIME/UWUVCI-IMAGES/master/"; bool iniFound = false; bool bootSoundFound = false; string iniUrl = ""; string bootSoundUrl = ""; string bootSoundExtension = "btsnd"; // Check for INI file if (console == GameConsoles.N64) { iniFound = TryFindFileInRepo(repoids, linkbase, "/game.ini", out iniUrl); } // Check for BootSound file bootSoundFound = TryFindFileInRepo(repoids, linkbase, $"/BootSound.{bootSoundExtension}", out bootSoundUrl); // Prompt user and download additional files if found if (iniFound || bootSoundFound) { string message = GetAdditionalFilesMessage(iniFound, bootSoundFound); var customMessage = new Custom_Message("Found additional Files", message); SetWindowOwner(customMessage); customMessage.ShowDialog(); if (addi) { DownloadAdditionalFiles(iniFound, iniUrl, bootSoundFound, bootSoundUrl, console, bootSoundExtension); addi = false; } } } /// /// Tries to find a specific file in the repository. /// /// List of repository IDs to search. /// Base URL for the repository. /// Specific file path to look for. /// The found file URL. /// True if the file is found, otherwise false. private bool TryFindFileInRepo(List repoids, string linkbase, string filePath, out string fileUrl) { foreach (var repoid in repoids) { fileUrl = linkbase + repoid + filePath; if (RemoteFileExists(fileUrl)) return true; } fileUrl = string.Empty; return false; } /// /// Generates the appropriate message for additional files found. /// /// Whether an INI file was found. /// Whether a BootSound file was found. /// A message string detailing the additional files found. private string GetAdditionalFilesMessage(bool iniFound, bool bootSoundFound) { if (iniFound && bootSoundFound) return "There is an additional INI and BootSound file available for download. Do you want to download those?"; if (iniFound) return "There is an additional INI file available for download. Do you want to download it?"; if (bootSoundFound) return "There is an additional BootSound file available for download. Do you want to download it?"; return "There are more additional files found. Do you want to download those?"; } /// /// Sets the owner of the window to the main window if possible. /// /// The window to set the owner for. private void SetWindowOwner(Custom_Message window) { try { window.Owner = mw; } catch (Exception) { // Suppress exception when setting owner fails } } /// /// Downloads additional files (INI and BootSound) if they exist. /// /// Whether an INI file was found. /// The URL of the INI file. /// Whether a BootSound file was found. /// The URL of the BootSound file. /// The game console type. /// The file extension for BootSound. private void DownloadAdditionalFiles(bool iniFound, string iniUrl, bool bootSoundFound, string bootSoundUrl, GameConsoles console, string bootSoundExtension) { var client = new WebClient(); string repoPath = Path.Combine(Directory.GetCurrentDirectory(), "bin", "repo"); if (iniFound) { string iniFilePath = Path.Combine(repoPath, "game.ini"); client.DownloadFile(iniUrl, iniFilePath); (Thing as N64Config).ini.Text = iniFilePath; GameConfiguration.N64Stuff.INIPath = iniFilePath; } if (bootSoundFound) { string bootSoundFilePath = Path.Combine(repoPath, $"bootSound.{bootSoundExtension}"); client.DownloadFile(bootSoundUrl, bootSoundFilePath); BootSound = bootSoundFilePath; switch (console) { case GameConsoles.NDS: case GameConsoles.NES: case GameConsoles.SNES: case GameConsoles.MSX: (Thing as OtherConfigs).sound.Text = bootSoundFilePath; break; case GameConsoles.GBA: (Thing as GBA).sound.Text = bootSoundFilePath; break; case GameConsoles.N64: (Thing as N64Config).sound.Text = bootSoundFilePath; break; case GameConsoles.WII: if (test == GameConsoles.GCN) (Thing as GCConfig).sound.Text = bootSoundFilePath; else (Thing as WiiConfig).sound.Text = bootSoundFilePath; break; case GameConsoles.TG16: (Thing as TurboGrafX).sound.Text = bootSoundFilePath; break; } } } public string GetURL(string console) { string lowerConsole = console.ToLowerInvariant(); string formattedConsole = (lowerConsole == "tg16" || lowerConsole == "tgcd") ? "tgfx" : lowerConsole; return $"https://uwuvci-prime.github.io/UWUVCI-Resources/{formattedConsole}/{formattedConsole}.html"; } WaveOutEvent waveOutEvent = new WaveOutEvent(); AudioFileReader audioFileReader; public System.Timers.Timer t; public bool passtrough = true; internal bool enableWii = true; internal bool backupenableWii = true; public void PlaySound() { try { t = new System.Timers.Timer(200); t.Elapsed += isDone; audioFileReader = new AudioFileReader(BootSound); waveOutEvent.Init(audioFileReader); t.Start(); Console.WriteLine("Playing file..."); waveOutEvent.Play(); } catch (Exception ex) { Console.WriteLine($"Error playing sound: {ex.Message}"); } } public void isDoneMW() { try { waveOutEvent?.Stop(); waveOutEvent?.Dispose(); audioFileReader?.Dispose(); t?.Stop(); } catch (Exception ex) { Console.WriteLine($"Error during sound cleanup: {ex.Message}"); } } public void isDone(object source, ElapsedEventArgs e) { try { if (waveOutEvent.PlaybackState == PlaybackState.Stopped || waveOutEvent.GetPositionTimeSpan() > TimeSpan.FromSeconds(6)) { waveOutEvent.Stop(); waveOutEvent.Dispose(); audioFileReader.Dispose(); t.Stop(); } } catch (Exception ex) { Console.WriteLine($"Error during playback check: {ex.Message}"); } } public void RestartIntoBypass() { using (Process p = new Process()) { p.StartInfo.FileName = System.Windows.Application.ResourceAssembly.Location; p.StartInfo.Arguments = $"{(debug ? "--debug " : string.Empty)}--skip{(saveworkaround ? " --spacebypass" : string.Empty)}"; p.Start(); } Environment.Exit(0); } /// The type of system (e.g., "Wii", "N64"). /// The repository ID for the image. /// An optional list of repository IDs to check for images. private void GetRepoImages(string SystemType, string repoid, List repoids = null) { string linkbase = "https://raw.githubusercontent.com/UWUVCI-PRIME/UWUVCI-IMAGES/master/"; string[] extensions = { "png", "jpg", "jpeg", "tga" }; // If no specific repoids are provided, generate possible repoids based on the given repoid if (repoids == null || repoids?.Count == 0) repoids = GenerateRepoIds(SystemType, repoid); // Iterate through all combinations of repoids and extensions to find an existing image foreach (string extension in extensions) foreach (string id in repoids) { string imageUrl = $"{linkbase}{id}/iconTex.{extension}"; if (RemoteFileExists(imageUrl)) { HandleImageLoading(imageUrl, extension, id); return; } } } /// /// Generates a list of possible repository IDs based on the system type and the provided repository ID. /// /// The type of system (e.g., "Wii", "N64"). /// The repository ID for the image. /// A list of possible repository IDs. private List GenerateRepoIds(string SystemType, string repoid) { string fakeId = new string(new char[] { repoid[0], repoid[2], repoid[1], repoid[3] }); return new List { SystemType + repoid, SystemType + repoid.Substring(0, 3) + "E", SystemType + repoid.Substring(0, 3) + "P", SystemType + repoid.Substring(0, 3) + "J", SystemType + fakeId, SystemType + fakeId.Substring(0, 3) + "E", SystemType + fakeId.Substring(0, 3) + "P", SystemType + fakeId.Substring(0, 3) + "J" }; } /// /// Handles the image loading process and displays any necessary messages to the user. /// /// The URL of the image to load. /// The file extension of the image. /// The repository ID associated with the image. private void HandleImageLoading(string imageUrl, string extension, string repoid) { if (extension.Equals("tga", StringComparison.OrdinalIgnoreCase)) ShowTgaWarning(); var imgMessage = new IMG_Message(imageUrl, imageUrl.Replace("iconTex", "bootTvTex"), repoid); try { imgMessage.Owner = mw; } catch (Exception) { // Swallow exception to prevent crashing when setting the owner fails } imgMessage.ShowDialog(); } /// /// Displays a warning message when a TGA image is detected. /// private void ShowTgaWarning() { var message = new Custom_Message("TGA Extension Warning", "TGA files can't natively be rendered in UWUVCI. Instead, the image may show an error. This is normal behavior.\n\n" + "If there are actual errors, please download the files from \"https://github.com/UWUVCI-PRIME/UWUVCI-IMAGES\", convert them to PNG, " + "and then manually insert them."); try { message.Owner = mw; } catch (Exception) { // Swallow exception to prevent crashing when setting the owner fails } message.ShowDialog(); } } } ================================================ FILE: UWUVCI AIO WPF/Models/N64Conf.cs ================================================ using System; namespace UWUVCI_AIO_WPF.Models { [Serializable] public class N64Conf { private string iniPath = null; public string INIPath { get { return iniPath; } set { iniPath = value; } } private bool darkFilter = false; public bool DarkFilter { get { return darkFilter; } set { darkFilter = value; } } private bool wideScreen = false; public bool WideScreen { get { return wideScreen; } set { wideScreen = value; } } public byte[] INIBin { get; set; } } } ================================================ FILE: UWUVCI AIO WPF/Models/PNGTGA.cs ================================================ using System; namespace UWUVCI_AIO_WPF.Models { [Serializable] public class PNGTGA { private string imgPath = null; public string ImgPath { get { return imgPath; } set { imgPath = value; } } public byte[] ImgBin { get; set; } = null; public string extension { get; set; } } } ================================================ FILE: UWUVCI AIO WPF/Models/TKeys.cs ================================================ using GameBaseClassLibrary; using System; namespace UWUVCI_AIO_WPF.Models { [Serializable] public class TKeys { public GameBases Base { get; set; } public string Tkey { get; set; } = null; } } ================================================ FILE: UWUVCI AIO WPF/Models/ToolStep.cs ================================================ namespace UWUVCI_AIO_WPF.Models { public class ToolStep { public string ToolName { get; set; } // The name of the tool to run (e.g., wit, nfs2iso2nfs) public string Arguments { get; set; } // The arguments to pass to the tool public string CurrentDirectory { get; set; } // The directory where the tool should be run public string Function { get; set; } // The function in UWUVCI where the step originated } } ================================================ FILE: UWUVCI AIO WPF/Properties/AssemblyInfo.cs ================================================ using System.Reflection; using System.Runtime.InteropServices; using System.Windows; // Allgemeine Informationen über eine Assembly werden über die folgenden // Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern, // die einer Assembly zugeordnet sind. [assembly: AssemblyTitle("UWUVCI AIO")] [assembly: AssemblyDescription("Ultimate Wii U Virtual Console Injector")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("NicoAICP, ZestyTS")] [assembly: AssemblyProduct("UWUVCI AIO")] [assembly: AssemblyCopyright("Copyright © 2025")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] // Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly // für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von // COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen. [assembly: ComVisible(false)] //Um mit dem Erstellen lokalisierbarer Anwendungen zu beginnen, legen Sie //ImCodeVerwendeteKultur in der .csproj-Datei //in einer fest. Wenn Sie in den Quelldateien beispielsweise Deutsch //(Deutschland) verwenden, legen Sie auf \"de-DE\" fest. Heben Sie dann die Auskommentierung //des nachstehenden NeutralResourceLanguage-Attributs auf. Aktualisieren Sie "en-US" in der nachstehenden Zeile, //sodass es mit der UICulture-Einstellung in der Projektdatei übereinstimmt. //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] [assembly: ThemeInfo( ResourceDictionaryLocation.None, //Speicherort der designspezifischen Ressourcenwörterbücher //(wird verwendet, wenn eine Ressource auf der Seite nicht gefunden wird, // oder in den Anwendungsressourcen-Wörterbüchern nicht gefunden werden kann.) ResourceDictionaryLocation.SourceAssembly //Speicherort des generischen Ressourcenwörterbuchs //(wird verwendet, wenn eine Ressource auf der Seite nicht gefunden wird, // designspezifischen Ressourcenwörterbuch nicht gefunden werden kann.) )] // Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten: // // Hauptversion // Nebenversion // Buildnummer // Revision // // Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden, // indem Sie "*" wie unten gezeigt eingeben: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("3.100.1")] [assembly: AssemblyFileVersion("3.100.1")] ================================================ FILE: UWUVCI AIO WPF/Properties/Resources.Designer.cs ================================================ //------------------------------------------------------------------------------ // // Dieser Code wurde von einem Tool generiert. // Laufzeitversion:4.0.30319.42000 // // Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn // der Code erneut generiert wird. // //------------------------------------------------------------------------------ namespace UWUVCI_AIO_WPF.Properties { using System; /// /// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. /// // Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert // -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert. // Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen // mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { private static global::System.Resources.ResourceManager resourceMan; private static global::System.Globalization.CultureInfo resourceCulture; [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] internal Resources() { } /// /// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("UWUVCI_AIO_WPF.Properties.Resources", typeof(Resources).Assembly); resourceMan = temp; } return resourceMan; } } /// /// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle /// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Globalization.CultureInfo Culture { get { return resourceCulture; } set { resourceCulture = value; } } /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap bootLogoTex { get { object obj = ResourceManager.GetObject("bootLogoTex", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap GB_alt1 { get { object obj = ResourceManager.GetObject("GB_alt1", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap GB_alt2 { get { object obj = ResourceManager.GetObject("GB_alt2", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap GBA { get { object obj = ResourceManager.GetObject("GBA", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap GBA_alt1 { get { object obj = ResourceManager.GetObject("GBA_alt1", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap GBA_alt2 { get { object obj = ResourceManager.GetObject("GBA_alt2", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap GBC { get { object obj = ResourceManager.GetObject("GBC", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap GBC_alt1 { get { object obj = ResourceManager.GetObject("GBC_alt1", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap GBC_alt2 { get { object obj = ResourceManager.GetObject("GBC_alt2", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap GCN { get { object obj = ResourceManager.GetObject("GCN", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap GCN_ICON2 { get { object obj = ResourceManager.GetObject("GCN_ICON2", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap GCN_ICON3 { get { object obj = ResourceManager.GetObject("GCN_ICON3", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap HBICON { get { object obj = ResourceManager.GetObject("HBICON", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap homebrew3 { get { object obj = ResourceManager.GetObject("homebrew3", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap Icon { get { object obj = ResourceManager.GetObject("Icon", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Sucht eine lokalisierte Ressource vom Typ System.Byte[]. /// internal static byte[] mario { get { object obj = ResourceManager.GetObject("mario", resourceCulture); return ((byte[])(obj)); } } /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap MSX { get { object obj = ResourceManager.GetObject("MSX", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap MSX_alt1 { get { object obj = ResourceManager.GetObject("MSX_alt1", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap MSX_alt2 { get { object obj = ResourceManager.GetObject("MSX_alt2", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap N64 { get { object obj = ResourceManager.GetObject("N64", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap N64_alt1 { get { object obj = ResourceManager.GetObject("N64_alt1", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap N64_alt2 { get { object obj = ResourceManager.GetObject("N64_alt2", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap NDS { get { object obj = ResourceManager.GetObject("NDS", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap NDS_Alt1 { get { object obj = ResourceManager.GetObject("NDS_Alt1", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap NDS_Alt2 { get { object obj = ResourceManager.GetObject("NDS_Alt2", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap NES { get { object obj = ResourceManager.GetObject("NES", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap NES_alt1 { get { object obj = ResourceManager.GetObject("NES_alt1", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap NES_alt2 { get { object obj = ResourceManager.GetObject("NES_alt2", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap newgameboy { get { object obj = ResourceManager.GetObject("newgameboy", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap SFAM { get { object obj = ResourceManager.GetObject("SFAM", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap SNES_alt1 { get { object obj = ResourceManager.GetObject("SNES_alt1", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap SNES_alt2 { get { object obj = ResourceManager.GetObject("SNES_alt2", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap SNES_PAL { get { object obj = ResourceManager.GetObject("SNES_PAL", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap SNES_USA { get { object obj = ResourceManager.GetObject("SNES_USA", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap TG16 { get { object obj = ResourceManager.GetObject("TG16", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap TGCD { get { object obj = ResourceManager.GetObject("TGCD", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap TGFX_alt1 { get { object obj = ResourceManager.GetObject("TGFX_alt1", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap TGFX_alt2 { get { object obj = ResourceManager.GetObject("TGFX_alt2", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap WII { get { object obj = ResourceManager.GetObject("WII", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap Wii2 { get { object obj = ResourceManager.GetObject("Wii2", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap wii3New { get { object obj = ResourceManager.GetObject("wii3New", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap WiiIcon { get { object obj = ResourceManager.GetObject("WiiIcon", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } /// /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap WIIWARE { get { object obj = ResourceManager.GetObject("WIIWARE", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } } } ================================================ FILE: UWUVCI AIO WPF/Properties/Resources.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ..\Resources\bootLogoTex.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\GBA.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\GBA alt1.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\GBA alt2.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\GBC.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\GBC alt1.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\GBC alt2.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\GB alt1.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\GB alt2.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\GCN.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\GCN ICON2.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\GCN ICON3.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\HBICON.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\homebrew3.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\Icon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\mario.mp3;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ..\Resources\MSX.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\MSX alt1.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\MSX alt2.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\N64.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\N64 alt1.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\N64 alt2.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\NDS.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\NDS Alt1.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\NDS Alt2.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\NES.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\NES alt1.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\NES alt2.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\newgameboy.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\SFAM.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\SNES alt1.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\SNES alt2.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\SNES-PAL.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\SNES-USA.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\TG16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\TGCD.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\TGFX alt1.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\TGFX alt2.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\WII.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\Wii2.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\wii3New.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\WiiIcon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\WIIWARE.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ================================================ FILE: UWUVCI AIO WPF/Properties/Settings.Designer.cs ================================================ //------------------------------------------------------------------------------ // // Dieser Code wurde von einem Tool generiert. // Laufzeitversion:4.0.30319.42000 // // Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn // der Code erneut generiert wird. // //------------------------------------------------------------------------------ namespace UWUVCI_AIO_WPF.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.13.0.0")] internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); public static Settings Default { get { return defaultInstance; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("False")] public bool PathsSet { get { return ((bool)(this["PathsSet"])); } set { this["PathsSet"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("")] public string BasePath { get { return ((string)(this["BasePath"])); } set { this["BasePath"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("")] public string OutPath { get { return ((string)(this["OutPath"])); } set { this["OutPath"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("")] public string Ckey { get { return ((string)(this["Ckey"])); } set { this["Ckey"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("False")] public bool SetBaseOnce { get { return ((bool)(this["SetBaseOnce"])); } set { this["SetBaseOnce"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("False")] public bool SetOutOnce { get { return ((bool)(this["SetOutOnce"])); } set { this["SetOutOnce"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("True")] public bool UpgradeRequired { get { return ((bool)(this["UpgradeRequired"])); } set { this["UpgradeRequired"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("")] public string SysKey { get { return ((string)(this["SysKey"])); } set { this["SysKey"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("")] public string SysKey1 { get { return ((string)(this["SysKey1"])); } set { this["SysKey1"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("False")] public bool dont { get { return ((bool)(this["dont"])); } set { this["dont"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("False")] public bool ndsw { get { return ((bool)(this["ndsw"])); } set { this["ndsw"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("False")] public bool snesw { get { return ((bool)(this["snesw"])); } set { this["snesw"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("False")] public bool gczw { get { return ((bool)(this["gczw"])); } set { this["gczw"] = value; } } [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("")] public string Ancast { get { return ((string)(this["Ancast"])); } set { this["Ancast"] = value; } } } } ================================================ FILE: UWUVCI AIO WPF/Properties/Settings.settings ================================================  False False False True False False False False ================================================ FILE: UWUVCI AIO WPF/Settings.cs ================================================ namespace UWUVCI_AIO_WPF.Properties { // Diese Klasse ermöglicht die Behandlung bestimmter Ereignisse der Einstellungsklasse: // Das SettingChanging-Ereignis wird ausgelöst, bevor der Wert einer Einstellung geändert wird. // Das PropertyChanged-Ereignis wird ausgelöst, nachdem der Wert einer Einstellung geändert wurde. // Das SettingsLoaded-Ereignis wird ausgelöst, nachdem die Einstellungswerte geladen wurden. // Das SettingsSaving-Ereignis wird ausgelöst, bevor die Einstellungswerte gespeichert werden. internal sealed partial class Settings { public Settings() { // // Heben Sie die Auskommentierung der unten angezeigten Zeilen auf, um Ereignishandler zum Speichern und Ändern von Einstellungen hinzuzufügen: // // this.SettingChanging += this.SettingChangingEventHandler; // // this.SettingsSaving += this.SettingsSavingEventHandler; // } private void SettingChangingEventHandler(object sender, System.Configuration.SettingChangingEventArgs e) { // Fügen Sie hier Code zum Behandeln des SettingChangingEvent-Ereignisses hinzu. } private void SettingsSavingEventHandler(object sender, System.ComponentModel.CancelEventArgs e) { // Fügen Sie hier Code zum Behandeln des SettingsSaving-Ereignisses hinzu. } } } ================================================ FILE: UWUVCI AIO WPF/UI/Done.xaml ================================================  ================================================ FILE: UWUVCI AIO WPF/UI/Done.xaml.cs ================================================ using System.Windows.Controls; namespace UWUVCI_AIO_WPF.UI { /// /// Interaktionslogik für Done.xaml /// public partial class Done : Page { public Done() { InitializeComponent(); } } } ================================================ FILE: UWUVCI AIO WPF/UI/Frames/InjectFrame.xaml ================================================  ================================================ FILE: UWUVCI AIO WPF/UI/Frames/SettingsFrame.xaml.cs ================================================ using System; using System.Diagnostics; using System.Windows; using System.Windows.Controls; using UWUVCI_AIO_WPF.Helpers; using UWUVCI_AIO_WPF.UI.Windows; namespace UWUVCI_AIO_WPF.UI.Frames { /// /// Interaktionslogik für SettingsFrame.xaml /// public partial class SettingsFrame : Page, IDisposable { MainWindow parent; public SettingsFrame(MainWindow mw) { InitializeComponent(); parent = mw; // spm.Content += "\nThis will most likely fix the Injection Process, if it's stuck before it shows Copy Base"; } public void Dispose() { } private void Button_Click(object sender, RoutedEventArgs e) { /* TitleKeys tk = new TitleKeys(); tk.ShowDialog();*/ } private void Button_Click_1(object sender, RoutedEventArgs e) { MainViewModel mvm = FindResource("mvm") as MainViewModel; mvm.EnterKey(true); } private void Button_Click_2(object sender, RoutedEventArgs e) { parent.paths(false); } private void Button_Click_3(object sender, RoutedEventArgs e) { MainViewModel mvm = FindResource("mvm") as MainViewModel; mvm.UpdateBases(); } private void Button_Click_4(object sender, RoutedEventArgs e) { Process[] pname = Process.GetProcessesByName("INICreator"); if (pname.Length == 0) { Process.Start(@"bin\Tools\INICreator.exe"); } } private void Button_Click_5(object sender, RoutedEventArgs e) { Custom_Message cm = new Custom_Message("Credits", "UWUVCI AIO - NicoAICP, Morilli, ZestyTS\nBeta Testers/Contributors - wowjinxy, Danis, Adolfobenjaminv\n\nBuildPcePkg & BuildTurboCDPcePkg - JohnnyGo\nCdecrypt - crediar\nCNUSPACKER - NicoAICP, Morilli\nINICreator - NicoAICP\nN64Converter - Morilli\npng2tga - Easy2Convert\ninject_gba_c (psb) - Morilli\nRetroInject_C - Morilli\ntga_verify - Morilli\nWiiUDownloader - Morilli\nwiiurpxtool - 0CHB0\nGoomba - FluBBa\nDarkFilter Removal N64 - MelonSpeedruns, ZestyTS\nNintendont SD Card Menu - TeconMoon\nwit - Wiimm\nGetExtTypePatcher - Fix94\nnfs2iso2nfs - sabykos, piratesephiroth, Fix94 and many more\nWii-VMC - wanikoko\nIcon/TV Bootimages - Flump, ZestyTS\nNKit - Nanook\nImage Creation Base - Phacox\nWiiGameLanguage Patcher - ReturnerS\nChangeAspectRatio - andot\nvWii Title Forwarder - Fix94"); try { cm.Owner = (FindResource("mvm") as MainViewModel).mw; } catch (Exception) { } cm.ShowDialog(); } private void Button_Click_6(object sender, RoutedEventArgs e) { MainViewModel mvm = FindResource("mvm") as MainViewModel; mvm.Update(true); } private void Button_Click_7(object sender, RoutedEventArgs e) { MainViewModel mvm = FindResource("mvm") as MainViewModel; mvm.UpdateTools(); } private void Button_Click_8(object sender, RoutedEventArgs e) { MainViewModel mvm = FindResource("mvm") as MainViewModel; mvm.ResetTKQuest(); } private void Button_Click_9(object sender, RoutedEventArgs e) { Process[] pname = Process.GetProcessesByName("NintendontConfig"); if (pname.Length == 0) { Process.Start(@"bin\Tools\NintendontConfig.exe"); } } private void Button_Click_10(object sender, RoutedEventArgs e) { JsonSettingsManager.Settings.dont = false; JsonSettingsManager.Settings.ndsw = false; JsonSettingsManager.Settings.snesw = false; JsonSettingsManager.Settings.gczw = false; JsonSettingsManager.SaveSettings(); } private void Button_Click_11(object sender, RoutedEventArgs e) { using (LogoCreator ic = new LogoCreator()) { try { ic.Owner = (FindResource("mvm") as MainViewModel).mw; } catch (Exception) { } ic.ShowDialog(); } } private void Button_Click_12(object sender, RoutedEventArgs e) { (FindResource("mvm") as MainViewModel).RestartIntoBypass(); } private void Button_Click_13(object sender, RoutedEventArgs e) { Process.Start("https://ko-fi.com/zestyts"); } private void BtnZestyTSVersion(object sender, RoutedEventArgs e) { Process.Start("https://zestyts.itch.io/uwuvci-v3"); } private void ShowTutorialScreens_Click(object sender, RoutedEventArgs e) { new IntroductionWindow().ShowDialog(); } } } ================================================ FILE: UWUVCI AIO WPF/UI/Frames/StartFrame.xaml ================================================  ================================================ FILE: UWUVCI AIO WPF/UI/Frames/StartFrame.xaml.cs ================================================ using System.Diagnostics; using System.Windows; using System.Windows.Controls; namespace UWUVCI_AIO_WPF.UI.Frames { /// /// Interaktionslogik für StartFrame.xaml /// public partial class StartFrame : Page { public StartFrame() { InitializeComponent(); tb.Text += "\n\nIf any Issues happen during injection and you updated from the old version using the AutoUpdater, please go to settings and click Update Tools."; } private void Button_Click(object sender, RoutedEventArgs e) { Process.Start("https://ko-fi.com/nicoaicp"); } private void Button_Click2(object sender, RoutedEventArgs e) { Process.Start("https://ko-fi.com/zestyts"); } } } ================================================ FILE: UWUVCI AIO WPF/UI/Windows/BaseGameWindow.xaml ================================================  ================================================ FILE: UWUVCI AIO WPF/UI/Windows/MenuWindow.xaml.cs ================================================ using System; using System.Collections.Generic; using System.IO; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; using System.Diagnostics; using NAudio.Wave; using UWUVCI_AIO_WPF.Models; using UWUVCI_AIO_WPF.UI.Frames; using GameBaseClassLibrary; using UWUVCI_AIO_WPF.UI.Frames.Path; namespace UWUVCI_AIO_WPF { public partial class MainWindow : Window { private readonly List _konamiCode = new List { Key.Up, Key.Up, Key.Down, Key.Down, Key.Left, Key.Right, Key.Left, Key.Right, Key.B, Key.A, Key.Enter }; private bool movingrn = false; private bool startedmoving = false; private int _match; public static byte[] StreamToBytes(Stream stream) { long originalPosition = stream.CanSeek ? stream.Position : 0; if (stream.CanSeek) stream.Position = 0; try { using (var memoryStream = new MemoryStream()) { stream.CopyTo(memoryStream); return memoryStream.ToArray(); } } finally { if (stream.CanSeek) stream.Position = originalPosition; } } internal void is32() { Wii.DataContext = this; Wii.IsEnabled = false; GC.DataContext = this; GC.IsEnabled = false; } static MemoryStream sound = new MemoryStream(Properties.Resources.mario); static MemoryStream ms = new MemoryStream(StreamToBytes(sound)); static WaveStream ws = new Mp3FileReader(ms); static WaveOutEvent output = new WaveOutEvent(); public MainWindow() { InitializeComponent(); load_frame.Content = new StartFrame(); (FindResource("mvm") as MainViewModel).setMW(this); } private void Window_KeyUp(object sender, KeyEventArgs e) { if (e.Key == _konamiCode[_match]) { if (++_match >= _konamiCode.Count) { _match = 0; output.PlaybackStopped += Media_Ended; output.Init(ws); output.Play(); } } else if (_match > 0 && e.Key != _konamiCode[_match]) { _match = 0; } } public static void Media_Ended(object sender, EventArgs e) { DisposeResources(); } private static void DisposeResources() { ms?.Dispose(); ws?.Dispose(); output?.Dispose(); } public bool move = true; private void ButtonCloseMenu_Click(object sender, RoutedEventArgs e) { ButtonOpenMenu.Visibility = Visibility.Visible; ButtonCloseMenu.Visibility = Visibility.Collapsed; } private void ButtonOpenMenu_Click(object sender, RoutedEventArgs e) { ButtonOpenMenu.Visibility = Visibility.Collapsed; ButtonCloseMenu.Visibility = Visibility.Visible; } private void ButtonCloseMenu_Click(object sender, MouseEventArgs e) { if (!movingrn) { // Uncomment if Storyboard is needed // Storyboard sb = this.FindResource("MenuClose") as Storyboard; // if (sb != null) { BeginStoryboard(sb); } } } private void ButtonOpenMenu_Click(object sender, MouseEventArgs e) { if (!movingrn) { // Uncomment if Storyboard is needed // Storyboard sb = this.FindResource("MenuOpen") as Storyboard; // if (sb != null) { BeginStoryboard(sb); } } } private void MoveWindow(object sender, MouseButtonEventArgs e) { startedmoving = true; try { if (e.ChangedButton == MouseButton.Left && move) { movingrn = true; DragMove(); } } catch (Exception) { // Exception handling logic can be added here } finally { startedmoving = false; } } private void DestroyFrame() { // Dispose of the content if necessary // (load_frame.Content as IDisposable)?.Dispose(); load_frame.Content = null; load_frame.NavigationService.RemoveBackEntry(); } public void ListView_Click(object sender, MouseButtonEventArgs e) { if (!startedmoving && !movingrn) { ResetMainViewModel(); try { MainViewModel mvm = FindResource("mvm") as MainViewModel; mvm.curr = (sender as ListView).SelectedItem as ListViewItem; UpdateUIForSelectedIndex(mvm, (sender as ListView).SelectedIndex); } catch { // Exception handling logic can be added here } } } private void ResetMainViewModel() { MainViewModel mvm = FindResource("mvm") as MainViewModel; if (mvm.curr != null) mvm.curr.Background = null; mvm.GameConfiguration = new GameConfig(); mvm.LGameBasesString.Clear(); mvm.CanInject = false; mvm.BaseDownloaded = false; mvm.RomSet = false; mvm.RomPath = null; mvm.Injected = false; mvm.CBasePath = null; mvm.bcf = null; mvm.BootSound = null; mvm.setThing(null); mvm.gc2rom = null; mvm.Index = -1; mvm.donttrim = false; mvm.NKITFLAG = false; mvm.prodcode = ""; mvm.foldername = ""; mvm.jppatch = false; mvm.GC = false; mvm.test = GameConsoles.WII; mvm.regionfrii = false; mvm.cd = false; mvm.regionfriijp = false; mvm.regionfriius = false; mvm.pixelperfect = false; mvm.injected2 = false; mvm.Brightness = 80; mvm.RendererScale = false; mvm.RemoveDeflicker = false; mvm.RemoveDithering = false; mvm.HalfVFilter = false; mvm.PixelArtUpscaler = 0; mvm.DSLayout = false; mvm.RemoveCreatedIMG(); mvm.isDoneMW(); DestroyFrame(); mvm.saveconf = null; mvm.GC = false; } private void UpdateUIForSelectedIndex(MainViewModel mvm, int selectedIndex) { Console.WriteLine(Directory.GetCurrentDirectory()); string title = selectedIndex switch { 0 => "UWUVCI AIO - NDS VC INJECT", 1 => "UWUVCI AIO - GBA VC INJECT", 2 => "UWUVCI AIO - N64 VC INJECT", 3 => "UWUVCI AIO - SNES VC INJECT", 4 => "UWUVCI AIO - NES VC INJECT", 5 => "UWUVCI AIO - TurboGrafX-16 VC INJECT", 6 => "UWUVCI AIO - MSX VC INJECT", 7 => "UWUVCI AIO - Wii VC INJECT", 8 => "UWUVCI AIO - GC VC INJECT", _ => tbTitleBar.Text }; tbTitleBar.Text = title; var console = selectedIndex switch { 0 => GameConsoles.NDS, 1 => GameConsoles.GBA, 2 => GameConsoles.N64, 3 => GameConsoles.SNES, 4 => GameConsoles.NES, 5 => GameConsoles.TG16, 6 => GameConsoles.MSX, 7 => GameConsoles.WII, 8 => GameConsoles.GCN, _ => GameConsoles.WII }; mvm.GameConfiguration = new GameConfig(); mvm.test = console; load_frame.Content = new INJECTFRAME(console); } public void paths(bool remove) { load_frame.Content = null; if (remove) load_frame.Content = new SettingsFrame(this); else load_frame.Content = new Paths(this); } private void Window_Close(object sender, RoutedEventArgs e) { Close(); } private void Window_Minimize(object sender, RoutedEventArgs e) { WindowState = WindowState.Minimized; } private void Button_MouseEnter(object sender, MouseEventArgs e) { min.Background = new SolidColorBrush(Color.FromArgb(100, 255, 255, 255)); } private void close_MouseEnter(object sender, MouseEventArgs e) { close.Background = new SolidColorBrush(Color.FromArgb(150, 255, 100, 100)); } private void close_MouseLeave(object sender, MouseEventArgs e) { close.Background = new SolidColorBrush(Color.FromArgb(0, 250, 250, 250)); } private void min_MouseLeave(object sender, MouseEventArgs e) { min.Background = new SolidColorBrush(Color.FromArgb(0, 250, 250, 250)); } private void sett_MouseEnter(object sender, MouseEventArgs e) { settings.Background = new SolidColorBrush(Color.FromArgb(100, 255, 255, 255)); } private void sett_MouseLeave(object sender, MouseEventArgs e) { settings.Background = new SolidColorBrush(Color.FromArgb(0, 250, 250, 250)); } public void setDebug(bool bypass) { MainViewModel mvm = FindResource("mvm") as MainViewModel; mvm.debug = true; spc.Visibility = Visibility.Visible; spc.Text = bypass ? "Debug & Space Bypass Mode" : "Debug Mode"; spc.ToolTip = bypass ? "Disables all Space checks. May cause issues.\n\"Unhides\" used Tools (Displays whats going on in the Background while a ProgressBar appears" : "\"Unhides\" used Tools (Displays whats going on in the Background while a ProgressBar appears"; } public void allowBypass() { MainViewModel mvm = FindResource("mvm") as MainViewModel; mvm.saveworkaround = true; spc.Visibility = Visibility.Visible; spc.Text = "Space Bypass Mode"; spc.ToolTip = "Disables all Space checks. May cause issues."; } private void Window_MouseUp(object sender, MouseButtonEventArgs e) { Task.Run(() => { System.Threading.Thread.Sleep(30); if (!startedmoving) { movingrn = false; } }); } private void settings_Click(object sender, RoutedEventArgs e) { MainViewModel mvm = FindResource("mvm") as MainViewModel; ResetMainViewModel(); tbTitleBar.Text = "UWUVCI AIO - Settings"; load_frame.Content = new SettingsFrame(this); } private void vwiiMode_Click(object sender, RoutedEventArgs e) { try { var p = new Process(); var fileName = Application.ResourceAssembly.Location; foreach (var file in Directory.GetFiles(Directory.GetCurrentDirectory(), "*.exe")) { if (Path.GetFileName(file).ToLower().Contains("vwii")) { fileName = file; break; } } p.StartInfo.FileName = fileName; p.Start(); Environment.Exit(0); } catch { // Exception handling logic can be added here } } } } ================================================ FILE: UWUVCI AIO WPF/UI/Windows/TitleKeys - Kopieren.xaml ================================================  ================================================ FILE: UWUVCI AIO WPF/UI/Windows/TitleKeys - Kopieren.xaml.cs ================================================ using System.Windows; namespace UWUVCI_AIO_WPF.UI.Windows { /// /// Interaktionslogik für TitleKeys___Kopieren.xaml /// public partial class TitleKeys_Kopieren : Window { public TitleKeys_Kopieren() { InitializeComponent(); } } } ================================================ FILE: UWUVCI AIO WPF/UI/Windows/TitleKeys.xaml ================================================