77 lines
2.5 KiB
C++
77 lines
2.5 KiB
C++
#include <string>
|
|
#include <cdlpp/cdltypes.hpp>
|
|
#include <boost/process.hpp>
|
|
#include <dlhandle.hpp>
|
|
#include "permassert.hpp"
|
|
using namespace std;
|
|
using namespace CDL;
|
|
|
|
|
|
|
|
class Eval {
|
|
static void eval(CMessage msg, CChannel channel, cmdargs& args) {
|
|
// Only bot owner may use this
|
|
if (msg->author->id != env.settings["owner"]) {
|
|
return;
|
|
}
|
|
// Check args
|
|
if (args.empty()) {
|
|
return;
|
|
}
|
|
// Generate code
|
|
remove("./codef.cpp");
|
|
ofstream codef("./codef.cpp");
|
|
codef << "#include <cdlpp/cdltypes.hpp>\n"
|
|
"#include <dlhandle.hpp>\n"
|
|
"extern \"C\"\n"
|
|
"void eval_main(CDL::CMessage msg, CDL::CChannel channel) {\n"
|
|
"using namespace CDL;"
|
|
<< args[0] <<
|
|
"}";
|
|
codef.close();
|
|
// Compile code
|
|
channel->start_typing([=] (const bool) {
|
|
string libnme = "./codef_"+to_string(msg->id)+".so";
|
|
boost::process::async_system(*env.aioc, [=] (boost::system::error_code, int code) {
|
|
// Check compiler result
|
|
if (code != 0) {
|
|
channel->send(":warning: Compilation failed");
|
|
return;
|
|
}
|
|
// Run code
|
|
try {
|
|
auto evalo = new Dlhandle(libnme);
|
|
auto fnc = evalo->get<void(CMessage, CChannel)>("eval_main");
|
|
if (not fnc) {
|
|
channel->send(":warning: Failed to find main function");
|
|
delete evalo; // Delete evalo directly
|
|
} else {
|
|
fnc(msg, channel);
|
|
// Delete evalo after a minute
|
|
auto t = new boost::asio::deadline_timer(*env.aioc, boost::posix_time::minutes(1));
|
|
t->async_wait([=] (const boost::system::error_code&) {
|
|
delete t;
|
|
delete evalo;
|
|
remove(libnme.c_str());
|
|
});
|
|
}
|
|
} catch (Dlhandle::Exception&) {
|
|
channel->send(":warning: Loading failed");
|
|
}
|
|
}, "gcc -std=c++17 ./codef.cpp -shared -fPIC -l cdlpp -o "+libnme);
|
|
});
|
|
}
|
|
|
|
|
|
public:
|
|
Eval() {
|
|
using namespace CDL;
|
|
// Commands
|
|
register_command("eval", eval, 1);
|
|
}
|
|
};
|
|
|
|
|
|
|
|
|
|
static Eval eval;
|