summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--plugins/MirLua/Modules/m_json/m_json.vcxproj28
-rw-r--r--plugins/MirLua/Modules/m_json/src/main.cpp88
-rw-r--r--plugins/MirLua/Modules/m_json/src/stdafx.cxx1
-rw-r--r--plugins/MirLua/src/m_hotkeys.cpp6
-rw-r--r--plugins/MirLua/src/m_http.cpp443
-rw-r--r--plugins/MirLua/src/m_json.cpp (renamed from plugins/MirLua/Modules/m_json/src/metatable.cpp)362
-rw-r--r--plugins/MirLua/src/m_json.h (renamed from plugins/MirLua/Modules/m_json/src/stdafx.h)67
-rw-r--r--plugins/MirLua/src/m_protocols.cpp16
-rw-r--r--plugins/MirLua/src/main.cpp2
-rw-r--r--plugins/MirLua/src/mlua.cpp16
-rw-r--r--plugins/MirLua/src/mlua_module_loader.cpp4
-rw-r--r--plugins/MirLua/src/mlua_script.cpp1
-rw-r--r--plugins/MirLua/src/stdafx.h8
-rw-r--r--plugins/MirLua/src/version.h2
14 files changed, 736 insertions, 308 deletions
diff --git a/plugins/MirLua/Modules/m_json/m_json.vcxproj b/plugins/MirLua/Modules/m_json/m_json.vcxproj
deleted file mode 100644
index 538ed63f5c..0000000000
--- a/plugins/MirLua/Modules/m_json/m_json.vcxproj
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup Label="ProjectConfigurations">
- <ProjectConfiguration Include="Debug|Win32">
- <Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Debug|x64">
- <Configuration>Debug</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
- <Configuration>Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|x64">
- <Configuration>Release</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- </ItemGroup>
- <PropertyGroup Label="Globals">
- <ProjectName>m_json</ProjectName>
- <ProjectGuid>{8A645067-7F45-4E65-AAFC-AFDA81C29A1D}</ProjectGuid>
- </PropertyGroup>
- <ImportGroup Label="PropertySheets">
- <Import Project="$(ProjectDir)..\module.props" />
- </ImportGroup>
-</Project> \ No newline at end of file
diff --git a/plugins/MirLua/Modules/m_json/src/main.cpp b/plugins/MirLua/Modules/m_json/src/main.cpp
deleted file mode 100644
index 3774442d7f..0000000000
--- a/plugins/MirLua/Modules/m_json/src/main.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-#include "stdafx.h"
-
-static int lua_Decode(lua_State *L)
-{
- const char *string = luaL_checkstring(L, 1);
-
- JSONNode *node = json_parse(string);
- new (L) JSON(node);
- luaL_setmetatable(L, MT_JSON);
-
- return 1;
-}
-
-static int lua_Encode(lua_State *L)
-{
- switch (lua_type(L, 1))
- {
- case LUA_TNIL:
- lua_pushliteral(L, "null");
- break;
- case LUA_TBOOLEAN:
- lua_pushstring(L, lua_toboolean(L, 1) ? "true" : "false");
- break;
- case LUA_TNUMBER:
- {
- if (lua_isinteger(L, 1)) {
- lua_pushfstring(L, "%I", lua_tointeger(L, 1));
- break;
- }
- char decpoint = lua_getlocaledecpoint();
- if (decpoint != '.') {
- char p[2] = { decpoint };
- luaL_gsub(L, lua_tostring(L, 1), p, ".");
- }
- else
- lua_pushfstring(L, "%f", lua_tonumber(L, 1));
- break;
- }
- case LUA_TSTRING:
- lua_pushfstring(L, "\"%s\"", lua_tostring(L, 1));
- break;
- case LUA_TTABLE:
- {
- JSONNode node;
- lua_pushnil(L);
- lua_pushvalue(L, 1);
- lua2json(L, node);
- lua_pop(L, 2);
- lua_pushstring(L, node.write().c_str());
- break;
- }
- case LUA_TUSERDATA:
- {
- JSONNode &node = *((JSON*)luaL_checkudata(L, 1, MT_JSON))->node;
- lua_pushstring(L, node.write().c_str());
- break;
- }
- case LUA_TLIGHTUSERDATA:
- if (lua_touserdata(L, 1) == NULL)
- {
- lua_pushliteral(L, "null");
- break;
- }
- default:
- luaL_argerror(L, 1, luaL_typename(L, 1));
- }
-
- return 1;
-}
-
-static const luaL_Reg methods[] =
-{
- { "Decode", lua_Decode },
- { "Encode", lua_Encode },
-
- { NULL, NULL }
-};
-
-extern "C" LUAMOD_API int luaopen_m_json(lua_State *L)
-{
- luaL_newlib(L, methods);
-
- luaL_newmetatable(L, MT_JSON);
- luaL_setfuncs(L, jsonApi, 0);
- lua_pop(L, 1);
-
- return 1;
-} \ No newline at end of file
diff --git a/plugins/MirLua/Modules/m_json/src/stdafx.cxx b/plugins/MirLua/Modules/m_json/src/stdafx.cxx
deleted file mode 100644
index 1577c4e3bc..0000000000
--- a/plugins/MirLua/Modules/m_json/src/stdafx.cxx
+++ /dev/null
@@ -1 +0,0 @@
-#include "stdafx.h" \ No newline at end of file
diff --git a/plugins/MirLua/src/m_hotkeys.cpp b/plugins/MirLua/src/m_hotkeys.cpp
index 6ab3f07625..2661197d2a 100644
--- a/plugins/MirLua/src/m_hotkeys.cpp
+++ b/plugins/MirLua/src/m_hotkeys.cpp
@@ -72,12 +72,8 @@ static int hotkeys_MakeHotkey(lua_State *L)
mod = (1 << (luaL_checkoption(L, 1, NULL, mods) - 1));
break;
case LUA_TTABLE:
- lua_pushnil(L);
- while (lua_next(L, 1) != 0)
- {
+ for (lua_pushnil(L); lua_next(L, 1); lua_pop(L, 1))
mod |= (1 << (luaL_checkoption(L, -1, NULL, mods) - 1));
- lua_pop(L, 1);
- }
break;
default:
luaL_argerror(L, 1, luaL_typename(L, 1));
diff --git a/plugins/MirLua/src/m_http.cpp b/plugins/MirLua/src/m_http.cpp
new file mode 100644
index 0000000000..ce09fdb392
--- /dev/null
+++ b/plugins/MirLua/src/m_http.cpp
@@ -0,0 +1,443 @@
+#include "stdafx.h"
+
+/***********************************************/
+
+#define MT_NETLIBHTTPHEADERS "NETLIBHTTPHEADERS"
+
+struct NETLIBHTTPHEADERS
+{
+ const NETLIBHTTPHEADER *headers;
+ int count;
+};
+
+static void AddHeader(NETLIBHTTPREQUEST *request, const char *name, const char *value)
+{
+ request->headers = (NETLIBHTTPHEADER*)mir_realloc(request->headers,
+ sizeof(NETLIBHTTPHEADER)*(request->headersCount + 1));
+ NETLIBHTTPHEADER &header = request->headers[request->headersCount];
+ header.szName = mir_strdup(name);
+ header.szValue = mir_strdup(value);
+ request->headersCount++;
+}
+
+static void SetHeader(NETLIBHTTPREQUEST *request, const char *name, const char *value)
+{
+ for (int i = 0; i < request->headersCount; i++) {
+ if (mir_strcmp(request->headers[i].szName, name) == 0) {
+ mir_free(request->headers[i].szValue);
+ request->headers[i].szValue = mir_strdup(value);
+ return;
+ }
+ }
+ AddHeader(request, name, value);
+}
+
+static int headers_Iterator(lua_State *L)
+{
+ NETLIBHTTPHEADER *headers = (NETLIBHTTPHEADER*)lua_touserdata(L, lua_upvalueindex(1));
+ int count = lua_tointeger(L, lua_upvalueindex(2));
+ int idx = lua_tointeger(L, lua_upvalueindex(3));
+
+ if (idx < count) {
+ lua_pushstring(L, headers[idx].szName);
+ lua_pushstring(L, headers[idx].szValue);
+ lua_pushinteger(L, idx + 1);
+ lua_replace(L, lua_upvalueindex(3));
+ return 2;
+ }
+
+ lua_pushnil(L);
+
+ return 1;
+}
+
+static int headers__call(lua_State *L)
+{
+ NETLIBHTTPHEADERS *headers = (NETLIBHTTPHEADERS*)luaL_checkudata(L, 1, MT_NETLIBHTTPHEADERS);
+
+ lua_pushlightuserdata(L, (void*)headers->headers);
+ lua_pushinteger(L, headers->count);
+ lua_pushinteger(L, 0);
+ lua_pushcclosure(L, headers_Iterator, 3);
+
+ return 1;
+}
+
+static int headers__index(lua_State *L)
+{
+ NETLIBHTTPHEADERS *headers = (NETLIBHTTPHEADERS*)luaL_checkudata(L, 1, MT_NETLIBHTTPHEADERS);
+
+ if (lua_isinteger(L, 2)) {
+ int idx = lua_tointeger(L, 2);
+ if (idx > 0 && idx <= headers->count) {
+ lua_pushstring(L, headers->headers[idx - 1].szValue);
+ return 1;
+ }
+ }
+
+ const char *key = lua_tostring(L, 2);
+ for (int i = 0; i < headers->count; i++) {
+ if (mir_strcmp(headers->headers[i].szName, key) == 0) {
+ lua_pushstring(L, headers->headers[i].szValue);
+ return 1;
+ }
+ }
+
+ lua_pushnil(L);
+
+ return 1;
+}
+
+static int headers__len(lua_State *L)
+{
+ NETLIBHTTPHEADERS *headers = (NETLIBHTTPHEADERS*)luaL_checkudata(L, 1, MT_NETLIBHTTPHEADERS);
+
+ lua_pushinteger(L, headers->count);
+
+ return 1;
+}
+
+static const luaL_Reg headersApi[] =
+{
+ { "__call", headers__call },
+ { "__index", headers__index },
+ { "__len", headers__len },
+
+ { NULL, NULL }
+};
+
+/***********************************************/
+
+#define MT_NETLIBHTTPCONTENT "NETLIBHTTPCONTENT"
+
+struct NETLIBHTTPCONTENT
+{
+ const char *data;
+ int length;
+};
+
+static int content__index(lua_State *L)
+{
+ NETLIBHTTPCONTENT *content = (NETLIBHTTPCONTENT*)luaL_checkudata(L, 1, MT_NETLIBHTTPCONTENT);
+
+ int idx = luaL_checkinteger(L, 2);
+ if (idx > 0 && idx <= content->length) {
+ lua_pushinteger(L, content->data[idx - 1]);
+ return 1;
+ }
+
+ lua_pushnil(L);
+
+ return 1;
+}
+
+static int content__len(lua_State *L)
+{
+ NETLIBHTTPCONTENT *content = (NETLIBHTTPCONTENT*)luaL_checkudata(L, 1, MT_NETLIBHTTPCONTENT);
+
+ lua_pushinteger(L, content->length);
+
+ return 1;
+}
+
+static int content__tostring(lua_State *L)
+{
+ NETLIBHTTPCONTENT *content = (NETLIBHTTPCONTENT*)luaL_checkudata(L, 1, MT_NETLIBHTTPCONTENT);
+
+ lua_pushlstring(L, content->data, content->length);
+
+ return 1;
+}
+
+static const luaL_Reg contentApi[] =
+{
+ { "__index", content__index },
+ { "__len", content__len },
+ { "__tostring", content__tostring },
+
+ { NULL, NULL }
+};
+
+/***********************************************/
+
+#define MT_NETLIBHTTPRESPONSE "NETLIBHTTPRESPONSE"
+
+static NETLIBHTTPREQUEST* response_Create(lua_State *L, NETLIBHTTPREQUEST *request)
+{
+ NETLIBHTTPREQUEST **response = (NETLIBHTTPREQUEST**)lua_newuserdata(L, sizeof(NETLIBHTTPREQUEST*));
+ *response = Netlib_HttpTransaction(hNetlib, request);
+ luaL_setmetatable(L, MT_NETLIBHTTPRESPONSE);
+
+ return *response;
+}
+
+static int response__index(lua_State *L)
+{
+ NETLIBHTTPREQUEST *response = *(NETLIBHTTPREQUEST**)luaL_checkudata(L, 1, MT_NETLIBHTTPRESPONSE);
+ const char *key = lua_tostring(L, 2);
+
+ if (mir_strcmpi(key, "Headers") == 0) {
+ NETLIBHTTPHEADERS *headers = (NETLIBHTTPHEADERS*)lua_newuserdata(L, sizeof(NETLIBHTTPHEADERS));
+ headers->headers = response->headers;
+ headers->count = response->headersCount;
+ luaL_setmetatable(L, MT_NETLIBHTTPHEADERS);
+ }
+ else if (mir_strcmpi(key, "Content") == 0) {
+ NETLIBHTTPCONTENT *content = (NETLIBHTTPCONTENT*)lua_newuserdata(L, sizeof(NETLIBHTTPCONTENT));
+ content->data = response->pData;
+ content->length = response->dataLength;
+ luaL_setmetatable(L, MT_NETLIBHTTPCONTENT);
+ }
+ else if (mir_strcmpi(key, "StatusCode") == 0)
+ lua_pushinteger(L, response->resultCode);
+ else if (mir_strcmpi(key, "IsSuccess") == 0) {
+ lua_pushboolean(L, HTTP_CODE_SUCCESS(response->resultCode));
+ }
+ else
+ lua_pushnil(L);
+
+ return 1;
+}
+
+static int response__gc(lua_State *L)
+{
+ NETLIBHTTPREQUEST **response = (NETLIBHTTPREQUEST**)luaL_checkudata(L, 1, MT_NETLIBHTTPRESPONSE);
+
+ Netlib_FreeHttpRequest(*response);
+
+ return 0;
+}
+
+static const luaL_Reg responseApi[] =
+{
+ { "__index", response__index },
+ { "__gc", response__gc },
+
+ { NULL, NULL }
+};
+
+/***********************************************/
+
+#define MT_NETLIBHTTPREQUEST "NETLIBHTTPREQUEST"
+
+static NETLIBHTTPREQUEST* CreateRequest(lua_State *L)
+{
+ NETLIBHTTPREQUEST **request = (NETLIBHTTPREQUEST**)lua_newuserdata(L, sizeof(NETLIBHTTPREQUEST*));
+ *request = (NETLIBHTTPREQUEST*)mir_calloc(sizeof(NETLIBHTTPREQUEST));
+ (*request)->cbSize = sizeof(NETLIBHTTPREQUEST);
+ (*request)->flags = NLHRF_HTTP11 | NLHRF_NODUMP;
+
+ luaL_setmetatable(L, MT_NETLIBHTTPREQUEST);
+
+ return *request;
+}
+
+static void request_SetUrl(lua_State *L, int idx, NETLIBHTTPREQUEST *request)
+{
+ const char *url = luaL_checkstring(L, idx);
+ request->szUrl = mir_strdup(url);
+ if (mir_strncmpi(request->szUrl, "https", 5) == 0)
+ request->flags |= NLHRF_SSL;
+ else
+ request->flags &= ~(NLHRF_SSL);
+}
+
+static void request_SetHeaders(lua_State *L, int idx, NETLIBHTTPREQUEST *request)
+{
+ if (lua_isnoneornil(L, idx))
+ return;
+
+ luaL_checktype(L, idx, LUA_TTABLE);
+
+ idx = lua_absindex(L, idx);
+ for (lua_pushnil(L); lua_next(L, idx); lua_pop(L, 2)) {
+ lua_pushvalue(L, -2);
+ const char *name = lua_tostring(L, -1);
+ const char *value = lua_tostring(L, -2);
+ AddHeader(request, name, value);
+ }
+}
+
+static void request_SetContent(lua_State *L, int idx, NETLIBHTTPREQUEST *request)
+{
+ CMStringA data;
+
+ switch (lua_type(L, idx))
+ {
+ case LUA_TNONE:
+ case LUA_TNIL:
+ return;
+ case LUA_TSTRING:
+ data = lua_tostring(L, idx);
+ SetHeader(request, "Content-Type", "text/plain");
+ break;
+ case LUA_TTABLE:
+ {
+ idx = lua_absindex(L, idx);
+ for (lua_pushnil(L); lua_next(L, idx); lua_pop(L, 2)) {
+ lua_pushvalue(L, -2);
+ const char *name = lua_tostring(L, -1);
+ const char *value = lua_tostring(L, -2);
+ data.AppendFormat("&%s=%s", name, value);
+ }
+ data.Delete(0);
+ SetHeader(request, "Content-Type", "application/x-www-form-urlencoded");
+ break;
+ }
+ default:
+ luaL_argerror(L, idx, luaL_typename(L, idx));
+ }
+
+ request->pData = mir_strdup(data);
+ request->dataLength = data.GetLength();
+}
+
+static void request_SetContentType(lua_State *L, int idx, NETLIBHTTPREQUEST *request)
+{
+ if (!lua_isstring(L, 2))
+ return;
+
+ const char *type = lua_tostring(L, 2);
+ SetHeader(request, "Content-Type", type);
+}
+
+static const char *httpMethods[] = { "GET", "POST", "PUT", "DELETE", NULL };
+
+static int request_Send(lua_State *L)
+{
+ luaL_checktype(L, 1, LUA_TTABLE);
+
+ NETLIBHTTPREQUEST *request = CreateRequest(L);
+
+ lua_getfield(L, 1, "Method");
+ request->requestType = (1 << (luaL_checkoption(L, -1, NULL, httpMethods)));
+ lua_pop(L, 1);
+
+ lua_getfield(L, 1, "Url");
+ request_SetUrl(L, -1, request);
+ lua_pop(L, 1);
+
+ lua_getfield(L, 1, "Headers");
+ request_SetHeaders(L, -1, request);
+ lua_pop(L, 1);
+
+ lua_getfield(L, 1, "Content");
+ request_SetContent(L, -1, request);
+ lua_pop(L, 1);
+
+ lua_getfield(L, 1, "Timeout");
+ request->timeout = luaL_optinteger(L, -1, 0);
+ lua_pop(L, 1);
+
+ response_Create(L, request);
+
+ return 1;
+}
+
+static int request_Get(lua_State *L)
+{
+ NETLIBHTTPREQUEST *request = CreateRequest(L);
+ request->requestType = REQUEST_GET;
+ request_SetUrl(L, 1, request);
+
+ response_Create(L, request);
+
+ return 1;
+}
+
+static int request_Post(lua_State *L)
+{
+ NETLIBHTTPREQUEST *request = CreateRequest(L);
+ request->requestType = REQUEST_POST;
+ request_SetUrl(L, 1, request);
+ request_SetContent(L, 2, request);
+ request_SetContentType(L, 3, request);
+
+ response_Create(L, request);
+
+ return 1;
+}
+
+static int request_Put(lua_State *L)
+{
+ NETLIBHTTPREQUEST *request = CreateRequest(L);
+ request->requestType = REQUEST_PUT;
+ request_SetUrl(L, 1, request);
+ request_SetContent(L, 2, request);
+ request_SetContentType(L, 3, request);
+
+ response_Create(L, request);
+
+ return 1;
+}
+
+static int request_Delete(lua_State *L)
+{
+ NETLIBHTTPREQUEST *request = CreateRequest(L);
+ request->requestType = REQUEST_DELETE;
+ request_SetUrl(L, 1, request);
+ request_SetContent(L, 2, request);
+ request_SetContentType(L, 2, request);
+
+ response_Create(L, request);
+
+ return 1;
+}
+
+static int request__gc(lua_State *L)
+{
+ NETLIBHTTPREQUEST **request = (NETLIBHTTPREQUEST**)luaL_checkudata(L, 1, MT_NETLIBHTTPREQUEST);
+
+ mir_free((*request)->szUrl);
+ for (size_t i = 0; i < (*request)->headersCount; i++) {
+ mir_free((*request)->headers[i].szName);
+ mir_free((*request)->headers[i].szValue);
+ }
+ mir_free((*request)->headers);
+ mir_free((*request)->pData);
+
+ return 0;
+}
+
+static const luaL_Reg requestApi[] =
+{
+ { "__gc", request__gc },
+
+ { NULL, NULL }
+};
+
+/***********************************************/
+
+static const luaL_Reg httpApi[] =
+{
+ { "Send", request_Send },
+ { "Get", request_Get },
+ { "Post", request_Post },
+ { "Put", request_Put },
+ { "Delete", request_Delete },
+
+ { NULL, NULL }
+};
+
+LUAMOD_API int luaopen_m_http(lua_State *L)
+{
+ luaL_newlib(L, httpApi);
+
+ luaL_newmetatable(L, MT_NETLIBHTTPREQUEST);
+ luaL_setfuncs(L, requestApi, 0);
+ lua_pop(L, 1);
+
+ luaL_newmetatable(L, MT_NETLIBHTTPRESPONSE);
+ luaL_setfuncs(L, responseApi, 0);
+ lua_pop(L, 1);
+
+ luaL_newmetatable(L, MT_NETLIBHTTPHEADERS);
+ luaL_setfuncs(L, headersApi, 0);
+ lua_pop(L, 1);
+
+ luaL_newmetatable(L, MT_NETLIBHTTPCONTENT);
+ luaL_setfuncs(L, contentApi, 0);
+ lua_pop(L, 1);
+
+ return 1;
+}
diff --git a/plugins/MirLua/Modules/m_json/src/metatable.cpp b/plugins/MirLua/src/m_json.cpp
index d7bfab5583..e4bbf233ef 100644
--- a/plugins/MirLua/Modules/m_json/src/metatable.cpp
+++ b/plugins/MirLua/src/m_json.cpp
@@ -1,135 +1,227 @@
-#include "stdafx.h"
-
-void lua2json(lua_State *L, JSONNode &node)
-{
- switch (lua_type(L, -1))
- {
- case LUA_TNIL:
- node.nullify();
- break;
- case LUA_TSTRING:
- node = lua_tostring(L, -1);
- break;
- case LUA_TBOOLEAN:
- node = lua_toboolean(L, -1) != 0;
- break;
- case LUA_TNUMBER:
- {
- lua_Integer val = lua_tointeger(L, -1);
- if (lua_isinteger(L, -1) && val >= LONG_MIN && val <= LONG_MIN)
- node = (long)val;
- else
- node = lua_tonumber(L, -1);
- break;
- }
- case LUA_TTABLE:
- {
- ptrA name(mir_strdup(node.name()));
- node.cast(JSON_ARRAY);
- node.set_name((char*)name);
-
- lua_pushnil(L);
- while (lua_next(L, -2) != 0) {
- JSONNode child;
- if (!lua_isnumber(L, -2)) {
- if (node.type() == JSON_ARRAY) {
- node.cast(JSON_NODE);
- node.set_name((char*)name);
- }
- const char *key = lua_tostring(L, -2);
- child.set_name(key);
- }
- lua2json(L, child);
- node << child;
-
- lua_pop(L, 1);
- }
-
- break;
- }
- }
-}
-
-static int json__index(lua_State *L)
-{
- JSONNode &node = *((JSON*)luaL_checkudata(L, 1, MT_JSON))->node;
-
- switch (node.type())
- {
- case JSON_NULL:
- lua_pushnil(L);
- break;
- case JSON_STRING:
- lua_pushstring(L, node.as_string().c_str());
- break;
- case JSON_NUMBER:
- lua_pushnumber(L, node.as_int());
- break;
- case JSON_BOOL:
- lua_pushboolean(L, node.as_bool());
- break;
- case JSON_NODE:
- case JSON_ARRAY:
- new (L) JSONNode(node);
- luaL_setmetatable(L, MT_JSON);
- }
-
- return 1;
-}
-
-static int json__newindex(lua_State *L)
-{
- JSONNode &node = *((JSON*)luaL_checkudata(L, 1, MT_JSON))->node;
- const char *key = lua_tostring(L, 2);
-
- JSONNode child = node[key];
- if (child.isnull()) {
- child.set_name(key);
- lua2json(L, child);
- node << child;
- return 0;
- }
-
- lua2json(L, child);
- node[key] = child;
-
- return 0;
-}
-
-static int json__len(lua_State *L)
-{
- JSONNode &node = *((JSON*)luaL_checkudata(L, 1, MT_JSON))->node;
-
- lua_pushnumber(L, node.size());
-
- return 1;
-}
-
-static int json__tostring(lua_State *L)
-{
- JSONNode &node = *((JSON*)luaL_checkudata(L, 1, MT_JSON))->node;
-
- lua_pushstring(L, node.write().c_str());
-
- return 1;
-}
-
-static int json__gc(lua_State *L)
-{
- JSON *json = (JSON*)luaL_checkudata(L, 1, MT_JSON);
-
- delete json;
-
- return 0;
-}
-
-const struct luaL_Reg jsonApi[] =
-{
- { "__index", json__index },
- { "__newindex", json__newindex },
- { "__len", json__len },
- { "__tostring", json__tostring },
- { "__gc", json__gc },
-
- { NULL, NULL }
-};
+#include "stdafx.h"
+
+static void lua2json(lua_State *L, JSONNode &node)
+{
+ switch (lua_type(L, -1))
+ {
+ case LUA_TNIL:
+ node.nullify();
+ break;
+ case LUA_TSTRING:
+ node = lua_tostring(L, -1);
+ break;
+ case LUA_TBOOLEAN:
+ node = lua_toboolean(L, -1) != 0;
+ break;
+ case LUA_TNUMBER:
+ {
+ lua_Integer val = lua_tointeger(L, -1);
+ if (lua_isinteger(L, -1) && val >= LONG_MIN && val <= LONG_MIN)
+ node = (long)val;
+ else
+ node = lua_tonumber(L, -1);
+ break;
+ }
+ case LUA_TTABLE:
+ {
+ ptrA name(mir_strdup(node.name()));
+ node.cast(JSON_ARRAY);
+ node.set_name((char*)name);
+
+ lua_pushnil(L);
+ while (lua_next(L, -2) != 0) {
+ JSONNode child;
+ if (!lua_isnumber(L, -2)) {
+ if (node.type() == JSON_ARRAY) {
+ node.cast(JSON_NODE);
+ node.set_name((char*)name);
+ }
+ const char *key = lua_tostring(L, -2);
+ child.set_name(key);
+ }
+ lua2json(L, child);
+ node << child;
+
+ lua_pop(L, 1);
+ }
+
+ break;
+ }
+ }
+}
+
+/***********************************************/
+
+static int json__index(lua_State *L)
+{
+ JSONNode &node = *((JSON*)luaL_checkudata(L, 1, MT_JSON))->node;
+
+ switch (node.type())
+ {
+ case JSON_NULL:
+ lua_pushnil(L);
+ break;
+ case JSON_STRING:
+ lua_pushstring(L, node.as_string().c_str());
+ break;
+ case JSON_NUMBER:
+ lua_pushnumber(L, node.as_int());
+ break;
+ case JSON_BOOL:
+ lua_pushboolean(L, node.as_bool());
+ break;
+ case JSON_NODE:
+ case JSON_ARRAY:
+ new (L) JSONNode(node);
+ luaL_setmetatable(L, MT_JSON);
+ }
+
+ return 1;
+}
+
+static int json__newindex(lua_State *L)
+{
+ JSONNode &node = *((JSON*)luaL_checkudata(L, 1, MT_JSON))->node;
+ const char *key = lua_tostring(L, 2);
+
+ JSONNode child = node[key];
+ if (child.isnull()) {
+ child.set_name(key);
+ lua2json(L, child);
+ node << child;
+ return 0;
+ }
+
+ lua2json(L, child);
+ node[key] = child;
+
+ return 0;
+}
+
+static int json__len(lua_State *L)
+{
+ JSONNode &node = *((JSON*)luaL_checkudata(L, 1, MT_JSON))->node;
+
+ lua_pushnumber(L, node.size());
+
+ return 1;
+}
+
+static int json__tostring(lua_State *L)
+{
+ JSONNode &node = *((JSON*)luaL_checkudata(L, 1, MT_JSON))->node;
+
+ lua_pushstring(L, node.write().c_str());
+
+ return 1;
+}
+
+static int json__gc(lua_State *L)
+{
+ JSON *json = (JSON*)luaL_checkudata(L, 1, MT_JSON);
+
+ delete json;
+
+ return 0;
+}
+
+const struct luaL_Reg jsonApi[] =
+{
+ { "__index", json__index },
+ { "__newindex", json__newindex },
+ { "__len", json__len },
+ { "__tostring", json__tostring },
+ { "__gc", json__gc },
+
+ { NULL, NULL }
+};
+
+
+/***********************************************/
+
+static int lua_Decode(lua_State *L)
+{
+ const char *string = luaL_checkstring(L, 1);
+
+ JSONNode *node = json_parse(string);
+ new (L) JSON(node);
+ luaL_setmetatable(L, MT_JSON);
+
+ return 1;
+}
+
+static int lua_Encode(lua_State *L)
+{
+ switch (lua_type(L, 1))
+ {
+ case LUA_TNIL:
+ lua_pushliteral(L, "null");
+ break;
+ case LUA_TBOOLEAN:
+ lua_pushstring(L, lua_toboolean(L, 1) ? "true" : "false");
+ break;
+ case LUA_TNUMBER:
+ {
+ if (lua_isinteger(L, 1)) {
+ lua_pushfstring(L, "%I", lua_tointeger(L, 1));
+ break;
+ }
+ char decpoint = lua_getlocaledecpoint();
+ if (decpoint != '.') {
+ char p[2] = { decpoint };
+ luaL_gsub(L, lua_tostring(L, 1), p, ".");
+ }
+ else
+ lua_pushfstring(L, "%f", lua_tonumber(L, 1));
+ break;
+ }
+ case LUA_TSTRING:
+ lua_pushfstring(L, "\"%s\"", lua_tostring(L, 1));
+ break;
+ case LUA_TTABLE:
+ {
+ JSONNode node;
+ lua_pushnil(L);
+ lua_pushvalue(L, 1);
+ lua2json(L, node);
+ lua_pop(L, 2);
+ lua_pushstring(L, node.write().c_str());
+ break;
+ }
+ case LUA_TUSERDATA:
+ {
+ JSONNode &node = *((JSON*)luaL_checkudata(L, 1, MT_JSON))->node;
+ lua_pushstring(L, node.write().c_str());
+ break;
+ }
+ case LUA_TLIGHTUSERDATA:
+ if (lua_touserdata(L, 1) == NULL)
+ {
+ lua_pushliteral(L, "null");
+ break;
+ }
+ default:
+ luaL_argerror(L, 1, luaL_typename(L, 1));
+ }
+
+ return 1;
+}
+
+static const luaL_Reg methods[] =
+{
+ { "Decode", lua_Decode },
+ { "Encode", lua_Encode },
+
+ { NULL, NULL }
+};
+
+LUAMOD_API int luaopen_m_json(lua_State *L)
+{
+ luaL_newlib(L, methods);
+
+ luaL_newmetatable(L, MT_JSON);
+ luaL_setfuncs(L, jsonApi, 0);
+ lua_pop(L, 1);
+
+ return 1;
+} \ No newline at end of file
diff --git a/plugins/MirLua/Modules/m_json/src/stdafx.h b/plugins/MirLua/src/m_json.h
index dcbdfbd56d..bb3a2e1568 100644
--- a/plugins/MirLua/Modules/m_json/src/stdafx.h
+++ b/plugins/MirLua/src/m_json.h
@@ -1,35 +1,32 @@
-#pragma once
-
-#include <Windows.h>
-#include <lua.hpp>
-#include <m_system.h>
-
-#include <m_json.h>
-#include <m_string.h>
-
-struct JSON
-{
- JSONNode *node;
- bool bDelete;
-
- JSON(JSONNode &refNode, bool bCopy = false)
- : node(bCopy ? json_copy(&refNode) : &refNode), bDelete(bCopy) { }
- JSON(JSONNode *n, bool bD = true)
- : node(n), bDelete(bD) { }
- ~JSON()
- {
- if (bDelete)
- json_delete(node);
- }
-
- __inline void* operator new(size_t size, lua_State *L)
- {
- return lua_newuserdata(L, size);
- }
-};
-
-void lua2json(lua_State *L, JSONNode &node);
-
-extern const luaL_Reg jsonApi[];
-
-#define MT_JSON "JSON" \ No newline at end of file
+#ifndef _LUA_M_JSON_H_
+#define _LUA_M_JSON_H_
+
+#include <m_json.h>
+
+struct JSON
+{
+ JSONNode *node;
+ bool bDelete;
+
+ JSON(JSONNode &refNode, bool bCopy = false)
+ : node(bCopy ? json_copy(&refNode) : &refNode), bDelete(bCopy) { }
+ JSON(JSONNode *n, bool bD = true)
+ : node(n), bDelete(bD) { }
+ ~JSON()
+ {
+ if (bDelete)
+ json_delete(node);
+ }
+
+ __inline void* operator new(size_t size, lua_State *L)
+ {
+ return lua_newuserdata(L, size);
+ }
+};
+
+#define MT_JSON "JSON"
+
+#define MLUA_JSON "m_json"
+LUAMOD_API int (luaopen_m_json)(lua_State *L);
+
+#endif //_LUA_M_PROTOCOLS_H_ \ No newline at end of file
diff --git a/plugins/MirLua/src/m_protocols.cpp b/plugins/MirLua/src/m_protocols.cpp
index 42b24c4936..ab206489f2 100644
--- a/plugins/MirLua/src/m_protocols.cpp
+++ b/plugins/MirLua/src/m_protocols.cpp
@@ -64,6 +64,21 @@ static int lua_Protocols(lua_State *L)
return 1;
}
+static int lua_RegisterProtocol(lua_State *L)
+{
+ ptrA name(mir_utf8decodeA(luaL_checkstring(L, 1)));
+
+ PROTOCOLDESCRIPTOR pd = { 0 };
+ pd.cbSize = sizeof(pd);
+ pd.szName = name;
+ pd.type = PROTOTYPE_PROTOCOL;
+ int res = Proto_RegisterModule(&pd);
+
+ lua_pushboolean(L, res == 0);
+
+ return 1;
+}
+
static int lua_ChainSend(lua_State *L)
{
MCONTACT hContact = luaL_checknumber(L, 1);
@@ -222,6 +237,7 @@ static luaL_Reg protocolsApi[] =
{
{ "GetProtocol", lua_GetProtocol },
{ "Protocols", lua_Protocols },
+ { "RegisterProtocol", lua_Protocols },
{ "CallSendChain", lua_ChainSend },
{ "CallReceiveChain", lua_ChainRecv },
diff --git a/plugins/MirLua/src/main.cpp b/plugins/MirLua/src/main.cpp
index 0dd0488d5c..7cb6ce4981 100644
--- a/plugins/MirLua/src/main.cpp
+++ b/plugins/MirLua/src/main.cpp
@@ -76,7 +76,7 @@ extern "C" int __declspec(dllexport) Load(void)
HookEvent(ME_SYSTEM_MODULESLOADED, OnModulesLoaded);
NETLIBUSER nlu = {};
- nlu.flags = NUF_NOOPTIONS;
+ nlu.flags = NUF_OUTGOING | NUF_INCOMING | NUF_HTTPCONNS;
nlu.szDescriptiveName.a = MODULE;
nlu.szSettingsModule = MODULE;
hNetlib = Netlib_RegisterUser(&nlu);
diff --git a/plugins/MirLua/src/mlua.cpp b/plugins/MirLua/src/mlua.cpp
index d3ded45a40..952e528e44 100644
--- a/plugins/MirLua/src/mlua.cpp
+++ b/plugins/MirLua/src/mlua.cpp
@@ -39,12 +39,13 @@ static int mlua_print(lua_State *L)
break;
case LUA_TNUMBER:
data.AppendFormat("%s", lua_tostring(L, i));
+ break;
case LUA_TSTRING:
data.AppendFormat("'%s'", lua_tostring(L, i));
break;
default:
if (luaL_callmeta(L, i, "__tostring")) {
- data.AppendFormat("[[%s]]", lua_tostring(L, i));
+ data.AppendFormat("'%s'", lua_tostring(L, -1));
break;
}
data.AppendFormat("%s(0x%p)", luaL_typename(L, i), lua_topointer(L, i));
@@ -142,24 +143,19 @@ static int mlua_interpolate(lua_State *L)
char pattern[128];
- if (lua_istable(L, 2))
- {
- for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 2))
- {
+ if (lua_istable(L, 2)) {
+ for (lua_pushnil(L); lua_next(L, 2); lua_pop(L, 2)) {
lua_pushvalue(L, -2);
const char *key = lua_tostring(L, -1);
const char *val = lua_tostring(L, -2);
mir_snprintf(pattern, "{%s}", key);
string = luaL_gsub(L, string, pattern, val);
- lua_pop(L, 1);
}
}
- else
- {
+ else {
int nargs = lua_gettop(L);
- for (int i = 2; i <= nargs; i++)
- {
+ for (int i = 2; i <= nargs; i++) {
const char *val = lua_tostring(L, i);
mir_snprintf(pattern, "{%d}", i - 1);
diff --git a/plugins/MirLua/src/mlua_module_loader.cpp b/plugins/MirLua/src/mlua_module_loader.cpp
index a35801373a..c28e6edaeb 100644
--- a/plugins/MirLua/src/mlua_module_loader.cpp
+++ b/plugins/MirLua/src/mlua_module_loader.cpp
@@ -30,9 +30,11 @@ void CMLuaModuleLoader::LoadModules()
Preload(MLUA_CHAT, luaopen_m_chat);
Preload(MLUA_CLIST, luaopen_m_clist);
Preload(MLUA_DATABASE, luaopen_m_database);
- Preload(MLUA_ICOLIB, luaopen_m_icolib);
Preload(MLUA_GENMENU, luaopen_m_genmenu);
Preload(MLUA_HOTKEYS, luaopen_m_hotkeys);
+ Preload(MLUA_HTTP, luaopen_m_http);
+ Preload(MLUA_ICOLIB, luaopen_m_icolib);
+ Preload(MLUA_JSON, luaopen_m_json);
Preload(MLUA_MESSAGE, luaopen_m_message);
Preload(MLUA_OPTIONS, luaopen_m_options);
Preload(MLUA_PROTOCOLS, luaopen_m_protocols);
diff --git a/plugins/MirLua/src/mlua_script.cpp b/plugins/MirLua/src/mlua_script.cpp
index 8b56674230..ad70bef24c 100644
--- a/plugins/MirLua/src/mlua_script.cpp
+++ b/plugins/MirLua/src/mlua_script.cpp
@@ -44,7 +44,6 @@ CMLuaScript::~CMLuaScript()
lua_pop(L, 1);
mir_free(moduleName);
- mir_free(fileName);
}
const char* CMLuaScript::GetModuleName() const
diff --git a/plugins/MirLua/src/stdafx.h b/plugins/MirLua/src/stdafx.h
index 08b15a246e..4b5ad5a78b 100644
--- a/plugins/MirLua/src/stdafx.h
+++ b/plugins/MirLua/src/stdafx.h
@@ -11,7 +11,7 @@
#include <m_langpack.h>
#include <m_options.h>
#include <m_netlib.h>
-
+#include <m_http.h>
#include <m_clist.h>
#include <m_hotkeys.h>
#include <m_icolib.h>
@@ -20,7 +20,6 @@
#include <m_chat.h>
#include <m_protocols.h>
#include <m_contacts.h>
-
#include <m_folders.h>
#include <m_popup.h>
#include <m_toptoolbar.h>
@@ -73,8 +72,13 @@ LUAMOD_API int (luaopen_m_clist)(lua_State *L);
#define MLUA_ICOLIB "m_icolib"
LUAMOD_API int (luaopen_m_icolib)(lua_State *L);
+#include "m_json.h"
+
#include "m_genmenu.h"
+#define MLUA_HTTP "m_http"
+LUAMOD_API int (luaopen_m_http)(lua_State *L);
+
#define MLUA_HOTKEYS "m_hotkeys"
LUAMOD_API int (luaopen_m_hotkeys)(lua_State *L);
diff --git a/plugins/MirLua/src/version.h b/plugins/MirLua/src/version.h
index 4f3f3a4c6e..1525666f2a 100644
--- a/plugins/MirLua/src/version.h
+++ b/plugins/MirLua/src/version.h
@@ -1,7 +1,7 @@
#define __MAJOR_VERSION 0
#define __MINOR_VERSION 11
#define __RELEASE_NUM 8
-#define __BUILD_NUM 4
+#define __BUILD_NUM 5
#include <stdver.h>