2 | //
3 | // Permission is hereby granted, free of charge, to any person obtaining a copy
4 | // of this software and associated documentation files (the "Software"), to deal
5 | // in the Software without restriction, including without limitation the rights
6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | // copies of the Software, and to permit persons to whom the Software is
8 | // furnished to do so, subject to the following conditions:
9 |
10 | // The above copyright notice and this permission notice shall be included in all
11 | // copies or substantial portions of the Software.
12 |
13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 | // SOFTWARE.
20 | //
21 | #include "dialogabout.h"
22 |
23 | #include "ui_dialogabout.h"
24 |
25 | DialogAbout::DialogAbout(QWidget *pParent) : QDialog(pParent), ui(new Ui::DialogAbout)
26 | {
27 | ui->setupUi(this);
28 |
29 | XAboutWidget::DATA _data = {};
30 |
31 | _data.sInfo += QString(
32 | "%1
")
34 | .arg(XOptions::getTitle(X_APPLICATIONDISPLAYNAME, X_APPLICATIONVERSION));
35 | _data.sInfo += QString(
36 | "Copyright (C) "
37 | "2019-2024 Hors
");
38 | _data.sInfo += QString(
39 | "%1: "
40 | "horsicq@gmail.com
")
43 | .arg(tr("Bugreports"));
44 | _data.sInfo += QString(
45 | "%1: "
46 | "http://ntinfo.biz
")
49 | .arg(tr("Website"));
50 | _data.sInfo += QString(
51 | "%1(Paypal): "
52 | "ntinfo.re@gmail.com
")
55 | .arg(tr("Donate"));
56 | _data.sInfo += QString(
57 | "%1(BTC): "
58 | "3DqddVBX9PKqMvNPXZ3gPHBNNRtD9CnmJo"
61 | "p>")
62 | .arg(tr("Donate"));
63 | _data.sInfo += QString(
64 | "
%1: "
65 | "https://github.com/horsicq/x64dbg-Plugin-Manager"
68 | "p>")
69 | .arg(tr("Source code"));
70 |
71 | _data.sLibraries += QString(
72 | "
QT Library "
73 | "%1 http://qt-project.org
")
76 | .arg(QT_VERSION_STR);
77 |
78 | _data.sLogoPath = ":/images/main.png";
79 | _data.sUpdatesLink = "https://github.com/horsicq/x64dbg-Plugin-Manager/releases";
80 | _data.sServerVersionLink = "https://raw.githubusercontent.com/horsicq/x64dbg-Plugin-Manager/master/release_version.txt";
81 | _data.sThanksLink = "https://github.com/horsicq/x64dbg-Plugin-Manager/blob/master/THANKS.md";
82 |
83 | ui->widgetAbout->setData(_data);
84 | }
85 |
86 | DialogAbout::~DialogAbout()
87 | {
88 | delete ui;
89 | }
90 |
91 | void DialogAbout::on_pushButtonOK_clicked()
92 | {
93 | this->close();
94 | }
95 |
--------------------------------------------------------------------------------
/gui_source/dialogoptions.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | DialogOptions
4 |
5 |
6 | Qt::ApplicationModal
7 |
8 |
9 |
10 | 0
11 | 0
12 | 463
13 | 221
14 |
15 |
16 |
17 | Options
18 |
19 |
20 | true
21 |
22 |
23 | -
24 |
25 |
26 | Stay on top
27 |
28 |
29 |
30 | -
31 |
32 |
33 | Root path
34 |
35 |
36 |
37 | 1
38 |
39 |
40 | 1
41 |
42 |
43 | 1
44 |
45 |
46 | 1
47 |
48 |
-
49 |
50 |
51 | -
52 |
53 |
54 | ...
55 |
56 |
57 |
58 |
59 |
60 |
61 | -
62 |
63 |
64 | Data path
65 |
66 |
67 |
68 | 1
69 |
70 |
71 | 1
72 |
73 |
74 | 1
75 |
76 |
77 | 1
78 |
79 |
-
80 |
81 |
82 | -
83 |
84 |
85 | ...
86 |
87 |
88 |
89 |
90 |
91 |
92 | -
93 |
94 |
95 | JSON link
96 |
97 |
98 |
99 | 1
100 |
101 |
102 | 1
103 |
104 |
105 | 1
106 |
107 |
108 | 1
109 |
110 |
-
111 |
112 |
113 |
114 |
115 |
116 | -
117 |
118 |
119 | Qt::Vertical
120 |
121 |
122 |
123 | 20
124 | 119
125 |
126 |
127 |
128 |
129 | -
130 |
131 |
-
132 |
133 |
134 | Qt::Horizontal
135 |
136 |
137 |
138 | 40
139 | 20
140 |
141 |
142 |
143 |
144 | -
145 |
146 |
147 | Cancel
148 |
149 |
150 |
151 | -
152 |
153 |
154 | OK
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
--------------------------------------------------------------------------------
/removemoduleprocess.cpp:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2019-2023 hors
2 | //
3 | // Permission is hereby granted, free of charge, to any person obtaining a copy
4 | // of this software and associated documentation files (the "Software"), to deal
5 | // in the Software without restriction, including without limitation the rights
6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | // copies of the Software, and to permit persons to whom the Software is
8 | // furnished to do so, subject to the following conditions:
9 |
10 | // The above copyright notice and this permission notice shall be included in all
11 | // copies or substantial portions of the Software.
12 |
13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 | // SOFTWARE.
20 | //
21 | #include "removemoduleprocess.h"
22 |
23 | RemoveModuleProcess::RemoveModuleProcess(QObject *pParent) : QObject(pParent)
24 | {
25 | bIsStop = false;
26 | currentStats = {};
27 | }
28 |
29 | void RemoveModuleProcess::setData(QString sDataPath, QString sRootPath, QList listModuleNames)
30 | {
31 | this->sDataPath = XBinary::convertPathName(sDataPath);
32 | this->sRootPath = XBinary::convertPathName(sRootPath);
33 | this->listModuleNames = listModuleNames;
34 | }
35 |
36 | void RemoveModuleProcess::stop()
37 | {
38 | bIsStop = true;
39 | }
40 |
41 | Utils::STATS RemoveModuleProcess::getCurrentStats()
42 | {
43 | return currentStats;
44 | }
45 |
46 | void RemoveModuleProcess::process()
47 | {
48 | QElapsedTimer elapsedTimer;
49 | elapsedTimer.start();
50 |
51 | bIsStop = false;
52 |
53 | currentStats.nTotalModule = listModuleNames.count();
54 |
55 | for (qint32 i = 0; (i < currentStats.nTotalModule) && (!bIsStop); i++) {
56 | currentStats.sModule = QString("%1: %2").arg(tr("Remove module")).arg(listModuleNames.at(i));
57 | emit infoMessage(currentStats.sModule);
58 |
59 | QString sFileName = Utils::getInstalledJsonFileName(sDataPath, listModuleNames.at(i));
60 |
61 | if (XBinary::isFileExists(sFileName)) {
62 | Utils::MDATA mdata = Utils::getMDataFromJSONFile(sFileName);
63 |
64 | currentStats.nTotalFile = mdata.listRemoveRecords.count();
65 |
66 | for (qint32 j = 0; (j < currentStats.nTotalFile) && (!bIsStop); j++) {
67 | Utils::HANDLE_RECORD record = mdata.listRemoveRecords.at(j);
68 |
69 | if (record.action == Utils::ACTION_REMOVEFILE) {
70 | XBinary::removeFile(sRootPath + QDir::separator() + record.sPath);
71 |
72 | if (!XBinary::isFileExists(sRootPath + QDir::separator() + record.sPath)) {
73 | currentStats.sFile = QString("%1: %2").arg(tr("Remove file")).arg(record.sPath);
74 | emit infoMessage(currentStats.sFile);
75 | } else {
76 | emit errorMessage(tr("%1: %2").arg(tr("Cannot remove file")).arg(sRootPath + QDir::separator() + record.sPath));
77 | bIsStop = true;
78 | }
79 | } else if (record.action == Utils::ACTION_REMOVEDIRECTORYIFEMPTY) {
80 | if (XBinary::isDirectoryEmpty(sRootPath + QDir::separator() + record.sPath)) {
81 | XBinary::removeDirectory(sRootPath + QDir::separator() + record.sPath);
82 |
83 | if (!XBinary::isDirectoryExists(sRootPath + QDir::separator() + record.sPath)) {
84 | currentStats.sFile = QString("%1: %2").arg(tr("Remove directory")).arg(record.sPath);
85 | emit infoMessage(currentStats.sFile);
86 | } else {
87 | emit errorMessage(tr("%1: %2").arg(tr("Cannot remove directory")).arg(sRootPath + QDir::separator() + record.sPath));
88 | bIsStop = true;
89 | }
90 | }
91 | }
92 |
93 | currentStats.nCurrentFile = j + 1;
94 | }
95 |
96 | if (!bIsStop) {
97 | XBinary::removeFile(sFileName);
98 |
99 | if (!XBinary::isFileExists(sFileName)) {
100 | emit infoMessage(QString("%1: %2").arg(tr("Remove file")).arg(sFileName));
101 | } else {
102 | emit errorMessage(tr("%1: %2").arg(tr("Cannot remove file")).arg(sFileName));
103 | bIsStop = true;
104 | }
105 | }
106 |
107 | if (bIsStop) {
108 | emit errorMessage(tr("Please, close all applications and try again."));
109 | }
110 | }
111 |
112 | currentStats.nCurrentModule = i + 1;
113 | }
114 |
115 | emit completed(elapsedTimer.elapsed());
116 | }
117 |
--------------------------------------------------------------------------------
/installmoduleprocess.cpp:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2019-2023 hors
2 | //
3 | // Permission is hereby granted, free of charge, to any person obtaining a copy
4 | // of this software and associated documentation files (the "Software"), to deal
5 | // in the Software without restriction, including without limitation the rights
6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | // copies of the Software, and to permit persons to whom the Software is
8 | // furnished to do so, subject to the following conditions:
9 |
10 | // The above copyright notice and this permission notice shall be included in all
11 | // copies or substantial portions of the Software.
12 |
13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 | // SOFTWARE.
20 | //
21 | #include "installmoduleprocess.h"
22 |
23 | InstallModuleProcess::InstallModuleProcess(QObject *pParent) : QObject(pParent)
24 | {
25 | currentStats = {};
26 | g_pPdStruct = nullptr;
27 | }
28 |
29 | void InstallModuleProcess::setData(QString sDataPath, QString sRootPath, QList listModuleFileNames, XBinary::PDSTRUCT *pPdStruct)
30 | {
31 | this->sDataPath = XBinary::convertPathName(sDataPath);
32 | this->sRootPath = XBinary::convertPathName(sRootPath);
33 | this->listModuleFileNames = listModuleFileNames;
34 | this->g_pPdStruct = pPdStruct;
35 | }
36 |
37 | void InstallModuleProcess::stop()
38 | {
39 | g_pPdStruct->bIsStop = true;
40 | }
41 |
42 | Utils::STATS InstallModuleProcess::getCurrentStats()
43 | {
44 | return currentStats;
45 | }
46 |
47 | void InstallModuleProcess::process()
48 | {
49 | QElapsedTimer elapsedTimer;
50 | elapsedTimer.start();
51 |
52 | currentStats.nTotalModule = listModuleFileNames.count();
53 |
54 | for (qint32 i = 0; (i < currentStats.nTotalModule) && (!(g_pPdStruct->bIsStop)); i++) {
55 | currentStats.sModule = QString("%1: %2").arg(tr("Install module")).arg(QFileInfo(listModuleFileNames.at(i)).baseName());
56 | emit infoMessage(currentStats.sModule);
57 |
58 | QFile file;
59 | file.setFileName(listModuleFileNames.at(i));
60 |
61 | if (file.open(QIODevice::ReadOnly)) {
62 | Utils::MDATA mdata = Utils::getMDataFromZip(&file, XBinary::convertPathName(sRootPath), g_pPdStruct);
63 |
64 | XZip zip(&file);
65 |
66 | QList listZipRecords = zip.getRecords(-1, g_pPdStruct);
67 |
68 | currentStats.nTotalFile = mdata.listInstallRecords.count();
69 |
70 | for (qint32 j = 0; (j < currentStats.nTotalFile) && (!(g_pPdStruct->bIsStop)); j++) {
71 | Utils::HANDLE_RECORD record = mdata.listInstallRecords.at(j);
72 |
73 | currentStats.sFile = QString("%1: %2").arg(tr("Install file")).arg(sRootPath + QDir::separator() + record.sPath);
74 | emit infoMessage(currentStats.sFile);
75 |
76 | if (record.action == Utils::ACTION_COPYFILE) {
77 | if (XBinary::isFileExists(sRootPath + QDir::separator() + record.sPath)) {
78 | if (!XBinary::removeFile(sRootPath + QDir::separator() + record.sPath)) {
79 | emit errorMessage(QString("%1: %2").arg(tr("Cannot remove file")).arg(sRootPath + QDir::separator() + record.sPath));
80 | g_pPdStruct->bIsStop = true;
81 | }
82 | }
83 |
84 | XArchive::RECORD archiveRecord = XArchive::getArchiveRecord("files/" + record.sPath, &listZipRecords);
85 | zip.decompressToFile(&archiveRecord, sRootPath + QDir::separator() + record.sPath);
86 |
87 | if (!XBinary::isFileHashValid(XBinary::HASH_SHA1, sRootPath + QDir::separator() + record.sPath, record.sSHA1)) {
88 | emit errorMessage(QString("%1: %2").arg(tr("Invalid file HASH")).arg(sRootPath + QDir::separator() + record.sPath));
89 | g_pPdStruct->bIsStop = true;
90 | }
91 | } else if (record.action == Utils::ACTION_MAKEDIRECTORY) {
92 | XBinary::createDirectory(sRootPath + QDir::separator() + record.sPath);
93 | }
94 |
95 | currentStats.nCurrentFile = j + 1;
96 | }
97 |
98 | QString sInfoFileName = Utils::getInstalledJsonFileName(sDataPath, mdata.sName);
99 |
100 | if (XBinary::isFileExists(sInfoFileName)) {
101 | if (!XBinary::removeFile(sInfoFileName)) {
102 | emit errorMessage(QString("%1: %2").arg(tr("Cannot remove file")).arg(sInfoFileName));
103 | g_pPdStruct->bIsStop = true;
104 | }
105 | }
106 |
107 | XArchive::RECORD archiveRecord = XArchive::getArchiveRecord("plugin_info.json", &listZipRecords);
108 | zip.decompressToFile(&archiveRecord, sInfoFileName);
109 |
110 | file.close();
111 | }
112 |
113 | currentStats.nCurrentModule = i + 1;
114 | }
115 |
116 | emit completed(elapsedTimer.elapsed());
117 | }
118 |
--------------------------------------------------------------------------------
/getfilefromserverprocess.cpp:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2019-2023 hors
2 | //
3 | // Permission is hereby granted, free of charge, to any person obtaining a copy
4 | // of this software and associated documentation files (the "Software"), to deal
5 | // in the Software without restriction, including without limitation the rights
6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | // copies of the Software, and to permit persons to whom the Software is
8 | // furnished to do so, subject to the following conditions:
9 |
10 | // The above copyright notice and this permission notice shall be included in all
11 | // copies or substantial portions of the Software.
12 |
13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 | // SOFTWARE.
20 | //
21 | #include "getfilefromserverprocess.h"
22 |
23 | GetFileFromServerProcess::GetFileFromServerProcess(QObject *pParent) : QObject(pParent)
24 | {
25 | pReply = 0;
26 | replyRed = 0;
27 | currentStats = {};
28 | }
29 |
30 | void GetFileFromServerProcess::setData(QList listWebRecords)
31 | {
32 | this->listWebRecords = listWebRecords;
33 | }
34 |
35 | void GetFileFromServerProcess::stop()
36 | {
37 | bIsStop = true;
38 |
39 | if (pReply) {
40 | pReply->abort();
41 | }
42 |
43 | if (replyRed) {
44 | replyRed->abort();
45 | }
46 | }
47 |
48 | Utils::STATS GetFileFromServerProcess::getCurrentStats()
49 | {
50 | return currentStats;
51 | }
52 |
53 | void GetFileFromServerProcess::process()
54 | {
55 | QElapsedTimer elapsedTimer;
56 | elapsedTimer.start();
57 |
58 | bIsStop = false;
59 |
60 | currentStats.nTotalModule = listWebRecords.count();
61 |
62 | for (qint32 i = 0; (i < currentStats.nTotalModule) && (!bIsStop); i++) {
63 | currentStats.sModule = listWebRecords.at(i).sLink;
64 | emit infoMessage(currentStats.sModule);
65 |
66 | QNetworkAccessManager nam;
67 | QNetworkRequest *pRequest = new QNetworkRequest(QUrl(listWebRecords.at(i).sLink));
68 | pReply = nam.get(*pRequest);
69 | QEventLoop loop;
70 | QObject::connect(pReply, SIGNAL(finished()), &loop, SLOT(quit()));
71 | QObject::connect(pReply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(_downloadProgress(qint64, qint64)));
72 | loop.exec();
73 |
74 | if (pReply->error() == QNetworkReply::NoError) {
75 | QString sRedirectUrl = pReply->attribute(QNetworkRequest::RedirectionTargetAttribute).toString();
76 |
77 | if (pReply->bytesAvailable() || (sRedirectUrl != "")) {
78 | bool bSuccess = false;
79 | QByteArray baData;
80 |
81 | if (sRedirectUrl != "") // Github redirect
82 | {
83 | QNetworkAccessManager namRed;
84 | QNetworkRequest *pRequestRed = new QNetworkRequest(QUrl(sRedirectUrl));
85 | replyRed = namRed.get(*pRequestRed);
86 | QEventLoop loopRed;
87 | QObject::connect(replyRed, SIGNAL(finished()), &loopRed, SLOT(quit()));
88 | QObject::connect(replyRed, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(_downloadProgress(qint64, qint64)));
89 | loopRed.exec();
90 |
91 | if (replyRed->bytesAvailable()) {
92 | baData = replyRed->readAll();
93 | bSuccess = true;
94 | }
95 | } else {
96 | baData = pReply->readAll();
97 | bSuccess = true;
98 | }
99 |
100 | if (bSuccess) {
101 | if (XBinary::isFileExists(listWebRecords.at(i).sFileName)) {
102 | if (!XBinary::removeFile(listWebRecords.at(i).sFileName)) {
103 | emit errorMessage(QString("%1: %2").arg(tr("Cannot remove file")).arg(listWebRecords.at(i).sFileName));
104 | bIsStop = true;
105 | }
106 | }
107 |
108 | if (XBinary::writeToFile(listWebRecords.at(i).sFileName, baData)) {
109 | currentStats.sFile = QString("%1: %2").arg(tr("Write data to file")).arg(listWebRecords.at(i).sFileName);
110 | emit infoMessage(currentStats.sFile);
111 | } else {
112 | emit errorMessage(QString("%1: %2").arg(tr("Cannot write data to file")).arg(listWebRecords.at(i).sFileName));
113 | }
114 | }
115 | }
116 | } else {
117 | emit errorMessage(pReply->errorString());
118 | bIsStop = true;
119 | }
120 |
121 | pReply->deleteLater();
122 | delete pRequest;
123 |
124 | pReply = 0;
125 |
126 | currentStats.nCurrentModule = i;
127 | }
128 |
129 | bIsStop = false;
130 |
131 | emit completed(elapsedTimer.elapsed());
132 | }
133 |
134 | void GetFileFromServerProcess::_downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
135 | {
136 | currentStats.nTotalBytes = bytesTotal;
137 | currentStats.nCurrentBytes = bytesReceived;
138 | }
139 |
--------------------------------------------------------------------------------
/updategitprocess.cpp:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2019-2023 hors
2 | //
3 | // Permission is hereby granted, free of charge, to any person obtaining a copy
4 | // of this software and associated documentation files (the "Software"), to deal
5 | // in the Software without restriction, including without limitation the rights
6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | // copies of the Software, and to permit persons to whom the Software is
8 | // furnished to do so, subject to the following conditions:
9 |
10 | // The above copyright notice and this permission notice shall be included in all
11 | // copies or substantial portions of the Software.
12 |
13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 | // SOFTWARE.
20 | //
21 | #include "updategitprocess.h"
22 |
23 | bool _sort_mdata(const Utils::MDATA &mdata1, const Utils::MDATA &mdata2)
24 | {
25 | bool bResult = false;
26 |
27 | if (mdata1.sName == "x64core") {
28 | bResult = true;
29 | } else if (mdata2.sName == "x64core") {
30 | bResult = false;
31 | } else {
32 | bResult = (mdata2.sUpdated > mdata1.sUpdated);
33 | }
34 |
35 | return bResult;
36 | }
37 |
38 | UpdateGitProcess::UpdateGitProcess(QObject *pParent) : QObject(pParent)
39 | {
40 | bIsStop = false;
41 | g_bInit = false;
42 | currentStats = {};
43 | }
44 |
45 | void UpdateGitProcess::setData(QString sServerListFileName, QString sServerLastestListFileName, bool bInit)
46 | {
47 | this->sServerListFileName = sServerListFileName;
48 | this->sServerLastestListFileName = sServerLastestListFileName;
49 | this->g_bInit = bInit;
50 | }
51 |
52 | void UpdateGitProcess::stop()
53 | {
54 | bIsStop = true;
55 | }
56 |
57 | Utils::STATS UpdateGitProcess::getCurrentStats()
58 | {
59 | return currentStats;
60 | }
61 |
62 | void UpdateGitProcess::process()
63 | {
64 | QElapsedTimer elapsedTimer;
65 | elapsedTimer.start();
66 |
67 | bIsStop = false;
68 |
69 | QList listMData = Utils::getModulesFromJSONFile(sServerLastestListFileName);
70 |
71 | if (g_bInit) { // The first core only
72 | QList _listMData;
73 |
74 | if (listMData.count()) {
75 | _listMData.append(listMData.at(0));
76 |
77 | listMData = _listMData;
78 | }
79 | } else {
80 | if (XBinary::isFileExists(sServerListFileName)) {
81 | QList _listMData = Utils::getModulesFromJSONFile(sServerListFileName);
82 |
83 | int nCount = listMData.count();
84 |
85 | for (int i = 0; i < nCount; i++) {
86 | QString sName = listMData.at(i).sName;
87 | Utils::MDATA mdata = Utils::getMDataByName(&_listMData, sName);
88 |
89 | if (mdata.sUpdated != "") {
90 | listMData[i].sUpdated = mdata.sUpdated;
91 | }
92 | }
93 | }
94 | }
95 |
96 | std::sort(listMData.begin(), listMData.end(), _sort_mdata);
97 |
98 | int nCount = listMData.count();
99 |
100 | int nNumbersOfGithub = 0;
101 |
102 | for (int i = 0; i < nCount; i++) {
103 | if (listMData.at(i).sGithub != "") {
104 | nNumbersOfGithub++;
105 | }
106 | }
107 |
108 | currentStats.nTotalModule = nNumbersOfGithub;
109 |
110 | for (int i = 0; (i < nCount) && (!bIsStop); i++) {
111 | Utils::MDATA mdata = listMData.at(i);
112 |
113 | if (mdata.sGithub != "") {
114 | #ifdef QT_DEBUG
115 | qDebug("Guthub %s", mdata.sGithub.toLatin1().data());
116 | #endif
117 |
118 | QString sGithub = mdata.sGithub;
119 | sGithub = sGithub.section("github.com/", 1, 1);
120 |
121 | QString sUserName = sGithub.section("/", 0, 0);
122 | QString sRepoName = sGithub.section("/", 1, 1);
123 |
124 | XGithub github(sUserName, sRepoName);
125 | github.setCredentials(sAuthUser, sAuthToken);
126 |
127 | connect(&github, SIGNAL(errorMessage(QString)), this, SIGNAL(errorMessage(QString)));
128 |
129 | XGithub::RELEASE_HEADER release = github.getLatestRelease(true);
130 |
131 | if (release.bValid) {
132 | mdata.sDate = release.dt.toString("yyyy-MM-dd"); // rewrite
133 |
134 | if (release.sTag != "") {
135 | mdata.sVersion = release.sTag;
136 | } else {
137 | mdata.sVersion = release.sName;
138 | }
139 |
140 | int nNumberOfAsserts = release.listRecords.count();
141 |
142 | QSet stDownloads;
143 |
144 | for (int j = 0; j < nNumberOfAsserts; j++) {
145 | if (Utils::checkPattern(release.listRecords.at(j).sSrc, &mdata)) {
146 | stDownloads.insert(release.listRecords.at(j).sSrc);
147 | }
148 | }
149 |
150 | QList listStrings = XGithub::getDownloadLinks(release.sBody);
151 |
152 | int nNumberOfLinks = listStrings.count();
153 |
154 | for (int j = 0; j < nNumberOfLinks; j++) {
155 | if (Utils::checkPattern(listStrings.at(j), &mdata)) {
156 | stDownloads.insert(listStrings.at(j));
157 | }
158 | }
159 |
160 | mdata.listDownloads = stDownloads.toList();
161 |
162 | Utils::updateJsonFile(sServerLastestListFileName, QList() << mdata);
163 | }
164 |
165 | if (release.bNetworkError) {
166 | #ifdef QT_DEBUG
167 | qDebug("Broken %s", mdata.sGithub.toLatin1().data());
168 | #endif
169 | break;
170 | }
171 | }
172 |
173 | currentStats.nCurrentModule = i + 1;
174 | }
175 |
176 | emit completed(elapsedTimer.elapsed());
177 | }
178 |
179 | void UpdateGitProcess::setCredentials(QString sUser, QString sToken)
180 | {
181 | sAuthUser = sUser;
182 | sAuthToken = sToken;
183 | }
184 |
--------------------------------------------------------------------------------
/gui_source/dialoginstallmodule.cpp:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2019-2023 hors
2 | //
3 | // Permission is hereby granted, free of charge, to any person obtaining a copy
4 | // of this software and associated documentation files (the "Software"), to deal
5 | // in the Software without restriction, including without limitation the rights
6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | // copies of the Software, and to permit persons to whom the Software is
8 | // furnished to do so, subject to the following conditions:
9 |
10 | // The above copyright notice and this permission notice shall be included in all
11 | // copies or substantial portions of the Software.
12 |
13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 | // SOFTWARE.
20 | //
21 | #include "dialoginstallmodule.h"
22 |
23 | #include "ui_dialoginstallmodule.h"
24 |
25 | DialogInstallModule::DialogInstallModule(QWidget *pParent, QString sDataPath, QString sRootPath) : QDialog(pParent), ui(new Ui::DialogInstallModule)
26 | {
27 | ui->setupUi(this);
28 |
29 | this->pParent = pParent;
30 | this->sDataPath = sDataPath;
31 | this->sRootPath = sRootPath;
32 | }
33 |
34 | DialogInstallModule::~DialogInstallModule()
35 | {
36 | delete ui;
37 | }
38 |
39 | void DialogInstallModule::setFileName(QString sModuleFileName)
40 | {
41 | this->sModuleFileName = sModuleFileName;
42 |
43 | XBinary::PDSTRUCT pdStructEmpty = XBinary::createPdStruct();
44 |
45 | _mdata = Utils::getMDataFromZip(sModuleFileName, XBinary::convertPathName(sRootPath), &pdStructEmpty);
46 |
47 | ui->widgetInfo->setData(&_mdata);
48 |
49 | int nCount = _mdata.listInstallRecords.count();
50 |
51 | ui->tableWidgetRecords->setColumnCount(1);
52 | ui->tableWidgetRecords->setRowCount(nCount);
53 |
54 | for (int i = 0; i < nCount; i++) {
55 | QTableWidgetItem *pItem = new QTableWidgetItem(_mdata.listInstallRecords.at(i).sPath);
56 | ui->tableWidgetRecords->setItem(i, 0, pItem);
57 | }
58 | }
59 |
60 | bool DialogInstallModule::setMData(Utils::MDATA *pMData)
61 | {
62 | bool bResult = false;
63 |
64 | QString sSHA1 = pMData->sSHA1;
65 |
66 | QString sModuleFileName = Utils::getModuleFileName(sDataPath, pMData->sName);
67 |
68 | bool bHash = XBinary::isFileHashValid(XBinary::HASH_SHA1, sModuleFileName, sSHA1);
69 |
70 | if (!bHash) {
71 | if (pMData->sGithub != "") {
72 | QString sConvertPath = Utils::getConvertPath(sDataPath, pMData->sName);
73 | QString sDownloadModulePath = Utils::getConvertModulePath(sDataPath, pMData->sName);
74 |
75 | XBinary::createDirectory(sConvertPath);
76 | XBinary::createDirectory(sDownloadModulePath);
77 |
78 | QList listWebRecords;
79 |
80 | int nCount = pMData->listDownloads.count();
81 |
82 | for (int i = 0; i < nCount; i++) {
83 | Utils::WEB_RECORD record = {};
84 |
85 | QString sLink = pMData->listDownloads.at(i);
86 |
87 | record.sFileName = sConvertPath + QDir::separator() + sLink.section("/", -1, -1);
88 | record.sFileName = record.sFileName.remove("?raw=true");
89 | record.sLink = sLink;
90 |
91 | listWebRecords.append(record);
92 | }
93 |
94 | DialogGetFileFromServerProcess dialogGetFileFromServer(pParent, listWebRecords);
95 |
96 | connect(&dialogGetFileFromServer, SIGNAL(errorMessage(QString)), this, SIGNAL(errorMessage(QString)));
97 |
98 | dialogGetFileFromServer.exec();
99 |
100 | DialogConvertProcess dialogConvertProcess(pParent, pMData, sDataPath);
101 |
102 | connect(&dialogConvertProcess, SIGNAL(errorMessage(QString)), this, SIGNAL(errorMessage(QString)));
103 |
104 | dialogConvertProcess.exec();
105 |
106 | Utils::MDATA mdata = *pMData;
107 |
108 | mdata.sBundleFileName = Utils::getModuleFileName(sDataPath, mdata.sName);
109 | mdata.sRoot = sDownloadModulePath;
110 |
111 | QString sErrorString;
112 |
113 | if (Utils::checkMData(&mdata, &sErrorString)) {
114 | DialogCreateModuleProcess dcmp(pParent, &mdata, false);
115 |
116 | connect(&dcmp, SIGNAL(errorMessage(QString)), this, SIGNAL(errorMessage(QString)));
117 |
118 | dcmp.exec();
119 | } else {
120 | emit errorMessage(sErrorString);
121 | }
122 |
123 | #ifndef QT_DEBUG
124 | XBinary::removeDirectory(sConvertPath);
125 | #endif
126 |
127 | Utils::updateJsonFile(Utils::getServerListFileName(sDataPath), QList() << mdata);
128 |
129 | sSHA1 = mdata.sSHA1;
130 | } else {
131 | Utils::WEB_RECORD record = {};
132 |
133 | record.sFileName = sModuleFileName;
134 | record.sLink = pMData->sSrc;
135 |
136 | DialogGetFileFromServerProcess dialogGetFileFromServer(pParent, QList() << record);
137 |
138 | connect(&dialogGetFileFromServer, SIGNAL(errorMessage(QString)), this, SIGNAL(errorMessage(QString)));
139 |
140 | dialogGetFileFromServer.exec();
141 | }
142 |
143 | bHash = XBinary::isFileHashValid(XBinary::HASH_SHA1, sModuleFileName, sSHA1);
144 | }
145 |
146 | if (bHash) {
147 | setFileName(sModuleFileName);
148 |
149 | bResult = true;
150 | } else {
151 | emit errorMessage(QString("%1: %2").arg(tr("Invalid SHA1")).arg(sModuleFileName));
152 | }
153 |
154 | return bResult;
155 | }
156 |
157 | void DialogInstallModule::on_pushButtonCancel_clicked()
158 | {
159 | this->close();
160 | }
161 |
162 | void DialogInstallModule::on_pushButtonOK_clicked()
163 | {
164 | DialogInstallModuleProcess dimp(this, sDataPath, sRootPath, QList() << sModuleFileName);
165 |
166 | connect(&dimp, SIGNAL(errorMessage(QString)), this, SIGNAL(errorMessage(QString)));
167 |
168 | dimp.exec();
169 |
170 | this->close();
171 | }
172 |
--------------------------------------------------------------------------------
/gui_source/dialogcreatemodule.cpp:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2019-2023 hors
2 | //
3 | // Permission is hereby granted, free of charge, to any person obtaining a copy
4 | // of this software and associated documentation files (the "Software"), to deal
5 | // in the Software without restriction, including without limitation the rights
6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | // copies of the Software, and to permit persons to whom the Software is
8 | // furnished to do so, subject to the following conditions:
9 |
10 | // The above copyright notice and this permission notice shall be included in all
11 | // copies or substantial portions of the Software.
12 |
13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 | // SOFTWARE.
20 | //
21 | #include "dialogcreatemodule.h"
22 |
23 | #include "ui_dialogcreatemodule.h"
24 |
25 | DialogCreateModule::DialogCreateModule(QWidget *pParent) : QDialog(pParent), ui(new Ui::DialogCreateModule)
26 | {
27 | ui->setupUi(this);
28 |
29 | mdata = {};
30 |
31 | _currentDate();
32 | ui->pushButtonSave->setEnabled(false);
33 | }
34 |
35 | DialogCreateModule::~DialogCreateModule()
36 | {
37 | delete ui;
38 | }
39 |
40 | void DialogCreateModule::on_pushButtonLoad_clicked()
41 | {
42 | // QString sInitDirectory=QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
43 | QString sInitDirectory;
44 |
45 | QString sFileName = QFileDialog::getOpenFileName(this, tr("Load project"), sInitDirectory, "*.pro.ini");
46 |
47 | if (sFileName != "") {
48 | QSettings settings(sFileName, QSettings::IniFormat);
49 |
50 | ui->lineEditName->setText(settings.value("Name", "").toString());
51 | ui->lineEditVersion->setText(settings.value("Version", "").toString());
52 | ui->dateEdit->setDate(QDate::fromString(settings.value("Date", QDate::currentDate().toString("yyyy-MM-dd")).toString(), "yyyy-MM-dd"));
53 | ui->lineEditAuthor->setText(settings.value("Author", "").toString());
54 | ui->lineEditBugreport->setText(settings.value("Bugreport", "").toString());
55 | ui->lineEditInfo->setText(settings.value("Info", "").toString());
56 | ui->lineEditRoot->setText(settings.value("Root", "").toString());
57 | }
58 | }
59 |
60 | void DialogCreateModule::on_pushButtonSave_clicked()
61 | {
62 | // QString sFileName=QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation)+QDir::separator()+ui->lineEditName->text()+".pro.ini";
63 | QString sFileName;
64 |
65 | sFileName = QFileDialog::getSaveFileName(this, tr("Save project"), sFileName, "*.pro.ini");
66 |
67 | if (sFileName != "") {
68 | QSettings settings(sFileName, QSettings::IniFormat);
69 |
70 | settings.setValue("Name", ui->lineEditName->text());
71 | settings.setValue("Version", ui->lineEditVersion->text());
72 | settings.setValue("Date", ui->dateEdit->date().toString("yyyy-MM-dd"));
73 | settings.setValue("Author", ui->lineEditAuthor->text());
74 | settings.setValue("Bugreport", ui->lineEditBugreport->text());
75 | settings.setValue("Info", ui->lineEditInfo->text());
76 | settings.setValue("Root", ui->lineEditRoot->text());
77 | }
78 | }
79 |
80 | void DialogCreateModule::on_pushButtonCreate_clicked()
81 | {
82 | QString sFileName = Utils::createBundleName(&mdata) + ".x64dbg.zip";
83 | sFileName = QFileDialog::getSaveFileName(this, tr("Save plugin bundle"), sFileName, "*.x64dbg.zip");
84 |
85 | if (sFileName != "") {
86 | mdata.sBundleFileName = sFileName;
87 |
88 | QString sErrorString;
89 |
90 | if (Utils::checkMData(&mdata, &sErrorString)) {
91 | DialogCreateModuleProcess dcmp(this, &mdata, true);
92 |
93 | connect(&dcmp, SIGNAL(errorMessage(QString)), this, SIGNAL(errorMessage(QString)));
94 |
95 | dcmp.exec();
96 | } else {
97 | emit errorMessage(sErrorString);
98 | }
99 | }
100 | }
101 |
102 | void DialogCreateModule::on_toolButtonRoot_clicked()
103 | {
104 | QString sDirectoryName = QFileDialog::getExistingDirectory(this, tr("Select plugin root directory"), ui->lineEditRoot->text());
105 |
106 | if (sDirectoryName != "") {
107 | ui->lineEditRoot->setText(sDirectoryName);
108 | }
109 | }
110 |
111 | void DialogCreateModule::on_lineEditRoot_textChanged(const QString &sDirectoryName)
112 | {
113 | mdata.sRoot = "";
114 |
115 | QString _sDirectoryName = sDirectoryName;
116 |
117 | if (sDirectoryName != "") {
118 | _sDirectoryName = XBinary::convertPathName(_sDirectoryName);
119 |
120 | QDir dir(_sDirectoryName);
121 |
122 | if (dir.exists()) {
123 | mdata.sRoot = _sDirectoryName;
124 |
125 | QList listRecords = Utils::getRecords(_sDirectoryName);
126 |
127 | int nCount = listRecords.count();
128 |
129 | ui->tableWidgetRecords->setColumnCount(1);
130 | ui->tableWidgetRecords->setRowCount(nCount);
131 |
132 | for (int i = 0; i < nCount; i++) {
133 | QTableWidgetItem *pItem = new QTableWidgetItem(listRecords.at(i).sPath);
134 | ui->tableWidgetRecords->setItem(i, 0, pItem);
135 | }
136 | }
137 | }
138 | }
139 |
140 | void DialogCreateModule::on_pushButtonCancel_clicked()
141 | {
142 | this->close();
143 | }
144 |
145 | void DialogCreateModule::on_lineEditName_textChanged(const QString &sName)
146 | {
147 | QSignalBlocker(ui->lineEditName);
148 |
149 | QString _sName = sName;
150 |
151 | if (_sName.contains(" ")) _sName.remove(" ");
152 | // TODO more checks
153 |
154 | ui->lineEditName->setText(_sName);
155 |
156 | mdata.sName = _sName;
157 |
158 | ui->pushButtonSave->setEnabled(_sName != "");
159 | }
160 |
161 | void DialogCreateModule::on_lineEditVersion_textChanged(const QString &sVersion)
162 | {
163 | // TODO Checks
164 | mdata.sVersion = sVersion;
165 | }
166 |
167 | void DialogCreateModule::on_pushButtonCurrentDate_clicked()
168 | {
169 | _currentDate();
170 | }
171 |
172 | void DialogCreateModule::_currentDate()
173 | {
174 | ui->dateEdit->setDate(QDate::currentDate());
175 | }
176 |
177 | void DialogCreateModule::on_dateEdit_dateChanged(const QDate &date)
178 | {
179 | mdata.sDate = date.toString("yyyy-MM-dd");
180 | }
181 |
182 | void DialogCreateModule::on_lineEditInfo_textChanged(const QString &sInfo)
183 | {
184 | mdata.sInfo = sInfo;
185 | }
186 |
187 | void DialogCreateModule::on_lineEditAuthor_textChanged(const QString &sAuthor)
188 | {
189 | mdata.sAuthor = sAuthor;
190 | }
191 |
192 | void DialogCreateModule::on_lineEditBugreport_textChanged(const QString &sBugreport)
193 | {
194 | mdata.sBugreport = sBugreport;
195 | }
196 |
--------------------------------------------------------------------------------
/utils.h:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2019-2024 hors
2 | //
3 | // Permission is hereby granted, free of charge, to any person obtaining a copy
4 | // of this software and associated documentation files (the "Software"), to deal
5 | // in the Software without restriction, including without limitation the rights
6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | // copies of the Software, and to permit persons to whom the Software is
8 | // furnished to do so, subject to the following conditions:
9 |
10 | // The above copyright notice and this permission notice shall be included in all
11 | // copies or substantial portions of the Software.
12 |
13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 | // SOFTWARE.
20 | //
21 | #ifndef UTILS_H
22 | #define UTILS_H
23 |
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 |
32 | #include "global.h"
33 | #include "xzip.h"
34 |
35 | class Utils : public QObject {
36 | Q_OBJECT
37 |
38 | public:
39 | enum ACTION {
40 | ACTION_UNKNOWN = 0,
41 | ACTION_COPYFILE,
42 | ACTION_REMOVEFILE,
43 | ACTION_REMOVEDIRECTORYIFEMPTY,
44 | ACTION_MAKEDIRECTORY,
45 | ACTION_UNPACKDIRECTORY,
46 | ACTION_UNPACKFILE
47 | };
48 |
49 | struct WEB_RECORD {
50 | QString sName;
51 | QString sFileName;
52 | QString sLink;
53 | };
54 |
55 | struct STATUS {
56 | bool bInstall;
57 | bool bUpdate;
58 | bool bRemove;
59 | QString sServerListVersion;
60 | QString sServerListDate;
61 | QString sInstalledVersion;
62 | QString sInstalledDate;
63 | WEB_RECORD webRecord;
64 | };
65 |
66 | struct STATS {
67 | QString sModule;
68 | qint64 nTotalModule;
69 | qint64 nCurrentModule;
70 | QString sFile;
71 | qint64 nTotalFile;
72 | qint64 nCurrentFile;
73 | qint64 nTotalBytes;
74 | qint64 nCurrentBytes;
75 | };
76 |
77 | struct RECORD {
78 | QString sFullPath;
79 | QString sPath;
80 | bool bIsFile;
81 | };
82 |
83 | struct HANDLE_RECORD {
84 | QString sSrc;
85 | QString sPath;
86 | QString sSHA1;
87 | QString sPattern;
88 | ACTION action;
89 | };
90 |
91 | struct MDATA {
92 | QString sName;
93 | QString sVersion;
94 | bool bIs32;
95 | bool bIs64;
96 | QString sDate;
97 | QString sAuthor;
98 | QString sBugreport;
99 | QString sInfo;
100 | QString sRoot;
101 | QString sBundleFileName;
102 | QList listInstallRecords;
103 | QList listRemoveRecords;
104 | QList listConvertRecords;
105 | qint64 nSize;
106 | qint64 nCompressedSize;
107 | QString sSrc;
108 | QString sSHA1;
109 | QString sGithub;
110 | QList listDownloads;
111 | QString sUpdated;
112 | };
113 |
114 | struct FILE_RECORD {
115 | QString sFullPath;
116 | QString sPath;
117 | QString sSHA1;
118 | // qint64 nSize;
119 | // qint64 nCompressedSize;
120 | };
121 |
122 | struct DIRECTORY_RECORD {
123 | QString sFullPath;
124 | QString sPath;
125 | };
126 |
127 | struct MODULES_DATA {
128 | QList listServerList;
129 | QList listInstalled;
130 | QMap mapStatus;
131 | QList listUpdates;
132 | };
133 |
134 | explicit Utils(QObject *pParent = nullptr);
135 |
136 | static QList getRecords(QString sRootPath);
137 | static bool checkMData(MDATA *pMData, QString *psErrorString);
138 | static QString createBundleName(MDATA *pMData);
139 | static bool isPluginValid(QString sFileName, XBinary::PDSTRUCT *pPdStruct);
140 | static bool isPluginValid(QIODevice *pDevice, XBinary::PDSTRUCT *pPdStruct);
141 |
142 | static QByteArray createPluginInfo(Utils::MDATA *pMData, QList *pListFileRecords, QList *pListDirectoryRecords);
143 | static MDATA getMDataFromZip(QString sFileName, QString sRootPath, XBinary::PDSTRUCT *pPdStruct);
144 | static MDATA getMDataFromZip(QIODevice *pDevice, QString sRootPath, XBinary::PDSTRUCT *pPdStruct);
145 | static MDATA getMDataFromData(QByteArray baData);
146 | static MDATA getMDataFromJSONFile(QString sFileName);
147 |
148 | static QList getInstalledModules(QString sDataPath, QString sRootPath);
149 | static QList getModulesFromJSONFile(QString sFileName);
150 | static QDate getDateFromJSONFile(QString sFileName);
151 |
152 | static bool createServerList(QString sListFileName, QList *pList, QString sWebPrefix, QString sDate);
153 |
154 | static void mDataToObject(Utils::MDATA *pMData, QJsonObject *pObject);
155 | static void objectToMData(QJsonObject *pObject, Utils::MDATA *pMData);
156 |
157 | static void handleRecordToObject(Utils::HANDLE_RECORD *pHandleRecord, QJsonObject *pObject);
158 | static void objectToHandleRecord(QJsonObject *pObject, Utils::HANDLE_RECORD *pHandleRecord);
159 |
160 | static QMap getModulesStatusMap(QString sDataPath, QList *pServerList, QList *pInstalled);
161 |
162 | static MODULES_DATA getModulesData(QString sDataPath);
163 | static QList getUpdates(QMap *pMapStatus);
164 |
165 | static QString getInstalledJsonFileName(QString sDataPath, QString sName);
166 | static QString getServerListFileName(QString sDataPath);
167 | static QString getServerLastestListFileName(QString sDataPath);
168 | static QString getModuleFileName(QString sDataPath, QString sName);
169 | static QString getConvertPath(QString sDataPath, QString sName);
170 | static QString getConvertDownloadFileName(QString sDataPath, QString sName, QString sPattern);
171 | static QString getConvertModulePath(QString sDataPath, QString sName);
172 |
173 | static Utils::MDATA getMDataByName(QList *pServerList, QString sName);
174 | static QList getNamesFromWebRecords(QList *pListWebRecords);
175 | static Utils::WEB_RECORD getWebRecordByName(QList *pListWebRecords, QString sName);
176 |
177 | static bool isGithubPresent(QString sServerListFileName);
178 |
179 | static bool updateJsonFile(QString sFileName, QList listMData);
180 | static bool updateServerList(QString sOldFileName, QString sNewFileName);
181 |
182 | static QString actionIdToString(ACTION action);
183 | static ACTION stringToActionId(QString sAction);
184 |
185 | static bool checkPattern(QString sString, Utils::MDATA *pMData);
186 |
187 | private:
188 | static void _getRecords(QString sRootPath, QString sCurrentPath, QList *pListRecords);
189 | };
190 |
191 | #endif // UTILS_H
192 |
--------------------------------------------------------------------------------
/createmoduleprocess.cpp:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2019-2023 hors
2 | //
3 | // Permission is hereby granted, free of charge, to any person obtaining a copy
4 | // of this software and associated documentation files (the "Software"), to deal
5 | // in the Software without restriction, including without limitation the rights
6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | // copies of the Software, and to permit persons to whom the Software is
8 | // furnished to do so, subject to the following conditions:
9 |
10 | // The above copyright notice and this permission notice shall be included in all
11 | // copies or substantial portions of the Software.
12 |
13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 | // SOFTWARE.
20 | //
21 | #include "createmoduleprocess.h"
22 |
23 | CreateModuleProcess::CreateModuleProcess(QObject *pParent) : QObject(pParent)
24 | {
25 | currentStats = {};
26 | g_pPdStruct = nullptr;
27 | }
28 |
29 | void CreateModuleProcess::setData(Utils::MDATA *pMData, bool bCreateInfoFile, XBinary::PDSTRUCT *pPdStruct)
30 | {
31 | this->pMData = pMData;
32 | this->bCreateInfoFile = bCreateInfoFile;
33 | this->g_pPdStruct = pPdStruct;
34 | }
35 |
36 | void CreateModuleProcess::stop()
37 | {
38 | g_pPdStruct->bIsStop = true;
39 | }
40 |
41 | Utils::STATS CreateModuleProcess::getCurrentStats()
42 | {
43 | return currentStats;
44 | }
45 |
46 | void CreateModuleProcess::process()
47 | {
48 | QElapsedTimer elapsedTimer;
49 | elapsedTimer.start();
50 |
51 | QList listFileRecords;
52 | QList listDirectoryRecords;
53 |
54 | QList listRecords = Utils::getRecords(XBinary::convertPathName(pMData->sRoot));
55 |
56 | QString sBundleFileName = pMData->sBundleFileName;
57 | QString sBundleInfoFileName = pMData->sBundleFileName + ".json";
58 |
59 | if (pMData->sDate == "") {
60 | pMData->sDate = QDate::currentDate().toString("yyyy-MM-dd");
61 | }
62 |
63 | bool bSuccess = true;
64 |
65 | if (XBinary::isFileExists(sBundleFileName)) {
66 | bSuccess = XBinary::removeFile(sBundleFileName);
67 |
68 | if (!bSuccess) {
69 | emit errorMessage(QString("%1: %2").arg(tr("Cannot remove")).arg(sBundleFileName));
70 | }
71 | }
72 |
73 | if (bCreateInfoFile) {
74 | if (XBinary::isFileExists(sBundleInfoFileName)) {
75 | bSuccess = XBinary::removeFile(sBundleInfoFileName);
76 |
77 | if (!bSuccess) {
78 | emit errorMessage(QString("%1: %2").arg(tr("Cannot remove")).arg(sBundleFileName));
79 | }
80 | }
81 | }
82 |
83 | QFileInfo fi(sBundleFileName);
84 |
85 | pMData->sSrc = fi.fileName();
86 |
87 | pMData->nSize = 0;
88 | pMData->nCompressedSize = 0;
89 | currentStats.nTotalFile = listRecords.count();
90 |
91 | if (bSuccess) {
92 | QFile fileResult;
93 |
94 | fileResult.setFileName(sBundleFileName);
95 |
96 | if (fileResult.open(QIODevice::ReadWrite)) {
97 | QList listZipFiles;
98 |
99 | for (int i = 0; (i < currentStats.nTotalFile) && (!(g_pPdStruct->bIsStop)); i++) {
100 | if (listRecords.at(i).bIsFile) {
101 | currentStats.sFile = QString("%1: %2").arg(tr("Add file")).arg(listRecords.at(i).sPath);
102 |
103 | emit infoMessage(currentStats.sFile);
104 |
105 | QFile file;
106 |
107 | file.setFileName(listRecords.at(i).sFullPath);
108 |
109 | if (file.open(QIODevice::ReadOnly)) {
110 | Utils::FILE_RECORD fileRecord = {};
111 |
112 | fileRecord.sFullPath = listRecords.at(i).sFullPath;
113 | fileRecord.sPath = listRecords.at(i).sPath;
114 | fileRecord.sSHA1 = XBinary::getHash(XBinary::HASH_SHA1, &file);
115 |
116 | XZip::ZIPFILE_RECORD zipFileRecord = {};
117 |
118 | zipFileRecord.sFileName = QString("files/") + fileRecord.sPath;
119 | zipFileRecord.method = XZip::CMETHOD_DEFLATE;
120 |
121 | XZip::addLocalFileRecord(&file, &fileResult, &zipFileRecord); // TODO handle errors
122 |
123 | pMData->nSize += zipFileRecord.nUncompressedSize;
124 | pMData->nCompressedSize += zipFileRecord.nCompressedSize;
125 |
126 | file.close();
127 |
128 | listFileRecords.append(fileRecord);
129 | listZipFiles.append(zipFileRecord);
130 | }
131 | } else {
132 | if (listRecords.at(i).sPath.toLower() == "x32") {
133 | pMData->bIs32 = true;
134 | }
135 |
136 | if (listRecords.at(i).sPath.toLower() == "x64") {
137 | pMData->bIs64 = true;
138 | }
139 |
140 | currentStats.sFile = QString("%1: %2").arg(tr("Add directory")).arg(listRecords.at(i).sPath);
141 |
142 | Utils::DIRECTORY_RECORD directoryRecord = {};
143 |
144 | directoryRecord.sFullPath = listRecords.at(i).sFullPath;
145 | directoryRecord.sPath = listRecords.at(i).sPath;
146 |
147 | listDirectoryRecords.append(directoryRecord);
148 | }
149 |
150 | currentStats.nCurrentFile = i + 1;
151 | }
152 |
153 | QByteArray baInfoFile = Utils::createPluginInfo(pMData, &listFileRecords, &listDirectoryRecords);
154 |
155 | QBuffer bufferInfoFile(&baInfoFile);
156 |
157 | if (bufferInfoFile.open(QIODevice::ReadOnly)) {
158 | XZip::ZIPFILE_RECORD zipFileRecord = {};
159 |
160 | zipFileRecord.sFileName = "plugin_info.json";
161 | zipFileRecord.method = XZip::CMETHOD_DEFLATE;
162 |
163 | XZip::addLocalFileRecord(&bufferInfoFile, &fileResult, &zipFileRecord);
164 |
165 | pMData->nSize += zipFileRecord.nUncompressedSize;
166 | pMData->nCompressedSize += zipFileRecord.nCompressedSize;
167 |
168 | listZipFiles.append(zipFileRecord);
169 |
170 | bufferInfoFile.close();
171 | }
172 |
173 | if (!(g_pPdStruct->bIsStop)) {
174 | currentStats.sFile = tr("Add central directory");
175 |
176 | XZip::addCentralDirectory(&fileResult, &listZipFiles, QString("%1 v%2").arg(X_APPLICATIONNAME).arg(X_APPLICATIONVERSION));
177 | }
178 |
179 | fileResult.close();
180 |
181 | pMData->sSHA1 = XBinary::getHash(XBinary::HASH_SHA1, sBundleFileName);
182 |
183 | if (bCreateInfoFile) {
184 | if (!XBinary::writeToFile(sBundleInfoFileName, Utils::createPluginInfo(pMData, &listFileRecords, &listDirectoryRecords))) {
185 | emit errorMessage(QString("%1: %2").arg(tr("Cannot write data to file")).arg(sBundleInfoFileName));
186 | }
187 | }
188 | }
189 | }
190 |
191 | emit completed(elapsedTimer.elapsed());
192 | }
193 |
--------------------------------------------------------------------------------
/gui_source/guimainwindow.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | GuiMainWindow
4 |
5 |
6 |
7 | 0
8 | 0
9 | 990
10 | 472
11 |
12 |
13 |
14 | GuiMainWindow
15 |
16 |
17 |
18 | -
19 |
20 |
-
21 |
22 |
23 | Update server list
24 |
25 |
26 |
27 | -
28 |
29 |
30 | Qt::Horizontal
31 |
32 |
33 |
34 | 40
35 | 20
36 |
37 |
38 |
39 |
40 | -
41 |
42 |
43 | Update all installed plugins
44 |
45 |
46 |
47 |
48 |
49 | -
50 |
51 |
52 | 0
53 |
54 |
55 |
56 | Server list
57 |
58 |
59 |
60 | 1
61 |
62 |
63 | 1
64 |
65 |
66 | 1
67 |
68 |
69 | 1
70 |
71 |
-
72 |
73 |
74 | Qt::CustomContextMenu
75 |
76 |
77 | QAbstractItemView::NoEditTriggers
78 |
79 |
80 | QAbstractItemView::SingleSelection
81 |
82 |
83 | QAbstractItemView::SelectRows
84 |
85 |
86 | true
87 |
88 |
89 | 5
90 |
91 |
92 | false
93 |
94 |
95 | false
96 |
97 |
98 | 20
99 |
100 |
101 | 20
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | Installed
110 |
111 |
112 |
113 | 1
114 |
115 |
116 | 1
117 |
118 |
119 | 1
120 |
121 |
122 | 1
123 |
124 | -
125 |
126 |
127 | Qt::CustomContextMenu
128 |
129 |
130 | QAbstractItemView::NoEditTriggers
131 |
132 |
133 | QAbstractItemView::SingleSelection
134 |
135 |
136 | QAbstractItemView::SelectRows
137 |
138 |
139 | true
140 |
141 |
142 | 5
143 |
144 |
145 | false
146 |
147 |
148 | false
149 |
150 |
151 | 20
152 |
153 |
154 | 20
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
206 |
207 |
208 | Exit
209 |
210 |
211 |
212 |
213 | About
214 |
215 |
216 |
217 |
218 | Open
219 |
220 |
221 |
222 |
223 | Create
224 |
225 |
226 |
227 |
228 | Options
229 |
230 |
231 |
232 |
233 | Update server list
234 |
235 |
236 |
237 |
238 | Update all installed plugins
239 |
240 |
241 |
242 |
243 |
244 |
245 |
--------------------------------------------------------------------------------