forked from Public-Mirror/Textractor
refactor extensions some and let user rearrange them
This commit is contained in:
parent
1e2f6e14ec
commit
3a3bdfd48e
@ -1,34 +1,46 @@
|
||||
#include "extensions.h"
|
||||
#include <shared_mutex>
|
||||
#include <QDir>
|
||||
|
||||
std::optional<Extension> LoadExtension(QString file)
|
||||
static std::optional<Extension> LoadExtension(QString extenName)
|
||||
{
|
||||
// Extension file format: {NUMBER}_{NAME}.dll and exports "OnNewSentence"
|
||||
QRegularExpressionMatch parsedFile = QRegularExpression("^(\\d+)_(.+).dll$").match(file);
|
||||
if (!parsedFile.hasMatch()) return {};
|
||||
HMODULE module = GetModuleHandleW(file.toStdWString().c_str());
|
||||
if (!module) module = LoadLibraryW(file.toStdWString().c_str());
|
||||
// Extension is dll and exports "OnNewSentence"
|
||||
HMODULE module = GetModuleHandleW(extenName.toStdWString().c_str());
|
||||
if (!module) module = LoadLibraryW(extenName.toStdWString().c_str());
|
||||
if (!module) return {};
|
||||
FARPROC callback = GetProcAddress(module, "OnNewSentence");
|
||||
if (!callback) return {};
|
||||
return Extension{ parsedFile.captured(1).toInt(), parsedFile.captured(2), (wchar_t*(*)(const wchar_t*, const InfoForExtension*))callback };
|
||||
return Extension{ extenName, (wchar_t*(*)(const wchar_t*, const InfoForExtension*))callback };
|
||||
}
|
||||
|
||||
std::shared_mutex extenMutex;
|
||||
std::set<Extension> extensions;
|
||||
|
||||
std::set<Extension> LoadExtensions()
|
||||
void Extension::Load(QString extenName)
|
||||
{
|
||||
std::set<Extension> newExtensions;
|
||||
QStringList files = QDir().entryList();
|
||||
for (auto file : files)
|
||||
if (auto extension = LoadExtension(file)) newExtensions.insert(extension.value());
|
||||
std::unique_lock<std::shared_mutex> extenLock(extenMutex);
|
||||
return extensions = newExtensions;
|
||||
if (auto extension = LoadExtension(extenName)) extensions.push_back(extension.value());
|
||||
}
|
||||
|
||||
bool DispatchSentenceToExtensions(std::wstring& sentence, std::unordered_map<std::string, int64_t> miscInfo)
|
||||
void Extension::SendToBack(QString extenName)
|
||||
{
|
||||
std::unique_lock<std::shared_mutex> extenLock(extenMutex);
|
||||
Extension* extenIter = std::find_if(extensions.begin(), extensions.end(), [&](Extension extension) { return extension.name == extenName; });
|
||||
Extension extension = *extenIter;
|
||||
extensions.erase(extenIter);
|
||||
extensions.push_back(extension);
|
||||
}
|
||||
|
||||
void Extension::Unload(QString extenName)
|
||||
{
|
||||
std::unique_lock<std::shared_mutex> extenLock(extenMutex);
|
||||
extensions.erase(std::find_if(extensions.begin(), extensions.end(), [&](Extension extension) { return extension.name == extenName; }));
|
||||
FreeLibrary(GetModuleHandleW(extenName.toStdWString().c_str()));
|
||||
}
|
||||
|
||||
QVector<QString> Extension::GetNames()
|
||||
{
|
||||
QVector<QString> ret;
|
||||
for (auto extension : extensions) ret.push_back(extension.name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool Extension::DispatchSentence(std::wstring& sentence, std::unordered_map<std::string, int64_t> miscInfo)
|
||||
{
|
||||
bool success = true;
|
||||
wchar_t* sentenceBuffer = (wchar_t*)HeapAlloc(GetProcessHeap(), 0, (sentence.size() + 1) * sizeof(wchar_t));
|
||||
@ -51,16 +63,3 @@ bool DispatchSentenceToExtensions(std::wstring& sentence, std::unordered_map<std
|
||||
HeapFree(GetProcessHeap(), 0, sentenceBuffer);
|
||||
return success;
|
||||
}
|
||||
|
||||
void UnloadExtension(int extenNumber)
|
||||
{
|
||||
std::unique_lock<std::shared_mutex> extenLock(extenMutex);
|
||||
if (extensions.find({ extenNumber }) == extensions.end()) return;
|
||||
QString extenFileName = QString::number(extenNumber) + "_" + extensions.find({ extenNumber })->name + ".dll";
|
||||
FreeLibrary(GetModuleHandleW(extenFileName.toStdWString().c_str()));
|
||||
QString removedFileName = extenFileName;
|
||||
removedFileName.remove(0, removedFileName.indexOf("_"));
|
||||
QFile::remove(removedFileName);
|
||||
if (!QFile::rename(extenFileName, removedFileName)) QFile::remove(extenFileName);
|
||||
extensions.erase(extensions.find({ extenNumber }));
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
#define EXTENSIONS_H
|
||||
|
||||
#include "qtcommon.h"
|
||||
#include <set>
|
||||
#include <shared_mutex>
|
||||
|
||||
struct InfoForExtension
|
||||
{
|
||||
@ -12,16 +12,21 @@ struct InfoForExtension
|
||||
~InfoForExtension() { if (next) delete next; };
|
||||
};
|
||||
|
||||
struct Extension
|
||||
class Extension
|
||||
{
|
||||
int number;
|
||||
public:
|
||||
static bool DispatchSentence(std::wstring& sentence, std::unordered_map<std::string, int64_t> miscInfo);
|
||||
static void Load(QString extenName);
|
||||
static void SendToBack(QString extenName);
|
||||
static void Unload(QString extenName);
|
||||
static QVector<QString> GetNames();
|
||||
|
||||
QString name;
|
||||
wchar_t*(*callback)(const wchar_t*, const InfoForExtension*);
|
||||
bool operator<(const Extension& other) const { return number < other.number; }
|
||||
wchar_t* (*callback)(const wchar_t*, const InfoForExtension*);
|
||||
|
||||
private:
|
||||
inline static std::shared_mutex extenMutex;
|
||||
inline static QVector<Extension> extensions;
|
||||
};
|
||||
|
||||
std::set<Extension> LoadExtensions();
|
||||
bool DispatchSentenceToExtensions(std::wstring& sentence, std::unordered_map<std::string, int64_t> miscInfo);
|
||||
void UnloadExtension(int extenNumber);
|
||||
|
||||
#endif // EXTENSIONS_H
|
||||
|
@ -11,24 +11,36 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
ui(new Ui::MainWindow)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
if (settings.contains("Window")) this->setGeometry(settings.value("Window").toRect());
|
||||
// TODO: add GUI for changing these
|
||||
if (settings.contains("Flush_Delay")) TextThread::flushDelay = settings.value("Flush_Delay").toInt();
|
||||
if (settings.contains("Max_Buffer_Size")) TextThread::maxBufferSize = settings.value("Max_Buffer_Size").toInt();
|
||||
|
||||
processCombo = findChild<QComboBox*>("processCombo");
|
||||
ttCombo = findChild<QComboBox*>("ttCombo");
|
||||
extenCombo = findChild<QComboBox*>("extenCombo");
|
||||
textOutput = findChild<QPlainTextEdit*>("textOutput");
|
||||
|
||||
QFile extenSaveFile("Extensions.txt");
|
||||
if (extenSaveFile.exists())
|
||||
{
|
||||
extenSaveFile.open(QIODevice::ReadOnly);
|
||||
for (auto extenName : QString(extenSaveFile.readAll()).split(">")) Extension::Load(extenName);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto file : QDir().entryList())
|
||||
if (file.endsWith(".dll") && file != "vnrhook.dll") Extension::Load(file.left(file.lastIndexOf(".dll")));
|
||||
}
|
||||
ReloadExtensions();
|
||||
|
||||
if (settings.contains("Window")) this->setGeometry(settings.value("Window").toRect());
|
||||
// TODO: add GUI for changing these
|
||||
if (settings.contains("Flush_Delay")) TextThread::flushDelay = settings.value("Flush_Delay").toInt();
|
||||
if (settings.contains("Max_Buffer_Size")) TextThread::maxBufferSize = settings.value("Max_Buffer_Size").toInt();
|
||||
|
||||
connect(this, &MainWindow::SigAddProcess, this, &MainWindow::AddProcess);
|
||||
connect(this, &MainWindow::SigRemoveProcess, this, &MainWindow::RemoveProcess);
|
||||
connect(this, &MainWindow::SigAddThread, this, &MainWindow::AddThread);
|
||||
connect(this, &MainWindow::SigRemoveThread, this, &MainWindow::RemoveThread);
|
||||
connect(this, &MainWindow::SigThreadOutput, this, &MainWindow::ThreadOutput);
|
||||
|
||||
ReloadExtensions();
|
||||
|
||||
Host::Start(
|
||||
[&](DWORD processId) { emit SigAddProcess(processId); },
|
||||
[&](DWORD processId) { emit SigRemoveProcess(processId); },
|
||||
@ -53,7 +65,7 @@ void MainWindow::AddProcess(unsigned processId)
|
||||
{
|
||||
processCombo->addItem(QString::number(processId, 16).toUpper() + ": " + GetModuleName(processId));
|
||||
QFile file("SavedHooks.txt");
|
||||
if (!file.open(QIODevice::ReadOnly)) return;
|
||||
file.open(QIODevice::ReadOnly);
|
||||
QString processName = GetFullModuleName(processId);
|
||||
QStringList allProcesses = QString(file.readAll()).split("\r", QString::SkipEmptyParts);
|
||||
for (auto hooks = allProcesses.rbegin(); hooks != allProcesses.rend(); ++hooks)
|
||||
@ -105,7 +117,7 @@ void MainWindow::ThreadOutput(TextThread* thread, QString output)
|
||||
|
||||
bool MainWindow::ProcessThreadOutput(TextThread* thread, std::wstring& output)
|
||||
{
|
||||
if (DispatchSentenceToExtensions(output, GetInfoForExtensions(thread)))
|
||||
if (Extension::DispatchSentence(output, GetInfoForExtensions(thread)))
|
||||
{
|
||||
output += L"\r\n";
|
||||
emit SigThreadOutput(thread, QString::fromStdWString(output));
|
||||
@ -140,7 +152,13 @@ DWORD MainWindow::GetSelectedProcessId()
|
||||
void MainWindow::ReloadExtensions()
|
||||
{
|
||||
extenCombo->clear();
|
||||
for (auto extension : LoadExtensions()) extenCombo->addItem(QString::number(extension.number) + ": " + extension.name);
|
||||
QFile extenSaveFile("Extensions.txt");
|
||||
extenSaveFile.open(QIODevice::WriteOnly | QIODevice::Truncate);
|
||||
for (auto extenName : Extension::GetNames())
|
||||
{
|
||||
extenSaveFile.write((extenName + ">").toUtf8());
|
||||
extenCombo->addItem(extenName);
|
||||
}
|
||||
}
|
||||
|
||||
std::unordered_map<std::string, int64_t> MainWindow::GetInfoForExtensions(TextThread* thread)
|
||||
@ -226,7 +244,7 @@ void MainWindow::on_saveButton_clicked()
|
||||
if (!(hook.type & HOOK_ENGINE))
|
||||
hookList += " , " + GenerateCode(hook, GetSelectedProcessId());
|
||||
QFile file("SavedHooks.txt");
|
||||
if (!file.open(QIODevice::Append | QIODevice::Text)) return;
|
||||
file.open(QIODevice::Append);
|
||||
file.write((hookList + "\r\n").toUtf8());
|
||||
}
|
||||
|
||||
@ -238,17 +256,25 @@ void MainWindow::on_ttCombo_activated(int index)
|
||||
|
||||
void MainWindow::on_addExtenButton_clicked()
|
||||
{
|
||||
QString extenFileName = QFileDialog::getOpenFileName(this, "Select Extension dll", "C:\\", "Extensions (*.dll)");
|
||||
QString extenFileName = QFileDialog::getOpenFileName(this, "Select Extension", "C:\\", "Extensions (*.dll)");
|
||||
if (!extenFileName.size()) return;
|
||||
QString extenName = extenFileName.split("/")[extenFileName.split("/").count() - 1];
|
||||
QString copyTo = QString::number(extenCombo->itemText(extenCombo->count() - 1).split(":")[0].toInt() + 1) + "_" + extenName;
|
||||
QFile::copy(extenFileName, copyTo);
|
||||
QString extenName = extenFileName.mid(extenFileName.lastIndexOf("/") + 1);
|
||||
QFile::copy(extenFileName, extenName);
|
||||
Extension::Load(extenName.left(extenName.lastIndexOf(".dll")));
|
||||
ReloadExtensions();
|
||||
}
|
||||
|
||||
void MainWindow::on_moveExtenButton_clicked()
|
||||
{
|
||||
if (extenCombo->currentText() == "") return;
|
||||
Extension::SendToBack(extenCombo->currentText());
|
||||
ReloadExtensions();
|
||||
Host::AddConsoleOutput(L"extension sent to back");
|
||||
}
|
||||
|
||||
void MainWindow::on_rmvExtenButton_clicked()
|
||||
{
|
||||
if (extenCombo->currentText() == "") return;
|
||||
UnloadExtension(extenCombo->currentText().split(":")[0].toInt());
|
||||
Extension::Unload(extenCombo->currentText());
|
||||
ReloadExtensions();
|
||||
}
|
||||
|
@ -2,11 +2,11 @@
|
||||
#define MAINWINDOW_H
|
||||
|
||||
#include "qtcommon.h"
|
||||
#include "host/host.h"
|
||||
#include <QMainWindow>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QComboBox>
|
||||
#include <QSettings>
|
||||
#include "host/host.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
@ -41,6 +41,7 @@ private slots:
|
||||
void on_hookButton_clicked();
|
||||
void on_saveButton_clicked();
|
||||
void on_addExtenButton_clicked();
|
||||
void on_moveExtenButton_clicked();
|
||||
void on_rmvExtenButton_clicked();
|
||||
|
||||
private:
|
||||
|
@ -216,6 +216,13 @@ QPushButton, QComboBox
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="moveExtenButton">
|
||||
<property name="text">
|
||||
<string>Move extension</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="rmvExtenButton">
|
||||
<property name="text">
|
||||
|
33
deploy.ps1
33
deploy.ps1
@ -1,4 +1,31 @@
|
||||
cd Builds/RelWithDebInfo/x86;
|
||||
Compress-Archive -Force -Path "Textractor.exe","styles","platforms","Qt5Core.dll","Qt5Gui.dll","Qt5Widgets.dll","vnrhook.dll","256_Remove Repetition.dll","512_Copy to Clipboard.dll","1024_Bing Translate.dll","2048_Extra Newlines.dll" -DestinationPath Textractor;
|
||||
cd Builds/RelWithDebInfo/x86;
|
||||
Compress-Archive -Force -DestinationPath Textractor -Path @(
|
||||
"Textractor.exe",
|
||||
"styles",
|
||||
"platforms",
|
||||
"Qt5Core.dll",
|
||||
"Qt5Gui.dll",
|
||||
"Qt5Widgets.dll",
|
||||
"vnrhook.dll",
|
||||
"Remove Repetition.dll",
|
||||
"Copy to Clipboard.dll",
|
||||
"Bing Translate.dll",
|
||||
"Extra Newlines.dll",
|
||||
"Extensions.txt"
|
||||
)
|
||||
|
||||
cd ../x64;
|
||||
Compress-Archive -Force -Path "Textractor.exe","styles","platforms","Qt5Core.dll","Qt5Gui.dll","Qt5Widgets.dll","vnrhook.dll","256_Remove Repetition.dll","512_Copy to Clipboard.dll","1024_Bing Translate.dll","2048_Extra Newlines.dll" -DestinationPath Textractor;
|
||||
Compress-Archive -Force -DestinationPath Textractor -Path @(
|
||||
"Textractor.exe",
|
||||
"styles",
|
||||
"platforms",
|
||||
"Qt5Core.dll",
|
||||
"Qt5Gui.dll",
|
||||
"Qt5Widgets.dll",
|
||||
"vnrhook.dll",
|
||||
"Remove Repetition.dll",
|
||||
"Copy to Clipboard.dll",
|
||||
"Bing Translate.dll",
|
||||
"Extra Newlines.dll",
|
||||
"Extensions.txt"
|
||||
)
|
@ -4,9 +4,9 @@ find_qt5(Core Widgets)
|
||||
|
||||
cmake_policy(SET CMP0037 OLD)
|
||||
|
||||
add_library(256_Remove\ Repetition SHARED removerepeat.cpp extensionimpl.cpp)
|
||||
add_library(512_Copy\ to\ Clipboard SHARED copyclipboard.cpp extensionimpl.cpp)
|
||||
add_library(1024_Bing\ Translate SHARED bingtranslate.cpp extensionimpl.cpp)
|
||||
add_library(2048_Extra\ Newlines SHARED extranewlines.cpp extensionimpl.cpp)
|
||||
add_library(Remove\ Repetition SHARED removerepeat.cpp extensionimpl.cpp)
|
||||
add_library(Copy\ to\ Clipboard SHARED copyclipboard.cpp extensionimpl.cpp)
|
||||
add_library(Bing\ Translate SHARED bingtranslate.cpp extensionimpl.cpp)
|
||||
add_library(Extra\ Newlines SHARED extranewlines.cpp extensionimpl.cpp)
|
||||
|
||||
target_link_libraries(1024_Bing\ Translate winhttp.lib Qt5::Widgets)
|
||||
target_link_libraries(Bing\ Translate winhttp.lib Qt5::Widgets)
|
||||
|
Loading…
x
Reference in New Issue
Block a user