diff options
Diffstat (limited to 'src/gui/windows/updaterwindow.cpp')
-rw-r--r-- | src/gui/windows/updaterwindow.cpp | 1217 |
1 files changed, 0 insertions, 1217 deletions
diff --git a/src/gui/windows/updaterwindow.cpp b/src/gui/windows/updaterwindow.cpp deleted file mode 100644 index 3858b0a5e..000000000 --- a/src/gui/windows/updaterwindow.cpp +++ /dev/null @@ -1,1217 +0,0 @@ -/* - * The ManaPlus Client - * Copyright (C) 2004-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * Copyright (C) 2011-2017 The ManaPlus Developers - * - * This file is part of The ManaPlus Client. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include "gui/windows/updaterwindow.h" - -#include "client.h" -#include "configuration.h" -#include "main.h" -#include "settings.h" - -#include "enums/gui/layouttype.h" - -#include "fs/files.h" -#include "fs/mkdir.h" -#include "fs/paths.h" - -#include "fs/virtfs/fs.h" - -#include "gui/widgets/button.h" -#include "gui/widgets/containerplacer.h" -#include "gui/widgets/itemlinkhandler.h" -#include "gui/widgets/label.h" -#include "gui/widgets/layout.h" -#include "gui/widgets/progressbar.h" -#include "gui/widgets/scrollarea.h" -#include "gui/widgets/staticbrowserbox.h" - -#include "net/download.h" -#include "net/updatetypeoperators.h" - -#include "resources/db/moddb.h" - -#include "utils/delete2.h" -#include "utils/foreach.h" -#include "utils/gettext.h" - -#include <sys/stat.h> - -#include <sstream> - -#include "debug.h" - -UpdaterWindow *updaterWindow = nullptr; - -const std::string xmlUpdateFile("resources.xml"); -const std::string txtUpdateFile("resources2.txt"); -const std::string updateServer2 - ("http://download.manaplus.org/manaplus/updates/"); -const std::string updateServer3 - ("http://download2.manaplus.org/manaplus/updates/"); -const std::string updateServer4 - ("http://download.evolonline.org/manaplus/updates/"); -const std::string updateServer5 - ("http://download3.manaplus.org/manaplus/updates/"); - -/** - * Load the given file into a vector of updateFiles. - */ -static STD_VECTOR<UpdateFile> loadXMLFile(const std::string &fileName, - const bool loadMods) -{ - STD_VECTOR<UpdateFile> files; - XML::Document doc(fileName, UseVirtFs_false, SkipError_false); - XmlNodeConstPtrConst rootNode = doc.rootNode(); - - if ((rootNode == nullptr) || !xmlNameEqual(rootNode, "updates")) - { - logger->log("Error loading update file: %s", fileName.c_str()); - return files; - } - - for_each_xml_child_node(fileNode, rootNode) - { - const bool isMod = xmlNameEqual(fileNode, "mod"); - if (!xmlNameEqual(fileNode, "update") && !isMod) - continue; - - UpdateFile file; - file.name = XML::getProperty(fileNode, "file", ""); - file.hash = XML::getProperty(fileNode, "hash", ""); - file.type = XML::getProperty(fileNode, "type", "data"); - file.desc = XML::getProperty(fileNode, "description", ""); - file.group = XML::getProperty(fileNode, "group", ""); - if (!file.group.empty() && (!isMod || !loadMods)) - continue; - - const std::string version = XML::getProperty( - fileNode, "version", ""); - if (!version.empty()) - { - if (version > CHECK_VERSION) - continue; - } - const std::string notVersion = XML::getProperty( - fileNode, "notVersion", ""); - if (!notVersion.empty()) - { - if (notVersion <= CHECK_VERSION) - continue; - } - if (XML::getProperty(fileNode, "required", "yes") == "yes") - file.required = true; - else - file.required = false; - - if (checkPath(file.name)) - files.push_back(file); - } - - return files; -} - -static STD_VECTOR<UpdateFile> loadTxtFile(const std::string &fileName) -{ - STD_VECTOR<UpdateFile> files; - std::ifstream fileHandler; - fileHandler.open(fileName.c_str(), std::ios::in); - - if (fileHandler.is_open()) - { - while (fileHandler.good()) - { - char name[256]; - char hash[50]; - fileHandler.getline(name, 256, ' '); - fileHandler.getline(hash, 50); - - UpdateFile thisFile; - thisFile.name = name; - thisFile.hash = hash; - thisFile.type = "data"; - thisFile.group.clear(); - thisFile.required = true; - thisFile.desc.clear(); - - if (!thisFile.name.empty() && checkPath(thisFile.name)) - files.push_back(thisFile); - } - } - else - { - logger->log("Error loading update file: %s", fileName.c_str()); - } - fileHandler.close(); - - return files; -} - -UpdaterWindow::UpdaterWindow(const std::string &restrict updateHost, - const std::string &restrict updatesDir, - const bool applyUpdates, - const UpdateTypeT updateType) : - // TRANSLATORS: updater window name - Window(_("Updating..."), Modal_false, nullptr, "update.xml"), - ActionListener(), - KeyListener(), - mDownloadProgress(0.0F), - mUpdateHost(updateHost), - mUpdatesDir(updatesDir), - mUpdatesDirReal(updatesDir), - mCurrentFile("news.txt"), - mNewLabelCaption(), - mDownloadMutex(), - mCurrentChecksum(0), - mMemoryBuffer(nullptr), - mDownload(nullptr), - mUpdateFiles(), - mTempUpdateFiles(), - mUpdateServerPath(mUpdateHost), - mItemLinkHandler(new ItemLinkHandler), - // TRANSLATORS: updater window label - mLabel(new Label(this, _("Connecting..."))), - // TRANSLATORS: updater window button - mCancelButton(new Button(this, _("Cancel"), "cancel", this)), - // TRANSLATORS: updater window button - mPlayButton(new Button(this, _("Play"), "play", this)), - mProgressBar(new ProgressBar(this, 0.0, 310, 0, - ProgressColorId::PROG_UPDATE, - "updateprogressbar.xml", "updateprogressbar_fill.xml")), - mBrowserBox(new StaticBrowserBox(this, Opaque_true, - "browserbox.xml")), - mScrollArea(new ScrollArea(this, mBrowserBox, - Opaque_true, "update_background.xml")), - mDownloadStatus(UpdateDownloadStatus::UPDATE_NEWS), - mDownloadedBytes(0), - mUpdateIndex(0), - mUpdateIndexOffset(0), - mUpdateType(updateType), - mStoreInMemory(true), - mDownloadComplete(true), - mUserCancel(false), - mLoadUpdates(applyUpdates), - mValidateXml(false), - mSkipPatches(false) -{ - setWindowName("UpdaterWindow"); - setResizable(true); - setDefaultSize(450, 400, ImagePosition::CENTER); - setMinWidth(310); - setMinHeight(220); - - mProgressBar->setSmoothProgress(false); - mBrowserBox->setOpaque(Opaque_false); - mBrowserBox->setLinkHandler(mItemLinkHandler); - mBrowserBox->setProcessVars(true); - mBrowserBox->setEnableKeys(true); - mBrowserBox->setEnableTabs(true); - mPlayButton->setEnabled(false); - - ContainerPlacer placer; - placer = getPlacer(0, 0); - - placer(0, 0, mScrollArea, 5, 3).setPadding(3); - placer(0, 3, mLabel, 5); - placer(0, 4, mProgressBar, 5); - placer(3, 5, mCancelButton); - placer(4, 5, mPlayButton); - - Layout &layout = getLayout(); - layout.setRowHeight(0, LayoutType::SET); - - addKeyListener(this); - - if (mUpdateHost.empty()) - { - const STD_VECTOR<std::string> &mirrors = settings.updateMirrors; - if (mirrors.begin() != mirrors.end()) - mUpdateHost = *mirrors.begin(); - mSkipPatches = true; - } - - loadWindowState(); -} - -void UpdaterWindow::postInit() -{ - Window::postInit(); - setVisible(Visible_true); - mCancelButton->requestFocus(); - removeProtocol(mUpdateServerPath); - - download(); -} - -UpdaterWindow::~UpdaterWindow() -{ - if (mLoadUpdates) - loadUpdates(); - - if (mDownload != nullptr) - { - mDownload->cancel(); - - delete2(mDownload) - } - free(mMemoryBuffer); - delete2(mItemLinkHandler); -} - -void UpdaterWindow::setProgress(const float p) -{ - // Do delayed progress bar update, since Guichan isn't thread-safe - MutexLocker lock(&mDownloadMutex); - mDownloadProgress = p; -} - -void UpdaterWindow::setLabel(const std::string &str) -{ - // Do delayed label text update, since Guichan isn't thread-safe - MutexLocker lock(&mDownloadMutex); - mNewLabelCaption = str; -} - -void UpdaterWindow::enable() -{ - mCancelButton->setEnabled(false); - mPlayButton->setEnabled(true); - mPlayButton->requestFocus(); - - if (client->getState() != State::GAME) - { - if ((mUpdateType & UpdateType::Close) != 0) - client->setState(State::LOAD_DATA); - } - else - { - deleteSelf(); - } -} - -void UpdaterWindow::action(const ActionEvent &event) -{ - const std::string &eventId = event.getId(); - if (eventId == "cancel") - { - // Register the user cancel - mUserCancel = true; - // Skip the updating process - if (mDownloadStatus != UpdateDownloadStatus::UPDATE_COMPLETE) - { - if (mDownload != nullptr) - mDownload->cancel(); - mDownloadStatus = UpdateDownloadStatus::UPDATE_ERROR; - } - } - else if (eventId == "play") - { - if (client->getState() != State::GAME) - client->setState(State::LOAD_DATA); - else - deleteSelf(); - } -} - -void UpdaterWindow::keyPressed(KeyEvent &event) -{ - const InputActionT actionId = event.getActionId(); - if (actionId == InputAction::GUI_CANCEL) - { - action(ActionEvent(nullptr, mCancelButton->getActionEventId())); - if (client->getState() != State::GAME) - client->setState(State::LOGIN); - else - deleteSelf(); - } - else if (actionId == InputAction::GUI_SELECT || - actionId == InputAction::GUI_SELECT2) - { - if (mDownloadStatus == UpdateDownloadStatus::UPDATE_COMPLETE || - mDownloadStatus == UpdateDownloadStatus::UPDATE_ERROR || - mDownloadStatus == UpdateDownloadStatus::UPDATE_IDLE) - { - action(ActionEvent(nullptr, mPlayButton->getActionEventId())); - } - else - { - action(ActionEvent(nullptr, mCancelButton->getActionEventId())); - } - } -} - -void UpdaterWindow::loadNews() -{ - if (mMemoryBuffer == nullptr) - { - logger->log1("Couldn't load news"); - return; - } - - // Reallocate and include terminating 0 character - mMemoryBuffer = static_cast<char*>(realloc( - mMemoryBuffer, mDownloadedBytes + 1)); - if (mMemoryBuffer == nullptr) - { - logger->log1("Couldn't load news"); - return; - } - mMemoryBuffer[mDownloadedBytes] = '\0'; - mBrowserBox->clearRows(); - - std::string newsName = mUpdatesDir + "/local/help/news.txt"; - mkdir_r((mUpdatesDir + "/local/help/").c_str()); - bool firstLine(true); - std::ofstream file; - std::stringstream ss(mMemoryBuffer); - std::string line; - file.open(newsName.c_str(), std::ios::out); - int cnt = 0; - const int maxNews = 50; - while (std::getline(ss, line, '\n')) - { - cnt ++; - if (firstLine) - { - firstLine = false; - const size_t i = line.find("##9 Latest client version: ##6"); - if (i == 0u) - continue; - - if (file.is_open()) - file << line << std::endl; - if (cnt < maxNews) - mBrowserBox->addRow(line); - } - else - { - if (file.is_open()) - file << line << std::endl; - if (cnt < maxNews) - mBrowserBox->addRow(line); - } - } - - file.close(); - if (cnt > maxNews) - { - mBrowserBox->addRow(""); - // TRANSLATORS: updater window checkbox - mBrowserBox->addRow("news", _("Show all news (can be slow)")); - mBrowserBox->addRow(""); - } - // Free the memory buffer now that we don't need it anymore - free(mMemoryBuffer); - mMemoryBuffer = nullptr; - mDownloadedBytes = 0; - - mBrowserBox->updateHeight(); - mScrollArea->setVerticalScrollAmount(0); -} - -void UpdaterWindow::loadPatch() -{ - if (mMemoryBuffer == nullptr) - { - logger->log1("Couldn't load patch"); - return; - } - - // Reallocate and include terminating 0 character - mMemoryBuffer = static_cast<char*>( - realloc(mMemoryBuffer, mDownloadedBytes + 1)); - if (mMemoryBuffer == nullptr) - { - logger->log1("Couldn't load patch"); - return; - } - mMemoryBuffer[mDownloadedBytes] = '\0'; - - std::string version; - - // Tokenize and add each line separately - char *line = strtok(mMemoryBuffer, "\n"); - if (line != nullptr) - { - version = line; - if (serverVersion < 1) - { - line = strtok(nullptr, "\n"); - if (line != nullptr) - { - mBrowserBox->addRow(strprintf("##9 Latest client version: " - "##6ManaPlus %s##0", line), true); - } - } - if (version > CHECK_VERSION) - { - mBrowserBox->addRow("", true); -#if defined(ANDROID) - const std::string url = "androidDownloadUrl"; - const std::string text = "androidDownloadUrl"; -#elif defined(WIN32) - const std::string url = "windowsDownloadUrl"; - const std::string text = "windowsDownloadUrl"; -#else // defined(ANDROID) - - const std::string url = "otherDownloadUrl"; - const std::string text = "otherDownloadUrl"; -#endif // defined(ANDROID) - - mBrowserBox->addRow(std::string(" ##1[@@").append( - branding.getStringValue(url)).append("|").append( - branding.getStringValue(text)).append("@@]"), true); - mBrowserBox->addRow("##1You can download it from", true); - mBrowserBox->addRow("##1ManaPlus updated.", true); - } - else - { - mBrowserBox->addRow("You have latest client version.", true); - } - } - - // Free the memory buffer now that we don't need it anymore - free(mMemoryBuffer); - mMemoryBuffer = nullptr; - mDownloadedBytes = 0; - - mBrowserBox->updateHeight(); - mScrollArea->setVerticalScrollAmount(0); -} - -int UpdaterWindow::updateProgress(void *ptr, - const DownloadStatusT status, - size_t dt, - const size_t dn) -{ - UpdaterWindow *const uw = reinterpret_cast<UpdaterWindow *>(ptr); - if (uw == nullptr) - return -1; - - if (status == DownloadStatus::Complete) - { - uw->mDownloadComplete = true; - } - else if (status == DownloadStatus::Error || - status == DownloadStatus::Cancelled) - { - if (uw->mDownloadStatus == UpdateDownloadStatus::UPDATE_COMPLETE || - uw->mDownloadStatus == UpdateDownloadStatus::UPDATE_NEWS) - { // ignoring error in last state (was UPDATE_PATCH) - uw->mDownloadStatus = UpdateDownloadStatus::UPDATE_COMPLETE; - uw->mDownloadComplete = true; - free(uw->mMemoryBuffer); - uw->mMemoryBuffer = nullptr; - } - else - { - uw->mDownloadStatus = UpdateDownloadStatus::UPDATE_ERROR; - } - } - - if (dt == 0u) - dt = 1; - - float progress = static_cast<float>(dn) / - static_cast<float>(dt); - - if (progress != progress) - progress = 0.0F; // check for NaN - if (progress < 0.0F) - progress = 0.0F; // no idea how this could ever happen, - // but why not check for it anyway. - if (progress > 1.0F) - progress = 1.0F; - - uw->setLabel(std::string(uw->mCurrentFile).append(" (") - .append(toString(CAST_S32(progress * 100))).append("%)")); - - uw->setProgress(progress); - - if ((client->getState() != State::UPDATE && - client->getState() != State::GAME) || - uw->mDownloadStatus == UpdateDownloadStatus::UPDATE_ERROR) - { - // If the action was canceled return an error code to stop the mThread - return -1; - } - - return 0; -} - -size_t UpdaterWindow::memoryWrite(void *ptr, size_t size, - size_t nmemb, void *stream) -{ - UpdaterWindow *const uw = reinterpret_cast<UpdaterWindow *>(stream); - const size_t totalMem = size * nmemb; - if (uw == nullptr) - return 0; - uw->mMemoryBuffer = static_cast<char*>(realloc(uw->mMemoryBuffer, - CAST_SIZE(uw->mDownloadedBytes) + totalMem)); - if (uw->mMemoryBuffer != nullptr) - { - memcpy(&(uw->mMemoryBuffer[uw->mDownloadedBytes]), ptr, totalMem); - uw->mDownloadedBytes += CAST_S32(totalMem); - } - - return totalMem; -} - -void UpdaterWindow::download() -{ - if (mDownload != nullptr) - { - mDownload->cancel(); - delete mDownload; - } - if (mDownloadStatus == UpdateDownloadStatus::UPDATE_PATCH) - { - mDownload = new Net::Download(this, - branding.getStringValue("updateMirror1") + mCurrentFile, - &updateProgress, - true, false, mValidateXml); - for (int f = 2; f < 8; f ++) - { - const std::string url = branding.getStringValue( - "updateMirror" + toString(f)); - if (!url.empty()) - mDownload->addMirror(url + mCurrentFile); - } - } - else - { - mDownload = new Net::Download(this, - urlJoin(mUpdateHost, mCurrentFile), - &updateProgress, - false, false, mValidateXml); - - if (mDownloadStatus == UpdateDownloadStatus::UPDATE_LIST2 || - mDownloadStatus == UpdateDownloadStatus::UPDATE_RESOURCES2) - { - const std::string str = urlJoin(mUpdateServerPath, mCurrentFile); - mDownload->addMirror(updateServer3 + str); - mDownload->addMirror(updateServer4 + str); - mDownload->addMirror(updateServer5 + str); - } - else - { - const STD_VECTOR<std::string> &mirrors = settings.updateMirrors; - FOR_EACH (STD_VECTOR<std::string>::const_iterator, it, mirrors) - { - mDownload->addMirror(pathJoin(*it, - mCurrentFile)); - } - } - } - - if (mStoreInMemory) - { - mDownload->setWriteFunction(&UpdaterWindow::memoryWrite); - } - else - { - if (mDownloadStatus == UpdateDownloadStatus::UPDATE_RESOURCES) - { - mDownload->setFile(pathJoin(mUpdatesDir, mCurrentFile), - mCurrentChecksum); - } - else - { - mDownload->setFile(pathJoin(mUpdatesDir, - mCurrentFile)); - } - } - - if (mDownloadStatus != UpdateDownloadStatus::UPDATE_RESOURCES) - mDownload->noCache(); - - setLabel(mCurrentFile + " (0%)"); - mDownloadComplete = false; - - mDownload->start(); -} - -void UpdaterWindow::loadUpdates() -{ - if (mUpdateFiles.empty()) - { // updates not downloaded - mUpdateFiles = loadXMLFile(pathJoin(mUpdatesDir, xmlUpdateFile), - false); - if (mUpdateFiles.empty()) - { - logger->log("Warning this server does not have a" - " %s file falling back to %s", xmlUpdateFile.c_str(), - txtUpdateFile.c_str()); - mUpdateFiles = loadTxtFile(pathJoin(mUpdatesDir, - txtUpdateFile)); - } - } - - std::string fixPath = mUpdatesDir + "/fix"; - const unsigned sz = CAST_U32(mUpdateFiles.size()); - for (mUpdateIndex = 0; mUpdateIndex < sz; mUpdateIndex++) - { - const UpdateFile &file = mUpdateFiles[mUpdateIndex]; - if (!file.group.empty()) - continue; - UpdaterWindow::addUpdateFile(mUpdatesDir, - fixPath, - file.name, - Append_false); - } - loadManaPlusUpdates(mUpdatesDir); - loadMods(mUpdatesDir, mUpdateFiles); -} - -void UpdaterWindow::loadLocalUpdates(const std::string &dir) -{ - STD_VECTOR<UpdateFile> updateFiles = loadXMLFile( - pathJoin(dir, xmlUpdateFile), - false); - - if (updateFiles.empty()) - { - logger->log("Warning this server does not have a" - " %s file falling back to %s", xmlUpdateFile.c_str(), - txtUpdateFile.c_str()); - updateFiles = loadTxtFile(pathJoin(dir, - txtUpdateFile)); - } - - const std::string fixPath = dir + "/fix"; - for (unsigned int updateIndex = 0, - fsz = CAST_U32(updateFiles.size()); - updateIndex < fsz; - updateIndex++) - { - const UpdateFile &file = updateFiles[updateIndex]; - if (!file.group.empty()) - continue; - UpdaterWindow::addUpdateFile(dir, - fixPath, - file.name, - Append_false); - } - loadManaPlusUpdates(dir); - loadMods(dir, updateFiles); -} - -void UpdaterWindow::unloadUpdates(const std::string &dir) -{ - STD_VECTOR<UpdateFile> updateFiles = loadXMLFile( - pathJoin(dir, xmlUpdateFile), - true); - - if (updateFiles.empty()) - { - updateFiles = loadTxtFile(pathJoin(dir, - txtUpdateFile)); - } - - const std::string fixPath = dir + "/fix"; - for (unsigned int updateIndex = 0, - fsz = CAST_U32(updateFiles.size()); - updateIndex < fsz; - updateIndex++) - { - UpdaterWindow::removeUpdateFile(dir, - fixPath, - updateFiles[updateIndex].name); - } - unloadManaPlusUpdates(dir); -} - -void UpdaterWindow::loadManaPlusUpdates(const std::string &dir) -{ - std::string fixPath = dir + "/fix"; - STD_VECTOR<UpdateFile> updateFiles = loadXMLFile( - pathJoin(fixPath, xmlUpdateFile), - false); - - for (unsigned int updateIndex = 0, - fsz = CAST_U32(updateFiles.size()); - updateIndex < fsz; - updateIndex++) - { - const UpdateFile &file = updateFiles[updateIndex]; - if (!file.group.empty()) - continue; - const std::string name = file.name; - if (strStartWith(name, "manaplus_")) - { - struct stat statbuf; - std::string fileName = pathJoin(fixPath, - name); - if (stat(fileName.c_str(), &statbuf) == 0) - { - VirtFs::mountZip(fileName, - Append_false); - } - } - } -} - -void UpdaterWindow::unloadManaPlusUpdates(const std::string &dir) -{ - const std::string fixPath = dir + "/fix"; - const STD_VECTOR<UpdateFile> updateFiles = loadXMLFile( - pathJoin(fixPath, xmlUpdateFile), - true); - - for (unsigned int updateIndex = 0, - fsz = CAST_U32(updateFiles.size()); - updateIndex < fsz; - updateIndex++) - { - std::string name = updateFiles[updateIndex].name; - if (strStartWith(name, "manaplus_")) - { - struct stat statbuf; - const std::string file = pathJoin( - fixPath, name); - if (stat(file.c_str(), &statbuf) == 0) - VirtFs::unmountZip(file); - } - } -} - -void UpdaterWindow::addUpdateFile(const std::string &restrict path, - const std::string &restrict fixPath, - const std::string &restrict file, - const Append append) -{ - const std::string tmpPath = pathJoin(path, file); - if (append == Append_false) - VirtFs::mountZip(tmpPath, append); - - const std::string fixFile = pathJoin(fixPath, file); - struct stat statbuf; - if (stat(fixFile.c_str(), &statbuf) == 0) - VirtFs::mountZip(fixFile, append); - - if (append == Append_true) - VirtFs::mountZip(tmpPath, append); -} - -void UpdaterWindow::removeUpdateFile(const std::string &restrict path, - const std::string &restrict fixPath, - const std::string &restrict file) -{ - VirtFs::unmountZip(pathJoin(path, file)); - const std::string fixFile = pathJoin(fixPath, file); - struct stat statbuf; - if (stat(fixFile.c_str(), &statbuf) == 0) - VirtFs::unmountZip(fixFile); -} - -void UpdaterWindow::logic() -{ - BLOCK_START("UpdaterWindow::logic") - // Update Scroll logic - mScrollArea->logic(); - - // Synchronize label caption when necessary - { - MutexLocker lock(&mDownloadMutex); - - if (mLabel->getCaption() != mNewLabelCaption) - { - mLabel->setCaption(mNewLabelCaption); - mLabel->adjustSize(); - } - - mProgressBar->setProgress(mDownloadProgress); - if (!mUpdateFiles.empty() && - CAST_SIZE(mUpdateIndex) <= mUpdateFiles.size()) - { - mProgressBar->setText(strprintf("%u/%u", mUpdateIndex - + mUpdateIndexOffset + 1, CAST_U32( - mUpdateFiles.size()) + CAST_S32( - mTempUpdateFiles.size()) + 1)); - } - else - { - mProgressBar->setText(""); - } - } - - switch (mDownloadStatus) - { - case UpdateDownloadStatus::UPDATE_ERROR: - mBrowserBox->addRow(""); - // TRANSLATORS: update message - mBrowserBox->addRow(_("##1 The update process is incomplete.")); - // TRANSLATORS: Continues "The update process is incomplete.". - mBrowserBox->addRow(_("##1 It is strongly recommended that")); - // TRANSLATORS: Begins "It is strongly recommended that". - mBrowserBox->addRow(_("##1 you try again later.")); - if (mDownload != nullptr) - mBrowserBox->addRow(mDownload->getError()); - mBrowserBox->updateHeight(); - mScrollArea->setVerticalScrollAmount( - mScrollArea->getVerticalMaxScroll()); - mDownloadStatus = UpdateDownloadStatus::UPDATE_COMPLETE; - break; - case UpdateDownloadStatus::UPDATE_NEWS: - if (mDownloadComplete) - { - // Parse current memory buffer as news and dispose of the data - loadNews(); - - mValidateXml = true; - mCurrentFile = xmlUpdateFile; - mStoreInMemory = false; - mDownloadStatus = UpdateDownloadStatus::UPDATE_LIST; - download(); // download() changes mDownloadComplete to false - } - break; - case UpdateDownloadStatus::UPDATE_PATCH: - if (mDownloadComplete) - { - // Parse current memory buffer as news and dispose of the data - loadPatch(); - - mUpdateHost = updateServer2 + mUpdateServerPath; - mUpdatesDir = pathJoin(mUpdatesDir, "fix"); - mCurrentFile = xmlUpdateFile; - mValidateXml = true; - mStoreInMemory = false; - mDownloadStatus = UpdateDownloadStatus::UPDATE_LIST2; - download(); - } - break; - - case UpdateDownloadStatus::UPDATE_LIST: - if (mDownloadComplete) - { - if (mCurrentFile == xmlUpdateFile) - { - mUpdateFiles = loadXMLFile(pathJoin( - mUpdatesDir, xmlUpdateFile), - true); - - if (mUpdateFiles.empty()) - { - logger->log("Warning this server does not have a %s" - " file falling back to %s", - xmlUpdateFile.c_str(), - txtUpdateFile.c_str()); - - // If the resources.xml file fails, - // fall back onto a older version - mCurrentFile = txtUpdateFile; - mValidateXml = false; - mStoreInMemory = false; - mDownloadStatus = UpdateDownloadStatus::UPDATE_LIST; - download(); - break; - } - } - else if (mCurrentFile == txtUpdateFile) - { - mValidateXml = true; - mUpdateFiles = loadTxtFile(pathJoin(mUpdatesDir, - txtUpdateFile)); - } - mStoreInMemory = false; - mDownloadStatus = UpdateDownloadStatus::UPDATE_RESOURCES; - } - break; - case UpdateDownloadStatus::UPDATE_RESOURCES: - if (mDownloadComplete) - { - if (CAST_SIZE(mUpdateIndex) < mUpdateFiles.size()) - { - UpdateFile thisFile = mUpdateFiles[mUpdateIndex]; - if (thisFile.type == "music" - && !config.getBoolValue("download-music")) - { - mUpdateIndex++; - break; - } - mCurrentFile = thisFile.name; - std::string checksum; - checksum = thisFile.hash; - std::stringstream ss(checksum); - ss >> std::hex >> mCurrentChecksum; - - std::ifstream temp(pathJoin(mUpdatesDir, - mCurrentFile).c_str()); - - mValidateXml = false; - if (!temp.is_open() || !validateFile(pathJoin( - mUpdatesDir, mCurrentFile), - mCurrentChecksum)) - { - temp.close(); - download(); - } - else - { - temp.close(); - logger->log("%s already here", mCurrentFile.c_str()); - } - mUpdateIndex++; - } - else - { - if (!mSkipPatches) - { - // Download of updates completed - mCurrentFile = "latest.txt"; - mStoreInMemory = true; - mDownloadStatus = UpdateDownloadStatus::UPDATE_PATCH; - mValidateXml = false; - download(); // download() changes - // mDownloadComplete to false - } - else - { - mDownloadStatus = - UpdateDownloadStatus::UPDATE_COMPLETE; - } - } - } - break; - case UpdateDownloadStatus::UPDATE_LIST2: - if (mDownloadComplete) - { - if (mCurrentFile == xmlUpdateFile) - { - mTempUpdateFiles = loadXMLFile(pathJoin( - mUpdatesDir, xmlUpdateFile), - true); - } - mUpdateIndexOffset = mUpdateIndex; - mUpdateIndex = 0; - mValidateXml = true; - mStoreInMemory = false; - mDownloadStatus = UpdateDownloadStatus::UPDATE_RESOURCES2; - download(); - } - break; - case UpdateDownloadStatus::UPDATE_RESOURCES2: - if (mDownloadComplete) - { - mValidateXml = false; - if (CAST_SIZE(mUpdateIndex) - < mTempUpdateFiles.size()) - { - const UpdateFile thisFile = mTempUpdateFiles[mUpdateIndex]; - mCurrentFile = thisFile.name; - std::string checksum; - checksum = thisFile.hash; - std::stringstream ss(checksum); - ss >> std::hex >> mCurrentChecksum; - - std::ifstream temp((pathJoin(mUpdatesDir, - mCurrentFile)).c_str()); - - if (!temp.is_open() || !validateFile(pathJoin( - mUpdatesDir, mCurrentFile), - mCurrentChecksum)) - { - temp.close(); - download(); - } - else - { - temp.close(); - logger->log("%s already here", mCurrentFile.c_str()); - } - mUpdateIndex++; - } - else - { - mUpdatesDir = mUpdatesDirReal; - mDownloadStatus = UpdateDownloadStatus::UPDATE_COMPLETE; - } - } - break; - case UpdateDownloadStatus::UPDATE_COMPLETE: - mUpdatesDir = mUpdatesDirReal; - enable(); - // TRANSLATORS: updater window label - setLabel(_("Completed")); - mDownloadStatus = UpdateDownloadStatus::UPDATE_IDLE; - break; - case UpdateDownloadStatus::UPDATE_IDLE: - break; - default: - logger->log("UpdaterWindow::logic unknown status: " - + toString(CAST_U32(mDownloadStatus))); - break; - } - BLOCK_END("UpdaterWindow::logic") -} - -bool UpdaterWindow::validateFile(const std::string &filePath, - const unsigned long hash) -{ - FILE *const file = fopen(filePath.c_str(), "rb"); - if (file == nullptr) - return false; - - const unsigned long adler = Net::Download::fadler32(file); - fclose(file); - return adler == hash; -} - -unsigned long UpdaterWindow::getFileHash(const std::string &filePath) -{ - int size = 0; - const char *const buf = VirtFs::loadFile(filePath, size); - if (buf == nullptr) - return 0; - unsigned long res = Net::Download::adlerBuffer(buf, size); - delete [] buf; - return res; -} - -void UpdaterWindow::loadFile(std::string file) -{ - mBrowserBox->clearRows(); - trim(file); - - StringVect lines; - Files::loadTextFileLocal(mUpdatesDir + "/local/help/news.txt", lines); - - for (size_t i = 0, sz = lines.size(); i < sz; ++i) - mBrowserBox->addRow(lines[i]); - mBrowserBox->updateHeight(); -} - -void UpdaterWindow::loadMods(const std::string &dir, - const STD_VECTOR<UpdateFile> &updateFiles) -{ - ModDB::load(); - std::string modsString = serverConfig.getValue("mods", ""); - std::set<std::string> modsList; - splitToStringSet(modsList, modsString, '|'); - - const std::string fixPath = dir + "/fix"; - for (unsigned int updateIndex = 0, - fsz = CAST_U32(updateFiles.size()); - updateIndex < fsz; - updateIndex ++) - { - const UpdateFile &file = updateFiles[updateIndex]; - if (file.group.empty()) - continue; - const std::set<std::string>::const_iterator - it = modsList.find(file.group); - if (it != modsList.end()) - { - UpdaterWindow::addUpdateFile(dir, - fixPath, - file.name, - Append_false); - } - } - - STD_VECTOR<UpdateFile> updateFiles2 = loadXMLFile( - pathJoin(fixPath, xmlUpdateFile), - true); - - for (unsigned int updateIndex = 0, - fsz = CAST_U32(updateFiles2.size()); - updateIndex < fsz; - updateIndex++) - { - const UpdateFile &file = updateFiles2[updateIndex]; - if (file.group.empty()) - continue; - std::string name = file.name; - if (strStartWith(name, "manaplus_")) - { - const std::set<std::string>::const_iterator - it = modsList.find(file.group); - if (it != modsList.end()) - { - struct stat statbuf; - std::string fileName = pathJoin(fixPath, - name); - if (stat(fileName.c_str(), &statbuf) == 0) - { - VirtFs::mountZip(fileName, - Append_false); - } - } - } - } - - loadDirMods(dir + "/local/"); -} - -void UpdaterWindow::loadDirMods(const std::string &dir) -{ - ModDB::load(); - const ModInfos &mods = ModDB::getAll(); - - std::string modsString = serverConfig.getValue("mods", ""); - StringVect modsList; - splitToStringVector(modsList, modsString, '|'); - FOR_EACH (StringVectCIter, it, modsList) - { - const std::string &name = *it; - const ModInfoCIterator modIt = mods.find(name); - if (modIt == mods.end()) - continue; - const ModInfo *const mod = (*modIt).second; - if (mod != nullptr) - { - const std::string &localDir = mod->getLocalDir(); - if (!localDir.empty()) - { - VirtFs::mountDir(pathJoin(dir, localDir), - Append_false); - } - } - } -} - -void UpdaterWindow::unloadMods(const std::string &dir) -{ - const ModInfos &mods = ModDB::getAll(); - std::string modsString = serverConfig.getValue("mods", ""); - StringVect modsList; - splitToStringVector(modsList, modsString, '|'); - FOR_EACH (StringVectCIter, it, modsList) - { - const std::string &name = *it; - const ModInfoCIterator modIt = mods.find(name); - if (modIt == mods.end()) - continue; - const ModInfo *const mod = (*modIt).second; - if (mod != nullptr) - { - const std::string &localDir = mod->getLocalDir(); - if (!localDir.empty()) - VirtFs::unmountDir(pathJoin(dir, localDir)); - } - } -} - -void UpdaterWindow::deleteSelf() -{ - scheduleDelete(); - updaterWindow = nullptr; -} |