1

Revert "Update pluginmanager.cpp"

This reverts commit 86cb1ec962bf8ea18a6a9c09021ffdfeab8c7bcb.

1
This commit is contained in:
恍兮惚兮 2024-03-29 18:07:15 +08:00
parent c1230d2271
commit 858b750f28
11 changed files with 232 additions and 188 deletions

View File

@ -66,6 +66,7 @@
#define MenuRemovePlugin L"Remove Plugin"
#define MenuPluginRankUp L"Up"
#define MenuPluginRankDown L"Down"
#define MenuPluginEnable L"Enable"
#define DefaultFont L"Arial"
#define CantLoadQtLoader L"Can't Load QtLoader.dll"
#define LblPluginNotify L"Qt Plugins Will be Loaded at Start Only."

View File

@ -66,6 +66,7 @@
#define MenuRemovePlugin L"移除插件"
#define MenuPluginRankUp L"上移"
#define MenuPluginRankDown L"下移"
#define MenuPluginEnable L"使用"
#define DefaultFont L"微软雅黑"
#define CantLoadQtLoader L"无法加载QtLoader.dll"
#define LblPluginNotify L"依赖于Qt的插件仅会在启动时载入。"

View File

@ -101,11 +101,6 @@ void LunaHost::on_proc_connect(DWORD pid)
autoattachexes.insert(WideStringToString(pexe.value()));
}
}
TextThread* LunaHost::getcurrthread(){
auto handle = g_hListBox_listtext->getdata(g_hListBox_listtext->currentidx());
auto tt=Host::GetThread(handle);
return tt;
}
LunaHost::LunaHost(){
configs=new confighelper;
@ -174,32 +169,34 @@ LunaHost::LunaHost(){
g_showtexts->settext(get);
g_showtexts->scrolltoend();
};
g_hListBox_listtext->add_menu(MenuCopyHookCode,[&](){if(auto tt=getcurrthread())toclipboard(std::wstring(tt->hp.hookcode));});
g_hListBox_listtext->add_menu_sep();
g_hListBox_listtext->add_menu(MenuRemoveHook,[&](){if(auto tt=getcurrthread())Host::RemoveHook(tt->tp.processId,tt->tp.addr);});
g_hListBox_listtext->add_menu(MenuDetachProcess,[&](){
if(auto tt=getcurrthread()){
g_hListBox_listtext->on_menu=[&]()->maybehavemenu{
auto handle = g_hListBox_listtext->getdata(g_hListBox_listtext->currentidx());
auto tt=Host::GetThread(handle);
if(!tt)return {};
Menu menu;
menu.add(MenuCopyHookCode,[&](){toclipboard(std::wstring(tt->hp.hookcode));});
menu.add_sep();
menu.add(MenuRemoveHook,[&](){Host::RemoveHook(tt->tp.processId,tt->tp.addr);});
menu.add(MenuDetachProcess,[&](){
Host::DetachProcess(tt->tp.processId);
userdetachedpids.insert(tt->tp.processId);
}
});
g_hListBox_listtext->add_menu_sep();
g_hListBox_listtext->add_menu(MenuRemeberSelect,[&](){
if(auto tt=getcurrthread())
userdetachedpids.insert(tt->tp.processId);
});
menu.add_sep();
menu.add(MenuRemeberSelect,[&](){
if(auto pexe=gmf(tt->tp.processId))
savedhookcontext[WideStringToString(pexe.value())]={
{"hookcode",WideStringToString(tt->hp.hookcode)},
{"ctx1",tt->tp.ctx},
{"ctx2",tt->tp.ctx2},
};
});
g_hListBox_listtext->add_menu(MenuForgetSelect,[&](){
if(auto tt=getcurrthread())
if(auto pexe=gmf(tt->tp.processId))
savedhookcontext.erase(WideStringToString(pexe.value()));
});
});
menu.add(MenuForgetSelect,[&](){
if(auto pexe=gmf(tt->tp.processId))
savedhookcontext.erase(WideStringToString(pexe.value()));
});
return menu;
};
g_showtexts = new multilineedit(this);
g_showtexts->setreadonly(true);
@ -414,8 +411,7 @@ void Pluginwindow::pluginrankmove(int moveoffset){
listplugins->insertitem(b,std::filesystem::path(pa).stem());
listplugins->setdata(b,(LONG_PTR)pa);
}
Pluginwindow::Pluginwindow(mainwindow*p,Pluginmanager* pl):mainwindow(p){
pluginmanager=pl;
Pluginwindow::Pluginwindow(mainwindow*p,Pluginmanager* pl):mainwindow(p),pluginmanager(pl){
(new label(this,LblPluginNotify))->setgeo(10,10,500,30);
(new label(this,LblPluginRemove))->setgeo( 10,40,500,30);
static auto listadd=[&](const std::wstring& s){
@ -425,7 +421,9 @@ Pluginwindow::Pluginwindow(mainwindow*p,Pluginmanager* pl):mainwindow(p){
};
listplugins = new listbox(this);
listplugins->add_menu(MenuAddPlugin,[&](){
listplugins->on_menu=[&](){
Menu menu;
menu.add(MenuAddPlugin,[&](){
if(auto f=pluginmanager->selectpluginfile())
switch (auto res=pluginmanager->addplugin(f.value()))
{
@ -440,21 +438,29 @@ Pluginwindow::Pluginwindow(mainwindow*p,Pluginmanager* pl):mainwindow(p){
};
MessageBoxW(winId,errorlog[res],MsgError,0);
}
});
listplugins->add_menu(MenuRemovePlugin,[&](){
});
auto idx=listplugins->currentidx();
if(idx==-1)return;
pluginmanager->remove((LPCWSTR)listplugins->getdata(idx));
listplugins->deleteitem(idx);
});
if(idx!=-1)
{
menu.add(MenuRemovePlugin,[&](){
auto idx=listplugins->currentidx();
pluginmanager->remove((LPCWSTR)listplugins->getdata(idx));
listplugins->deleteitem(idx);
});
menu.add_sep();
menu.add(MenuPluginRankUp,std::bind(&Pluginwindow::pluginrankmove,this,-1));
menu.add(MenuPluginRankDown,std::bind(&Pluginwindow::pluginrankmove,this,1));
menu.add_sep();
menu.add_checkable(MenuPluginEnable,pluginmanager->getenable(idx),[&,idx](bool check){
pluginmanager->setenable(idx,check);
});
}
return menu;
};
listplugins->add_menu_sep();
listplugins->add_menu(MenuPluginRankUp,std::bind(&Pluginwindow::pluginrankmove,this,-1));
listplugins->add_menu(MenuPluginRankDown,std::bind(&Pluginwindow::pluginrankmove,this,1));
for(int i=0;i<pluginmanager->PluginRank.size();i++){
listadd(pluginmanager->PluginRank[i]);
for(int i=0;i<pluginmanager->count();i++){
listadd(pluginmanager->getname(i));
}
settext(WndPlugins);
setcentral(500,400);

View File

@ -101,7 +101,6 @@ class LunaHost:public mainwindow{
void on_thread_delete(TextThread& thread);
void on_proc_connect(DWORD pid);
public:
TextThread* getcurrthread();
confighelper* configs;
int64_t currentselect=0;
bool check_toclipboard;

View File

@ -37,65 +37,4 @@ confighelper::confighelper(){
confighelper::~confighelper(){
writefile(configpath.c_str(), configs.dump(4));
}
void confighelper::pluginsremove(const std::string&s){
auto &plgs=configs["plugins"];
auto it=std::remove_if(plgs.begin(),plgs.end(),[&](auto&t){
std::string p=t["path"];
return p==s;
});
plgs.erase(it, plgs.end());
}
void confighelper::pluginrankswap(int a,int b){
auto &plgs=configs["plugins"];
auto _b=plgs[b];
plgs[b]=plgs[a];
plgs[a]=_b;
}
void confighelper::pluginsadd(const pluginitem& item){
configs["plugins"].push_back(item.dump());
}
int confighelper::pluginsnum(){
return configs["plugins"].size();
}
pluginitem confighelper::pluginsget(int i){
return pluginitem{configs["plugins"][i]};
}
template<typename T>
T safequeryjson(const nlohmann::json& js,const std::string& key,const T &defaultv){
if(js.find(key)==js.end()){
return defaultv;
}
return js[key];
}
pluginitem::pluginitem(const nlohmann::json& js){
path=js["path"];
isQt=safequeryjson(js,"isQt",false);
isref=safequeryjson(js,"isref",false);
}
std::wstring pluginitem::wpath(){
auto wp=StringToWideString(path);
if(isref)return std::filesystem::current_path()/wp;
else return wp;
}
std::pair<std::wstring,bool> castabs2ref(const std::wstring&p){
auto curr=std::filesystem::current_path().wstring();
if(startWith(p,curr)){
return {p.substr(curr.size()+1),true};
}
return {p,false};
}
pluginitem::pluginitem(const std::wstring& pabs,bool _isQt){
isQt=_isQt;
auto [p,_isref]=castabs2ref(pabs);
isref=_isref;
path=WideStringToString(p);
}
nlohmann::json pluginitem::dump() const{
return {
{"path",path},
{"isQt",isQt},
{"isref",isref}
};
}

View File

@ -1,26 +1,13 @@
#ifndef LUNA_CONFIG_HELPER
#define LUNA_CONFIG_HELPER
#include<nlohmann/json.hpp>
struct pluginitem{
std::string path;
bool isQt;
bool isref;
pluginitem(const nlohmann::json&);
pluginitem(const std::wstring&,bool);
std::wstring wpath();
nlohmann::json dump() const;
};
class confighelper{
nlohmann::json configs;
std::wstring configpath;
public:
nlohmann::json configs;
confighelper();
~confighelper();
pluginitem pluginsget(int);
int pluginsnum();
void pluginsadd(const pluginitem&);
void pluginsremove(const std::string&);
void pluginrankswap(int,int);
template<class T>
T get(const std::string&key,T default1){
if(configs.find(key)==configs.end())return default1;
@ -31,5 +18,11 @@ public:
configs[key]=v;
}
};
template<typename T>
T safequeryjson(const nlohmann::json& js,const std::string& key,const T &defaultv){
if(js.find(key)==js.end()){
return defaultv;
}
return js[key];
}
#endif

View File

@ -314,20 +314,24 @@ gridlayout::gridlayout(int row,int col):control(0){
void gridlayout::setmargin(int m){
margin=m;
}
void control::menu_dispatch(WPARAM wparam){
void Menu::dispatch(WPARAM wparam){
auto idx=LOWORD(wparam);
menu_callbacks[idx].callback();
DestroyMenu(hmenu);
}
HMENU control::load_menu(){
HMENU hMenu = CreatePopupMenu();
HMENU Menu::load(){
hmenu = CreatePopupMenu();
for(int i=0;i<menu_callbacks.size();i++){
AppendMenuW(hMenu,menu_callbacks[i].type,i,menu_callbacks[i].str.c_str());
AppendMenuW(hmenu,menu_callbacks[i].type,i,menu_callbacks[i].str.c_str());
}
return hMenu;
return hmenu;
}
void control::add_menu(const std::wstring& str,std::function<void()> callback, UINT type){
menu_callbacks.push_back({callback,type,str});
void Menu::add(const std::wstring& str,std::function<void()> callback){
menu_callbacks.push_back({MF_STRING,callback,str});
}
void control::add_menu_sep(){
menu_callbacks.push_back({[](){},MF_SEPARATOR,L""});
void Menu::add_checkable(const std::wstring& str,bool check,std::function<void(bool)> callback){
menu_callbacks.push_back({(UINT)(MF_STRING|(check?MF_CHECKED:MF_UNCHECKED)),std::bind(callback,!check),str});
}
void Menu::add_sep(){
menu_callbacks.push_back({MF_SEPARATOR});
}

View File

@ -2,22 +2,31 @@
#define LUNA_BASE_CONTROLS_H
#include"window.h"
#include <CommCtrl.h>
class Menu{
public:
void dispatch(WPARAM);
struct menuinfos{
UINT type;
std::function<void()> callback;
std::wstring str;
};
std::vector<menuinfos>menu_callbacks;
HMENU load();
HMENU hmenu;
void add(const std::wstring&,std::function<void()> callback);
void add_checkable(const std::wstring&,bool,std::function<void(bool)> callback);
void add_sep();
};
using maybehavemenu=std::optional<Menu>;
class control:public basewindow{
public:
mainwindow* parent;
control(mainwindow*);
virtual void dispatch(WPARAM);
virtual void dispatch_2(WPARAM wParam, LPARAM lParam);
void menu_dispatch(WPARAM);
HMENU load_menu();
struct menuinfos{
std::function<void()> callback;
UINT type;
std::wstring str;
};
std::vector<menuinfos>menu_callbacks;
void add_menu(const std::wstring&,std::function<void()> callback, UINT type=MF_STRING);
void add_menu_sep();
maybehavemenu menu;
std::function<maybehavemenu()> on_menu=[]()->maybehavemenu{return {};};
};
class button:public control{

View File

@ -128,45 +128,49 @@ void Pluginmanager::loadqtdlls(std::vector<std::wstring>&collectQtplugs){
}
SetEnvironmentVariableW(L"PATH",envs.c_str());
#if 1
auto modules=QtLoadLibrarys(collectQtplugs);
if(modules.empty())return;
#else
HMODULE* modules;
if(std::true_type::value){
auto vmodules=QtLoadLibrarys(collectQtplugs);
if(vmodules.empty())return;
modules=vmodules.data();
}
else{
auto QtLoadLibrary = loadqtloader(pluginpath);
if(!QtLoadLibrary){
MessageBoxW(host->winId,CantLoadQtLoader,L"Error",0);
return ;
}
std::vector<wchar_t*>saves;
for(auto&p:collectQtplugs){
auto str=new wchar_t[p.size()+1];
wcscpy(str,p.c_str());
saves.emplace_back(str);
}
modules=QtLoadLibrary(saves.data(),collectQtplugs.size());
for(auto str:saves)delete str;
auto QtLoadLibrary = loadqtloader(pluginpath);
if(!QtLoadLibrary){
MessageBoxW(host->winId,CantLoadQtLoader,L"Error",0);
return ;
}
std::vector<wchar_t*>saves;
for(auto&p:collectQtplugs){
auto str=new wchar_t[p.size()+1];
wcscpy(str,p.c_str());
saves.emplace_back(str);
}
auto modules=QtLoadLibrary(saves.data(),collectQtplugs.size());
for(auto str:saves)delete str;
#endif
for(int i=0;i<collectQtplugs.size();i++){
wprintf(L"%s %p %p",collectQtplugs[i].c_str(),modules[i],GetProcAddress(modules[i],"OnNewSentence"));
OnNewSentenceS[collectQtplugs[i]]=GetProcAddress(modules[i],"OnNewSentence");
}
}
Pluginmanager::Pluginmanager(LunaHost* _host):host(_host){
Pluginmanager::Pluginmanager(LunaHost* _host):host(_host),configs(_host->configs){
try {
std::scoped_lock lock(OnNewSentenceSLock);
std::vector<std::wstring>collectQtplugs;
for (auto i=0;i<host->configs->pluginsnum();i++) {
auto plg=host->configs->pluginsget(i);
for (auto i=0;i<count();i++) {
auto plg=get(i);
bool isqt=plg.isQt;
auto path=plg.wpath();
PluginRank.push_back(path);
OnNewSentenceS[path]=0;
if(isqt){
if(plg.enable==false)continue;
collectQtplugs.push_back((path));
continue;
}
OnNewSentenceS[path]=GetProcAddress(LoadLibraryW(path.c_str()),"OnNewSentence");
else
OnNewSentenceS[path]=GetProcAddress(LoadLibraryW(path.c_str()),"OnNewSentence");
}
loadqtdlls(collectQtplugs);
@ -174,7 +178,7 @@ Pluginmanager::Pluginmanager(LunaHost* _host):host(_host){
} catch (const std::exception& ex) {
std::cerr << "Error: " << ex.what() << std::endl;
std::wcerr << "Error: " << ex.what() << std::endl;
}
}
@ -184,14 +188,19 @@ bool Pluginmanager::dispatch(TextThread& thread, std::wstring& sentence){
wcscpy_s(sentenceBuffer, sentence.size() + 1, sentence.c_str());
concurrency::reader_writer_lock::scoped_lock_read readLock(OnNewSentenceSLock);
bool interupt=false;
for (const auto& pathl :{std::vector<std::wstring>{L"InternalClipBoard"}, PluginRank}){
for(const auto&path:pathl){
auto funptr=OnNewSentenceS[path];
if(funptr==0)continue;
if (!*(sentenceBuffer = ((OnNewSentence_t)funptr)(sentenceBuffer, sentenceInfo))){interupt=true;break;};
for(int i=0;i<count()+1;i++){
std::wstring path;
if(i==count())path=L"InternalClipBoard";
else {
if(getenable(i)==false)continue;
path=getname(i);
}
if(interupt)break;
auto funptr=OnNewSentenceS[path];
if(funptr==0)continue;
wprintf(L"%s %p\n",path.c_str(), funptr);
if (!*(sentenceBuffer = ((OnNewSentence_t)funptr)(sentenceBuffer, sentenceInfo)))
break;
}
sentence = sentenceBuffer;
@ -199,6 +208,73 @@ bool Pluginmanager::dispatch(TextThread& thread, std::wstring& sentence){
return !sentence.empty();
}
void Pluginmanager::remove(const std::string&s){
auto &plgs=configs->configs["plugins"];
auto it=std::remove_if(plgs.begin(),plgs.end(),[&](auto&t){
std::string p=t["path"];
return p==s;
});
plgs.erase(it, plgs.end());
}
void Pluginmanager::add(const pluginitem& item){
configs->configs["plugins"].push_back(item.dump());
}
int Pluginmanager::count(){
return configs->configs["plugins"].size();
}
pluginitem Pluginmanager::get(int i){
return pluginitem{configs->configs["plugins"][i]};
}
void Pluginmanager::set(int i,const pluginitem& item){
configs->configs["plugins"][i]=item.dump();
}
pluginitem::pluginitem(const nlohmann::json& js){
path=js["path"];
isQt=safequeryjson(js,"isQt",false);
isref=safequeryjson(js,"isref",false);
enable=safequeryjson(js,"enable",true);
}
std::wstring pluginitem::wpath(){
auto wp=StringToWideString(path);
if(isref)return std::filesystem::current_path()/wp;
else return wp;
}
std::pair<std::wstring,bool> castabs2ref(const std::wstring&p){
auto curr=std::filesystem::current_path().wstring();
if(startWith(p,curr)){
return {p.substr(curr.size()+1),true};
}
return {p,false};
}
pluginitem::pluginitem(const std::wstring& pabs,bool _isQt){
isQt=_isQt;
auto [p,_isref]=castabs2ref(pabs);
isref=_isref;
path=WideStringToString(p);
enable=true;
}
nlohmann::json pluginitem::dump() const{
return {
{"path",path},
{"isQt",isQt},
{"isref",isref},
{"enable",enable}
};
}
bool Pluginmanager::getenable(int idx){
return get(idx).enable;
}
void Pluginmanager::setenable(int idx,bool en){
auto item=get(idx);
item.enable=en;
set(idx,item);
}
std::wstring Pluginmanager::getname(int idx){
return get(idx).wpath();
}
std::optional<LPVOID> Pluginmanager::checkisvalidplugin(const std::wstring& pl){
auto path=std::filesystem::path(pl);
if (!std::filesystem::exists(path))return{};
@ -221,22 +297,16 @@ bool Pluginmanager::checkisdump(const std::wstring& dll){
return false;
}
void Pluginmanager::remove(const std::wstring& ss){
std::scoped_lock lock(OnNewSentenceSLock);
auto it = std::find(PluginRank.begin(), PluginRank.end(), ss);
if (it != PluginRank.end()) {
PluginRank.erase(it);
}
host->configs->pluginsremove(WideStringToString(ss));
remove(WideStringToString(ss));
}
std::optional<std::wstring>Pluginmanager::selectpluginfile(){
return SelectFile(host->winId,L"Plugin Files\0*.dll;*.xdll\0");
return SelectFile(0,L"Plugin Files\0*.dll;*.xdll\0");
}
void Pluginmanager::swaprank(int a,int b){
std::scoped_lock lock(OnNewSentenceSLock);
auto _b=PluginRank[b];
PluginRank[b]=PluginRank[a];
PluginRank[a]=_b;
host->configs->pluginrankswap(a,b);
auto &plgs=configs->configs["plugins"];
auto _b=plgs[b];
plgs[b]=plgs[a];
plgs[a]=_b;
}
DWORD Rva2Offset(DWORD rva, PIMAGE_SECTION_HEADER psh, PIMAGE_NT_HEADERS pnt)
{
@ -330,10 +400,8 @@ addpluginresult Pluginmanager::addplugin(const std::wstring& p){
std::scoped_lock lock(OnNewSentenceSLock);
if(checkisdump(p))return addpluginresult::dumplicate;
PluginRank.push_back(p);
//std::swap(PluginRank.end()-2,PluginRank.end()-1);
OnNewSentenceS[p]=plugin;
host->configs->pluginsadd({p,isQt});
add({p,isQt});
return addpluginresult::success;
}

View File

@ -2,29 +2,50 @@
#define LUNA_PLUGINMANAGER_H
#include"Plugin/plugindef.h"
#include"textthread.h"
#include<nlohmann/json.hpp>
class LunaHost;
class confighelper;
enum class addpluginresult{
success,
invaliddll,
isnotaplugins,
dumplicate
};
struct pluginitem{
std::string path;
bool isQt;
bool isref;
bool enable;
pluginitem(const nlohmann::json&);
pluginitem(const std::wstring&,bool);
std::wstring wpath();
nlohmann::json dump() const;
};
class Pluginmanager{
std::unordered_map<std::wstring,LPVOID>OnNewSentenceS;
std::optional<LPVOID> checkisvalidplugin(const std::wstring&);
concurrency::reader_writer_lock OnNewSentenceSLock;
bool checkisdump(const std::wstring&);
confighelper* configs;
LunaHost* host;
std::array<InfoForExtension, 20> GetSentenceInfo(TextThread& thread);
void loadqtdlls(std::vector<std::wstring>&collectQtplugs);
public:
std::vector<std::wstring>PluginRank;
Pluginmanager(LunaHost*);
bool dispatch(TextThread&, std::wstring& sentence);
addpluginresult addplugin(const std::wstring&);
void swaprank(int,int);
void remove(const std::wstring&);
std::optional<std::wstring>selectpluginfile();
pluginitem get(int);
std::wstring getname(int);
bool getenable(int);
void set(int,const pluginitem&);
void setenable(int ,bool);
int count();
void add(const pluginitem&);
void remove(const std::string&);
void remove(const std::wstring&);
void swaprank(int,int);
};
#endif

View File

@ -77,7 +77,9 @@ LRESULT mainwindow::wndproc(UINT message, WPARAM wParam, LPARAM lParam){
if(lParam==0){
for(auto ctl:controls){
if(lastcontexthwnd==ctl->winId){
ctl->menu_dispatch(wParam);break;
if(ctl->menu)
ctl->menu.value().dispatch(wParam);
break;
}
}
}
@ -94,11 +96,12 @@ LRESULT mainwindow::wndproc(UINT message, WPARAM wParam, LPARAM lParam){
bool succ=false;lastcontexthwnd=0;
for(auto ctl:controls){
if((HWND)wParam==ctl->winId){
auto hm=ctl->load_menu();
auto hm=ctl->on_menu();
ctl->menu=hm;
if(hm){
int xPos = LOWORD(lParam);
int yPos = HIWORD(lParam);
TrackPopupMenu(hm, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON,
TrackPopupMenu(hm.value().load(), TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON,
xPos, yPos, 0, winId, NULL);
lastcontexthwnd=ctl->winId;
succ=true;