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-12-10 04:23:21 +01:00
# include <thread>
2019-12-17 00:15:40 +01:00
# include <memory>
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"
2019-12-17 00:15:40 +01:00
# include "install/sdmc_xci.hpp"
# include "install/sdmc_nsp.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-11-30 17:12:45 +01:00
# include "sdInstall.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-11-17 16:01:06 +01:00
mainApp - > instpage - > awooImage - > SetVisible ( ! inst : : config : : gayMode ) ;
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 ( ) {
2019-12-10 04:30:40 +01:00
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! " , " Nintendo ninjas have been dispatched to your current location. " , " And we didn't even have to shove a political ideology down your throat to get here! " } ;
2019-11-03 21:02:15 +01:00
srand ( time ( NULL ) ) ;
return ( finishMessages [ rand ( ) % finishMessages . size ( ) ] ) ;
}
2019-11-30 17:12:45 +01:00
void installNspFromFile ( std : : vector < std : : filesystem : : path > ourTitleList , int whereToInstall )
2019-10-23 00:14:37 +02:00
{
2019-11-03 22:16:52 +01:00
inst : : util : : initInstallServices ( ) ;
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-30 17:12:45 +01:00
unsigned int titleItr ;
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-30 17:12:45 +01:00
for ( titleItr = 0 ; titleItr < ourTitleList . size ( ) ; titleItr + + ) {
2019-11-30 18:06:49 +01:00
inst : : ui : : setTopInstInfoText ( " Installing " + inst : : util : : shortenString ( ourTitleList [ titleItr ] . filename ( ) . string ( ) , 40 , true ) + " from SD card " ) ;
2019-12-17 00:15:40 +01:00
std : : unique_ptr < tin : : install : : Install > installTask ;
2019-11-29 09:23:11 +01:00
2019-11-30 17:12:45 +01:00
if ( ourTitleList [ titleItr ] . extension ( ) = = " .xci " | | ourTitleList [ titleItr ] . extension ( ) = = " .xcz " ) {
2019-12-17 00:15:40 +01:00
auto sdmcXCI = std : : make_shared < tin : : install : : xci : : SDMCXCI > ( ourTitleList [ titleItr ] ) ;
installTask = std : : make_unique < tin : : install : : xci : : XCIInstallTask > ( m_destStorageId , inst : : config : : ignoreReqVers , sdmcXCI ) ;
2019-11-29 09:23:11 +01:00
} else {
2019-12-17 00:15:40 +01:00
auto sdmcNSP = std : : make_shared < tin : : install : : nsp : : SDMCNSP > ( ourTitleList [ titleItr ] ) ;
installTask = std : : make_unique < tin : : install : : nsp : : NSPInstall > ( m_destStorageId , inst : : config : : ignoreReqVers , sdmcNSP ) ;
2019-12-06 21:03:12 +01:00
}
2019-12-17 00:15:40 +01:00
LOG_DEBUG ( " %s \n " , " Preparing installation " ) ;
inst : : ui : : setInstInfoText ( " Preparing installation... " ) ;
inst : : ui : : setInstBarPerc ( 0 ) ;
installTask - > Prepare ( ) ;
installTask - > Begin ( ) ;
2019-10-23 00:14:37 +02:00
}
}
2019-11-02 01:12:00 +01:00
catch ( std : : exception & e )
{
2019-11-30 18:12:59 +01:00
LOG_DEBUG ( " Failed to install " ) ;
LOG_DEBUG ( " %s " , e . what ( ) ) ;
2019-11-02 01:12:00 +01:00
fprintf ( stdout , " %s " , e . what ( ) ) ;
2019-11-30 17:12:45 +01:00
inst : : ui : : setInstInfoText ( " Failed to install " + inst : : util : : shortenString ( ourTitleList [ titleItr ] . filename ( ) . string ( ) , 42 , true ) ) ;
2019-11-04 01:13:10 +01:00
inst : : ui : : setInstBarPerc ( 0 ) ;
2019-12-10 04:23:21 +01:00
std : : thread audioThread ( inst : : util : : playAudio , " romfs:/audio/bark.wav " ) ;
2019-11-30 17:12:45 +01:00
inst : : ui : : mainApp - > CreateShowDialog ( " Failed to install " + inst : : util : : shortenString ( ourTitleList [ titleItr ] . filename ( ) . string ( ) , 42 , true ) + " ! " , " Partially installed contents can be removed from the System Settings applet. \n \n " + ( std : : string ) e . what ( ) , { " OK " } , true ) ;
2019-12-10 04:23:21 +01:00
audioThread . join ( ) ;
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 + + ) {
2019-11-30 17:12:45 +01:00
if ( ourTitleList . size ( ) = = 1 ) ourTitleList [ 0 ] = oldNamesOfFiles [ i ] ;
2019-11-06 03:13:41 +01:00
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-12-10 04:23:21 +01:00
std : : thread audioThread ( inst : : util : : playAudio , " romfs:/audio/awoo.wav " ) ;
2019-11-30 17:12:45 +01:00
if ( ourTitleList . size ( ) > 1 ) {
2019-11-06 03:45:26 +01:00
if ( inst : : config : : deletePrompt ) {
2019-11-30 17:12:45 +01:00
if ( inst : : ui : : mainApp - > CreateShowDialog ( std : : to_string ( ourTitleList . 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 ) {
for ( long unsigned int i = 0 ; i < ourTitleList . size ( ) ; i + + ) {
if ( std : : filesystem : : exists ( ourTitleList [ i ] ) ) std : : filesystem : : remove ( ourTitleList [ i ] ) ;
2019-11-06 03:45:26 +01:00
}
2019-11-02 01:12:00 +01:00
}
2019-11-30 17:12:45 +01:00
} else inst : : ui : : mainApp - > CreateShowDialog ( std : : to_string ( ourTitleList . 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-30 17:12:45 +01:00
if ( inst : : ui : : mainApp - > CreateShowDialog ( inst : : util : : shortenString ( ourTitleList [ 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 ( ourTitleList [ 0 ] ) ) std : : filesystem : : remove ( ourTitleList [ 0 ] ) ;
} else inst : : ui : : mainApp - > CreateShowDialog ( inst : : util : : shortenString ( ourTitleList [ 0 ] . filename ( ) . string ( ) , 42 , true ) + " installed! " , nspInstStuff : : finishedMessage ( ) , { " OK " } , true ) ;
2019-11-02 01:12:00 +01:00
}
2019-12-10 04:23:21 +01:00
audioThread . join ( ) ;
2019-11-02 01:12:00 +01:00
}
2019-10-26 03:00:13 +02:00
2019-11-30 18:12:59 +01:00
LOG_DEBUG ( " Done " ) ;
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
}
}