#include "Updater.h" #include #include #include #include // Inhalt der Updater Klasse aus Updater.h // Konstruktor Updater::Updater(KSGClient::PatchServerClient* psc) : ReferenceCounter() { client = psc; fehler = new Text(); } // Destruktor Updater::~Updater() { if (client->istVerbunden()) client->trenne(1); client->release(); fehler->release(); } // nicht constant int Updater::getNextDateiGruppe(Text* zDgPfad) { if (!client->istVerbunden() && !client->verbinde()) { fehler->setText(client->getLetzterFehler()); return -1; } KSGTDatei* sDgTb = client->getDateiGruppenListe(); if (!sDgTb) { fehler->setText(client->getLetzterFehler()); client->trenne(0); return -1; } client->trenne(0); 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("Verbinden . . ."); zParams->zStatus->unlockZeichnung(); } if (!client->istVerbunden() && !client->verbinde()) { fehler->setText(client->getLetzterFehler()); return 1; } bool clientGruppe = 0; KSGTDatei* dgL = client->getDateiGruppenListe(); if (!dgL) { fehler->setText(client->getLetzterFehler()); client->trenne(0); 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->getLetzterFehler()); client->trenne(0); 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); 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->getLetzterFehler()); client->trenne(0); 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); 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->getLetzterFehler()); client->trenne(0); 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->getText())) { 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->getText())) { 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->getLetzterFehler()); client->trenne(0); 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); 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); return 2; } client->trenne(0); fehler->setText(""); return 0; } // constant const char* Updater::getError() const { return fehler->getText(); } int Updater::getDownload() const { return client->getDownload(); }