#include "Updater.h" #include #include #include // Inhalt der Updater Klasse aus Updater.h // Konstruktor Updater::Updater() { client = new PSKlient(); fehler = new Text(); ref = 1; } // Destruktor Updater::~Updater() { if( client->istRegistriert() ) { if( !client->istVerbunden() ) client->verbinde(); client->trenne( 1 ); } client->release(); fehler->release(); } // nicht constant int Updater::getNextDateiGruppe( Text *zDgPfad ) { client->lock(); if( !client->istVerbunden() && !client->verbinde() ) { fehler->setText( client->zError()->getText() ); client->unlock(); return -1; } KSGTDatei *sDgTb = client->getDateiGruppenListe(); if( !sDgTb ) { fehler->setText( client->zError()->getText() ); client->trenne( 0 ); client->unlock(); return -1; } client->trenne( 0 ); client->unlock(); KSGTDatei *lDgTb = new KSGTDatei( "data/dg.ksgt" ); // Tabellen Spalten: Id, Pfad, Version, Priorität lDgTb->laden(); InitDatei *ur = new InitDatei(); for( int i = 0; i < sDgTb->getZeilenAnzahl(); i++ ) { int id = TextZuInt( sDgTb->zFeld( i, 0 )->getText(), 10 ); int vs = TextZuInt( sDgTb->zFeld( i, 2 )->getText(), 10 ); bool gefunden = 0; for( int j = 0; j < lDgTb->getZeilenAnzahl(); j++ ) { if( id == TextZuInt( lDgTb->zFeld( j, 0 )->getText(), 10 ) ) { if( vs != TextZuInt( lDgTb->zFeld( j, 2 )->getText(), 10 ) ) { if( !sDgTb->zFeld( i, 1 )->getLength() ) ur->addWert( sDgTb->zFeld( i, 0 )->getText(), "SOFORT" ); else if( !lDgTb->zFeld( j, 3 )->istGleich( "NICHT" ) ) ur->addWert( sDgTb->zFeld( i, 0 )->getText(), lDgTb->zFeld( j, 3 )->getText() ); } gefunden = 1; break; } } if( gefunden ) continue; if( !sDgTb->zFeld( i, 1 )->getLength() ) ur->addWert( sDgTb->zFeld( i, 0 )->getText(), "SOFORT" ); else if( DateiExistiert( sDgTb->getFeld( i, 1 ) ) ) ur->addWert( sDgTb->zFeld( i, 0 )->getText(), "SPÄTER" ); } lDgTb->release(); if( !ur->getWertAnzahl() ) { ur->release(); sDgTb->release(); return 0; } int gruppe = 0; for( int i = 0; i < ur->getWertAnzahl(); i++ ) { if( ur->zWert( i )->istGleich( "SOFORT" ) ) { gruppe = TextZuInt( ur->zName( i )->getText(), 10 ); break; } } if( !gruppe ) { unsigned int klein = 0xFFFFFFFF; for( int i = 0; i < ur->getWertAnzahl(); i++ ) { if( !ur->zWert( i )->istGleich( "SPÄTER" ) ) { unsigned int num = TextZuInt( ur->zWert( i )->getText(), 10 ); if( num < klein ) { klein = num; gruppe = TextZuInt( ur->zName( i )->getText(), 10 ); } } } if( !gruppe ) { for( int i = 0; i < ur->getWertAnzahl(); i++ ) { if( ur->zWert( i )->istGleich( "SPÄTER" ) ) { gruppe = TextZuInt( ur->zName( i )->getText(), 10 ); break; } } } } ur->release(); if( zDgPfad ) { // Pfad der Dateigruppe ermitteln for( int i = 0; i < sDgTb->getZeilenAnzahl(); i++ ) { if( gruppe == TextZuInt( sDgTb->zFeld( i, 0 )->getText(), 10 ) ) { zDgPfad->setText( sDgTb->zFeld( i, 1 )->getText() ); break; } } } sDgTb->release(); return gruppe; } int Updater::update( UpdateParams *zParams ) { if( zParams->zStatus ) { zParams->zStatus->lockZeichnung(); zParams->zStatus->setText( "Warte auf Update . . ." ); zParams->zStatus->unlockZeichnung(); } client->lock(); if( zParams->zStatus ) { zParams->zStatus->lockZeichnung(); zParams->zStatus->setText( "Verbinden . . ." ); zParams->zStatus->unlockZeichnung(); } if( !client->istVerbunden() && !client->verbinde() ) { fehler->setText( client->zError()->getText() ); client->unlock(); return 1; } bool clientGruppe = 0; KSGTDatei *dgL = client->getDateiGruppenListe(); if( !dgL ) { fehler->setText( client->zError()->getText() ); client->trenne( 0 ); client->unlock(); return 1; } Text *pfad = new Text( "" ); for( int i = 0; i < dgL->getZeilenAnzahl(); i++ ) { // Pfad der Dateigruppe ermitteln if( zParams->dateiGruppe == TextZuInt( dgL->zFeld( i, 0 )->getText(), 10 ) ) { pfad->setText( dgL->zFeld( i, 1 )->getText() ); if( !pfad->getLength() ) clientGruppe = 1; break; } } if( !clientGruppe ) pfad->append( "/" ); Text *dlPf = new Text( pfad->getText() ); dlPf->append( "data/update/datei_versionen.ini" ); InitDatei *dateiListe = new InitDatei( dlPf ); dateiListe->laden(); Text *dsPf = new Text( pfad->getText() ); dsPf->append( "data/update/datei_status.ini" ); InitDatei *dateiStatus = new InitDatei( dsPf ); dateiStatus->laden(); Text *llPf = new Text( pfad->getText() ); llPf->append( "data/update/datei_remove.patch" ); Datei *removeListe = new Datei(); removeListe->setDatei( llPf ); if( !removeListe->existiert() ) removeListe->erstellen(); removeListe->open( Datei::Style::schreiben ); KSGTDatei *dl = client->getDateiListe( zParams->dateiGruppe ); // Liste mit Dateien aus der Gruppe if( !dl ) { // error dgL->release(); pfad->release(); dateiListe->release(); dateiStatus->release(); removeListe->release(); fehler->setText( client->zError()->getText() ); client->trenne( 0 ); client->unlock(); return 1; } for( int i = 0; i < dl->getZeilenAnzahl(); i++ ) { if( dl->zFeld( i, 0 )->istGleich( "1" ) ) { // existierende Datei if( !dateiListe->wertExistiert( dl->zFeld( i, 1 )->getText() ) ) { dateiListe->addWert( dl->zFeld( i, 1 )->getText(), dl->zFeld( i, 2 )->getText() ); dateiStatus->addWert( dl->zFeld( i, 1 )->getText(), "Ausstehend" ); } else { if( !dateiListe->zWert( dl->zFeld( i, 1 )->getText() )->istGleich( dl->zFeld( i, 2 )->getText() ) ) { dateiListe->setWert( dl->zFeld( i, 1 )->getText(), dl->zFeld( i, 2 )->getText() ); dateiStatus->setWert( dl->zFeld( i, 1 )->getText(), "Ausstehend" ); } } } else { // gelöschte Datei removeListe->schreibe( dl->zFeld( i, 1 )->getText(), dl->zFeld( i, 1 )->getLength() ); removeListe->schreibe( "\n", 1 ); dateiListe->removeWert( dl->zFeld( i, 1 )->getText() ); dateiStatus->removeWert( dl->zFeld( i, 1 )->getText() ); } } removeListe->close(); removeListe->release(); dateiListe->speichern(); dateiStatus->speichern(); dl->release(); Text *ldPf = new Text( pfad->getText() ); ldPf->append( "data/versionen.ini" ); InitDatei *lokaleDateien = new InitDatei( ldPf ); if( !lokaleDateien->laden() ) DateiPfadErstellen( lokaleDateien->zPfad()->getText() ); __int64 maxAktionen = 0; for( int i = 0; i < dateiListe->getWertAnzahl(); i++ ) { bool geändert = 0; if( !lokaleDateien->wertExistiert( dateiListe->zName( i )->getText() ) ) { geändert = 1; if( dateiStatus->zWert( dateiListe->zName( i )->getText() ) && dateiStatus->zWert( dateiListe->zName( i )->getText() )->istGleich( "Fertig" ) ) geändert = 0; } else { if( !lokaleDateien->zWert( dateiListe->zName( i )->getText() )->istGleich( dateiListe->zWert( i )->getText() ) ) geändert = 1; else dateiStatus->setWert( dateiListe->zName( i )->getText(), "Fertig" ); } if( geändert && !dateiStatus->zWert( dateiListe->zName( i )->getText() )->istGleich( "Fertig" ) ) { maxAktionen += client->getDateiGröße( zParams->dateiGruppe, dateiListe->zName( i )->getText() ); if( dateiStatus->zWert( dateiListe->zName( i )->getText() )->istGleich( "InBearbeitung" ) ) { Text *jPf = new Text( pfad->getText() ); jPf->append( "data/update/jetzt_position.patch" ); Datei *jetzt = new Datei(); jetzt->setDatei( jPf ); if( jetzt->open( Datei::Style::lesen ) ) { __int64 pos = 0; jetzt->lese( (char*)&pos, 8 ); maxAktionen -= pos; jetzt->close(); } jetzt->release(); } } } dateiStatus->speichern(); if( zParams->zFortschritt ) { zParams->zFortschritt->reset(); zParams->zFortschritt->setAktionAnzahl( maxAktionen ); } for( int i = 0; i < dateiStatus->getWertAnzahl(); i++ ) { if( dateiStatus->zWert( i )->istGleich( "InBearbeitung" ) ) { Text *jPf = new Text( pfad->getText() ); jPf->append( "data/update/jetzt_position.patch" ); Datei *jetzt = new Datei(); jetzt->setDatei( jPf ); __int64 pos = 0; if( jetzt->open( Datei::Style::lesen ) ) { jetzt->lese( (char*)&pos, 8 ); jetzt->close(); } jetzt->release(); Text *zielPf = new Text( pfad->getText() ); zielPf->append( "data/update/download/" ); zielPf->append( dateiStatus->zName( i )->getText() ); InitDatei *poIni = new InitDatei( "data/patch/po.ini" ); poIni->laden(); int maxbps = 0; if( poIni->wertExistiert( "ülps" ) && poIni->zWert( "ülps" )->getLength() && poIni->wertExistiert( "üle" ) ) { if( poIni->zWert( "üle" )->istGleich( "kb/s" ) ) maxbps = (int)TextZuInt( poIni->zWert( "ülps" )->getText(), 10 ) * 1024; if( poIni->zWert( "üle" )->istGleich( "mb/s" ) ) maxbps = (int)TextZuInt( poIni->zWert( "ülps" )->getText(), 10 ) * 1024 * 1024; } poIni->release(); if( zParams->zStatus ) { zParams->zStatus->lockZeichnung(); zParams->zStatus->setText( dateiStatus->zName( i )->getText() ); zParams->zStatus->unlockZeichnung(); } if( client->downloadDatei( zParams->dateiGruppe, &pos, dateiStatus->zName( i )->getText(), zielPf->getText(), zParams->zFortschritt, zParams->abbruch, maxbps ) ) { if( ( *zParams->abbruch ) ) { // übertragung unterbrochen jPf = new Text( pfad->getText() ); jPf->append( "data/update/jetzt_position.patch" ); jetzt = new Datei(); jetzt->setDatei( jPf ); if( jetzt->open( Datei::Style::schreiben ) ) { jetzt->schreibe( (char*)&pos, 8 ); jetzt->close(); } jetzt->release(); dgL->release(); pfad->release(); dateiListe->release(); dateiStatus->release(); zielPf->release(); lokaleDateien->release(); fehler->setText( "" ); client->trenne( 0 ); client->unlock(); return 2; } else { dateiStatus->setWert( i, "Fertig" ); dateiStatus->speichern(); } } else { // error dgL->release(); pfad->release(); dateiListe->release(); dateiStatus->release(); zielPf->release(); lokaleDateien->release(); fehler->setText( client->zError()->getText() ); client->trenne( 0 ); client->unlock(); return 1; } zielPf->release(); break; } } for( int i = 0; i < dateiStatus->getWertAnzahl(); i++ ) { if( dateiStatus->zWert( i )->istGleich( "Ausstehend" ) ) { dateiStatus->setWert( i, "InBearbeitung" ); Text *jPf = new Text( pfad->getText() ); jPf->append( "data/update/jetzt_position.patch" ); Datei *jetzt = new Datei(); jetzt->setDatei( jPf ); __int64 pos = 0; jetzt->open( Datei::Style::schreiben ); jetzt->schreibe( (char*)&pos, 8 ); jetzt->close(); jetzt->release(); dateiStatus->speichern(); Text *zielPf = new Text( pfad->getText() ); zielPf->append( "data/update/download/" ); zielPf->append( dateiStatus->zName( i )->getText() ); InitDatei *poIni = new InitDatei( "data/patch/po.ini" ); poIni->laden(); int maxbps = 0; if( poIni->wertExistiert( "ülps" ) && poIni->zWert( "ülps" )->getLength() && poIni->wertExistiert( "üle" ) ) { if( poIni->zWert( "üle" )->istGleich( "kb/s" ) ) maxbps = (int)TextZuInt( poIni->zWert( "ülps" )->getText(), 10 ) * 1024; if( poIni->zWert( "üle" )->istGleich( "mb/s" ) ) maxbps = (int)TextZuInt( poIni->zWert( "ülps" )->getText(), 10 ) * 1024 * 1024; } poIni->release(); if( zParams->zStatus ) { zParams->zStatus->lockZeichnung(); zParams->zStatus->setText( dateiStatus->zName( i )->getText() ); zParams->zStatus->unlockZeichnung(); } if( client->downloadDatei( zParams->dateiGruppe, &pos, dateiStatus->zName( i )->getText(), zielPf->getText(), zParams->zFortschritt, zParams->abbruch, maxbps ) ) { if( ( *zParams->abbruch ) ) { // übertragung unterbrochen jPf = new Text( pfad->getText() ); jPf->append( "data/update/jetzt_position.patch" ); jetzt = new Datei(); jetzt->setDatei( jPf ); if( jetzt->open( Datei::Style::schreiben ) ) { jetzt->schreibe( (char*)&pos, 8 ); jetzt->close(); } jetzt->release(); dgL->release(); pfad->release(); dateiListe->release(); dateiStatus->release(); zielPf->release(); lokaleDateien->release(); fehler->setText( "" ); client->trenne( 0 ); client->unlock(); return 2; } else { dateiStatus->setWert( i, "Fertig" ); dateiStatus->speichern(); } } else { // error dgL->release(); pfad->release(); dateiListe->release(); dateiStatus->release(); zielPf->release(); lokaleDateien->release(); fehler->setText( client->zError()->getText() ); client->trenne( 0 ); client->unlock(); return 1; } zielPf->release(); } } if( zParams->zStatus ) { zParams->zStatus->lockZeichnung(); zParams->zStatus->setText( "Übernehme Änderungen..." ); zParams->zStatus->unlockZeichnung(); } removeListe = new Datei(); llPf = new Text( pfad->getText() ); llPf->append( "data/update/datei_remove.patch" ); removeListe->setDatei( llPf ); removeListe->open( Datei::Style::lesen ); Text *zeile = removeListe->leseZeile(); while( zeile ) { zeile->remove( "\r\n" ); zeile->remove( "\n" ); if( !zeile->getLength() ) break; Text pf = pfad->getText(); pf += zeile->getText(); lokaleDateien->removeWert( zeile->getText() ); DateiRemove( pf ); zeile->release(); zeile = removeListe->leseZeile(); } lokaleDateien->speichern(); removeListe->close(); removeListe->remove(); removeListe->release(); if( clientGruppe ) { // Es wird der Patcher selbst geupdatet Text *uPf = new Text( pfad->getText() ); uPf->append( "data/update/unable/list.patch" ); Datei *unable = new Datei(); unable->setDatei( uPf ); unable->erstellen(); unable->open( Datei::Style::schreiben ); bool fertig = 1; for( int i = 0; i < dateiStatus->getWertAnzahl(); i++ ) { Text *altPfad = new Text( pfad->getText() ); altPfad->append( "data/update/download/" ); altPfad->append( dateiStatus->zName( i )->getText() ); Text *neuPfad = new Text( pfad->getText() ); neuPfad->append( dateiStatus->zName( i )->getText() ); if( DateiExistiert( altPfad->getThis() ) ) { bool b = 0; if( !DateiExistiert( neuPfad->getText() ) ) DateiPfadErstellen( neuPfad->getText() ); if( DateiExistiert( neuPfad->getText() ) ) { if( DateiRemove( neuPfad->getText() ) ) { if( !DateiUmbenennen( altPfad->getText(), neuPfad->getText() ) ) b = 1; } else b = 1; } else { if( !DateiUmbenennen( altPfad->getText(), neuPfad->getText() ) ) b = 1; } if( b ) { unable->schreibe( "\2", 1 ); unable->schreibe( neuPfad->getText(), neuPfad->getLength() ); unable->schreibe( "=>", 2 ); unable->schreibe( altPfad->getText(), altPfad->getLength() ); unable->schreibe( "\n", 1 ); fertig = 0; } } altPfad->release(); neuPfad->release(); if( !lokaleDateien->wertExistiert( dateiStatus->zName( i )->getText() ) ) lokaleDateien->addWert( dateiStatus->zName( i )->getText(), dateiListe->zWert( dateiStatus->zName( i )->getText() )->getText() ); else lokaleDateien->setWert( dateiStatus->zName( i )->getText(), dateiListe->zWert( dateiStatus->zName( i )->getText() )->getText() ); } unable->close(); if( fertig ) unable->remove(); unable->release(); } else { // Es werden Spiele und Karten geupdatet for( int i = 0; i < dateiStatus->getWertAnzahl(); i++ ) { Text *altPfad = new Text( pfad->getText() ); altPfad->append( "data/update/download/" ); altPfad->append( dateiStatus->zName( i )->getText() ); Text *neuPfad = new Text( pfad->getText() ); neuPfad->append( dateiStatus->zName( i )->getText() ); if( DateiExistiert( altPfad->getThis() ) ) { bool b = 0; if( !DateiExistiert( neuPfad->getText() ) ) DateiPfadErstellen( neuPfad->getText() ); if( DateiExistiert( neuPfad->getText() ) ) { if( DateiRemove( neuPfad->getText() ) ) { if( !DateiUmbenennen( altPfad->getText(), neuPfad->getText() ) ) b = 1; } else b = 1; } else { if( !DateiUmbenennen( altPfad->getText(), neuPfad->getText() ) ) b = 1; } if( b ) { // error dgL->release(); pfad->release(); lokaleDateien->speichern(); lokaleDateien->release(); dateiListe->release(); dateiStatus->release(); fehler->setText( client->zError()->getText() ); client->trenne( 0 ); client->unlock(); return 1; } } altPfad->release(); neuPfad->release(); if( !lokaleDateien->wertExistiert( dateiStatus->zName( i )->getText() ) ) lokaleDateien->addWert( dateiStatus->zName( i )->getText(), dateiListe->zWert( dateiStatus->zName( i )->getText() )->getText() ); else lokaleDateien->setWert( dateiStatus->zName( i )->getText(), dateiListe->zWert( dateiStatus->zName( i )->getText() )->getText() ); } } lokaleDateien->speichern(); lokaleDateien->release(); dateiListe->release(); dateiStatus->release(); Text *jpPf = new Text( pfad->getText() ); jpPf->append( "data/update/jetzt_position.patch" ); DateiRemove( jpPf ); Text *dvPf = new Text( pfad->getText() ); dvPf->append( "data/update/datei_versionen.ini" ); DateiRemove( dvPf ); dsPf = new Text( pfad->getText() ); dsPf->append( "data/update/datei_status.ini" ); DateiRemove( dsPf ); if( clientGruppe ) { Text *ulPf = new Text( pfad->getText() ); ulPf->append( "data/update/unable/list.patch" ); if( DateiExistiert( ulPf ) ) { // es gibt Dateien, die der Patcher (wegen momentaner Benutzung) nicht pätchen konnte dgL->release(); pfad->release(); fehler->setText( "" ); client->trenne( 0 ); client->unlock(); return 3; } } pfad->release(); KSGTDatei *lDgL = new KSGTDatei( "data/dg.ksgt" ); lDgL->laden(); bool gefunden = 0; for( int i = 0; i < lDgL->getZeilenAnzahl(); i++ ) { if( zParams->dateiGruppe == TextZuInt( lDgL->zFeld( i, 0 )->getText(), 10 ) ) { for( int j = 0; j < dgL->getZeilenAnzahl(); j++ ) { if( zParams->dateiGruppe == TextZuInt( dgL->zFeld( j, 0 )->getText(), 10 ) ) { lDgL->setFeld( i, 2, dgL->zFeld( j, 2 )->getText() ); break; } } gefunden = 1; break; } } if( !gefunden ) { unsigned int rfPos = 0; for( int i = 0; i < lDgL->getZeilenAnzahl(); i++ ) { if( rfPos <= TextZuInt( lDgL->zFeld( i, 3 )->getText(), 10 ) ) rfPos = TextZuInt( lDgL->zFeld( i, 3 )->getText(), 10 ) + 1; } rfPos++; for( int i = 0; i < dgL->getZeilenAnzahl(); i++ ) { if( zParams->dateiGruppe == TextZuInt( dgL->zFeld( i, 0 )->getText(), 10 ) ) { RCArray< Text > *zeile = new RCArray< Text >(); zeile->set( new Text( dgL->zFeld( i, 0 )->getText() ), 0 ); zeile->set( new Text( dgL->zFeld( i, 1 )->getText() ), 1 ); zeile->set( new Text( dgL->zFeld( i, 2 )->getText() ), 2 ); Text *rfPosT = new Text(); rfPosT->append( rfPos ); zeile->set( rfPosT, 3 ); lDgL->addZeile( 4, zeile ); zeile->release(); break; } } } dgL->release(); lDgL->speichern(); lDgL->release(); if( ( *zParams->abbruch ) ) { fehler->setText( "" ); client->trenne( 0 ); client->unlock(); return 2; } client->trenne( 0 ); client->unlock(); fehler->setText( "" ); return 0; } // constant char *Updater::getError() const { return fehler->getText(); } int Updater::getDownload() const { return client->getDownload(); } // Reference Counting UpdaterV *Updater::getThis() { ref++; return this; } UpdaterV *Updater::release() { ref--; if( !ref ) delete this; return 0; }