Most of Boobot's JS object implementation
This commit is contained in:
parent
47de861f45
commit
f47d8adc36
@ -17,6 +17,22 @@ APIHelper::APIHelper() : BASE_URL("https://discordapp.com/api"), CHANNELS_URL(BA
|
||||
void APIHelper::send_message(std::string channel_id, std::string message) {
|
||||
if (message == "") {
|
||||
Logger::write("[send_message] Tried to send empty message", Logger::LogLevel::Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
if (message.length() > 4000) {
|
||||
Logger::write("[send_message] Tried to send a message over 4000 characters", Logger::LogLevel::Warning);
|
||||
return;
|
||||
}
|
||||
else if (message.length() > 2000) {
|
||||
std::cout << message.length() << std::endl;
|
||||
|
||||
std::string first = message.substr(0, 2000);
|
||||
std::string second = message.substr(2000);
|
||||
send_message(channel_id, first);
|
||||
std::this_thread::sleep_for(50ms);
|
||||
send_message(channel_id, second);
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string url = CHANNELS_URL + "/" + channel_id + "/messages";
|
||||
|
@ -152,11 +152,11 @@ void GatewayHandler::on_event_guild_create(json data) {
|
||||
guild_member.roles.push_back(&roles[role_id]);
|
||||
}
|
||||
|
||||
guilds[guild.id].members.push_back(guild_member);
|
||||
guilds[guild.id].members[user_id] = guild_member;
|
||||
}
|
||||
|
||||
if (v8_instances.count(guild.id) == 0) {
|
||||
v8_instances[guild.id] = std::make_unique<V8Instance>(ah);
|
||||
v8_instances[guild.id] = std::make_unique<V8Instance>(guild.id, ah, &guilds, &channels, &users, &roles);
|
||||
Logger::write("Created v8 instance for guild " + guild.id, Logger::LogLevel::Debug);
|
||||
}
|
||||
|
||||
@ -209,36 +209,32 @@ void GatewayHandler::on_event_guild_member_add(json data) {
|
||||
guild_member.roles.push_back(&roles[role_id]);
|
||||
}
|
||||
|
||||
guilds[guild_id].members.push_back(guild_member);
|
||||
guilds[guild_id].members[user_id] = guild_member;
|
||||
|
||||
Logger::write("Added new member " + guild_member.user->id + " to guild " + guild_id, Logger::LogLevel::Debug);
|
||||
}
|
||||
|
||||
void GatewayHandler::on_event_guild_member_update(json data) {
|
||||
std::cout << data.dump(4) << std::endl;
|
||||
|
||||
std::string user_id = data["user"]["id"];
|
||||
DiscordObjects::Guild &guild = guilds[data["guild_id"]];
|
||||
|
||||
auto it = std::find_if(guild.members.begin(), guild.members.begin(), [user_id](const DiscordObjects::GuildMember &gm) {
|
||||
return gm.user->id == user_id;
|
||||
});
|
||||
auto it = guild.members.find(user_id);
|
||||
if (it != guild.members.end()) {
|
||||
bool nick_changed = false;
|
||||
size_t roles_change = 0;
|
||||
|
||||
std::string nick = data.value("nick", it->nick);
|
||||
if (it->nick != nick) {
|
||||
it->nick = nick;
|
||||
std::string nick = data.value("nick", "null");
|
||||
if (it->second.nick != nick) {
|
||||
it->second.nick = nick;
|
||||
nick_changed = true;
|
||||
}
|
||||
|
||||
roles_change = it->roles.size();
|
||||
it->roles.clear(); // reset and re-fill, changing the differences is probably more expensive anyway.
|
||||
roles_change = it->second.roles.size();
|
||||
it->second.roles.clear(); // reset and re-fill, changing the differences is probably more expensive anyway.
|
||||
for (std::string role_id : data["roles"]) {
|
||||
it->roles.push_back(&roles[role_id]);
|
||||
it->second.roles.push_back(&roles[role_id]);
|
||||
}
|
||||
roles_change = it->roles.size() - roles_change;
|
||||
roles_change = it->second.roles.size() - roles_change;
|
||||
|
||||
std::string debug_string = "Updated member " + user_id + " of guild " + guild.id;
|
||||
if (nick_changed) debug_string += ". Nick changed to " + nick;
|
||||
@ -256,15 +252,12 @@ void GatewayHandler::on_event_guild_member_remove(json data) {
|
||||
DiscordObjects::Guild &guild = guilds[data["guild_id"]];
|
||||
std::string user_id = data["user"]["id"];
|
||||
|
||||
auto it = std::find_if(guild.members.begin(), guild.members.begin(), [user_id](const DiscordObjects::GuildMember &gm) {
|
||||
return gm.user->id == user_id;
|
||||
});
|
||||
|
||||
auto it = guild.members.find(user_id);
|
||||
if (it != guilds[guild.id].members.end()) {
|
||||
guild.members.erase(it);
|
||||
|
||||
DiscordObjects::User &user = users[user_id];
|
||||
user.guilds.erase(std::remove(user.guilds.begin(), user.guilds.end(), user.id));
|
||||
user.guilds.erase(std::remove(user.guilds.begin(), user.guilds.end(), guild.id));
|
||||
|
||||
if (user.guilds.size() == 0) {
|
||||
users.erase(users.find(user_id));
|
||||
@ -275,7 +268,7 @@ void GatewayHandler::on_event_guild_member_remove(json data) {
|
||||
}
|
||||
}
|
||||
else {
|
||||
Logger::write("Tried to remove guild member " + user_id + " which doesn't exist", Logger::LogLevel::Warning);
|
||||
Logger::write("Tried to remove guild member " + user_id + " who doesn't exist", Logger::LogLevel::Warning);
|
||||
}
|
||||
}
|
||||
|
||||
@ -373,9 +366,12 @@ void GatewayHandler::on_event_channel_delete(json data) {
|
||||
|
||||
void GatewayHandler::on_event_message_create(json data) {
|
||||
std::string message = data["content"];
|
||||
auto channel = channels[data["channel_id"]];
|
||||
|
||||
DiscordObjects::User sender(data["author"]);
|
||||
DiscordObjects::Channel &channel = channels[data["channel_id"]];
|
||||
DiscordObjects::Guild &guild = guilds[channel.guild_id];
|
||||
DiscordObjects::GuildMember &sender = guild.members[data["author"]["id"]];
|
||||
|
||||
if (sender.user->bot) return; // ignore bots to prevent looping
|
||||
|
||||
std::vector<std::string> words;
|
||||
boost::split(words, message, boost::is_any_of(" "));
|
||||
@ -431,14 +427,14 @@ void GatewayHandler::on_event_message_create(json data) {
|
||||
else if (words[0] == "`info") {
|
||||
ah->send_message(channel.id, ":information_source: trivia-bot by Jack. <http://github.com/jackb-p/TriviaDiscord>");
|
||||
}
|
||||
else if (words[0] == "`js" && message.length() > 4) {
|
||||
else if (words[0] == "~js" && message.length() > 4) {
|
||||
std::string js = message.substr(4);
|
||||
auto it = v8_instances.find(channel.guild_id);
|
||||
if (it != v8_instances.end() && js.length() > 0) {
|
||||
it->second->exec_js(js, channel.id);
|
||||
it->second->exec_js(js, &channel, &sender);
|
||||
}
|
||||
}
|
||||
else if (words[0] == "`createjs" && message.length() > 8) {
|
||||
else if (words[0] == "~createjs" && message.length() > 8) {
|
||||
std::string args = message.substr(10);
|
||||
size_t seperator_loc = args.find("|");
|
||||
if (seperator_loc != std::string::npos) {
|
||||
@ -455,7 +451,7 @@ void GatewayHandler::on_event_message_create(json data) {
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (words[0] == "`shutdown" && sender.id == "82232146579689472") { // it me
|
||||
else if (words[0] == "`shutdown" && sender.user->id == "82232146579689472") { // it me
|
||||
ah->send_message(channel.id, ":zzz: Goodbye!");
|
||||
// TODO: without needing c, hdl - c.close(hdl, websocketpp::close::status::going_away, "`shutdown command used.");
|
||||
}
|
||||
@ -482,12 +478,10 @@ void GatewayHandler::on_event_message_create(json data) {
|
||||
auto it = guilds.find(words[2]);
|
||||
if (it != guilds.end()) {
|
||||
std::string user_id = words[3];
|
||||
auto it2 = std::find_if(it->second.members.begin(), it->second.members.end(), [user_id](const DiscordObjects::GuildMember &gm) {
|
||||
return user_id == gm.user->id;
|
||||
});
|
||||
|
||||
auto it2 = it->second.members.find(user_id);
|
||||
if (it2 != it->second.members.end()) {
|
||||
ah->send_message(channel.id, it2->to_debug_string());
|
||||
ah->send_message(channel.id, it2->second.to_debug_string());
|
||||
}
|
||||
else {
|
||||
ah->send_message(channel.id, ":question: Unrecognised user.");
|
||||
@ -532,13 +526,18 @@ void GatewayHandler::on_event_message_create(json data) {
|
||||
}
|
||||
}
|
||||
else if (command_helper->get_command(channel.guild_id, words[0], custom_command)) {
|
||||
std::string args = "";
|
||||
if (message.length() > (words[0].length() + 1)) {
|
||||
args = message.substr(words[0].length() + 1);
|
||||
}
|
||||
|
||||
auto it = v8_instances.find(channel.guild_id);
|
||||
if (it != v8_instances.end() && custom_command.script.length() > 0) {
|
||||
it->second->exec_js(custom_command.script, channel.id);
|
||||
it->second->exec_js(custom_command.script, &channel, &sender, args);
|
||||
}
|
||||
}
|
||||
else if (games.find(channel.id) != games.end()) { // message received in channel with ongoing game
|
||||
games[channel.id]->handle_answer(message, sender);
|
||||
games[channel.id]->handle_answer(message, *sender.user);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include "../json/json.hpp"
|
||||
|
||||
@ -72,7 +73,7 @@ namespace DiscordObjects {
|
||||
bool unavailable;
|
||||
|
||||
std::vector<Channel *> channels;
|
||||
std::vector<GuildMember> members;
|
||||
std::map<std::string, GuildMember> members;
|
||||
std::vector<Role *> roles;
|
||||
//std::vector<std::unique_ptr<DiscordObjects::User>> users;
|
||||
};
|
||||
|
@ -58,13 +58,9 @@ namespace DiscordObjects {
|
||||
}
|
||||
|
||||
inline std::string Role::to_debug_string() {
|
||||
std::stringstream colour_ss;
|
||||
colour_ss << std::setw(6) << std::setfill('0') << colour;
|
||||
std::string colour_str = colour_ss.str();
|
||||
|
||||
return "**__Role " + id + "__**"
|
||||
+ "\n**name:** " + name
|
||||
+ "\n**colour:** #" + colour_str
|
||||
+ "\n**colour:** " + std::to_string(colour)
|
||||
+ "\n**hoist:** " + std::to_string(hoist)
|
||||
+ "\n**position:** " + std::to_string(position)
|
||||
+ "\n**permissions:** " + std::to_string(permissions)
|
||||
|
@ -1,125 +0,0 @@
|
||||
Example data:
|
||||
|
||||
!!!!!!!!!!!!!!!!! GUILD_CREATE Event
|
||||
{
|
||||
"afk_channel_id": null,
|
||||
"afk_timeout": 300,
|
||||
"channels": [
|
||||
{
|
||||
"id": "200398901767962624",
|
||||
"is_private": false,
|
||||
"last_message_id": "201355522635595776",
|
||||
"name": "general",
|
||||
"permission_overwrites": [],
|
||||
"position": 0,
|
||||
"topic": "",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"bitrate": 64000,
|
||||
"id": "200398901767962625",
|
||||
"is_private": false,
|
||||
"name": "General",
|
||||
"permission_overwrites": [],
|
||||
"position": 0,
|
||||
"type": "voice",
|
||||
"user_limit": 0
|
||||
}
|
||||
],
|
||||
"default_message_notifications": 0,
|
||||
"emojis": [],
|
||||
"features": [],
|
||||
"icon": null,
|
||||
"id": "200398901767962624",
|
||||
"joined_at": "2016-07-06T23:54:20.824000+00:00",
|
||||
"large": false,
|
||||
"member_count": 2,
|
||||
"members": [
|
||||
{
|
||||
"deaf": false,
|
||||
"joined_at": "2016-07-06T23:53:41.425000+00:00",
|
||||
"mute": false,
|
||||
"roles": [
|
||||
"200399346498273280"
|
||||
],
|
||||
"user": {
|
||||
"avatar": "1dc076d2d273615dd23546c86dbdfd9c",
|
||||
"discriminator": "8212",
|
||||
"id": "82232146579689472",
|
||||
"username": "Jack"
|
||||
}
|
||||
},
|
||||
{
|
||||
"deaf": false,
|
||||
"joined_at": "2016-07-06T23:54:20.824000+00:00",
|
||||
"mute": false,
|
||||
"roles": [
|
||||
"200399601507893248"
|
||||
],
|
||||
"user": {
|
||||
"avatar": "e871ceecaa362718af6d3174bc941977",
|
||||
"bot": true,
|
||||
"discriminator": "8194",
|
||||
"id": "199657095258177539",
|
||||
"username": "trivia-bot"
|
||||
}
|
||||
}
|
||||
],
|
||||
"mfa_level": 0,
|
||||
"name": "EleGiggle",
|
||||
"owner_id": "82232146579689472",
|
||||
"presences": [
|
||||
{
|
||||
"game": null,
|
||||
"status": "online",
|
||||
"user": {
|
||||
"id": "82232146579689472"
|
||||
}
|
||||
},
|
||||
{
|
||||
"game": null,
|
||||
"status": "online",
|
||||
"user": {
|
||||
"id": "199657095258177539"
|
||||
}
|
||||
}
|
||||
],
|
||||
"region": "london",
|
||||
"roles": [
|
||||
{
|
||||
"color": 0,
|
||||
"hoist": false,
|
||||
"id": "200398901767962624",
|
||||
"managed": false,
|
||||
"mentionable": false,
|
||||
"name": "@everyone",
|
||||
"permissions": 36953089,
|
||||
"position": 0
|
||||
},
|
||||
{
|
||||
"color": 3066993,
|
||||
"hoist": true,
|
||||
"id": "200399346498273280",
|
||||
"managed": false,
|
||||
"mentionable": false,
|
||||
"name": "All Perms",
|
||||
"permissions": 506715199,
|
||||
"position": 1
|
||||
},
|
||||
{
|
||||
"color": 15844367,
|
||||
"hoist": true,
|
||||
"id": "200399601507893248",
|
||||
"managed": false,
|
||||
"mentionable": false,
|
||||
"name": "Robot",
|
||||
"permissions": 536083519,
|
||||
"position": 1
|
||||
}
|
||||
],
|
||||
"splash": null,
|
||||
"unavailable": false,
|
||||
"verification_level": 0,
|
||||
"voice_states": []
|
||||
}
|
||||
|
@ -1,14 +1,20 @@
|
||||
#include <iostream>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include "V8Instance.hpp"
|
||||
#include "../APIHelper.hpp"
|
||||
#include "../Logger.hpp"
|
||||
|
||||
using namespace v8;
|
||||
V8Instance::V8Instance(std::string guild_id, std::shared_ptr<APIHelper> ah, std::map<std::string, DiscordObjects::Guild> *guilds, std::map<std::string, DiscordObjects::Channel> *channels,
|
||||
std::map<std::string, DiscordObjects::User> *users, std::map<std::string, DiscordObjects::Role> *roles) {
|
||||
|
||||
V8Instance::V8Instance(std::shared_ptr<APIHelper> ah) {
|
||||
this->guild_id = guild_id;
|
||||
this->ah = ah;
|
||||
this->guilds = guilds;
|
||||
this->channels = channels;
|
||||
this->users = users;
|
||||
this->roles = roles;
|
||||
|
||||
create();
|
||||
}
|
||||
|
||||
@ -38,17 +44,91 @@ v8::Local<v8::Context> V8Instance::create_context() {
|
||||
Local<ObjectTemplate> global = ObjectTemplate::New(isolate);
|
||||
// bind print() function
|
||||
Local<External> self = External::New(isolate, (void *) this);
|
||||
global->Set(String::NewFromUtf8(isolate, "print", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, V8Instance::js_print, self));
|
||||
Logger::write("[v8] Created global obj, linked print function", Logger::LogLevel::Debug);
|
||||
|
||||
global->Set(
|
||||
String::NewFromUtf8(isolate, "print", NewStringType::kNormal).ToLocalChecked(),
|
||||
FunctionTemplate::New(isolate, V8Instance::js_print, self)
|
||||
);
|
||||
global->SetAccessor(
|
||||
String::NewFromUtf8(isolate, "server", NewStringType::kNormal).ToLocalChecked(),
|
||||
V8Instance::js_get_server,
|
||||
(AccessorSetterCallback) 0,
|
||||
self
|
||||
);
|
||||
global->SetAccessor(
|
||||
String::NewFromUtf8(isolate, "channel", NewStringType::kNormal).ToLocalChecked(),
|
||||
V8Instance::js_get_channel,
|
||||
(AccessorSetterCallback) 0,
|
||||
self
|
||||
);
|
||||
global->SetAccessor(
|
||||
String::NewFromUtf8(isolate, "user", NewStringType::kNormal).ToLocalChecked(),
|
||||
V8Instance::js_get_user,
|
||||
(AccessorSetterCallback) 0,
|
||||
self
|
||||
);
|
||||
global->SetAccessor(
|
||||
String::NewFromUtf8(isolate, "input", NewStringType::kNormal).ToLocalChecked(),
|
||||
V8Instance::js_get_input,
|
||||
(AccessorSetterCallback) 0,
|
||||
self
|
||||
);
|
||||
|
||||
Logger::write("[v8] Created global obj, linked data and functions", Logger::LogLevel::Debug);
|
||||
|
||||
return Context::New(isolate, NULL, global);
|
||||
}
|
||||
|
||||
void V8Instance::js_get_server(Local<String> property, const PropertyCallbackInfo<Value> &info) {
|
||||
auto data = info.Data().As<External>();
|
||||
V8Instance *self = static_cast<V8Instance *>(data->Value());
|
||||
|
||||
Local<Object> obj = Object::New(info.GetIsolate());
|
||||
self->add_to_obj(obj, (*self->guilds)[self->guild_id]);
|
||||
info.GetReturnValue().Set(obj);
|
||||
}
|
||||
|
||||
void V8Instance::js_get_channel(Local<String> property, const PropertyCallbackInfo<Value> &info) {
|
||||
auto data = info.Data().As<External>();
|
||||
V8Instance *self = static_cast<V8Instance *>(data->Value());
|
||||
|
||||
if (!self->current_channel) {
|
||||
Logger::write("[v8] current_channel is null pointer", Logger::LogLevel::Severe);
|
||||
info.GetReturnValue().SetNull();
|
||||
return;
|
||||
}
|
||||
|
||||
Local<Object> obj = Object::New(info.GetIsolate());
|
||||
self->add_to_obj(obj, (*self->current_channel));
|
||||
info.GetReturnValue().Set(obj);
|
||||
}
|
||||
|
||||
void V8Instance::js_get_user(Local<String> property, const PropertyCallbackInfo<Value> &info) {
|
||||
auto data = info.Data().As<External>();
|
||||
V8Instance *self = static_cast<V8Instance *>(data->Value());
|
||||
|
||||
if (!self->current_sender) {
|
||||
Logger::write("[v8] current_sender is null pointer", Logger::LogLevel::Severe);
|
||||
info.GetReturnValue().SetNull();
|
||||
return;
|
||||
}
|
||||
|
||||
Local<Object> obj = Object::New(info.GetIsolate());
|
||||
self->add_to_obj(obj, (*self->current_sender));
|
||||
info.GetReturnValue().Set(obj);
|
||||
}
|
||||
|
||||
void V8Instance::js_get_input(Local<String> property, const PropertyCallbackInfo<Value> &info) {
|
||||
auto data = info.Data().As<External>();
|
||||
V8Instance *self = static_cast<V8Instance *>(data->Value());
|
||||
|
||||
info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), self->current_input.c_str(), NewStringType::kNormal).ToLocalChecked());
|
||||
}
|
||||
|
||||
void V8Instance::clean_up() {
|
||||
Logger::write("[v8] Cleaning up", Logger::LogLevel::Debug);
|
||||
isolate->Exit();
|
||||
isolate->Dispose();
|
||||
delete array_buffer_allocator;
|
||||
}
|
||||
|
||||
void V8Instance::reload() {
|
||||
@ -56,11 +136,15 @@ void V8Instance::reload() {
|
||||
create();
|
||||
}
|
||||
|
||||
void V8Instance::exec_js(std::string js, std::string channel_id) {
|
||||
void V8Instance::exec_js(std::string js, DiscordObjects::Channel *channel, DiscordObjects::GuildMember *sender, std::string args) {
|
||||
HandleScope handle_scope(isolate);
|
||||
Local<Context> context(isolate->GetCurrentContext());
|
||||
|
||||
Logger::write("[v8] Executing JS: " + js, Logger::LogLevel::Debug);
|
||||
current_sender = sender;
|
||||
current_channel = channel;
|
||||
current_input = args;
|
||||
|
||||
Logger::write("[v8] Preparing JS: " + js, Logger::LogLevel::Debug);
|
||||
|
||||
Local<String> source = String::NewFromUtf8(isolate, js.c_str(), NewStringType::kNormal).ToLocalChecked();
|
||||
|
||||
@ -75,7 +159,7 @@ void V8Instance::exec_js(std::string js, std::string channel_id) {
|
||||
|
||||
std::string err_msg = *error;
|
||||
Logger::write("[v8] Compilation error: " + err_msg, Logger::LogLevel::Debug);
|
||||
ah->send_message(channel_id, ":warning: **Compilation error:** `" + err_msg + "`");
|
||||
ah->send_message(channel->id, ":warning: **Compilation error:** `" + err_msg + "`");
|
||||
|
||||
return;
|
||||
}
|
||||
@ -87,21 +171,23 @@ void V8Instance::exec_js(std::string js, std::string channel_id) {
|
||||
|
||||
std::string err_msg = *error;
|
||||
Logger::write("[v8] Runtime error: " + err_msg, Logger::LogLevel::Debug);
|
||||
ah->send_message(channel_id, ":warning: **Runtime error:** `" + err_msg + "`");
|
||||
|
||||
return;
|
||||
ah->send_message(channel->id, ":warning: **Runtime error:** `" + err_msg + "`");
|
||||
}
|
||||
|
||||
Logger::write("[v8] Script compiled and run", Logger::LogLevel::Debug);
|
||||
|
||||
current_sender = nullptr;
|
||||
current_channel = nullptr;
|
||||
current_input = "";
|
||||
|
||||
if (print_text != "") {
|
||||
ah->send_message(channel_id, print_text);
|
||||
ah->send_message(channel->id, print_text);
|
||||
print_text = "";
|
||||
}
|
||||
}
|
||||
|
||||
void V8Instance::js_print(const v8::FunctionCallbackInfo<v8::Value> &args) {
|
||||
auto data = args.Data().As<v8::External>();
|
||||
auto data = args.Data().As<External>();
|
||||
V8Instance *self = static_cast<V8Instance *>(data->Value());
|
||||
|
||||
std::string output = "";
|
||||
@ -110,4 +196,130 @@ void V8Instance::js_print(const v8::FunctionCallbackInfo<v8::Value> &args) {
|
||||
v8::String::Utf8Value str(args[i]);
|
||||
self->print_text += *str;
|
||||
}
|
||||
}
|
||||
|
||||
void V8Instance::add_to_obj(Local<Object> &object, std::string field_name, std::string value) {
|
||||
add_to_obj(object, field_name, value.c_str());
|
||||
}
|
||||
|
||||
void V8Instance::add_to_obj(Local<Object> &object, std::string field_name, const char value[]) {
|
||||
if (value == "null") {
|
||||
object->Set(String::NewFromUtf8(isolate, field_name.c_str(), NewStringType::kNormal).ToLocalChecked(), Null(isolate));
|
||||
return;
|
||||
}
|
||||
|
||||
object->Set(String::NewFromUtf8(isolate, field_name.c_str(), NewStringType::kNormal).ToLocalChecked(),
|
||||
String::NewFromUtf8(isolate, value, NewStringType::kNormal).ToLocalChecked());
|
||||
}
|
||||
|
||||
void V8Instance::add_to_obj(Local<Object> &object, std::string field_name, int32_t value) {
|
||||
object->Set(String::NewFromUtf8(isolate, field_name.c_str(), NewStringType::kNormal).ToLocalChecked(),
|
||||
Integer::New(isolate, value));
|
||||
}
|
||||
|
||||
void V8Instance::add_to_obj(Local<Object> &object, std::string field_name, bool value) {
|
||||
object->Set(String::NewFromUtf8(isolate, field_name.c_str(), NewStringType::kNormal).ToLocalChecked(),
|
||||
Boolean::New(isolate, value));
|
||||
}
|
||||
|
||||
void V8Instance::add_to_obj(Local<Object> &object, std::string field_name, Local<Object> value) {
|
||||
object->Set(String::NewFromUtf8(isolate, field_name.c_str(), NewStringType::kNormal).ToLocalChecked(), value);
|
||||
}
|
||||
|
||||
void V8Instance::add_to_obj(Local<Object> &object, std::string field_name, Local<Array> value) {
|
||||
object->Set(String::NewFromUtf8(isolate, field_name.c_str(), NewStringType::kNormal).ToLocalChecked(), value);
|
||||
}
|
||||
|
||||
void V8Instance::add_to_obj(Local<Object> &object, DiscordObjects::Guild guild) {
|
||||
/* Boobot fields */
|
||||
add_to_obj(object, "Id", guild.id);
|
||||
add_to_obj(object, "Name", guild.name);
|
||||
add_to_obj(object, "IconUrl", "https://discordapp.com/api/guilds/" + guild.id + "/icons/" + guild.icon + ".jpg");
|
||||
|
||||
Local<Object> owner_obj = Object::New(isolate);
|
||||
DiscordObjects::GuildMember &owner = guild.members[guild.owner_id];
|
||||
add_to_obj(owner_obj, owner);
|
||||
add_to_obj(object, "Owner", owner_obj);
|
||||
|
||||
Local<Array> roles_arr = Array::New(isolate, guild.roles.size());
|
||||
for (uint32_t i = 0; i < guild.roles.size(); i++) {
|
||||
Local<Object> obj = Object::New(isolate);
|
||||
DiscordObjects::Role &role = *guild.roles[i];
|
||||
add_to_obj(obj, role);
|
||||
|
||||
roles_arr->Set(i, obj);
|
||||
}
|
||||
add_to_obj(object, "Roles", roles_arr);
|
||||
|
||||
Local<Array> members_arr = Array::New(isolate, guild.members.size());
|
||||
int i = 0;
|
||||
for (auto it : guild.members) {
|
||||
Local<Object> obj = Object::New(isolate);
|
||||
DiscordObjects::GuildMember &member = it.second;
|
||||
add_to_obj(obj, member);
|
||||
|
||||
members_arr->Set(i, obj);
|
||||
i++;
|
||||
}
|
||||
add_to_obj(object, "Users", members_arr);
|
||||
}
|
||||
|
||||
void V8Instance::add_to_obj(Local<Object> &object, DiscordObjects::Channel channel) {
|
||||
/* Boobot fields */
|
||||
add_to_obj(object, "Id", channel.id);
|
||||
add_to_obj(object, "Name", channel.name);
|
||||
add_to_obj(object, "Topic", channel.topic);
|
||||
add_to_obj(object, "IsVoice", channel.type == "voice");
|
||||
|
||||
Local<Array> users = Array::New(isolate, 1);
|
||||
users->Set(0, String::NewFromUtf8(isolate, "NOT IMPLEMENTED", NewStringType::kNormal).ToLocalChecked());
|
||||
add_to_obj(object, "Users", users);
|
||||
|
||||
/* Additional fields */
|
||||
add_to_obj(object, "LastMessageId", channel.last_message_id);
|
||||
add_to_obj(object, "Bitrate", channel.bitrate);
|
||||
add_to_obj(object, "UserLimit", channel.user_limit);
|
||||
}
|
||||
|
||||
void V8Instance::add_to_obj(Local<Object> &object, DiscordObjects::Role role) {
|
||||
/* Boobot fields */
|
||||
add_to_obj(object, "Id", role.id);
|
||||
add_to_obj(object, "Name", role.name);
|
||||
add_to_obj(object, "Position", role.position);
|
||||
add_to_obj(object, "Red", "NOT IMPLEMENTED");
|
||||
add_to_obj(object, "Blue", "NOT IMPLEMENTED");
|
||||
add_to_obj(object, "Green", "NOT IMPLEMENTED");
|
||||
|
||||
/* Additional fields */
|
||||
add_to_obj(object, "Mentionable", role.mentionable);
|
||||
add_to_obj(object, "Mention", "<@&" + role.id + ">");
|
||||
add_to_obj(object, "Hoist", role.hoist);
|
||||
}
|
||||
|
||||
void V8Instance::add_to_obj(Local<Object> &object, DiscordObjects::GuildMember member) {
|
||||
/* Boobot fields */
|
||||
add_to_obj(object, "Id", member.user->id);
|
||||
add_to_obj(object, "Name", member.user->username);
|
||||
add_to_obj(object, "Mention", "<@!" + member.user->id + ">");
|
||||
add_to_obj(object, "AvatarUrl", "https://discordapp.com/api/users/" + member.user->id + "/avatars/" + member.user->avatar + ".jpg");
|
||||
|
||||
Local<Array> roles = Array::New(isolate, member.roles.size());
|
||||
int i = 0;
|
||||
for (DiscordObjects::Role *role : member.roles) {
|
||||
Local<Object> role_obj = Object::New(isolate);
|
||||
add_to_obj(role_obj, *role);
|
||||
|
||||
roles->Set(i, role_obj);
|
||||
i++;
|
||||
}
|
||||
add_to_obj(object, "Roles", roles);
|
||||
|
||||
add_to_obj(object, "State", "NOT IMPLEMENTED");
|
||||
add_to_obj(object, "CurrentGame", "NOT IMPLEMENTED");
|
||||
|
||||
/* Additional fields */
|
||||
add_to_obj(object, "Nick", member.nick);
|
||||
add_to_obj(object, "Deaf", member.deaf);
|
||||
add_to_obj(object, "Mute", member.mute);
|
||||
add_to_obj(object, "JoinedAt", member.joined_at);
|
||||
}
|
@ -2,30 +2,66 @@
|
||||
#define BOT_JS_V8INSTANCE
|
||||
|
||||
#include <memory>
|
||||
#include <map>
|
||||
|
||||
#include <include/v8.h>
|
||||
#include <include/libplatform/libplatform.h>
|
||||
|
||||
#include "../data_structures/Guild.hpp"
|
||||
#include "../data_structures/Channel.hpp"
|
||||
#include "../data_structures/Role.hpp"
|
||||
#include "../data_structures/GuildMember.hpp"
|
||||
#include "../data_structures/User.hpp"
|
||||
|
||||
class APIHelper;
|
||||
|
||||
using namespace v8;
|
||||
|
||||
class V8Instance {
|
||||
public:
|
||||
V8Instance(std::shared_ptr<APIHelper> ah);
|
||||
V8Instance(std::string guild_id, std::shared_ptr<APIHelper> ah, std::map<std::string, DiscordObjects::Guild> *guilds,
|
||||
std::map<std::string, DiscordObjects::Channel> *channels, std::map<std::string, DiscordObjects::User> *users, std::map<std::string, DiscordObjects::Role> *roles);
|
||||
~V8Instance();
|
||||
void reload();
|
||||
void exec_js(std::string js, std::string channel_id);
|
||||
void exec_js(std::string js, DiscordObjects::Channel *channel, DiscordObjects::GuildMember *sender, std::string args = "");
|
||||
|
||||
private:
|
||||
void clean_up();
|
||||
void create();
|
||||
v8::Local<v8::Context> create_context();
|
||||
static void js_print(const v8::FunctionCallbackInfo<v8::Value> &args);
|
||||
Local<Context> create_context();
|
||||
|
||||
v8::ArrayBuffer::Allocator *array_buffer_allocator;
|
||||
v8::Isolate *isolate;
|
||||
void add_to_obj(Local<Object> &object, std::string field_name, std::string value);
|
||||
void add_to_obj(Local<Object> &object, std::string field_name, const char value[]);
|
||||
void add_to_obj(Local<Object> &object, std::string field_name, int32_t value);
|
||||
void add_to_obj(Local<Object> &object, std::string field_name, bool value);
|
||||
void add_to_obj(Local<Object> &object, std::string field_name, Local<Object> value);
|
||||
void add_to_obj(Local<Object> &object, std::string field_name, Local<Array> value);
|
||||
|
||||
void add_to_obj(Local<Object> &object, DiscordObjects::Guild guild);
|
||||
void add_to_obj(Local<Object> &object, DiscordObjects::Channel channel);
|
||||
void add_to_obj(Local<Object> &object, DiscordObjects::Role role);
|
||||
void add_to_obj(Local<Object> &object, DiscordObjects::GuildMember member);
|
||||
|
||||
static void js_print(const FunctionCallbackInfo<Value> &args);
|
||||
static void js_get_server(Local<String> property, const PropertyCallbackInfo<Value> &info);
|
||||
static void js_get_channel(Local<String> property, const PropertyCallbackInfo<Value> &info);
|
||||
static void js_get_user(Local<String> property, const PropertyCallbackInfo<Value> &info);
|
||||
static void js_get_input(Local<String> property, const PropertyCallbackInfo<Value> &info);
|
||||
|
||||
std::map<std::string, DiscordObjects::Guild> *guilds;
|
||||
std::map<std::string, DiscordObjects::Channel> *channels;
|
||||
std::map<std::string, DiscordObjects::User> *users;
|
||||
std::map<std::string, DiscordObjects::Role> *roles;
|
||||
|
||||
std::string guild_id;
|
||||
Isolate *isolate;
|
||||
std::shared_ptr<APIHelper> ah;
|
||||
|
||||
/* variables which change when a new command is executed */
|
||||
std::string print_text;
|
||||
std::string current_input;
|
||||
DiscordObjects::Channel *current_channel;
|
||||
DiscordObjects::GuildMember *current_sender;
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user