patchlist.cpp 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. #include "patchlist.h"
  2. #include <QDebug>
  3. PatchList::PatchList(LotroDatManager *mgr, QObject *parent) : QObject(parent)
  4. {
  5. lotro_mgr_ = mgr;
  6. qInfo() << "PatchList: Initialising patchsets";
  7. texts_patch_ = new TextsPatch(mgr);
  8. graphics_patch_ = new GraphicsPatch(mgr);
  9. sounds_patch_ = new SoundsPatch(mgr);
  10. videos_patch_ = new VideosPatch(mgr);
  11. qInfo() << "PatchList: Patchsets were initialized, initializing threads";
  12. texts_patch_thread_ = new QThread(this);
  13. graphics_patch_thread_ = new QThread(this);
  14. sounds_patch_thread_ = new QThread(this);
  15. videos_patch_thread_ = new QThread(this);
  16. texts_patch_->moveToThread(texts_patch_thread_);
  17. graphics_patch_->moveToThread(graphics_patch_thread_);
  18. sounds_patch_->moveToThread(sounds_patch_thread_);
  19. videos_patch_->moveToThread(videos_patch_thread_);
  20. connect(texts_patch_, &TextsPatch::operationStarted, this, &PatchList::onPatchOperationStarted, Qt::QueuedConnection);
  21. connect(graphics_patch_, &GraphicsPatch::operationStarted, this, &PatchList::onPatchOperationStarted, Qt::QueuedConnection);
  22. connect(sounds_patch_, &SoundsPatch::operationStarted, this, &PatchList::onPatchOperationStarted, Qt::QueuedConnection);
  23. connect(videos_patch_, &VideosPatch::operationStarted, this, &PatchList::onPatchOperationStarted, Qt::QueuedConnection);
  24. connect(texts_patch_, &TextsPatch::operationFinished, this, &PatchList::onPatchOperationFinished, Qt::QueuedConnection);
  25. connect(graphics_patch_, &GraphicsPatch::operationFinished, this, &PatchList::onPatchOperationFinished, Qt::QueuedConnection);
  26. connect(sounds_patch_, &SoundsPatch::operationFinished, this, &PatchList::onPatchOperationFinished, Qt::QueuedConnection);
  27. connect(videos_patch_, &VideosPatch::operationFinished, this, &PatchList::onPatchOperationFinished, Qt::QueuedConnection);
  28. connect(texts_patch_, &TextsPatch::progressChanged, this, &PatchList::onPatchOperationProgressChanged, Qt::QueuedConnection);
  29. connect(graphics_patch_, &GraphicsPatch::progressChanged, this, &PatchList::onPatchOperationProgressChanged, Qt::QueuedConnection);
  30. connect(sounds_patch_, &SoundsPatch::progressChanged, this, &PatchList::onPatchOperationProgressChanged, Qt::QueuedConnection);
  31. connect(videos_patch_, &VideosPatch::progressChanged, this, &PatchList::onPatchOperationProgressChanged, Qt::QueuedConnection);
  32. connect(lotro_mgr_, &LotroDatManager::operationStarted, this, &PatchList::onLotroManagerOperationStarted, Qt::QueuedConnection);
  33. connect(lotro_mgr_, &LotroDatManager::operationFinished, this, &PatchList::onLotroManagerOperationFinished, Qt::QueuedConnection);
  34. qInfo() << "PatchList: Patchset threads initialized, starting workers";
  35. texts_patch_thread_->start();
  36. graphics_patch_thread_->start();
  37. sounds_patch_thread_->start();
  38. videos_patch_thread_->start();
  39. patch_update_timer.setInterval(5 * 60 * 1000); // Once in 5 minutes check for updates
  40. connect(&patch_update_timer, &QTimer::timeout, this, &PatchList::update);
  41. }
  42. PatchList::~PatchList()
  43. {
  44. qDebug() << "PatchList: finishing work";
  45. texts_patch_thread_->quit();
  46. graphics_patch_thread_->quit();
  47. sounds_patch_thread_->quit();
  48. videos_patch_thread_->quit();
  49. if (!texts_patch_thread_->wait(500)) {
  50. qDebug() << "PatchList: ERROR, TEXTS PATCHSET DIDNT STOP, FORCEFULLY TERMINATING!";
  51. texts_patch_thread_->terminate();
  52. texts_patch_thread_->wait();
  53. }
  54. if (!graphics_patch_thread_->wait(500)) {
  55. qDebug() << "PatchList: ERROR, GRAPHICS PATCHSET DIDNT STOP, FORCEFULLY TERMINATING!";
  56. graphics_patch_thread_->terminate();
  57. graphics_patch_thread_->wait();
  58. }
  59. if (!sounds_patch_thread_->wait(500)) {
  60. qDebug() << "PatchList: ERROR, SOUNDS PATCHSET DIDNT STOP, FORCEFULLY TERMINATING!";
  61. sounds_patch_thread_->terminate();
  62. sounds_patch_thread_->wait();
  63. }
  64. if (!videos_patch_thread_->wait(500)) {
  65. qDebug() << "PatchList: ERROR, VIDEOS PATCHSET DIDNT STOP, FORCEFULLY TERMINATING!";
  66. videos_patch_thread_->terminate();
  67. videos_patch_thread_->wait();
  68. }
  69. qDebug() << "Patchlist: all jobs stopped, destroying";
  70. delete texts_patch_;
  71. delete graphics_patch_;
  72. delete sounds_patch_;
  73. delete videos_patch_;
  74. }
  75. QList<Patch *> PatchList::getPatchList()
  76. {
  77. return {texts_patch_, graphics_patch_, sounds_patch_, videos_patch_};
  78. }
  79. LotroDatManager *PatchList::getManager()
  80. {
  81. return lotro_mgr_;
  82. }
  83. void PatchList::onPatchOperationProgressChanged(Patch::OperationProgress operation_progress, Patch *patch)
  84. {
  85. patch_operations_status_[patch] = operation_progress;
  86. Patch::OperationProgress total_status;
  87. for (const Patch::OperationProgress &st : patch_operations_status_) {
  88. total_status = total_status + st;
  89. }
  90. emit progressChanged(total_status);
  91. }
  92. void PatchList::onLotroManagerOperationFinished(QString operation_name, QVector<QVariant>, bool result)
  93. {
  94. qDebug() << "LotroManager: operation finished " << operation_name;
  95. if (operation_name == "initializeManager") {
  96. --active_operations_num_;
  97. if (active_operations_num_ == 0) {
  98. emit patchOperationsFinished();
  99. }
  100. if (result) {
  101. startAutoUpdate();
  102. update();
  103. } else {
  104. qCritical() << "DatManager initialisation error!!!";
  105. }
  106. }
  107. if (operation_name == "createBackup" || operation_name == "restoreFromBackup" || operation_name == "removeBackup") {
  108. if (operation_name == "createBackup" && result) {
  109. Settings::setValue("Backup/installed", true);
  110. Settings::setValue("Backup/creation_time", QDateTime::currentDateTime().toString("dd-MM-yyyy HH:mm:ss"));
  111. }
  112. if (operation_name == "removeBackup" && result) {
  113. Settings::setValue("Backup/installed", false);
  114. Settings::setValue("Backup/creation_time", "none");
  115. }
  116. emit backupSettingsInfoChanged();
  117. --active_operations_num_;
  118. if (active_operations_num_ == 0) {
  119. emit patchOperationsFinished();
  120. }
  121. }
  122. }
  123. void PatchList::onLotroManagerOperationStarted(QString operation_name, QVector<QVariant>)
  124. {
  125. qDebug() << "LotroManager: operation started " << operation_name;
  126. }
  127. void PatchList::startAutoUpdate()
  128. {
  129. auto_updates_enabled_ = true;
  130. patch_update_timer.start();
  131. }
  132. void PatchList::stopAutoUpdate()
  133. {
  134. patch_update_timer.stop();
  135. auto_updates_enabled_ = false;
  136. }
  137. void PatchList::initialize() {
  138. ++active_operations_num_;
  139. emit patchOperationsStarted();
  140. QMetaObject::invokeMethod(lotro_mgr_, &LotroDatManager::initializeManager, Qt::QueuedConnection);
  141. }
  142. void PatchList::createBackup()
  143. {
  144. if (active_operations_num_ > 0) {
  145. qWarning() << "Tried to start create backup operation, while others are still running!";
  146. return;
  147. }
  148. ++active_operations_num_;
  149. emit patchOperationsStarted();
  150. QMetaObject::invokeMethod(lotro_mgr_, "createBackup", Qt::QueuedConnection);
  151. }
  152. void PatchList::restoreFromBackup()
  153. {
  154. if (active_operations_num_ > 0) {
  155. qWarning() << "Tried to start restore from backup operation, while others are still running!";
  156. return;
  157. }
  158. ++active_operations_num_;
  159. emit patchOperationsStarted();
  160. QMetaObject::invokeMethod(lotro_mgr_, "restoreFromBackup", Qt::QueuedConnection);
  161. }
  162. void PatchList::removeBackup()
  163. {
  164. if (active_operations_num_ > 0) {
  165. qWarning() << "Tried to start remove backup operation, while others are still running!";
  166. return;
  167. }
  168. ++active_operations_num_;
  169. emit patchOperationsStarted();
  170. QMetaObject::invokeMethod(lotro_mgr_, "removeBackup", Qt::QueuedConnection);
  171. }
  172. void PatchList::onPatchOperationStarted(Patch::Operation, Patch*)
  173. {
  174. if (active_operations_num_ == 0) {
  175. emit patchOperationsStarted();
  176. }
  177. ++active_operations_num_;
  178. }
  179. void PatchList::onPatchOperationFinished(Patch::Operation, Patch*)
  180. {
  181. --active_operations_num_;
  182. if (active_operations_num_ == 0) {
  183. emit patchOperationsFinished();
  184. }
  185. }
  186. void PatchList::update()
  187. {
  188. if (active_operations_num_ > 0) {
  189. qWarning() << "Tried to start patch update chain, while there are already some operations on them!";
  190. return;
  191. }
  192. qInfo() << "PatchList: Starting update chain!";
  193. for (Patch* patch : getPatchList()) {
  194. QMetaObject::invokeMethod(patch, "enqueue",
  195. Q_ARG(QList<Patch::Operation>,
  196. QList<Patch::Operation>({Patch::E_CHECKFORUPDATES,
  197. Patch::E_DOWNLOAD,
  198. Patch::E_INSTALL,
  199. Patch::E_ACTIVATE})));
  200. }
  201. }
  202. void PatchList::forceInstallPatches()
  203. {
  204. if (active_operations_num_ > 0) {
  205. qWarning() << "Trying to start force patch installation, while there are already some operations running!";
  206. return;
  207. }
  208. auto is_database_enabled = [](QString db_name) -> bool {
  209. return Settings::getValue("DatabaseDownload/" + db_name).toBool();
  210. };
  211. for (const QString& db_name : QStringList(
  212. {"text", "font", "image", "loadscreen",
  213. "texture", "sound", "video", "micro"})) {
  214. Settings::setValue("DatabaseNeedInstall/" + db_name, is_database_enabled(db_name));
  215. }
  216. update();
  217. }