diff options
-rw-r--r-- | plugins/MirLua/Modules/m_json/m_json.vcxproj | 28 | ||||
-rw-r--r-- | plugins/MirLua/Modules/m_json/src/main.cpp | 88 | ||||
-rw-r--r-- | plugins/MirLua/Modules/m_json/src/stdafx.cxx | 1 | ||||
-rw-r--r-- | plugins/MirLua/src/m_hotkeys.cpp | 6 | ||||
-rw-r--r-- | plugins/MirLua/src/m_http.cpp | 443 | ||||
-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.cpp | 16 | ||||
-rw-r--r-- | plugins/MirLua/src/main.cpp | 2 | ||||
-rw-r--r-- | plugins/MirLua/src/mlua.cpp | 16 | ||||
-rw-r--r-- | plugins/MirLua/src/mlua_module_loader.cpp | 4 | ||||
-rw-r--r-- | plugins/MirLua/src/mlua_script.cpp | 1 | ||||
-rw-r--r-- | plugins/MirLua/src/stdafx.h | 8 | ||||
-rw-r--r-- | plugins/MirLua/src/version.h | 2 |
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>
|