#28 Обновление от 06.05.2021

باز‌کردن
Endevir قصد ادغام 2 تغییر را از LotRO_Legacy/lol_tmp به LotRO_Legacy/legacy_v2_interface_mini دارد

+ 1 - 0
src/Legacy/Legacy.pro

@@ -11,6 +11,7 @@ TARGET = Legacy
 TEMPLATE = app
 
 CONFIG += resources_big
+#CONFIG += staticlib
 
 SOURCES += \
     main.cpp \

+ 2 - 2
src/Legacy/Legacy_resource.rc

@@ -1,6 +1,6 @@
 #include <windows.h>
 
-IDI_ICON1	ICON	DISCARDABLE	"D:\\Programming\\Projects\\Legacy_v2\\resources\\appicon.ico"
+IDI_ICON1	ICON	DISCARDABLE	"C:\\Qt-5.14.2\\Projects\\Legacy_v2\\resources\\appicon.ico"
 
 VS_VERSION_INFO VERSIONINFO
 	FILEVERSION 0,0,0,0
@@ -12,7 +12,7 @@ VS_VERSION_INFO VERSIONINFO
 	FILEFLAGS 0x0L
 #endif
 	FILEOS VOS__WINDOWS32
-	FILETYPE VFT_APP
+	FILETYPE VFT_DLL
 	FILESUBTYPE 0x0L
 	BEGIN
 		BLOCK "StringFileInfo"

+ 4 - 4
src/Legacy/legacyapplication.cpp

@@ -88,16 +88,16 @@ bool LegacyApplication::init() {
     return true;
 }
 
-void LegacyApplication::InitModules() {
+void LegacyApplication::InitModules(){
     modules_init_timer_.stop();
 
-    QtConcurrent::run([this]() {
+    QtConcurrent::run([this](){
         emit ModulesInitializationStarted();
         AppErrorStatus status = CheckAppPrerequesities();
         emit ErrorStatusChanged(status);
         qDebug() << "NEW ERROR STATUS: " << status;
 
-        if (status == E_NO_ERRORS) {
+        if(status == E_NO_ERRORS){
             QMetaObject::invokeMethod(&PatchInstaller::instance(), &PatchInstaller::init, Qt::BlockingQueuedConnection);
             QMetaObject::invokeMethod(&PatchDownloader::instance(), &PatchDownloader::init, Qt::BlockingQueuedConnection);
             QMetaObject::invokeMethod(&PatchDownloader::instance(), &PatchDownloader::checkForUpdates, Qt::QueuedConnection);
@@ -105,6 +105,6 @@ void LegacyApplication::InitModules() {
     });
 }
 
-void LegacyApplication::close() {
+void LegacyApplication::close(){
     gui->close();
 }

+ 2 - 2
src/Legacy/main.cpp

@@ -12,7 +12,7 @@ int main(int argc, char *argv[])
 {
     QApplication app(argc, argv);
 
-    if (argc <= 1 || (argc > 1 && std::string(argv[1]) != "-prelaunched")) {
+    /*if (argc <= 1 || (argc > 1 && std::string(argv[1]) != "-prelaunched")) {
         QMessageBox msgBox;
         msgBox.setIcon(QMessageBox::Warning);
 
@@ -37,7 +37,7 @@ int main(int argc, char *argv[])
         msgBox.setText("Приложение уже запущено.\nРазрешено запускать только один экземпляр приложения.\nЕсли вы уверены, что Наследие закрыто, попробуйте перезагрузить компьютер.");
         msgBox.exec();
         return false;
-    }
+    }*/
 
     if (!LegacyApplication::instance().init()) {
         return 1;

+ 1 - 0
src/Legacy/models/datoriginalfilesdatabase.cpp

@@ -30,6 +30,7 @@ DatOriginalFilesDatabase::~DatOriginalFilesDatabase() {
 void DatOriginalFilesDatabase::addFile(int file_id, int dat_id, int version, int iteration, const LOTRO_DAT::SubfileData &data) {
     std::stringstream options_stream;
     options_stream << data.options;
+
     const QString options = QString::fromStdString(options_stream.str());
     _add_file_prepared_query->bindValue(":file_id", file_id);
     _add_file_prepared_query->bindValue(":dat_id", dat_id);

+ 27 - 39
src/Legacy/models/downloader.cpp

@@ -13,20 +13,17 @@ Downloader::Downloader(QObject *parent) : QObject(parent), busy_(false), m_WebCt
 Downloader::~Downloader() {
 }
 
-QUrl Downloader::getUrl() const
-{
+QUrl Downloader::getUrl() const{
     return url_;
 }
 
-void Downloader::setUrl(const QUrl &_url)
-{
+void Downloader::setUrl(const QUrl &_url){
     url_ = _url;
 }
 
-void Downloader::waitForDownloaded() const
-{
-    if (!busy_)
-        return;
+void Downloader::waitForDownloaded() const{
+
+    if(!busy_) return;
 
     QEventLoop loop;
     connect(qApp, &QApplication::aboutToQuit, &loop, &QEventLoop::quit);
@@ -34,28 +31,23 @@ void Downloader::waitForDownloaded() const
     loop.exec();
 }
 
-bool Downloader::isStarted() const
-{
+bool Downloader::isStarted() const{
     return busy_;
 }
 
-double Downloader::getPercent() const
-{
+double Downloader::getPercent() const{
     return bytes_total_ > 0.01 ? double(bytes_downloaded_) * 100.0 / double(bytes_total_) : 0;
 }
 
-quint64 Downloader::getBytesTotal() const
-{
+quint64 Downloader::getBytesTotal() const{
     return bytes_total_;
 }
 
-quint64 Downloader::getBytesDownloaded() const
-{
+quint64 Downloader::getBytesDownloaded() const{
     return bytes_downloaded_;
 }
 
-quint64 Downloader::getElapsedTime() const
-{
+quint64 Downloader::getElapsedTime() const{
     quint64 delta_size = getBytesTotal() - getBytesDownloaded();
     quint64 avg_speed = qMax(quint64(1), getAverageSpeed());
 
@@ -67,23 +59,20 @@ quint64 Downloader::getElapsedTime() const
     return delta_size / avg_speed;
 }
 
-quint64 Downloader::getCurrentSpeed() const
-{
+quint64 Downloader::getCurrentSpeed() const{
     return download_speed_;
 }
 
-quint64 Downloader::getAverageSpeed() const
-{
+quint64 Downloader::getAverageSpeed() const{
     return average_speed_;
 }
 
-Downloader::Status Downloader::getDownloadStatus() const
-{
+Downloader::Status Downloader::getDownloadStatus() const{
     return {isStarted(), getPercent(), getBytesTotal(), getBytesDownloaded(), getCurrentSpeed(), getAverageSpeed(), getElapsedTime()};
 }
 
-QString Downloader::getSpeedFormatted(quint64 speed_bytes_per_sec)
-{
+QString Downloader::getSpeedFormatted(quint64 speed_bytes_per_sec){
+
     float speed = speed_bytes_per_sec;
 
     QString unit;
@@ -99,8 +88,8 @@ QString Downloader::getSpeedFormatted(quint64 speed_bytes_per_sec)
     return QString::number(speed, 'f', 1) + " " + unit;
 }
 
-QString Downloader::getSizeFormatted(quint64 bytes)
-{
+QString Downloader::getSizeFormatted(quint64 bytes){
+
     float size = bytes;
     QString unit;
     if (size < 1024) {
@@ -118,8 +107,8 @@ QString Downloader::getSizeFormatted(quint64 bytes)
     return QString::number(size, 'f', 1) + " " + unit;
 }
 
-QString Downloader::getElapsedTimeFormatted(quint64 elapsed_time_secs)
-{
+QString Downloader::getElapsedTimeFormatted(quint64 elapsed_time_secs){
+
     qint64 secs = elapsed_time_secs;
     qint64 mins = 0;
     qint64 hours = 0;
@@ -181,8 +170,8 @@ QString Downloader::getElapsedTimeFormatted(quint64 elapsed_time_secs)
     return result;
 }
 
-void Downloader::start()
-{
+void Downloader::start(){
+
     if (busy_) {
         qDebug() << "Cannot download " << url_ << ", downloader is busy!";
         return;
@@ -227,15 +216,15 @@ void Downloader::onDownloadProgressChanged(qint64 bytesReceived, qint64 bytesTot
     }
 }
 
-void Downloader::stop()
-{
+void Downloader::stop(){
+
     if (m_CurrentReply) {
         m_CurrentReply->abort();
     }
     busy_ = false;
 }
 
-void Downloader::onDownloadFinished(QNetworkReply*) {
+void Downloader::onDownloadFinished(QNetworkReply*){
     if (m_CurrentReply)
         m_CurrentReply->deleteLater();
 
@@ -245,11 +234,10 @@ void Downloader::onDownloadFinished(QNetworkReply*) {
     emit downloadFinished(this);
 }
 
-void Downloader::onReadyRead()
-{
+void Downloader::onReadyRead(){
     QByteArray readdata = m_CurrentReply->readAll();
-    if (targetFile && targetFile->isWritable())
+    if(targetFile && targetFile->isWritable())
         targetFile->write(readdata);
-    if (targetBytearray)
+    if(targetBytearray)
         targetBytearray->append(readdata);
 }

+ 3 - 1
src/Legacy/models/patchdownloader.cpp

@@ -67,8 +67,10 @@ void PatchDownloader::checkForUpdates() {
         query.addQueryItem(patch, "100");
     }
 
+    QString newfonts = Settings::getValue("Lotro/newfonts") > 0 ? "" : "/newfonts";
+
     QUrl target_url;
-    target_url.setUrl(Settings::getValue("Network/patch_updates_url").toString());
+    target_url.setUrl(Settings::getValue("Network/patch_updates_url").toString() + newfonts);
     target_url.setQuery(query);
 
     QByteArray target_array;

+ 108 - 90
src/Legacy/models/patchinstaller.cpp

@@ -21,38 +21,58 @@ QString getComponentNameFromId(int id) {
     case 202: return "textures";
     case 300: return "sounds";
     case 301: return "videos";
+    case 500: return "fonts";
     }
     return "none";
 }
 
-PatchInstaller::PatchInstaller(QObject *parent) : QObject(parent) {
-        client_local_file_ = new LOTRO_DAT::DatFile(100);
-        client_general_file_ = new LOTRO_DAT::DatFile(101);
+void PatchInstaller::createDatFile(int id, QString name, int component, QString path){
+    datfiles[id] = datfile();
+    datfiles[id].id = id;
+    datfiles[id].name = name;
+    datfiles[id].path = path;
+    datfiles[id].file = new LOTRO_DAT::DatFile(component);
+    datfiles[id].file->Init(path.toStdString());// инициализируем
+    datfiles[id].init = datfiles[id].file->Initialized(); // проверяем инициализацию
+    if(datfiles[id].init){
+       datfiles[id].maxiter = datfiles[id].file->GetDatFileMaxIteration();
+       qInfo() << "Init" << datfiles[id].name << ", result" << datfiles[id].init << ", iterations - " << datfiles[id].maxiter;
+    } else {
+        qCritical() << "Failed CheckAppPrerequisities: initialization of " + name + " dat file failed!";
+    }
+}
+
+const QMap<int, PatchInstaller::datfile>& PatchInstaller::getDatFiles(){
+    return this->datfiles;
+}
+
+
+PatchInstaller::PatchInstaller(QObject *parent) : QObject(parent){
         connect(&PatchDownloader::instance(), &PatchDownloader::finished, this, [this](){startPatchInstallationChain();});
 }
 
-bool PatchInstaller::initialised() {
-    return client_general_file_->Initialized() && client_local_file_->Initialized();
+bool PatchInstaller::initialised(){
+    foreach(datfile file, datfiles){
+        if(file.init == false) return false;
+    }
+    return true;
 }
 
-void PatchInstaller::checkIfUpdatedByGame()
-{
-    const int client_local_maxiter = client_local_file_->GetDatFileMaxIteration();
-    const int client_general_maxiter = client_general_file_->GetDatFileMaxIteration();
+void PatchInstaller::checkIfUpdatedByGame(){
 
     const int client_local_saved_maxiter = _current_applied_patches_info.client_local_header_maxiter;
     const int client_general_saved_maxiter = _current_applied_patches_info.client_general_header_maxiter;
+    const int client_surface_saved_maxiter = _current_applied_patches_info.client_surface_header_maxiter;
 
     emit updatedByGameStatusChanged(
-        (client_local_saved_maxiter != -1 && client_local_maxiter != client_local_saved_maxiter) ||
-        (client_general_saved_maxiter != -1 && client_general_maxiter != client_general_saved_maxiter)
+        (client_local_saved_maxiter != -1 && datfiles[0].maxiter != client_local_saved_maxiter) ||
+        (client_general_saved_maxiter != -1 && datfiles[1].maxiter != client_general_saved_maxiter) ||
+        (client_surface_saved_maxiter != -1 && datfiles[3].maxiter != client_surface_saved_maxiter)
     );
 }
 
 PatchInstaller::~PatchInstaller() {
     deinit();
-    delete client_local_file_;
-    delete client_general_file_;
 }
 
 // ############## PRIVATE ############## //
@@ -63,17 +83,34 @@ bool PatchInstaller::datPathIsRelevant() {
 
     QString client_local_filepath = game_folder + "/client_local_" + locale_prefix + ".dat";
     QString client_general_filepath = game_folder + "/client_general.dat";
+    QString client_surface_filepath = game_folder + "/client_surface.dat";
 
-    QString client_local_current_path = QString::fromStdString(client_local_file_->GetFilename());
-    QString client_general_current_path = QString::fromStdString(client_general_file_->GetFilename());
+    QString client_local_current_path = QString::fromStdString(datfiles[0].file->GetFilename());
+    QString client_general_current_path = QString::fromStdString(datfiles[1].file->GetFilename());
+    QString client_surface_current_path = QString::fromStdString(datfiles[3].file->GetFilename());
 
     return QFileInfo(client_local_filepath) != QFileInfo(client_local_current_path)
-            || QFileInfo(client_general_filepath) != QFileInfo(client_general_current_path);
+            || QFileInfo(client_general_filepath) != QFileInfo(client_general_current_path)
+            || QFileInfo(client_surface_filepath) != QFileInfo(client_surface_current_path);
 }
 
 void PatchInstaller::deinit() {
-    client_local_file_->Deinit();
-    client_general_file_->Deinit();
+    if (datfiles.find(0) != datfiles.end() && datfiles[0].file) {
+        datfiles[0].file->Deinit(); // Сначала деинициализируем сам dat-файл
+        delete datfiles[0].file; // Чистим память за объектом dat-файла
+        datfiles.remove(0); // Удаляем служебную инфу по dat-файлу
+    }
+    if (datfiles.find(1) != datfiles.end() && datfiles[1].file) {
+        datfiles[1].file->Deinit();
+        delete datfiles[1].file;
+        datfiles.remove(1);
+    }
+
+    if (datfiles.find(3) != datfiles.end() && datfiles[3].file) {
+        datfiles[3].file->Deinit();
+        delete datfiles[3].file;
+        datfiles.remove(3);
+    }
     emit deinitialized();
 }
 
@@ -111,7 +148,7 @@ void PatchInstaller::installPatch(QString patch_name, LOTRO_DAT::Database* datab
         }
 
         const int dat_id = file.options["did"] ? file.options["did"].as<int>() : E_CLIENT_LOCAL;
-        if (dat_id != E_CLIENT_LOCAL && dat_id != E_CLIENT_GENERAL) {
+        if (dat_id != E_CLIENT_LOCAL && dat_id != E_CLIENT_GENERAL &&  dat_id != E_CLIENT_SURFACE) {
             qWarning() << "Unknown dat id parameter for file " << file.options["fid"].as<long long>() << " (dat id value = " << dat_id << "), SKIPPING!";
             continue;
         }
@@ -120,34 +157,24 @@ void PatchInstaller::installPatch(QString patch_name, LOTRO_DAT::Database* datab
         int file_version = -1;
         int file_iteration = -1;
 
-        if (dat_id == E_CLIENT_LOCAL) {
-            file_version = client_local_file_->GetFileVersion(file_id);
-            file_iteration = client_local_file_->getSubfileInfo(file_id).iteration;
-        } else if (dat_id == E_CLIENT_GENERAL) {
-            file_version = client_general_file_->GetFileVersion(file_id);
-            file_iteration = client_general_file_->getSubfileInfo(file_id).iteration;
-        }
+        file_version = datfiles[dat_id].file->GetFileVersion(file_id);
+        file_iteration = datfiles[dat_id].file->getSubfileInfo(file_id).iteration;
 
         // qDebug() << "File" << file_id << "version:" << file_version << "iteration:" << file_iteration;
         if (file_version != _patch_files_versions && file_version != 0) {
             LOTRO_DAT::SubfileData data;
-            if (dat_id == E_CLIENT_LOCAL) {
-                data = client_local_file_->GetFile(file_id);
-            } else if (dat_id == E_CLIENT_GENERAL) {
-                data = client_general_file_->GetFile(file_id);
+
+            data = datfiles[dat_id].file->GetFile(file_id);
+
+            // тут у нас только текстуры шрифтов, их отменять не нужно
+            if (dat_id != E_CLIENT_SURFACE){
+                orig_files_db.addFile(file_id, dat_id, file_version, file_iteration, data);
             }
-            orig_files_db.addFile(file_id, dat_id, file_version, file_iteration, data);
+
         }
 
-        //if (file.options["ext"].as<std::string>() == ".txt") {
-        //    file.text_data = QString::fromStdU16String(file.text_data).replace("[", "[ he" + QString::number(file_id) + "he ").toStdU16String();
-        //}
+        datfiles[dat_id].file->PatchFile(file, _patch_files_versions);
 
-        if (dat_id == E_CLIENT_LOCAL) {
-            client_local_file_->PatchFile(file, _patch_files_versions);
-        } else if (dat_id == E_CLIENT_GENERAL) {
-            client_general_file_->PatchFile(file, _patch_files_versions);
-        }
     }
     const QString hashsum = Settings::getValue("PatchDatabases/" + patch_name + "/hashsum").toString();
     if (patch_name == "text") {
@@ -199,18 +226,13 @@ void PatchInstaller::installOriginalPatch(QString patch_name)
     qDebug() << "Files in database: " << orig_db.getRowsCount();
     DatOriginalFilesDatabase::FileOperation operation = [this](int file_id, int dat_id, int version, int iteration, const LOTRO_DAT::SubfileData& data) {
         int original_file_version = 0;
-        if (dat_id == E_CLIENT_LOCAL) {
-            original_file_version = client_local_file_->GetFileVersion(file_id);
-        } else if (dat_id == E_CLIENT_GENERAL) {
-            original_file_version = client_general_file_->GetFileVersion(file_id);
-        }
 
+        original_file_version = datfiles[dat_id].file->GetFileVersion(file_id);
 
-        if (original_file_version == _patch_files_versions && dat_id == E_CLIENT_LOCAL) {
-            client_local_file_->PatchFile(data, version, iteration);
-        } else if (original_file_version == _patch_files_versions && dat_id == E_CLIENT_GENERAL) {
-            client_general_file_->PatchFile(data, version, iteration);
+        if (original_file_version == _patch_files_versions){
+            datfiles[dat_id].file->PatchFile(data, version, iteration);
         }
+
         current_status.finished_parts++;
         if (current_status.finished_parts * 100 / current_status.total_parts !=
                 (current_status.finished_parts - 1) * 100 * 10 / current_status.total_parts) {
@@ -340,17 +362,25 @@ void PatchInstaller::installVideos(LOTRO_DAT::Database* database) {
     qInfo() << "PatchInstaller: finished downloading videos";
 }
 
-PatchInstaller::AppliedPatchesInfo PatchInstaller::getAppliedPatchesInfoFromDatFile() {
+PatchInstaller::AppliedPatchesInfo PatchInstaller::getAppliedPatchesInfoFromDatFile(){
+
     PatchInstaller::AppliedPatchesInfo result;
-    const LOTRO_DAT::SubfileData patch_versions_file = client_local_file_->GetFile(_applied_patches_file_id);
-    if (patch_versions_file.Empty()) {
-        result.has_no_patch_mark = true;
-    } else {
+    const LOTRO_DAT::SubfileData patch_versions_file = datfiles[0].file->GetFile(_applied_patches_file_id);
+    result.has_no_patch_mark = true;
+
+    std::string schar = (char*)patch_versions_file.binary_data.data();
+    QString sstr = QString::fromStdString(schar);
+    qInfo() << sstr;
+
+    if(!patch_versions_file.Empty() && sstr != "" && sstr.indexOf("HI_FROM_ENDEVIR")) {
+
         const QString text_data = QString::fromUtf8(reinterpret_cast<const char*>(patch_versions_file.binary_data.data() + 4), patch_versions_file.binary_data.size() - 4);
         const QStringList text_data_splitted = text_data.split("\n");
-        if (text_data_splitted.length() < 0 || text_data_splitted[0] != _patch_mark_header) {
+qInfo() << text_data;
+        if (text_data_splitted.length() < 0 || text_data_splitted[0] != _patch_mark_header){
             return result;
         }
+
         for (const QString& str: text_data_splitted) {
             if (str.startsWith("TEXTS:")) {
                 result.texts_patch_hashsum = QString(str).remove(0, 6);
@@ -370,8 +400,11 @@ PatchInstaller::AppliedPatchesInfo PatchInstaller::getAppliedPatchesInfoFromDatF
                 result.client_local_header_maxiter = QString(str).remove(0, 28).toInt();
             } else if (str.startsWith("CLIENT_GENERAL_HEADER_MAXITER:")) {
                 result.client_general_header_maxiter = QString(str).remove(0, 30).toInt();
+            } else if (str.startsWith("CLIENT_SURFACE_HEADER_MAXITER:")) {
+                result.client_surface_header_maxiter = QString(str).remove(0, 30).toInt();
             }
         }
+
         if (result.texts_patch_hashsum != "" || result.images_patch_hashsum != "" || result.textures_patch_hashsum != "" ||
             result.sounds_patch_hashsum != "" || result.videos_patch_hashsum != "" || result.fonts_patch_hashsum != "" ||
             result.loadscreens_patch_hashsum != "")
@@ -379,10 +412,12 @@ PatchInstaller::AppliedPatchesInfo PatchInstaller::getAppliedPatchesInfoFromDatF
             result.has_no_patch_mark = false;
         }
     }
+    qInfo() << "Dat is modified: " << result.has_no_patch_mark;
     return result;
 }
 
-void PatchInstaller::insertPatchesInfoInDatFile(const PatchInstaller::AppliedPatchesInfo& info) {
+void PatchInstaller::insertPatchesInfoInDatFile(const PatchInstaller::AppliedPatchesInfo& info){
+
     LOTRO_DAT::SubfileData file_data;
     file_data.options["fid"] = _applied_patches_file_id;
     file_data.options["ext"] = LOTRO_DAT::StringFromFileType(LOTRO_DAT::TEXT);
@@ -395,16 +430,15 @@ void PatchInstaller::insertPatchesInfoInDatFile(const PatchInstaller::AppliedPat
     patches_info_data += "TEXTURES:" + info.textures_patch_hashsum + "\n";
     patches_info_data += "FONTS:" + info.fonts_patch_hashsum + "\n";
     patches_info_data += "VIDEOS:" + info.videos_patch_hashsum + "\n";
-
-    const int client_local_maxiter = client_local_file_->GetDatFileMaxIteration();
-    const int client_general_maxiter = client_general_file_->GetDatFileMaxIteration();
-
-    patches_info_data += "CLIENT_LOCAL_HEADER_MAXITER:" + QString::number(client_local_maxiter) + "\n";
-    patches_info_data += "CLIENT_GENERAL_HEADER_MAXITER:" + QString::number(client_general_maxiter) + "\n";
+    patches_info_data += "CLIENT_LOCAL_HEADER_MAXITER:" + QString::number(datfiles[0].file->GetDatFileMaxIteration()) + "\n";
+    patches_info_data += "CLIENT_GENERAL_HEADER_MAXITER:" + QString::number(datfiles[1].file->GetDatFileMaxIteration()) + "\n";
+    patches_info_data += "CLIENT_SURFACE_HEADER_MAXITER:" + QString::number(datfiles[3].file->GetDatFileMaxIteration()) + "\n";
 
     QByteArray data = QByteArray((char*)&_applied_patches_file_id, 4) + patches_info_data.toUtf8();
+    qInfo() << "Set info to dat-file: " << data;
     file_data.binary_data = LOTRO_DAT::BinaryData(data.data(), data.size());
-    client_local_file_->PatchFile(file_data, _patch_files_versions, 1, true);
+    datfiles[0].file->PatchFile(file_data, _patch_files_versions, 1, true);
+
 }
 
 
@@ -413,27 +447,19 @@ void PatchInstaller::insertPatchesInfoInDatFile(const PatchInstaller::AppliedPat
 void PatchInstaller::init()
 {
     emit initializationStarted();
-    if (client_local_file_->Initialized() || client_general_file_->Initialized()) {
-        // Firstly - deinitializing existing client_local files.
-        deinit();
-    }
     qInfo() << "PatchInstaller: Starting initialisation of LotroDatManager";
     qRegisterMetaType<PatchInstaller::Status>();
 
+    // Деинициализируем старые файлы, если они были
+    deinit();
+
+    // Создаем массив нужных нам dat-файлов
     QString game_folder = Settings::getValue("Lotro/game_path").toString();
     QString locale_prefix = Settings::getValue("Lotro/original_locale").toString();
-
-    QString client_local_filepath = game_folder + "/client_local_" + locale_prefix + ".dat";
-    QString client_general_filepath = game_folder + "/client_general.dat";
-
-    // Initialising client_local_*.dat file and client_general.dat
-
-    client_local_file_->Init(client_local_filepath.toStdString());
-    client_general_file_->Init(client_general_filepath.toStdString());
-
-    qInfo() << "PatchInstaller: initialisation successfull! Dat files: "
-             << QString::fromStdString(client_general_file_->GetFilename())
-             << QString::fromStdString(client_local_file_->GetFilename());
+    createDatFile(0, "client_local", 100, game_folder + "/client_local_" + locale_prefix + ".dat");
+    createDatFile(1, "client_general", 101, game_folder + "/client_general.dat");
+    createDatFile(3, "client_surface", 0, game_folder + "/client_surface.dat");
+    // Создаем массив нужных нам dat-файлов
 
     _current_applied_patches_info = getAppliedPatchesInfoFromDatFile();
     checkIfUpdatedByGame();
@@ -460,17 +486,10 @@ void PatchInstaller::startGame(bool remove_dat_files) {
         args << "-skiprawdownload";
     }
 
-    client_general_file_->Deinit();
-    client_local_file_->Deinit();
-
-    if (remove_dat_files) {
-        QString game_folder = Settings::getValue("Lotro/game_path").toString();
-        QString locale_prefix = Settings::getValue("Lotro/original_locale").toString();
-
-        QString client_local_filepath = game_folder + "/client_local_" + locale_prefix + ".dat";
-        QString client_general_filepath = game_folder + "/client_general.dat";
-        QFile::remove(client_local_filepath);
-        QFile::remove(client_general_filepath);
+    deinit();
+    if (remove_dat_files){
+        QFile::remove(datfiles[0].path);
+        QFile::remove(datfiles[1].path);
     }
 
     QString username = Settings::getValue("Account/username").toString();
@@ -481,7 +500,6 @@ void PatchInstaller::startGame(bool remove_dat_files) {
 
     qInfo() << "Starting LOTRO. Path =" << game_folder;
 
-    deinit();
 
     QProcess process;
     process.startDetached(game_folder + "/LotroLauncher.exe", args, game_folder);

+ 18 - 1
src/Legacy/models/patchinstaller.h

@@ -29,8 +29,20 @@ public:
         QString videos_patch_hashsum = "";
         int client_local_header_maxiter = -1;
         int client_general_header_maxiter = -1;
+        int client_surface_header_maxiter = -1;
     };
 
+    struct datfile {
+        int id;
+        QString name;
+        QString path;
+        bool init = false;
+        int maxiter = -1;
+        LOTRO_DAT::DatFile* file;
+    };
+
+    QMap<int, datfile> datfiles;
+
 public:
     static PatchInstaller& instance() {
         static PatchInstaller instance_;
@@ -47,7 +59,8 @@ private:
 
     enum RESOURCE_FILE_TYPE : int {
         E_CLIENT_LOCAL = 0,
-        E_CLIENT_GENERAL = 1
+        E_CLIENT_GENERAL = 1,
+        E_CLIENT_SURFACE = 3
     };
 
     explicit PatchInstaller(QObject *parent = nullptr);
@@ -68,6 +81,9 @@ private:
 
     void insertPatchesInfoInDatFile(const AppliedPatchesInfo& info);
 
+    void createDatFile(int id, QString name, int component, QString path);
+    const QMap<int, datfile>& getDatFiles();
+
 public slots:
     void deinit();
     void init();
@@ -91,6 +107,7 @@ signals:
 private:
     LOTRO_DAT::DatFile* client_local_file_;
     LOTRO_DAT::DatFile* client_general_file_;
+    LOTRO_DAT::DatFile* client_surface_file_;
 
     AppliedPatchesInfo _current_applied_patches_info;
     Status current_status;

BIN
src/Legacy/models/patchinstaller.rar


+ 1 - 0
src/Legacy/models/settings.cpp

@@ -15,6 +15,7 @@ QMap<QString, QVariant> defaults = {
     // Lotro Manager
     {"Lotro/game_path", "none"},
     {"Lotro/original_locale", "English"},
+    {"Lotro/newfonts", 0},
     {"Lotro/skip_raw_download", true},
     {"Lotro/no_splash_screen", false},
 

+ 34 - 61
src/Legacy/utils.cpp

@@ -14,10 +14,10 @@
 #include <QApplication>
 
 #include <LotroDat/datfile.h>
-
 #include "models/settings.h"
 #include "utils.h"
 
+
 bool checkInternetConnection(QUrl url) {
     QNetworkAccessManager nam;
     QNetworkRequest req(url);
@@ -103,10 +103,30 @@ bool isRunning(const QString &process) {
   return output.startsWith(QString("\"%1").arg(process));
 }
 
+AppErrorStatus validateFile(QString name, QString path){
+    QFileInfo check_file(path);
+    if(!check_file.exists() || !check_file.isFile()){
+        qCritical() << "Failed CheckAppPrerequisities: file " + name + " do not exist!";
+        return E_DAT_FILES_MISSING;
+    }
+
+    if (!QFile::setPermissions(path,QFileDevice::ReadUser |QFileDevice::WriteUser |QFileDevice::ExeUser)){
+        qCritical() << "Failed CheckAppPrerequisities: incorrect " + name + " permissions!";
+        return E_WRONG_FILE_PERMISSIONS;
+    }
+
+    if (LOTRO_DAT::DatFile::checkIfPatchedByLegacyV1(check_file.absoluteFilePath().toStdString())){
+        qCritical() << "Failed CheckAppPrerequisities: found Legacy v1 patch mark in " + name + "!";
+        return E_PATCHED_BY_OLD_LEGACY;
+    }
+
+    return E_NO_ERRORS;
+}
+
+AppErrorStatus CheckAppPrerequesities(){
 
-AppErrorStatus CheckAppPrerequesities() {
     qInfo() << "Starting CheckAppPrerequisities...";
-    if (isRunning("LotroLauncher.exe") || isRunning("lotroclient.exe") || isRunning("lotroclient64.exe")) {
+    if(isRunning("LotroLauncher.exe") || isRunning("lotroclient.exe") || isRunning("lotroclient64.exe")){
         qCritical() << "Failed CheckAppPrerequisites: found running LOTRO client!";
         return E_LOTRO_RUNNING;
     }
@@ -119,7 +139,7 @@ AppErrorStatus CheckAppPrerequesities() {
 
     // Checking LotroLauncher.exe availability
     QFileInfo lotro_launcher_exe(game_folder_path + "/LotroLauncher.exe");
-    if (!lotro_launcher_exe.exists()) {
+    if(!lotro_launcher_exe.exists()){
         qCritical() << "Failed CheckAppPrerequisities: cannot find file LotroLauncher.exe";
         return E_WRONG_GAME_FOLDER;
     } else {
@@ -131,63 +151,15 @@ AppErrorStatus CheckAppPrerequesities() {
     }
 
     // Checking DAT files availability & correctness
-    QString client_local_filepath = game_folder_path + "/client_local_" + locale_prefix + ".dat";
-    QString client_general_filepath = game_folder_path + "/client_general.dat";
-
-    qInfo() << "CheckAppPrerequisities: client_local_filepath = " << client_local_filepath;
-    qInfo() << "CheckAppPrerequisities: client_general_filepath = " << client_general_filepath;
-
-
-    QFileInfo client_local_file(client_local_filepath);
-    QFileInfo client_general_file(client_general_filepath);
-
-    if (!client_general_file.exists() || !client_local_file.exists()) {
-        qCritical() << "Failed CheckAppPrerequisities: dat files do not exist!";
-        return E_DAT_FILES_MISSING;
-    } else {
-        if (!QFile::setPermissions(client_general_filepath,
-                                   QFileDevice::ReadUser |
-                                   QFileDevice::WriteUser |
-                                   QFileDevice::ExeUser)) {
-
-            qCritical() << "Failed CheckAppPrerequisities: incorrect client general permissions!";
-            return E_WRONG_FILE_PERMISSIONS;
-        }
-
-        if (!QFile::setPermissions(client_local_filepath,
-                                   QFileDevice::ReadUser |
-                                   QFileDevice::WriteUser |
-                                   QFileDevice::ExeUser)) {
-
-            qCritical() << "Failed CheckAppPrerequisities: incorrect client local permissions!";
-            return E_WRONG_FILE_PERMISSIONS;
-        }
-
-        if (LOTRO_DAT::DatFile::checkIfPatchedByLegacyV1(client_local_file.absoluteFilePath().toStdString())) {
-            qCritical() << "Failed CheckAppPrerequisities: found Legacy v1 patch mark in client local!";
-            return E_PATCHED_BY_OLD_LEGACY;
-        }
-        if (LOTRO_DAT::DatFile::checkIfPatchedByLegacyV1(client_general_file.absoluteFilePath().toStdString())) {
-            qCritical() << "Failed CheckAppPrerequisities: found Legacy v1 patch mark in client general!";
-            return E_PATCHED_BY_OLD_LEGACY;
-        }
-
-        LOTRO_DAT::DatFile file(0);
-        if (!file.Init(client_local_file.absoluteFilePath().toStdString())) {
-            qCritical() << "Failed CheckAppPrerequisities: initialization of client local dat file failed!";
-            return E_DAT_FILE_INCORRECT;
-        } else {
-            file.Deinit();
-        }
-        if (!file.Init(client_general_file.absoluteFilePath().toStdString())) {
-            qCritical() << "Failed CheckAppPrerequisities: initialization of client general dat file failed!";
-            return E_DAT_FILE_INCORRECT;
-        } else {
-            file.Deinit();
-        }
-    }
-
-    if (!checkInternetConnection(QUrl(Settings::getValue("Network/patch_updates_url").toString()))) {
+    AppErrorStatus result = validateFile("client_local", game_folder_path + "/client_local_" + locale_prefix + ".dat");
+    if(result != E_NO_ERRORS) return result;
+    result = validateFile("client_general", game_folder_path + "/client_general.dat");
+    if(result != E_NO_ERRORS) return result;
+    result = validateFile("client_surface", game_folder_path + "/client_surface.dat");
+    if(result != E_NO_ERRORS) return result;
+
+    // Проверка интернет-соединения
+    if (!checkInternetConnection(QUrl(Settings::getValue("Network/patch_updates_url").toString()))){
         qCritical() << "Failed CheckAppPrerequisities: no server connection!";
         return E_NO_SERVER_CONNECTION;
     }
@@ -216,3 +188,4 @@ QDebug operator<<(QDebug dbg, const AppErrorStatus &status)
 
     return dbg;
 }
+

+ 15 - 0
src/Legacy/widgets/translationcomponents.cpp

@@ -13,6 +13,14 @@ TranslationComponents::TranslationComponents(QWidget *parent) :
     ui->setupUi(this);
     setAttribute(Qt::WA_StyledBackground, true);
 
+
+    int newfonts = Settings::getValue("Lotro/newfonts").toInt();
+    ui->newfonts->setChecked(newfonts > 0 ? true : false);
+    QPalette p = ui->newfonts->palette();
+    p.setColor(QPalette::Active, QPalette::WindowText, Qt::white);
+    p.setColor(QPalette::Inactive, QPalette::WindowText, Qt::white);
+    ui->newfonts->setPalette(p);
+
     ui->texts_block_label->setTooltipParentWidget(parentWidget());
     ui->texts_block_label->raise();
     ui->texts_block_label->setTooltipText("Перевод текстовых элементов в игре: названий, квестов, предметов, эмоций, интерфейса и т.д.");
@@ -155,3 +163,10 @@ void TranslationComponents::checkIfSettingsDoNotMatchCurrentDatState() {
         emit noNeedToPatch();
     }
 }
+
+void TranslationComponents::on_newfonts_stateChanged(int arg1)
+{
+  Settings::setValue("Lotro/newfonts", arg1);
+  QMetaObject::invokeMethod(&PatchDownloader::instance(), &PatchDownloader::checkForUpdates, Qt::QueuedConnection);
+}
+

+ 3 - 0
src/Legacy/widgets/translationcomponents.h

@@ -40,6 +40,9 @@ private slots:
     void onSoundsChange(bool new_value);
     void onLoadscreensChange(bool new_value);
 
+    void on_newfonts_stateChanged(int arg1);
+
+
 private:
     Ui::TranslationComponents *ui;
 };

+ 19 - 1
src/Legacy/widgets/translationcomponents.ui

@@ -84,13 +84,31 @@
          <enum>QFrame::NoFrame</enum>
         </property>
         <property name="text">
-         <string>Тексты</string>
+         <string>Тексты </string>
         </property>
         <property name="alignment">
          <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
         </property>
        </widget>
       </item>
+      <item>
+       <widget class="QCheckBox" name="newfonts">
+        <property name="font">
+         <font>
+          <pointsize>10</pointsize>
+         </font>
+        </property>
+        <property name="text">
+         <string>упрощенные шрифты</string>
+        </property>
+        <property name="iconSize">
+         <size>
+          <width>12</width>
+          <height>12</height>
+         </size>
+        </property>
+       </widget>
+      </item>
       <item>
        <spacer name="horizontalSpacer">
         <property name="orientation">