mirror of
https://github.com/martravi/wiiqt.git
synced 2024-11-22 00:59:18 +01:00
* fix installing saves to nand dump
* add installing saves to nand in savetoy
This commit is contained in:
parent
d5d094862d
commit
14b4cb1f3d
@ -883,7 +883,7 @@ bool NandDump::InstallSave( const SaveGame &save )
|
||||
QString path = basePath + p + "/data";
|
||||
|
||||
//make sure the path exists
|
||||
if( !QFileInfo( path ).exists() || !QDir().mkpath( path ) )
|
||||
if( !QFileInfo( path ).exists() && !QDir().mkpath( path ) )
|
||||
{
|
||||
qWarning() << "NandDump::InstallSave -> error creating" << path;
|
||||
return false;
|
||||
@ -892,6 +892,8 @@ bool NandDump::InstallSave( const SaveGame &save )
|
||||
if( !QFileInfo( basePath + p + "/content" ).exists() )
|
||||
QDir().mkpath( basePath + p + "/content" );
|
||||
|
||||
path = p + "/data";
|
||||
|
||||
quint16 dataIdx = 0;
|
||||
quint16 entryIdx = 0;
|
||||
foreach( QString entry, save.entries )
|
||||
|
@ -122,28 +122,10 @@ void AesSetKey( const QByteArray &key )
|
||||
QByteArray GetSha1( const QByteArray &stuff )
|
||||
{
|
||||
return QCryptographicHash::hash( stuff, QCryptographicHash::Sha1 );
|
||||
/*SHA1Context sha;
|
||||
SHA1Reset( &sha );
|
||||
SHA1Input( &sha, (const unsigned char*)stuff.data(), stuff.size() );
|
||||
if( !SHA1Result( &sha ) )
|
||||
{
|
||||
qWarning() << "GetSha1 -> sha error";
|
||||
return QByteArray();
|
||||
}
|
||||
QByteArray ret( 20, '\0' );
|
||||
quint8 *p = (quint8 *)ret.data();
|
||||
for( int i = 0; i < 5 ; i++ )
|
||||
{
|
||||
quint32 part = qFromBigEndian( sha.Message_Digest[ i ] );
|
||||
memcpy( p + ( i * 4 ), &part, 4 );
|
||||
}
|
||||
return ret;*/
|
||||
}
|
||||
|
||||
|
||||
QByteArray GetMd5( const QByteArray &stuff )
|
||||
{
|
||||
//qDebug() << "GetMd5" << hex << stuff.size();
|
||||
return QCryptographicHash::hash( stuff, QCryptographicHash::Md5 );
|
||||
}
|
||||
|
||||
@ -245,6 +227,14 @@ const QByteArray DataFromSave( const SaveGame &save, const QString &name )
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
quint32 SaveItemSize( const SaveGame &save )
|
||||
{
|
||||
quint32 ret = 0;
|
||||
foreach( QByteArray ba, save.data )
|
||||
ret += ba.size();
|
||||
return ret;
|
||||
}
|
||||
|
||||
quint8 AttrFromSave( const SaveGame &save, const QString &name )
|
||||
{
|
||||
if( !save.tid || save.entries.size() != save.attr.size() )
|
||||
|
@ -64,6 +64,7 @@ QByteArray GetMd5( const QByteArray &stuff );
|
||||
|
||||
bool IsValidSave( const SaveGame &save );
|
||||
const QByteArray DataFromSave( const SaveGame &save, const QString &name );
|
||||
quint32 SaveItemSize( const SaveGame &save );
|
||||
quint8 AttrFromSave( const SaveGame &save, const QString &name );
|
||||
|
||||
//get a padded version of the given buffer
|
||||
|
@ -15,7 +15,8 @@
|
||||
#ifdef Q_WS_MAC
|
||||
static QString sneekPath = "/Volumes/VMware Shared Folders/host-c/QtWii/test";
|
||||
#else
|
||||
static QString sneekPath = "/media/SDHC_4GB";
|
||||
//static QString sneekPath = "/media/SDHC_4GB";
|
||||
static QString sneekPath = "../../test";
|
||||
#endif
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow), bannerthread( this )
|
||||
@ -43,7 +44,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
|
||||
connect( &pcIconTimer, SIGNAL( timeout() ), this, SLOT( ShowNextPcIcon() ) );
|
||||
|
||||
//GetSavesFromSneek( "/media/WiiFat500" );
|
||||
GetSavesFromSneek( sneekPath );
|
||||
//GetSavesFromSneek( sneekPath );
|
||||
//GetSavesFromPC( "./saveBackups" );
|
||||
|
||||
}
|
||||
@ -754,3 +755,138 @@ void MainWindow::ClearPcGuiInfo()
|
||||
ui->plainTextEdit_pcDesc->clear();
|
||||
ui->comboBox_pcSelect->clear();
|
||||
}
|
||||
|
||||
//button to install PC save clicked
|
||||
void MainWindow::on_pushButton_pcInstall_clicked()
|
||||
{
|
||||
QString nPath = bannerthread.NandBasePath();
|
||||
if( nPath.isEmpty() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
QList<QListWidgetItem*>selected = ui->listWidget_pcSaves->selectedItems();
|
||||
quint32 cnt = selected.size();
|
||||
if( cnt != 1 )
|
||||
return;
|
||||
|
||||
SaveListItem *si = static_cast< SaveListItem * >( selected.at( 0 ) );
|
||||
|
||||
int i = ui->comboBox_pcSelect->currentIndex();
|
||||
|
||||
//find the item in the list of infos that matches this item
|
||||
currentPcSave = 0xffffffff;
|
||||
cnt = pcInfos.size();
|
||||
for( quint32 i = 0; i < cnt; i++ )
|
||||
{
|
||||
if( si->Tid() == pcInfos.at( i ).tid )
|
||||
{
|
||||
currentPcSave = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( currentPcSave == 0xffffffff )
|
||||
{
|
||||
qWarning() << "MainWindow::on_pushButton_pcInstall_clicked() -> tid not found";
|
||||
return;
|
||||
}
|
||||
if( i < 0 || i >= pcInfos.at( currentPcSave ).sizes.size() )
|
||||
{
|
||||
qWarning() << "MainWindow::on_pushButton_pcInstall_clicked() -> index is out of range";
|
||||
return;
|
||||
}
|
||||
|
||||
//read datad.bin from the zip file
|
||||
QString zipPath = pcInfos.at( currentPcSave ).paths.at( i );
|
||||
QByteArray dataBin;
|
||||
QuaZip zip( zipPath );
|
||||
if( !zip.open( QuaZip::mdUnzip ) )
|
||||
{
|
||||
qWarning("on_pushButton_pcInstall_clicked(): zip.open(): %d", zip.getZipError() );
|
||||
return;
|
||||
}
|
||||
zip.setFileNameCodec("IBM866");
|
||||
QuaZipFile file(&zip);
|
||||
QString name;
|
||||
for( bool more = zip.goToFirstFile(); more; more = zip.goToNextFile() )
|
||||
{
|
||||
if( !file.open( QIODevice::ReadOnly ) )
|
||||
{
|
||||
qWarning("on_pushButton_pcInstall_clicked(): file.open(): %d", file.getZipError() );
|
||||
zip.close();
|
||||
return;
|
||||
}
|
||||
name = file.getActualFileName();
|
||||
if( file.getZipError() != UNZ_OK )
|
||||
{
|
||||
qWarning("on_pushButton_pcInstall_clicked(): file.getFileName(): %d", file.getZipError());
|
||||
file.close();
|
||||
zip.close();
|
||||
return;
|
||||
}
|
||||
if( name != "data.bin" )
|
||||
{
|
||||
file.close();
|
||||
continue;
|
||||
}
|
||||
dataBin = file.readAll();
|
||||
if( file.getZipError() != UNZ_OK )
|
||||
{
|
||||
qWarning("on_pushButton_pcInstall_clicked(): file.getFileName(): %d", file.getZipError());
|
||||
file.close();
|
||||
zip.close();
|
||||
return;
|
||||
}
|
||||
file.close();
|
||||
break;
|
||||
}
|
||||
zip.close();
|
||||
if( dataBin.isEmpty() )
|
||||
{
|
||||
qWarning() << "no data.bin found in the archive" << zipPath;
|
||||
return;
|
||||
}
|
||||
SaveGame save = SaveDataBin::StructFromDataBin( dataBin );
|
||||
if( !IsValidSave( save ) )
|
||||
{
|
||||
qWarning() << "got an invalid save from the data.bin in" << zipPath;
|
||||
return;
|
||||
}
|
||||
|
||||
//see if the sneek nand and already has a save for this game
|
||||
cnt = ui->listWidget_sneekSaves->count();
|
||||
for( quint32 i = 0; i < cnt; i++ )
|
||||
{
|
||||
QListWidgetItem* item = ui->listWidget_sneekSaves->item( i );
|
||||
si = static_cast< SaveListItem * >( item );
|
||||
bool ok = false;
|
||||
quint64 t = si->Tid().toLongLong( &ok, 16 );
|
||||
if( !ok || t != save.tid )
|
||||
continue;
|
||||
|
||||
//delete old save from sneek nand
|
||||
if( !bannerthread.DeleteSaveFromSneekNand( save.tid ) )
|
||||
{
|
||||
qWarning() << "error deleting the old save";
|
||||
return;
|
||||
}
|
||||
|
||||
//delete old save from sneek browser
|
||||
si = static_cast< SaveListItem * >( ui->listWidget_sneekSaves->takeItem( i ) );
|
||||
delete si;
|
||||
si = NULL;
|
||||
|
||||
break;
|
||||
}
|
||||
bool success = bannerthread.InstallSaveToSneekNand( save );
|
||||
if( !success )
|
||||
{
|
||||
qWarning() << "error installing the save";
|
||||
return;
|
||||
}
|
||||
//add this new item to the sneek list view
|
||||
quint32 size = SaveItemSize( save );
|
||||
QByteArray bnr = DataFromSave( save, "/banner.bin" );
|
||||
SaveBanner sb( bnr );
|
||||
new SaveListItem( sb, QString( "%1" ).arg( save.tid, 16, 16, QChar( '0' ) ) , size, ui->listWidget_sneekSaves );
|
||||
ui->statusBar->showMessage( tr( "Installed save to extracted nand" ), 5000 );
|
||||
}
|
||||
|
@ -62,6 +62,7 @@ private:
|
||||
|
||||
|
||||
private slots:
|
||||
void on_pushButton_pcInstall_clicked();
|
||||
void on_actionSet_Local_Path_triggered();
|
||||
void on_pushButton_pcDelete_clicked();
|
||||
void on_comboBox_pcSelect_currentIndexChanged(int index);
|
||||
|
@ -21,7 +21,7 @@
|
||||
<item row="0" column="0">
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
<number>1</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="sneekTab">
|
||||
<attribute name="title">
|
||||
|
@ -63,7 +63,6 @@ SaveGame SaveLoadThread::GetSave( quint64 tid )
|
||||
return nand.GetSaveData( tid );
|
||||
}
|
||||
|
||||
|
||||
void SaveLoadThread::run()
|
||||
{
|
||||
if ( abort )
|
||||
@ -262,6 +261,20 @@ void SaveLoadThread::GetPCSaves()
|
||||
emit SendProgress( 100 );
|
||||
}
|
||||
|
||||
const QString SaveLoadThread::NandBasePath()
|
||||
{
|
||||
if( isRunning() )
|
||||
return QString();
|
||||
return nand.BasePath();
|
||||
}
|
||||
|
||||
bool SaveLoadThread::InstallSaveToSneekNand( SaveGame save )
|
||||
{
|
||||
if( isRunning() )
|
||||
return false;
|
||||
return nand.InstallSave( save );
|
||||
}
|
||||
|
||||
void SaveLoadThread::GetSavesFromNandDump()
|
||||
{
|
||||
emit SendProgress( 0 );
|
||||
|
@ -38,7 +38,9 @@ public:
|
||||
|
||||
//TODO: these arent done on the work thread, but instead in the calling thread
|
||||
bool DeleteSaveFromSneekNand( quint64 tid );
|
||||
bool InstallSaveToSneekNand( SaveGame save );
|
||||
SaveGame GetSave( quint64 tid );
|
||||
const QString NandBasePath();
|
||||
|
||||
|
||||
void ForceQuit();
|
||||
|
Loading…
Reference in New Issue
Block a user