2019-11-01 21:00:28 +01:00
/*
Copyright ( c ) 2017 - 2018 Adubbz
Permission is hereby granted , free of charge , to any person obtaining a copy
of this software and associated documentation files ( the " Software " ) , to deal
in the Software without restriction , including without limitation the rights
to use , copy , modify , merge , publish , distribute , sublicense , and / or sell
copies of the Software , and to permit persons to whom the Software is
furnished to do so , subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software .
THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER
LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING FROM ,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE .
*/
2019-10-23 00:14:37 +02:00
# include <cstring>
# include <sstream>
2019-10-26 03:00:13 +02:00
# include <filesystem>
2019-11-03 21:02:15 +01:00
# include <ctime>
2019-10-30 02:58:53 +01:00
2019-10-23 00:14:37 +02:00
# include "install/install_nsp.hpp"
2019-11-29 09:23:11 +01:00
# include "install/install_xci.hpp"
# include "install/local_xci.hpp"
2019-10-23 00:14:37 +02:00
# include "nx/fs.hpp"
# include "util/file_util.hpp"
# include "util/title_util.hpp"
# include "util/error.hpp"
# include "ui/MainApplication.hpp"
2019-10-30 02:58:53 +01:00
# include "nspInstall.hpp"
2019-10-29 00:47:49 +01:00
# include "util/config.hpp"
# include "util/util.hpp"
2019-10-23 00:14:37 +02:00
namespace inst : : ui {
extern MainApplication * mainApp ;
2019-10-27 04:36:45 +01:00
void setTopInstInfoText ( std : : string ourText ) {
2019-10-24 21:53:54 +02:00
mainApp - > instpage - > pageInfoText - > SetText ( ourText ) ;
2019-10-23 00:14:37 +02:00
mainApp - > CallForRender ( ) ;
}
2019-10-27 04:36:45 +01:00
void setInstInfoText ( std : : string ourText ) {
mainApp - > instpage - > installInfoText - > SetText ( ourText ) ;
mainApp - > CallForRender ( ) ;
}
2019-10-25 03:33:41 +02:00
void setInstBarPerc ( double ourPercent ) {
mainApp - > instpage - > installBar - > SetVisible ( true ) ;
mainApp - > instpage - > installBar - > SetProgress ( ourPercent ) ;
mainApp - > CallForRender ( ) ;
}
2019-10-23 00:14:37 +02:00
void loadMainMenu ( ) {
mainApp - > LoadLayout ( mainApp - > mainPage ) ;
}
2019-10-24 21:53:54 +02:00
void loadInstallScreen ( ) {
mainApp - > instpage - > pageInfoText - > SetText ( " " ) ;
2019-10-27 04:36:45 +01:00
mainApp - > instpage - > installInfoText - > SetText ( " " ) ;
2019-10-25 03:33:41 +02:00
mainApp - > instpage - > installBar - > SetProgress ( 0 ) ;
mainApp - > instpage - > installBar - > SetVisible ( false ) ;
2019-10-31 16:56:16 +01:00
if ( inst : : config : : gayMode ) mainApp - > instpage - > awooImage - > SetVisible ( false ) ;
else mainApp - > instpage - > awooImage - > SetVisible ( true ) ;
2019-10-24 21:53:54 +02:00
mainApp - > LoadLayout ( mainApp - > instpage ) ;
mainApp - > CallForRender ( ) ;
}
2019-10-23 00:14:37 +02:00
}
namespace nspInstStuff {
2019-11-03 21:02:15 +01:00
std : : string finishedMessage ( ) {
std : : vector < std : : string > finishMessages = { " Enjoy your \" legal backups \" ! " , " I'm sure after you give the game a try you'll have tons of fun actually buying it! " , " You buy gamu right? Nintendo-san thanka-you for your purchase! " , " Bypassing DRM is great, isn't it? " , " You probably saved like six trees by not buying the game! All that plastic goes somewhere! " } ;
srand ( time ( NULL ) ) ;
return ( finishMessages [ rand ( ) % finishMessages . size ( ) ] ) ;
}
2019-11-02 01:12:00 +01:00
void installNspFromFile ( std : : vector < std : : filesystem : : path > ourNspList , int whereToInstall )
2019-10-23 00:14:37 +02:00
{
2019-11-03 22:16:52 +01:00
inst : : util : : initInstallServices ( ) ;
2019-11-09 17:13:26 +01:00
if ( appletGetAppletType ( ) = = AppletType_Application | | appletGetAppletType ( ) = = AppletType_SystemApplication ) appletBeginBlockingHomeButton ( 0 ) ;
2019-10-24 21:53:54 +02:00
inst : : ui : : loadInstallScreen ( ) ;
2019-11-02 01:12:00 +01:00
bool nspInstalled = true ;
2019-11-14 20:04:40 +01:00
NcmStorageId m_destStorageId = NcmStorageId_SdCard ;
2019-11-06 03:13:41 +01:00
std : : vector < std : : string > filesToBeRenamed = { } ;
std : : vector < std : : string > oldNamesOfFiles = { } ;
2019-10-23 00:14:37 +02:00
2019-11-14 20:04:40 +01:00
if ( whereToInstall ) m_destStorageId = NcmStorageId_BuiltInUser ;
2019-11-08 17:02:25 +01:00
unsigned int nspItr ;
2019-10-23 03:33:13 +02:00
2019-11-17 21:38:01 +01:00
std : : vector < int > previousClockValues ;
if ( inst : : config : : overClock ) {
previousClockValues . push_back ( inst : : util : : setClockSpeed ( 0 , 1785000000 ) [ 0 ] ) ;
previousClockValues . push_back ( inst : : util : : setClockSpeed ( 1 , 76800000 ) [ 0 ] ) ;
previousClockValues . push_back ( inst : : util : : setClockSpeed ( 2 , 1600000000 ) [ 0 ] ) ;
}
2019-11-02 01:12:00 +01:00
try
2019-10-23 00:14:37 +02:00
{
2019-11-08 17:02:25 +01:00
for ( nspItr = 0 ; nspItr < ourNspList . size ( ) ; nspItr + + ) {
2019-11-29 09:23:11 +01:00
if ( ourNspList [ nspItr ] . extension ( ) = = " .xci " | | ourNspList [ nspItr ] . extension ( ) = = " .xcz " ) {
inst : : ui : : setTopInstInfoText ( " Installing " + inst : : util : : shortenString ( ourNspList [ nspItr ] . filename ( ) . string ( ) , 42 , true ) ) ;
tin : : install : : xci : : LocalXCI xci ( ourNspList [ nspItr ] ) ;
tin : : install : : xci : : XCIInstallTask task ( xci , m_destStorageId , inst : : config : : ignoreReqVers ) ;
printf ( " Preparing installation \n " ) ;
inst : : ui : : setInstInfoText ( " Preparing installation... " ) ;
inst : : ui : : setInstBarPerc ( 0 ) ;
task . Prepare ( ) ;
task . Begin ( ) ;
} else {
inst : : ui : : setTopInstInfoText ( " Installing " + inst : : util : : shortenString ( ourNspList [ nspItr ] . filename ( ) . string ( ) , 42 , true ) ) ;
if ( ourNspList [ nspItr ] . extension ( ) = = " .nsz " ) {
oldNamesOfFiles . push_back ( ourNspList [ nspItr ] ) ;
std : : string newfilename = ourNspList [ nspItr ] . string ( ) . substr ( 0 , ourNspList [ nspItr ] . string ( ) . find_last_of ( ' . ' ) ) + " _temp.nsp " ;
rename ( ourNspList [ nspItr ] , newfilename ) ;
filesToBeRenamed . push_back ( newfilename ) ;
ourNspList [ nspItr ] = newfilename ;
}
std : : string path = " @Sdcard:// " + ourNspList [ nspItr ] . string ( ) . erase ( 0 , 6 ) ;
nx : : fs : : IFileSystem fileSystem ;
fileSystem . OpenFileSystemWithId ( path , FsFileSystemType_ApplicationPackage , 0 ) ;
tin : : install : : nsp : : SimpleFileSystem simpleFS ( fileSystem , " / " , path + " / " ) ;
tin : : install : : nsp : : NSPInstallTask task ( simpleFS , m_destStorageId , inst : : config : : ignoreReqVers ) ;
printf ( " Preparing installation \n " ) ;
inst : : ui : : setInstInfoText ( " Preparing installation... " ) ;
inst : : ui : : setInstBarPerc ( 0 ) ;
task . Prepare ( ) ;
task . Begin ( ) ;
2019-11-03 19:18:42 +01:00
}
2019-10-23 00:14:37 +02:00
}
}
2019-11-02 01:12:00 +01:00
catch ( std : : exception & e )
{
2019-11-03 19:18:42 +01:00
printf ( " Failed to install " ) ;
2019-11-02 01:12:00 +01:00
printf ( " %s " , e . what ( ) ) ;
fprintf ( stdout , " %s " , e . what ( ) ) ;
2019-11-22 18:17:12 +01:00
inst : : ui : : setInstInfoText ( " Failed to install " + inst : : util : : shortenString ( ourNspList [ nspItr ] . filename ( ) . string ( ) , 42 , true ) ) ;
2019-11-04 01:13:10 +01:00
inst : : ui : : setInstBarPerc ( 0 ) ;
2019-11-22 18:17:12 +01:00
inst : : ui : : mainApp - > CreateShowDialog ( " Failed to install " + inst : : util : : shortenString ( ourNspList [ nspItr ] . filename ( ) . string ( ) , 42 , true ) + " ! " , " Partially installed contents can be removed from the System Settings applet. \n \n " + ( std : : string ) e . what ( ) , { " OK " } , true ) ;
2019-11-02 01:12:00 +01:00
nspInstalled = false ;
}
2019-10-23 00:14:37 +02:00
2019-11-17 21:38:01 +01:00
if ( previousClockValues . size ( ) > 0 ) {
inst : : util : : setClockSpeed ( 0 , previousClockValues [ 0 ] ) ;
inst : : util : : setClockSpeed ( 1 , previousClockValues [ 1 ] ) ;
inst : : util : : setClockSpeed ( 2 , previousClockValues [ 2 ] ) ;
}
2019-11-06 03:13:41 +01:00
for ( unsigned int i = 0 ; i < filesToBeRenamed . size ( ) ; i + + ) {
if ( ourNspList . size ( ) = = 1 ) ourNspList [ 0 ] = oldNamesOfFiles [ i ] ;
if ( std : : filesystem : : exists ( filesToBeRenamed [ i ] ) ) {
rename ( filesToBeRenamed [ i ] . c_str ( ) , oldNamesOfFiles [ i ] . c_str ( ) ) ;
}
}
2019-11-02 01:12:00 +01:00
if ( nspInstalled ) {
2019-11-04 01:13:10 +01:00
inst : : ui : : setInstInfoText ( " Install complete " ) ;
inst : : ui : : setInstBarPerc ( 100 ) ;
2019-11-02 01:12:00 +01:00
if ( ourNspList . size ( ) > 1 ) {
2019-11-06 03:45:26 +01:00
if ( inst : : config : : deletePrompt ) {
2019-11-16 19:45:02 +01:00
if ( inst : : ui : : mainApp - > CreateShowDialog ( std : : to_string ( ourNspList . size ( ) ) + " files installed successfully! Delete them from the SD card? " , " The original files aren't needed anymore after they've been installed " , { " No " , " Yes " } , false ) = = 1 ) {
2019-11-06 03:45:26 +01:00
for ( long unsigned int i = 0 ; i < ourNspList . size ( ) ; i + + ) {
if ( std : : filesystem : : exists ( ourNspList [ i ] ) ) std : : filesystem : : remove ( ourNspList [ i ] ) ;
}
2019-11-02 01:12:00 +01:00
}
2019-11-08 17:02:25 +01:00
} else inst : : ui : : mainApp - > CreateShowDialog ( std : : to_string ( ourNspList . size ( ) ) + " files installed successfully! " , nspInstStuff : : finishedMessage ( ) , { " OK " } , true ) ;
2019-11-02 01:12:00 +01:00
} else {
2019-11-06 03:45:26 +01:00
if ( inst : : config : : deletePrompt ) {
2019-11-22 18:17:12 +01:00
if ( inst : : ui : : mainApp - > CreateShowDialog ( inst : : util : : shortenString ( ourNspList [ 0 ] . filename ( ) . string ( ) , 32 , true ) + " installed! Delete it from the SD card? " , " The original file isn't needed anymore after it's been installed " , { " No " , " Yes " } , false ) = = 1 ) if ( std : : filesystem : : exists ( ourNspList [ 0 ] ) ) std : : filesystem : : remove ( ourNspList [ 0 ] ) ;
} else inst : : ui : : mainApp - > CreateShowDialog ( inst : : util : : shortenString ( ourNspList [ 0 ] . filename ( ) . string ( ) , 42 , true ) + " installed! " , nspInstStuff : : finishedMessage ( ) , { " OK " } , true ) ;
2019-11-02 01:12:00 +01:00
}
}
2019-10-26 03:00:13 +02:00
2019-10-23 00:14:37 +02:00
printf ( " Done " ) ;
2019-11-09 17:13:26 +01:00
if ( appletGetAppletType ( ) = = AppletType_Application | | appletGetAppletType ( ) = = AppletType_SystemApplication ) appletEndBlockingHomeButton ( ) ;
2019-10-23 03:33:13 +02:00
inst : : ui : : loadMainMenu ( ) ;
2019-11-03 22:16:52 +01:00
inst : : util : : deinitInstallServices ( ) ;
2019-10-24 21:53:54 +02:00
return ;
2019-10-23 00:14:37 +02:00
}
}