void Bot::onText(bot_exchange_format& f) { long i, l; l = _onTexts.GetLength(); std::string nick = std::string(f[1]); std::string text = std::string(f[2]); v7_val_t attr; if ((u_char)f[3] == 0) { attr = v7_mk_undefined(); } else { attr = v7_mk_object(v7); v7_val_t size = v7_mk_number((u_char)f[4]); v7_set(v7, attr, "size", ~0, size); COLORREF col = (u_long)f[5]; int r = GetRValue(col); int g = GetGValue(col); int b = GetBValue(col); char strCol[8]; sprintf(strCol, "#%02X%02X%02X", r, g, b); v7_val_t color = v7_mk_string(v7, strCol, ~0, 1); v7_set(v7, attr, "color", ~0, color); v7_val_t effects = v7_mk_number((u_long)f[6]); v7_set(v7, attr, "effects", ~0, effects); v7_val_t charset = v7_mk_number((u_char)f[7]); v7_set(v7, attr, "charset", ~0, charset); v7_val_t pitch = v7_mk_number((u_char)f[8]); v7_set(v7, attr, "pitch", ~0, pitch); std::string font = std::string(f[9]); v7_val_t fontName = v7_mk_string(v7, font.c_str(), ~0, 1); v7_set(v7, attr, "font", ~0, fontName); } v7_val_t nickName = v7_mk_string(v7, nick.c_str(), ~0, 0); v7_val_t fullText = v7_mk_string(v7, text.c_str(), ~0, 0); for (i = 0; i < l; i++) { v7_val_t* func = (v7_val_t*)_onTexts.GetAt(i); v7_val_t args; args = v7_mk_array(v7); v7_array_push(v7, args, nickName); v7_array_push(v7, args, fullText); v7_array_push(v7, args, attr); v7_apply(v7, *func, *v7Obj, args, NULL); } }
void Bot::onJoin(bot_exchange_format& f) { long l = _onJoin.GetLength(); if (l == 0) return; v7_val_t user = v7_mk_object(v7); v7_val_t userName = v7_mk_string(v7, std::string(f[1]).c_str(), ~0, 1); v7_set(v7, user, "name", ~0, userName); v7_val_t flags = v7_mk_number((u_long)f[2]); v7_set(v7, user, "flags", ~0, flags); v7_val_t age = v7_mk_number((u_char)f[3]); v7_set(v7, user, "age", ~0, age); v7_val_t count = v7_mk_number((int)f[4]); v7_set(v7, user, "count", ~0, count); v7_val_t gifts = v7_mk_number((u_long)f[5]); v7_set(v7, user, "gifts", ~0, gifts); long i; v7_val_t* func; v7_val_t args; for (i = 0; i < l; i++) { func = (v7_val_t*)_onJoin.GetAt(i); args = v7_mk_array(v7); v7_array_push(v7, args, user); v7_apply(v7, *func, *v7Obj, args, NULL); } }
void Bot::onIm(TString& nick, TString& text) { v7_val_t theNick = v7_mk_string(v7, nick.GetAsChar(), ~0, 1); v7_val_t theText = v7_mk_string(v7, text.GetAsChar(), ~0, 1); v7_val_t* func; v7_val_t args; long i; long l = _onMotd.GetLength(); for (i = 0; i < l; i++) { func = (v7_val_t*)_onIm.GetAt(i); args = v7_mk_array(v7); v7_array_push(v7, args, theNick); v7_array_push(v7, args, theText); v7_apply(v7, *func, *v7Obj, args, NULL); } }
static void export_read_only_vars_to_v7(struct v7 *v7) { struct ro_var *rv; if (v7 == NULL) return; v7_val_t obj = v7_mk_object(v7); for (rv = g_ro_vars; rv != NULL; rv = rv->next) { v7_set(v7, obj, rv->name, ~0, v7_mk_string(v7, *rv->ptr, ~0, 1)); } v7_val_t Sys = v7_get(v7, v7_get_global(v7), "Sys", ~0); v7_set(v7, Sys, "ro_vars", ~0, obj); }
static void setup_request_object(struct v7 *v7, v7_val_t request, struct http_message *hm) { int i, qslen = hm->query_string.len; v7_val_t headers = v7_mk_object(v7); /* TODO(lsm): implement as getters to save memory */ v7_set(v7, request, "headers", ~0, headers); v7_set(v7, request, "method", ~0, v7_mk_string(v7, hm->method.p, hm->method.len, 1)); v7_set(v7, request, "url", ~0, v7_mk_string(v7, hm->uri.p, hm->uri.len + (qslen == 0 ? 0 : qslen + 1), 1)); v7_set(v7, request, "body", ~0, v7_mk_string(v7, hm->body.p, hm->body.len, 1)); for (i = 0; hm->header_names[i].len > 0; i++) { const struct mg_str *name = &hm->header_names[i]; const struct mg_str *value = &hm->header_values[i]; v7_set(v7, headers, name->p, name->len, v7_mk_string(v7, value->p, value->len, 1)); } }
SJ_PRIVATE enum v7_err Wifi_status(struct v7 *v7, v7_val_t *res) { char *status = sj_wifi_get_status_str(); if (status == NULL) { *res = V7_UNDEFINED; goto clean; } *res = v7_mk_string(v7, status, strlen(status), 1); clean: if (status != NULL) { free(status); } return V7_OK; }
SJ_PRIVATE enum v7_err Wifi_show(struct v7 *v7, v7_val_t *res) { char *ssid = sj_wifi_get_connected_ssid(); if (ssid == NULL) { *res = V7_UNDEFINED; goto clean; } *res = v7_mk_string(v7, ssid, strlen(ssid), 1); clean: if (ssid != NULL) { free(ssid); } return V7_OK; }
size_t sj_uart_recv_cb(void *ctx, const char *d, size_t len) { struct user_data *ud = (struct user_data *) ctx; v7_val_t s, cb = ud->cb; size_t want = ud->want; if (len < want || v7_is_undefined(ud->cb)) return 0; ud->cb = V7_UNDEFINED; ud->want = 0; s = v7_mk_string(ud->v7, d, want, 1); sj_invoke_cb1(ud->v7, cb, s); return want; }
void Bot::onLeft(TString& nick) { long l = _onLeft.GetLength(); if (l == 0) return; long i; v7_val_t* func; v7_val_t args; v7_val_t userName = v7_mk_string(v7, nick.GetAsChar(), ~0, 1); for (i = 0; i < l; i++) { func = (v7_val_t*)_onLeft.GetAt(i); args = v7_mk_array(v7); v7_array_push(v7, args, userName); v7_apply(v7, *func, *v7Obj, args, NULL); } }
void Bot::onMotd(TString& motd) { v7_val_t theMotd = v7_mk_string(v7, motd.GetAsChar(), ~0, 1); v7_val_t* func; v7_val_t args; long i; long l = _onMotd.GetLength(); for (i = 0; i < l; i++) { func = (v7_val_t*)_onMotd.GetAt(i); args = v7_mk_array(v7); v7_array_push(v7, args, theMotd); v7_apply(v7, *func, *v7Obj, args, NULL); } }
static enum v7_err UART_recv(struct v7 *v7, v7_val_t *res) { struct esp_sj_uart_state *us; enum v7_err ret = esp_sj_uart_get_state(v7, &us); if (ret != V7_OK) return ret; cs_rbuf_t *rxb = esp_uart_rx_buf(us->uart_no); size_t len = MIN((size_t) v7_to_number(v7_arg(v7, 0)), rxb->used); uint8_t *data; len = cs_rbuf_get(rxb, len, &data); *res = v7_mk_string(v7, (const char *) data, len, 1 /* copy */); cs_rbuf_consume(rxb, len); us->recv_pending = 0; /* This is required to unblock interrupts after buffer has been filled. * And won't hurt in general. */ esp_sj_uart_schedule_dispatcher(us->uart_no); return V7_OK; }
SJ_PRIVATE enum v7_err Wifi_ip(struct v7 *v7, v7_val_t *res) { v7_val_t arg0 = v7_arg(v7, 0); char *ip = NULL; ip = v7_is_number(arg0) && v7_get_double(v7, arg0) == 1 ? sj_wifi_get_ap_ip() : sj_wifi_get_sta_ip(); if (ip == NULL) { *res = V7_UNDEFINED; goto clean; } *res = v7_mk_string(v7, ip, strlen(ip), 1); clean: if (ip != NULL) { free(ip); } return V7_OK; }
static int notify_js(enum js_update_status us, const char *info) { #ifndef CS_DISABLE_JS if (!v7_is_undefined(s_updater_notify_cb)) { if (info == NULL) { sj_invoke_cb1(s_v7, s_updater_notify_cb, v7_mk_number(s_v7, us)); } else { sj_invoke_cb2(s_v7, s_updater_notify_cb, v7_mk_number(s_v7, us), v7_mk_string(s_v7, info, ~0, 1)); }; return 1; } #else (void) us; (void) info; #endif return 0; }
void Bot::onTalk(TString& nick, unsigned char flag) { long l = _onTalk.GetLength(); if (l == 0) return; long i; v7_val_t* func; v7_val_t args; v7_val_t userName = v7_mk_string(v7, nick.GetAsChar(), ~0, 1); v7_val_t theFlag = v7_mk_number(flag); for (i = 0; i < l; i++) { func = (v7_val_t*)_onTalk.GetAt(i); args = v7_mk_array(v7); v7_array_push(v7, args, userName); v7_array_push(v7, args, theFlag); v7_apply(v7, *func, *v7Obj, args, NULL); } }
void sj_wifi_scan_done(const char **ssids, void *arg) { struct wifi_cb_arg *cba = (struct wifi_cb_arg *) arg; struct v7 *v7 = cba->v7; v7_val_t res = v7_mk_undefined(); const char **p; v7_own(v7, &res); if (ssids != NULL) { res = v7_mk_array(v7); for (p = ssids; *p != NULL; p++) { v7_array_push(v7, res, v7_mk_string(v7, *p, strlen(*p), 1)); } } /* Free the struct in case callback launches a new scan. */ cba->v7 = NULL; v7_disown(v7, &cba->v); sj_invoke_cb1(v7, cba->v, res); v7_disown(v7, &res); }
/* * Parse URL; used for: * * - `URL.parse()` * - `Http.request()` and `Http.get()`, when provided `opts` is a string. */ static enum v7_err sj_url_parse(struct v7 *v7, v7_val_t url_v, v7_val_t *res) { enum v7_err rcode = V7_OK; v7_val_t opts, protocol_v; size_t i, j, len; int state = 0; const char *url; if (!v7_is_string(url_v)) { rcode = v7_throwf(v7, "TypeError", "URL must be a string"); goto clean; } url = v7_get_string_data(v7, &url_v, &len); opts = v7_mk_object(v7); for (i = j = 0; j < len; j++) { switch (state) { case 0: if (url[j] == '/') { protocol_v = v7_mk_string(v7, url + i, j - i - 1, 1); v7_set(v7, opts, "protocol", ~0, protocol_v); j += 1; i = j + 1; state = 1; } break; case 1: if (url[j] == '/' || (j > i && url[j] == ':') || j == len - 1) { int hl = j - i; if (j == len - 1 && url[j] != '/' && url[j] != ':') hl++; v7_set(v7, opts, "hostname", ~0, v7_mk_string(v7, url + i, hl, 1)); if (url[j] == '/' || j == len - 1) { const char *protocol = v7_to_cstring(v7, &protocol_v); int port = strcasecmp(protocol, "https") == 0 ? 443 : 80; v7_set(v7, opts, "port", ~0, v7_mk_number(port)); i = j; if (j == len - 1) j--; state = 3; } else { i = j + 1; state = 2; } } break; case 2: if (url[j] == '/' || j == len - 1) { char ps[6]; size_t l = j - i; if (j == len - 1) l++; if (l > sizeof(ps) - 1) l = sizeof(ps) - 1; memcpy(ps, url + i, l); ps[l] = '\0'; v7_set(v7, opts, "port", ~0, v7_mk_number(atoi(ps))); i = j; if (j == len - 1) j--; state = 3; } break; case 3: if (j == len - 1) { v7_val_t path_v = j - i > 0 ? v7_mk_string(v7, url + i, j - i + 1, 1) : v7_mk_string(v7, "/", 1, 1); v7_set(v7, opts, "path", ~0, path_v); } break; } } *res = opts; clean: return rcode; }
/* Callback for json_walk() */ static void frozen_cb(void *data, const char *name, size_t name_len, const char *path, const struct json_token *token) { struct json_parse_ctx *ctx = (struct json_parse_ctx *) data; v7_val_t v = V7_UNDEFINED; (void) path; v7_own(ctx->v7, &v); switch (token->type) { case JSON_TYPE_STRING: v = v7_mk_string(ctx->v7, token->ptr, token->len, 1 /* copy */); break; case JSON_TYPE_NUMBER: v = v7_mk_number(ctx->v7, cs_strtod(token->ptr, NULL)); break; case JSON_TYPE_TRUE: v = v7_mk_boolean(ctx->v7, 1); break; case JSON_TYPE_FALSE: v = v7_mk_boolean(ctx->v7, 0); break; case JSON_TYPE_NULL: v = V7_NULL; break; case JSON_TYPE_OBJECT_START: v = v7_mk_object(ctx->v7); break; case JSON_TYPE_ARRAY_START: v = v7_mk_array(ctx->v7); break; case JSON_TYPE_OBJECT_END: case JSON_TYPE_ARRAY_END: { /* Object or array has finished: deallocate its frame */ ctx->frame = free_json_frame(ctx, ctx->frame); } break; default: LOG(LL_ERROR, ("Wrong token type %d\n", token->type)); break; } if (!v7_is_undefined(v)) { if (name != NULL && name_len != 0) { /* Need to define a property on the current object/array */ if (v7_is_object(ctx->frame->val)) { v7_set(ctx->v7, ctx->frame->val, name, name_len, v); } else if (v7_is_array(ctx->v7, ctx->frame->val)) { /* * TODO(dfrank): consult name_len. Currently it's not a problem due to * the implementation details of frozen, but it might change */ int idx = (int) cs_strtod(name, NULL); v7_array_set(ctx->v7, ctx->frame->val, idx, v); } else { LOG(LL_ERROR, ("Current value is neither object nor array\n")); } } else { /* This is a root value */ assert(ctx->frame == NULL); /* * This value will also be the overall result of JSON parsing * (it's already owned by the `v7_alt_json_parse()`) */ ctx->result = v; } if (token->type == JSON_TYPE_OBJECT_START || token->type == JSON_TYPE_ARRAY_START) { /* New object or array has just started, so we need to allocate a frame * for it */ struct json_parse_frame *new_frame = alloc_json_frame(ctx, v); new_frame->up = ctx->frame; ctx->frame = new_frame; } } v7_disown(ctx->v7, &v); }
static void mqtt_ev_handler(struct mg_connection *nc, int ev, void *ev_data) { struct mg_mqtt_message *msg = (struct mg_mqtt_message *) ev_data; struct user_data *ud = (struct user_data *) nc->user_data; struct v7 *v7 = ud->v7; v7_val_t cb; (void) nc; (void) ev_data; switch (ev) { case MG_EV_CONNECT: if (*(int *) ev_data == 0) { mg_send_mqtt_handshake(nc, ud->client_id); } else { cb = v7_get(v7, ud->client, SJ_MQTT_ERROR_CB, ~0); if (!v7_is_undefined(cb)) { sj_invoke_cb0(v7, cb); } } break; case MG_EV_MQTT_CONNACK: { /* * Call connect or error cb if they were registered. */ const char *key; if (msg->connack_ret_code == MG_EV_MQTT_CONNACK_ACCEPTED) { key = SJ_MQTT_CONNECT_CB; } else { key = SJ_MQTT_ERROR_CB; } cb = v7_get(v7, ud->client, key, ~0); if (!v7_is_undefined(cb)) { sj_invoke_cb0(v7, cb); } break; } case MG_EV_MQTT_PUBLISH: cb = v7_get(v7, ud->client, SJ_MQTT_MESSAGE_CB, ~0); if (!v7_is_undefined(cb)) { v7_val_t topic = v7_mk_string(v7, msg->topic, strlen(msg->topic), 1); v7_val_t payload = v7_mk_string(v7, msg->payload.p, msg->payload.len, 1); sj_invoke_cb2(v7, cb, topic, payload); } break; case MG_EV_CLOSE: /* * Invoke close cb and then destroys all mg state. */ cb = v7_get(v7, ud->client, SJ_MQTT_CLOSE_CB, ~0); if (!v7_is_undefined(cb)) { sj_invoke_cb0(v7, cb); } v7_def(v7, ud->client, "_nc", ~0, _V7_DESC_HIDDEN(1), V7_UNDEFINED); v7_disown(v7, &ud->client); free(ud->client_id); free(ud); break; } }
Bot::Bot(bot_manager* mgr, const char* name, const char* workDir) { _mgr = mgr; _name = name; /*_workDir = std::string(ExePath()).c_str(); _workDir += L"\\plugins\\BMP\\"; TString botNamee = name; botNamee.ToUpper(); _workDir += botNamee.GetAsWChar(); MessageBox(NULL, _workDir.GetAsChar(), "Work Dir", 0);*/ setActive(); _workDir = workDir; _workDir += L"bmp\\"; bool isScriptOk = true; if (!EnsureDirExists(_workDir.GetAsWChar())) { isScriptOk = false; } _charset.color = RGB(0xff, 0x99, 0x00); _activeBot = this; _scriptFile = _workDir.GetAsWChar(); _scriptFile += L"main.js"; if (isScriptOk && !FileExists(std::string(_scriptFile.GetAsChar()))) { TString strSay = L"BMP Plugin will not work, please put file 'main.js' into work dir. ("; strSay += _scriptFile.GetAsWChar(); strSay += L")"; //say(strSay); MessageBox(NULL, strSay.GetAsChar(), "BMP Bot Alert", 0); isScriptOk = false; } v7 = v7_create(); enum v7_err rcode = V7_OK; v7_val_t result; //events function define v7_set_method(v7, v7_get_global(v7), "on", (v7_cfunction_t*)&jsBotEvent); //utilities functions v7_set_method(v7, v7_get_global(v7), "say", (v7_cfunction_t*)&jsBotSay); v7_set_method(v7, v7_get_global(v7), "setTimeout", (v7_cfunction_t*)&jsSetTimeout); v7_set_method(v7, v7_get_global(v7), "setInterval", (v7_cfunction_t*)&jsSetInterval); v7_set_method(v7, v7_get_global(v7), "clearTimeout", (v7_cfunction_t*)&jsClearTimeout); v7_set_method(v7, v7_get_global(v7), "clearInterval", (v7_cfunction_t*)&jsClearInterval); botObj = new v7_val_t; v7_own(v7, botObj); *botObj = v7_mk_object(v7); v7_val_t botName = v7_mk_string(v7, name, ~0, 1); v7_set(v7, *botObj, "name", ~0, botName); v7_set(v7, v7_get_global(v7), "BOT", ~0, *botObj); v7_set_method(v7, *botObj, "setFontStyle", (v7_cfunction_t*)&jsBotFontStyle); v7_set_method(v7, *botObj, "load", (v7_cfunction_t*)&jsBotLoadFile); //rcode = v7_exec(v7, "var a = \"aaa\"; say(a); print(\"Yeah\");", &result); if (isScriptOk) { rcode = v7_exec_file(v7, _scriptFile.GetAsChar(), &result); if (rcode != V7_OK) { if (result == V7_SYNTAX_ERROR) MessageBox(NULL, "script fail syntax error", "Nooo", 0); else if (result == V7_EXEC_EXCEPTION) MessageBox(NULL, "script fail, exception", "Nooo", 0); else if (result == V7_EXEC_EXCEPTION) MessageBox(NULL, "script fail, exception", "Nooo", 0); else if (result == V7_AST_TOO_LARGE) MessageBox(NULL, "script fail, ast too large", "Nooo", 0); } else { v7_val_t vObj; v7_own(v7, &vObj); vObj = v7_mk_object(v7); v7Obj = &vObj; } } }