From 6f99f13cf590c323fd5bd5b4d6855e59f582fb0e Mon Sep 17 00:00:00 2001 From: aunsane Date: Tue, 12 Sep 2017 22:02:30 +0300 Subject: MirLua: massive refactoring - m_msg_buttonbar moved to m_srrm - version bump --- plugins/MirLua/MirLua.vcxproj | 3 +- plugins/MirLua/Modules/m_enumerable/src/main.cpp | 10 +- .../m_msg_buttonsbar/m_msg_buttonsbar.vcxproj | 33 ---- .../MirLua/Modules/m_msg_buttonsbar/src/main.cpp | 146 --------------- .../MirLua/Modules/m_msg_buttonsbar/src/stdafx.cxx | 1 - .../MirLua/Modules/m_msg_buttonsbar/src/stdafx.h | 12 -- plugins/MirLua/Modules/m_toptoolbar/src/main.cpp | 20 ++- plugins/MirLua/Modules/m_toptoolbar/src/stdafx.h | 2 +- plugins/MirLua/include/mirlua.h | 23 +++ plugins/MirLua/src/m_core.cpp | 57 +++--- plugins/MirLua/src/m_database.cpp | 44 +++-- plugins/MirLua/src/m_database.h | 9 + plugins/MirLua/src/m_genmenu.h | 2 + plugins/MirLua/src/m_hotkeys.cpp | 2 +- plugins/MirLua/src/m_icolib.cpp | 136 +++++++++++--- plugins/MirLua/src/m_protocols.cpp | 124 ++++++------- plugins/MirLua/src/m_protocols.h | 3 + plugins/MirLua/src/m_sounds.cpp | 12 +- plugins/MirLua/src/m_srmm.cpp | 108 +++++++++++ plugins/MirLua/src/mlua.cpp | 183 ++++++++++++++++++- plugins/MirLua/src/mlua_metatable.h | 48 +++-- plugins/MirLua/src/mlua_module_loader.cpp | 1 + plugins/MirLua/src/mlua_options.h | 2 + plugins/MirLua/src/mlua_script.cpp | 33 +--- plugins/MirLua/src/mlua_script.h | 2 - plugins/MirLua/src/mlua_utils.cpp | 199 ++------------------- plugins/MirLua/src/stdafx.h | 28 +-- plugins/MirLua/src/version.h | 2 +- 28 files changed, 641 insertions(+), 604 deletions(-) delete mode 100644 plugins/MirLua/Modules/m_msg_buttonsbar/m_msg_buttonsbar.vcxproj delete mode 100644 plugins/MirLua/Modules/m_msg_buttonsbar/src/main.cpp delete mode 100644 plugins/MirLua/Modules/m_msg_buttonsbar/src/stdafx.cxx delete mode 100644 plugins/MirLua/Modules/m_msg_buttonsbar/src/stdafx.h create mode 100644 plugins/MirLua/include/mirlua.h create mode 100644 plugins/MirLua/src/m_database.h create mode 100644 plugins/MirLua/src/m_srmm.cpp (limited to 'plugins') diff --git a/plugins/MirLua/MirLua.vcxproj b/plugins/MirLua/MirLua.vcxproj index 2df46203b7..1872992a5f 100644 --- a/plugins/MirLua/MirLua.vcxproj +++ b/plugins/MirLua/MirLua.vcxproj @@ -34,10 +34,11 @@ Sync - $(ProjectDir)..\..\libs\liblua\include;%(AdditionalIncludeDirectories) + $(ProjectDir)..\..\libs\liblua\include;$(ProjectDir)include;%(AdditionalIncludeDirectories) + diff --git a/plugins/MirLua/Modules/m_enumerable/src/main.cpp b/plugins/MirLua/Modules/m_enumerable/src/main.cpp index b905b18b62..8494c1385a 100644 --- a/plugins/MirLua/Modules/m_enumerable/src/main.cpp +++ b/plugins/MirLua/Modules/m_enumerable/src/main.cpp @@ -429,9 +429,6 @@ extern "C" LUAMOD_API int luaopen_m_enumerable(lua_State *L) { luaL_newlib(L, methods); - lua_pushcfunction(L, lua__new); - lua_setglobal(L, MT_ENUMERABLE); - luaL_newmetatable(L, MT_ENUMERABLE); luaL_setfuncs(L, enumerableMeta, 0); lua_pushvalue(L, -1); @@ -439,5 +436,12 @@ extern "C" LUAMOD_API int luaopen_m_enumerable(lua_State *L) luaL_setfuncs(L, enumerableApi, 0); lua_pop(L, 1); + lua_createtable(L, 0, 1); + lua_pushcfunction(L, lua__new); + lua_setfield(L, -2, "new"); + lua_pushvalue(L, -1); + lua_setglobal(L, MT_ENUMERABLE); + lua_pop(L, 1); + return 1; } diff --git a/plugins/MirLua/Modules/m_msg_buttonsbar/m_msg_buttonsbar.vcxproj b/plugins/MirLua/Modules/m_msg_buttonsbar/m_msg_buttonsbar.vcxproj deleted file mode 100644 index 4da3d4da50..0000000000 --- a/plugins/MirLua/Modules/m_msg_buttonsbar/m_msg_buttonsbar.vcxproj +++ /dev/null @@ -1,33 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - m_msg_buttonsbar - {DCBE5EC2-84B2-4C03-810C-BD13D975D8D9} - - - - - - - Sync - - - diff --git a/plugins/MirLua/Modules/m_msg_buttonsbar/src/main.cpp b/plugins/MirLua/Modules/m_msg_buttonsbar/src/main.cpp deleted file mode 100644 index d2a35adc46..0000000000 --- a/plugins/MirLua/Modules/m_msg_buttonsbar/src/main.cpp +++ /dev/null @@ -1,146 +0,0 @@ -#include "stdafx.h" - -int hLangpack = 0; - -static BBButton* MakeBBButton(lua_State *L) -{ - BBButton *bbb = (BBButton*)mir_calloc(sizeof(BBButton)); - bbb->dwDefPos = 100; - - lua_getfield(L, -1, "Module"); - bbb->pszModuleName = mir_utf8decodeA(luaL_checkstring(L, -1)); - lua_pop(L, 1); - - lua_getfield(L, -1, "ButtonID"); - bbb->dwButtonID = luaL_checkinteger(L, -1); - lua_pop(L, 1); - - lua_getfield(L, -1, "Flags"); - bbb->bbbFlags = lua_tointeger(L, -1); - lua_pop(L, 1); - - lua_getfield(L, -1, "Tooltip"); - bbb->pwszTooltip = mir_utf8decodeW(lua_tostring(L, -1)); - lua_pop(L, 1); - - lua_getfield(L, -1, "Icon"); - bbb->hIcon = (HANDLE)lua_touserdata(L, -1); - lua_pop(L, 1); - - return bbb; -} - -static int lua_AddButton(lua_State *L) -{ - if (lua_type(L, 1) != LUA_TTABLE) - { - lua_pushlightuserdata(L, 0); - return 1; - } - - BBButton* bbb = MakeBBButton(L); - - INT_PTR res = Srmm_AddButton(bbb); - lua_pushinteger(L, res); - - return 1; -} - -static int lua_ModifyButton(lua_State *L) -{ - if (lua_type(L, 1) != LUA_TTABLE) - { - lua_pushlightuserdata(L, 0); - return 1; - } - - BBButton* bbb = MakeBBButton(L); - - INT_PTR res = Srmm_ModifyButton(bbb); - lua_pushinteger(L, res); - - mir_free((void*)bbb->pszModuleName); - mir_free((void*)bbb->pwszTooltip); - mir_free(bbb); - - return 1; -} - -static int lua_RemoveButton(lua_State *L) -{ - ptrA szModuleName(mir_utf8decodeA(luaL_checkstring(L, 1))); - - BBButton mbb = {}; - mbb.pszModuleName = szModuleName; - mbb.dwButtonID = luaL_checkinteger(L, 2); - - INT_PTR res = ::Srmm_RemoveButton(&mbb); - lua_pushinteger(L, res); - - return 1; -} - -static luaL_Reg msgbuttinsbarApi[] = -{ - { "AddButton", lua_AddButton }, - { "ModifyButton", lua_ModifyButton }, - { "RemoveButton", lua_RemoveButton }, - - { NULL, NULL } -}; - -/***********************************************/ - -#define MT_CUSTOMBUTTONCLICKDATA "CustomButtonClickData" - -static int bcd_new(lua_State *L) -{ - CustomButtonClickData *bcd = (CustomButtonClickData*)lua_touserdata(L, 1); - if (bcd == NULL) - { - lua_pushnil(L); - return 1; - } - - CustomButtonClickData **udata = (CustomButtonClickData**)lua_newuserdata(L, sizeof(CustomButtonClickData*)); - *udata = bcd; - - luaL_setmetatable(L, MT_CUSTOMBUTTONCLICKDATA); - - return 1; -} - -static int bcd__index(lua_State *L) -{ - CustomButtonClickData *bcd = *(CustomButtonClickData**)luaL_checkudata(L, 1, MT_CUSTOMBUTTONCLICKDATA); - const char *key = lua_tostring(L, 2); - - if (mir_strcmpi(key, "Module") == 0) - lua_pushstring(L, ptrA(mir_utf8encode(bcd->pszModule))); - else if (mir_strcmpi(key, "ButtonID") == 0) - lua_pushinteger(L, bcd->dwButtonId); - else if (mir_strcmpi(key, "hContact") == 0) - lua_pushinteger(L, bcd->hContact); - else if (mir_strcmpi(key, "Flags") == 0) - lua_pushinteger(L, bcd->flags); - else - lua_pushnil(L); - - return 1; -} - -/***********************************************/ - -extern "C" LUAMOD_API int luaopen_m_msg_buttonsbar(lua_State *L) -{ - luaL_newlib(L, msgbuttinsbarApi); - - lua_register(L, MT_CUSTOMBUTTONCLICKDATA, bcd_new); - - luaL_newmetatable(L, MT_CUSTOMBUTTONCLICKDATA); - lua_pushcfunction(L, bcd__index); - lua_setfield(L, -2, "__index"); - lua_pop(L, 1); - - return 1; -} diff --git a/plugins/MirLua/Modules/m_msg_buttonsbar/src/stdafx.cxx b/plugins/MirLua/Modules/m_msg_buttonsbar/src/stdafx.cxx deleted file mode 100644 index fd4f341c7b..0000000000 --- a/plugins/MirLua/Modules/m_msg_buttonsbar/src/stdafx.cxx +++ /dev/null @@ -1 +0,0 @@ -#include "stdafx.h" diff --git a/plugins/MirLua/Modules/m_msg_buttonsbar/src/stdafx.h b/plugins/MirLua/Modules/m_msg_buttonsbar/src/stdafx.h deleted file mode 100644 index 39dfe8a861..0000000000 --- a/plugins/MirLua/Modules/m_msg_buttonsbar/src/stdafx.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef _COMMON_H_ -#define _COMMON_H_ - -#include - -#include - -#include -#include -#include - -#endif //_COMMON_H_ \ No newline at end of file diff --git a/plugins/MirLua/Modules/m_toptoolbar/src/main.cpp b/plugins/MirLua/Modules/m_toptoolbar/src/main.cpp index af73c963ce..17a8d95b00 100644 --- a/plugins/MirLua/Modules/m_toptoolbar/src/main.cpp +++ b/plugins/MirLua/Modules/m_toptoolbar/src/main.cpp @@ -29,11 +29,11 @@ static TTBButton* MakeTBButton(lua_State *L) lua_pop(L, 1); lua_getfield(L, -1, "wParamUp"); - tbb->wParamUp = (WPARAM)lua_touserdata(L, -1); + tbb->wParamUp = (WPARAM)luaM_tomparam(L, -1); lua_pop(L, 1); lua_getfield(L, -1, "lParamUp"); - tbb->lParamUp = (LPARAM)lua_touserdata(L, -1); + tbb->lParamUp = (LPARAM)luaM_tomparam(L, -1); lua_pop(L, 1); // dn state @@ -46,11 +46,11 @@ static TTBButton* MakeTBButton(lua_State *L) lua_pop(L, 1); lua_getfield(L, -1, "wParamDown"); - tbb->wParamDown = (WPARAM)lua_touserdata(L, -1); + tbb->wParamDown = (WPARAM)luaM_tomparam(L, -1); lua_pop(L, 1); lua_getfield(L, -1, "lParamDown"); - tbb->lParamDown = (LPARAM)lua_touserdata(L, -1); + tbb->lParamDown = (LPARAM)luaM_tomparam(L, -1); lua_pop(L, 1); return tbb; @@ -64,9 +64,15 @@ static int lua_AddButton(lua_State *L) return 1; } - TTBButton* tbb = MakeTBButton(L); + TTBButton *tbb = MakeTBButton(L); + + HANDLE res = TopToolbar_AddButton(tbb); + if (res == (HANDLE)-1) + { + lua_pushnil(L); + return 1; + } - HANDLE res = ::TopToolbar_AddButton(tbb); lua_pushlightuserdata(L, res); mir_free(tbb->name); @@ -81,7 +87,7 @@ static int lua_RemoveButton(lua_State *L) { HANDLE hTTButton = (HANDLE)lua_touserdata(L, 1); - INT_PTR res = ::CallService(MS_TTB_REMOVEBUTTON, (WPARAM)hTTButton, 0); + INT_PTR res = CallService(MS_TTB_REMOVEBUTTON, (WPARAM)hTTButton, 0); lua_pushinteger(L, res); return 1; diff --git a/plugins/MirLua/Modules/m_toptoolbar/src/stdafx.h b/plugins/MirLua/Modules/m_toptoolbar/src/stdafx.h index d69907bf2c..45e1eea058 100644 --- a/plugins/MirLua/Modules/m_toptoolbar/src/stdafx.h +++ b/plugins/MirLua/Modules/m_toptoolbar/src/stdafx.h @@ -3,7 +3,7 @@ #include -#include +#include #include #include diff --git a/plugins/MirLua/include/mirlua.h b/plugins/MirLua/include/mirlua.h new file mode 100644 index 0000000000..eee10289bb --- /dev/null +++ b/plugins/MirLua/include/mirlua.h @@ -0,0 +1,23 @@ +#ifndef _MIRLUA_H_ +#define _MIRLUA_H_ + +#include + +__forceinline UINT_PTR luaM_tomparam(lua_State *L, int idx) +{ + switch (lua_type(L, idx)) + { + case LUA_TBOOLEAN: + return lua_toboolean(L, idx); + case LUA_TSTRING: + return (UINT_PTR)lua_tostring(L, idx); + case LUA_TLIGHTUSERDATA: + return (UINT_PTR)lua_touserdata(L, idx); + case LUA_TNUMBER: + if (lua_isinteger(L, idx)) + return (UINT_PTR)lua_tointeger(L, idx); + } + return NULL; +} + +#endif //_MIRLUA_H_ \ No newline at end of file diff --git a/plugins/MirLua/src/m_core.cpp b/plugins/MirLua/src/m_core.cpp index c58ce9cf1f..2042aa57bd 100644 --- a/plugins/MirLua/src/m_core.cpp +++ b/plugins/MirLua/src/m_core.cpp @@ -86,6 +86,36 @@ static int core_HookEvent(lua_State *L) return 1; } +static int core_HookTemporaryEvent(lua_State *L) +{ + const char *name = luaL_checkstring(L, 1); + luaL_checktype(L, 2, LUA_TFUNCTION); + + lua_pushvalue(L, 2); + int ref = luaL_ref(L, LUA_REGISTRYINDEX); + + HANDLE res = NULL; + CMLuaScript *script = CMLuaScript::GetScriptFromEnviroment(L); + if (script) + res = HookEventObjParam(name, HookEventScriptParam, script, ref); + else + res = HookEventObjParam(name, HookEventLuaStateParam, L, ref); + // event does not exists, call hook immideatelly + if (res == NULL) + { + lua_pushnil(L); + lua_pushnil(L); + luaM_pcall(L, 2, 1); + return lua_tointeger(script->L, -1); + } + + CMLua::HookRefs.insert(new HandleRefParam(L, res, ref)); + + lua_pushlightuserdata(L, res); + + return 1; +} + static int core_UnhookEvent(lua_State *L) { luaL_checktype(L, 1, LUA_TLIGHTUSERDATA); @@ -120,17 +150,6 @@ static int core_NotifyEventHooks(lua_State *L) return 1; } -static int core_DestroyHookableEvent(lua_State *L) -{ - luaL_checktype(L, 1, LUA_TLIGHTUSERDATA); - HANDLE hEvent = lua_touserdata(L, 1); - - int res = DestroyHookableEvent(hEvent); - lua_pushboolean(L, !res); - - return 1; -} - /***********************************************/ INT_PTR CreateServiceFunctionLuaStateParam(void *obj, WPARAM wParam, LPARAM lParam, LPARAM param) @@ -250,16 +269,6 @@ static int core_IsPluginLoaded(lua_State *L) return 1; } -static int core_Utf8DecodeA(lua_State *L) -{ - return luaM_toansi(L); -} - -static int core_Utf8DecodeW(lua_State *L) -{ - return luaM_toucs2(L); -} - static int core_Free(lua_State *L) { if (lua_islightuserdata(L, 1)) @@ -368,12 +377,11 @@ static int core_TerminateThread(lua_State *L) luaL_Reg coreApi[] = { { "CreateHookableEvent", core_CreateHookableEvent }, - // potentially unsefe for use in scripts - //{ "DestroyHookableEvent", core_DestroyHookableEvent }, { "NotifyEventHooks", core_NotifyEventHooks }, { "HookEvent", core_HookEvent }, + { "HookTemporaryEvent", core_HookTemporaryEvent }, { "UnhookEvent", core_UnhookEvent }, { "CreateServiceFunction", core_CreateServiceFunction }, @@ -384,9 +392,6 @@ luaL_Reg coreApi[] = { "IsPluginLoaded", core_IsPluginLoaded }, - { "Utf8DecodeA", core_Utf8DecodeA }, - { "Utf8DecodeW", core_Utf8DecodeW }, - { "Free", core_Free }, { "Translate", core_Translate }, diff --git a/plugins/MirLua/src/m_database.cpp b/plugins/MirLua/src/m_database.cpp index 0e40c92bee..bdb5822fcf 100644 --- a/plugins/MirLua/src/m_database.cpp +++ b/plugins/MirLua/src/m_database.cpp @@ -2,6 +2,8 @@ static int db_FindFirstContact(lua_State *L) { + ObsoleteMethod(L, "Use Contacts method"); + const char *szProto = lua_tostring(L, 1); MCONTACT res = db_find_first(szProto); @@ -12,6 +14,8 @@ static int db_FindFirstContact(lua_State *L) static int db_FindNextContact(lua_State *L) { + ObsoleteMethod(L, "Use Contacts method"); + MCONTACT hContact = luaL_checkinteger(L, 1); const char *szProto = lua_tostring(L, 2); @@ -24,11 +28,11 @@ static int db_FindNextContact(lua_State *L) static int db_ContactIterator(lua_State *L) { MCONTACT hContact = lua_tointeger(L, lua_upvalueindex(1)); - const char *szProto = lua_tostring(L, lua_upvalueindex(2)); + const char *szModule = lua_tostring(L, lua_upvalueindex(2)); hContact = hContact == NULL - ? db_find_first(szProto) - : db_find_next(hContact, szProto); + ? db_find_first(szModule) + : db_find_next(hContact, szModule); if (hContact) { @@ -44,10 +48,27 @@ static int db_ContactIterator(lua_State *L) static int db_Contacts(lua_State *L) { - const char *szProto = lua_tostring(L, 1); + const char *szModule = NULL; + + switch (lua_type(L, 1)) + { + case LUA_TNONE: + break; + case LUA_TSTRING: + szModule = lua_tostring(L, 1); + break; + case LUA_TUSERDATA: + { + PROTOACCOUNT **pa = (PROTOACCOUNT**)luaL_checkudata(L, 1, MT_PROTOACCOUNT); + szModule = (*pa)->szModuleName; + break; + } + default: + luaL_argerror(L, 1, luaL_typename(L, 1)); + } lua_pushinteger(L, 0); - lua_pushstring(L, szProto); + lua_pushstring(L, szModule); lua_pushcclosure(L, db_ContactIterator, 2); return 1; @@ -493,6 +514,7 @@ static int db_WriteSetting(lua_State *L) MCONTACT hContact = lua_tointeger(L, 1); LPCSTR szModule = luaL_checkstring(L, 2); LPCSTR szSetting = luaL_checkstring(L, 3); + luaL_checkany(L, 4); DBVARIANT dbv = { 0 }; if (lua_isnoneornil(L, 5)) @@ -675,14 +697,16 @@ int MT::Index(lua_State *L, DBCONTACTWRITESETTING *dbcw) #define MT_DBEVENTINFO "DBEVENTINFO" template <> -void MT::Init(lua_State *L, DBEVENTINFO **dbei) +DBEVENTINFO* MT::Init(lua_State *L) { MEVENT hDbEvent = luaL_checkinteger(L, 1); - *dbei = (DBEVENTINFO*)mir_calloc(sizeof(DBEVENTINFO)); - (*dbei)->cbBlob = db_event_getBlobSize((MEVENT)hDbEvent); - (*dbei)->pBlob = (PBYTE)mir_calloc((*dbei)->cbBlob); - db_event_get((MEVENT)hDbEvent, (*dbei)); + DBEVENTINFO* dbei = (DBEVENTINFO*)mir_calloc(sizeof(DBEVENTINFO)); + dbei->cbBlob = db_event_getBlobSize((MEVENT)hDbEvent); + dbei->pBlob = (PBYTE)mir_calloc(dbei->cbBlob); + db_event_get((MEVENT)hDbEvent, dbei); + + return dbei; } template <> diff --git a/plugins/MirLua/src/m_database.h b/plugins/MirLua/src/m_database.h new file mode 100644 index 0000000000..73ba76f28c --- /dev/null +++ b/plugins/MirLua/src/m_database.h @@ -0,0 +1,9 @@ +#ifndef _LUA_M_DATABASE_H_ +#define _LUA_M_DATABASE_H_ + +#include + +#define MLUA_DATABASE "m_database" +LUAMOD_API int (luaopen_m_database)(lua_State *L); + +#endif //_LUA_M_DATABASE_H_ \ No newline at end of file diff --git a/plugins/MirLua/src/m_genmenu.h b/plugins/MirLua/src/m_genmenu.h index ecb04092e1..b368627dc8 100644 --- a/plugins/MirLua/src/m_genmenu.h +++ b/plugins/MirLua/src/m_genmenu.h @@ -1,6 +1,8 @@ #ifndef _LUA_M_GENMENU_H_ #define _LUA_M_GENMENU_H_ +#include + #define MLUA_GENMENU "m_genmenu" LUAMOD_API int (luaopen_m_genmenu)(lua_State *L); diff --git a/plugins/MirLua/src/m_hotkeys.cpp b/plugins/MirLua/src/m_hotkeys.cpp index 2b2aed8c18..faf1dbe6d0 100644 --- a/plugins/MirLua/src/m_hotkeys.cpp +++ b/plugins/MirLua/src/m_hotkeys.cpp @@ -43,7 +43,7 @@ static int hotkeys_Register(lua_State *L) int hScriptLangpack = CMLuaScript::GetScriptIdFromEnviroment(L); - INT_PTR res = ::CallService("CoreHotkeys/Register", (WPARAM)hScriptLangpack, (LPARAM)&hk); + INT_PTR res = Hotkey_Register(&hk, hScriptLangpack); lua_pushboolean(L, res); return 1; diff --git a/plugins/MirLua/src/m_icolib.cpp b/plugins/MirLua/src/m_icolib.cpp index ef8ee4ff85..48e5eeadd5 100644 --- a/plugins/MirLua/src/m_icolib.cpp +++ b/plugins/MirLua/src/m_icolib.cpp @@ -1,35 +1,117 @@ #include "stdafx.h" -static int icolib_AddIcon(lua_State *L) +static void MakeSKINICONDESC(lua_State *L, SKINICONDESC &sid) { - const char *name = luaL_checkstring(L, 1); - ptrW description(mir_utf8decodeW(luaL_checkstring(L, 2))); - ptrW section(mir_utf8decodeW(luaL_optstring(L, 3, MODULE))); - ptrW filePath(mir_utf8decodeW(lua_tostring(L, 4))); + lua_getfield(L, -1, "Flags"); + sid.flags = lua_tointeger(L, -1); + lua_pop(L, 1); + + if (!(sid.flags & SIDF_ALL_UNICODE)) + sid.flags |= SIDF_ALL_UNICODE; + + lua_getfield(L, -1, "Name"); + sid.pszName = mir_utf8decodeA(luaL_checkstring(L, -1)); + lua_pop(L, 1); + + lua_getfield(L, -1, "Description"); + sid.description.w = mir_utf8decodeW(luaL_checkstring(L, -1)); + lua_pop(L, 1); - if (filePath == NULL) + lua_getfield(L, -1, "Section"); + sid.section.w = mir_utf8decodeW(luaL_optstring(L, 3, MODULE)); + lua_pop(L, 1); + + lua_getfield(L, -1, "DefaultFile"); + sid.defaultFile.w = mir_utf8decodeW(lua_tostring(L, -1)); + lua_pop(L, 1); + + if (sid.defaultFile.w == NULL) { - filePath = (wchar_t*)mir_calloc(MAX_PATH + 1); - GetModuleFileName(g_hInstance, filePath, MAX_PATH); + sid.defaultFile.w = (wchar_t*)mir_calloc(MAX_PATH + 1); + GetModuleFileName(g_hInstance, sid.defaultFile.w, MAX_PATH); } - SKINICONDESC si = { 0 }; - si.flags = SIDF_ALL_UNICODE; - si.pszName = mir_utf8decodeA(name); - si.description.w = description; - si.section.w = section; - si.defaultFile.w = filePath; - si.hDefaultIcon = GetIcon(IDI_SCRIPT); + lua_getfield(L, -1, "DefaultIndex"); + sid.iDefaultIndex = lua_tointeger(L, -1); + lua_pop(L, 1); + + lua_getfield(L, -1, "DefaultIcon"); + sid.hDefaultIcon = (HICON)lua_touserdata(L, -1); + lua_pop(L, 1); + + lua_getfield(L, -1, "SizeX"); + sid.iDefaultIndex = lua_tointeger(L, -1); + lua_pop(L, 1); + + lua_getfield(L, -1, "SizeY"); + sid.iDefaultIndex = lua_tointeger(L, -1); + lua_pop(L, 1); +} + +static int lua_AddIcon(lua_State *L) +{ + SKINICONDESC sid; + + if (lua_type(L, 1) == LUA_TSTRING) + { + sid.flags = SIDF_ALL_UNICODE; + sid.pszName = mir_utf8decodeA(luaL_checkstring(L, 1)); + sid.description.w = mir_utf8decodeW(luaL_checkstring(L, 2)); + sid.section.w = mir_utf8decodeW(luaL_optstring(L, 3, MODULE)); + sid.defaultFile.w = mir_utf8decodeW(lua_tostring(L, 4)); + sid.hDefaultIcon = GetIcon(IDI_SCRIPT); + + if (sid.defaultFile.w == NULL) + { + sid.defaultFile.w = (wchar_t*)mir_calloc(MAX_PATH + 1); + GetModuleFileName(g_hInstance, sid.defaultFile.w, MAX_PATH); + } + } + else if(lua_type(L, 1) == LUA_TTABLE) + MakeSKINICONDESC(L, sid); + else + luaL_argerror(L, 1, luaL_typename(L, 1)); int hScriptLangpack = CMLuaScript::GetScriptIdFromEnviroment(L); - HANDLE res = IcoLib_AddIcon(&si, hScriptLangpack); + HANDLE res = IcoLib_AddIcon(&sid, hScriptLangpack); lua_pushlightuserdata(L, res); + mir_free((void*)sid.pszName); + mir_free((void*)sid.description.w); + mir_free((void*)sid.section.w); + mir_free((void*)sid.defaultFile.w); + + return 1; +} + +static int lua_GetIcon(lua_State *L) +{ + luaL_checktype(L, 1, LUA_TLIGHTUSERDATA); + bool big = luaM_toboolean(L, 2); + + HICON hIcon = NULL; + switch (lua_type(L, 1)) + { + case LUA_TLIGHTUSERDATA: + hIcon = IcoLib_GetIconByHandle(lua_touserdata(L, 1), big); + break; + case LUA_TSTRING: + hIcon = IcoLib_GetIcon(lua_tostring(L, 1), big); + break; + default: + luaL_argerror(L, 1, luaL_typename(L, 1)); + } + + if (hIcon) + lua_pushlightuserdata(L, hIcon); + else + lua_pushnil(L); + return 1; } -static int icolib_GetIcon(lua_State *L) +static int lua_GetIconHandle(lua_State *L) { const char *name = luaL_checkstring(L, 1); @@ -39,21 +121,29 @@ static int icolib_GetIcon(lua_State *L) return 1; } -static int icolib_RemoveIcon(lua_State *L) +static int lua_RemoveIcon(lua_State *L) { - if (lua_isuserdata(L, 1)) + switch (lua_type(L, 1)) + { + case LUA_TLIGHTUSERDATA: IcoLib_RemoveIconByHandle(lua_touserdata(L, 1)); - else if (lua_isstring(L, 1)) + break; + case LUA_TSTRING: IcoLib_RemoveIcon(luaL_checkstring(L, 1)); + break; + default: + luaL_argerror(L, 1, luaL_typename(L, 1)); + } return 0; } static luaL_Reg icolibApi[] = { - { "AddIcon", icolib_AddIcon }, - { "GetIcon", icolib_GetIcon }, - { "RemoveIcon", icolib_RemoveIcon }, + { "AddIcon", lua_AddIcon }, + { "GetIcon", lua_GetIcon }, + { "GetIconHandle", lua_GetIconHandle }, + { "RemoveIcon", lua_RemoveIcon }, { NULL, NULL } }; diff --git a/plugins/MirLua/src/m_protocols.cpp b/plugins/MirLua/src/m_protocols.cpp index f4b246a0cf..979388eed6 100644 --- a/plugins/MirLua/src/m_protocols.cpp +++ b/plugins/MirLua/src/m_protocols.cpp @@ -4,26 +4,26 @@ HANDLE hRecvMessage = NULL; static int lua_GetProtocol(lua_State *L) { - const char *name = NULL; + const char *szProto = NULL; switch (lua_type(L, 1)) { case LUA_TNUMBER: { - const char *proto = GetContactProto(lua_tonumber(L, 1)); - PROTOACCOUNT *pa = Proto_GetAccount(proto); + const char *szModule = GetContactProto(lua_tonumber(L, 1)); + PROTOACCOUNT *pa = Proto_GetAccount(szModule); if (pa) - name = pa->szProtoName; - } + szProto = pa->szProtoName; break; + } case LUA_TSTRING: - name = lua_tostring(L, 1); + szProto = lua_tostring(L, 1); break; default: luaL_argerror(L, 1, luaL_typename(L, 1)); } - PROTOCOLDESCRIPTOR *pd = Proto_IsProtocolLoaded(name); + PROTOCOLDESCRIPTOR *pd = Proto_IsProtocolLoaded(szProto); if (pd) MT::Set(L, pd); else @@ -64,38 +64,6 @@ static int lua_Protocols(lua_State *L) return 1; } -static int lua_CallService(lua_State *L) -{ - const char *szProto = NULL; - - switch (lua_type(L, 1)) - { - case LUA_TNUMBER: - szProto = GetContactProto(lua_tonumber(L, 1)); - break; - case LUA_TSTRING: - szProto = lua_tostring(L, 1); - break; - case LUA_TUSERDATA: - luaL_checkudata(L, 1, "PROTOCOLDESCRIPTOR"); - lua_getfield(L, 1, "Name"); - szProto = lua_tostring(L, -1); - lua_pop(L, 1); - break; - default: - luaL_argerror(L, 1, luaL_typename(L, 1)); - } - - const char *service = luaL_checkstring(L, 2); - WPARAM wParam = (WPARAM)luaM_tomparam(L, 3); - LPARAM lParam = (LPARAM)luaM_tomparam(L, 4); - - INT_PTR res = CallProtoService(szProto, service, wParam, lParam); - lua_pushinteger(L, res); - - return 1; -} - static int lua_ChainSend(lua_State *L) { MCONTACT hContact = luaL_checknumber(L, 1); @@ -184,11 +152,11 @@ static int lua_Accounts(lua_State *L) szProto = lua_tostring(L, 1); break; case LUA_TUSERDATA: - luaL_checkudata(L, 1, "PROTOCOLDESCRIPTOR"); - lua_getfield(L, 1, "Name"); - szProto = lua_tostring(L, -1); - lua_pop(L, 1); + { + PROTOCOLDESCRIPTOR **pd = (PROTOCOLDESCRIPTOR**)luaL_checkudata(L, 1, MT_PROTOCOLDESCRIPTOR); + szProto = (*pd)->szName; break; + } default: luaL_argerror(L, 1, luaL_typename(L, 1)); } @@ -196,7 +164,6 @@ static int lua_Accounts(lua_State *L) int count; PROTOACCOUNT **accounts; Proto_EnumAccounts(&count, &accounts); - lua_pushinteger(L, 0); lua_pushinteger(L, count); @@ -207,6 +174,38 @@ static int lua_Accounts(lua_State *L) return 1; } +static int lua_CallService(lua_State *L) +{ + const char *szModule = NULL; + + switch (lua_type(L, 1)) + { + case LUA_TNUMBER: + szModule = GetContactProto(lua_tonumber(L, 1)); + break; + case LUA_TSTRING: + szModule = lua_tostring(L, 1); + break; + case LUA_TUSERDATA: + { + PROTOACCOUNT **pa = (PROTOACCOUNT**)luaL_checkudata(L, 1, MT_PROTOACCOUNT); + szModule = (*pa)->szModuleName; + break; + } + default: + luaL_argerror(L, 1, luaL_typename(L, 1)); + } + + const char *service = luaL_checkstring(L, 2); + WPARAM wParam = (WPARAM)luaM_tomparam(L, 3); + LPARAM lParam = (LPARAM)luaM_tomparam(L, 4); + + INT_PTR res = CallProtoService(szModule, service, wParam, lParam); + lua_pushinteger(L, res); + + return 1; +} + /***********************************************/ INT_PTR FilterRecvMessage(WPARAM wParam, LPARAM lParam) @@ -223,59 +222,38 @@ static luaL_Reg protocolsApi[] = { { "GetProtocol", lua_GetProtocol }, { "Protocols", lua_Protocols }, - { "CallService", lua_CallService }, + { "CallSendChain", lua_ChainSend }, { "CallReceiveChain", lua_ChainRecv }, { "GetAccount", lua_GetAccount }, { "Accounts", lua_Accounts }, + { "CallService", lua_CallService }, + { NULL, NULL } }; /***********************************************/ -#define MT_PROTOCOLDESCRIPTOR "PROTOCOLDESCRIPTOR" - -template <> -int MT::Index(lua_State *L, PROTOCOLDESCRIPTOR *proto) -{ - const char *key = luaL_checkstring(L, 2); - - if (mir_strcmpi(key, "CallService") == 0) - { - lua_pushstring(L, proto->szName); - lua_pushcfunction(L, lua_CallService); - } - else if (mir_strcmpi(key, "Accounts") == 0) - { - lua_pushstring(L, proto->szName); - lua_pushcfunction(L, lua_Accounts); - } - else - lua_pushnil(L); - - return 1; -} - -/***********************************************/ - LUAMOD_API int luaopen_m_protocols(lua_State *L) { luaL_newlib(L, protocolsApi); MT(L, MT_PROTOCOLDESCRIPTOR) .Field(&PROTOCOLDESCRIPTOR::szName, "Name", LUA_TSTRINGA) - .Field(&PROTOCOLDESCRIPTOR::type, "Type", LUA_TINTEGER); + .Field(&PROTOCOLDESCRIPTOR::type, "Type", LUA_TINTEGER) + .Field(lua_Accounts, "Accounts"); - MT(L, "PROTOACCOUNT") + MT(L, MT_PROTOACCOUNT) .Field(&PROTOACCOUNT::szModuleName, "ModuleName", LUA_TSTRINGA) .Field(&PROTOACCOUNT::tszAccountName, "AccountName", LUA_TSTRINGW) .Field(&PROTOACCOUNT::szProtoName, "ProtoName", LUA_TSTRINGA) .Field(&PROTOACCOUNT::bIsEnabled, "IsEnabled", LUA_TBOOLEAN) .Field(&PROTOACCOUNT::bIsVisible, "IsVisible", LUA_TBOOLEAN) .Field(&PROTOACCOUNT::bIsVirtual, "IsVirtual", LUA_TBOOLEAN) - .Field(&PROTOACCOUNT::bOldProto, "IsOldProto", LUA_TBOOLEAN); + .Field(&PROTOACCOUNT::bOldProto, "IsOldProto", LUA_TBOOLEAN) + .Field(lua_CallService, "CallService"); MT(L, "ACKDATA") .Field(&ACKDATA::szModule, "Module", LUA_TSTRINGA) diff --git a/plugins/MirLua/src/m_protocols.h b/plugins/MirLua/src/m_protocols.h index 1b8ef74d43..b80d38023b 100644 --- a/plugins/MirLua/src/m_protocols.h +++ b/plugins/MirLua/src/m_protocols.h @@ -4,6 +4,9 @@ #define MLUA_PROTOCOLS "m_protocols" LUAMOD_API int (luaopen_m_protocols)(lua_State *L); +#define MT_PROTOCOLDESCRIPTOR "PROTOCOLDESCRIPTOR" +#define MT_PROTOACCOUNT "PROTOACCOUNT" + extern HANDLE hRecvMessage; INT_PTR FilterRecvMessage(WPARAM wParam, LPARAM lParam); diff --git a/plugins/MirLua/src/m_sounds.cpp b/plugins/MirLua/src/m_sounds.cpp index b7e86b4c91..7c044caaee 100644 --- a/plugins/MirLua/src/m_sounds.cpp +++ b/plugins/MirLua/src/m_sounds.cpp @@ -1,6 +1,6 @@ #include "stdafx.h" -static int sounds_AddSound(lua_State *L) +static int lua_AddSound(lua_State *L) { ptrA name(mir_utf8decodeA(luaL_checkstring(L, 1))); ptrW description(mir_utf8decodeW(luaL_checkstring(L, 2))); @@ -13,7 +13,7 @@ static int sounds_AddSound(lua_State *L) return 1; } -static int sounds_PlaySound(lua_State *L) +static int lua_PlaySound(lua_State *L) { const char *name = luaL_checkstring(L, 1); @@ -23,7 +23,7 @@ static int sounds_PlaySound(lua_State *L) return 1; } -static int sounds_PlayFile(lua_State *L) +static int lua_PlayFile(lua_State *L) { ptrW filePath(mir_utf8decodeW(luaL_checkstring(L, 1))); @@ -35,10 +35,10 @@ static int sounds_PlayFile(lua_State *L) static luaL_Reg soundApi[] = { - { "AddSound", sounds_AddSound }, - { "PlaySound", sounds_PlaySound }, + { "AddSound", lua_AddSound }, - { "PlayFile", sounds_PlayFile }, + { "PlaySound", lua_PlaySound }, + { "PlayFile", lua_PlayFile }, { NULL, NULL } }; diff --git a/plugins/MirLua/src/m_srmm.cpp b/plugins/MirLua/src/m_srmm.cpp new file mode 100644 index 0000000000..a1b7240cec --- /dev/null +++ b/plugins/MirLua/src/m_srmm.cpp @@ -0,0 +1,108 @@ +#include "stdafx.h" + +static void MakeBBButton(lua_State *L, BBButton &bbb) +{ + bbb.dwDefPos = 100; + + lua_getfield(L, -1, "Module"); + bbb.pszModuleName = mir_utf8decodeA(luaL_checkstring(L, -1)); + lua_pop(L, 1); + + lua_getfield(L, -1, "ButtonId"); + bbb.dwButtonID = luaL_checkinteger(L, -1); + lua_pop(L, 1); + + lua_getfield(L, -1, "Flags"); + bbb.bbbFlags = luaL_optinteger(L, -1, BBBF_ISIMBUTTON); + lua_pop(L, 1); + + lua_getfield(L, -1, "Text"); + bbb.pwszText = mir_utf8decodeW(lua_tostring(L, -1)); + lua_pop(L, 1); + + lua_getfield(L, -1, "Tooltip"); + bbb.pwszTooltip = mir_utf8decodeW(lua_tostring(L, -1)); + lua_pop(L, 1); + + lua_getfield(L, -1, "Icon"); + bbb.hIcon = (HANDLE)lua_touserdata(L, -1); + lua_pop(L, 1); +} + +static int lua_AddButton(lua_State *L) +{ + luaL_checktype(L, 1, LUA_TTABLE); + + BBButton bbb; + MakeBBButton(L, bbb); + + int hScriptLangpack = CMLuaScript::GetScriptIdFromEnviroment(L); + + INT_PTR res = Srmm_AddButton(&bbb, hScriptLangpack); + lua_pushboolean(L, res == 0); + + mir_free((void*)bbb.pszModuleName); + mir_free((void*)bbb.pwszText); + mir_free((void*)bbb.pwszTooltip); + + return 1; +} + +static int lua_ModifyButton(lua_State *L) +{ + if (lua_type(L, 1) != LUA_TTABLE) + { + lua_pushlightuserdata(L, 0); + return 1; + } + + BBButton bbb; + MakeBBButton(L, bbb); + + INT_PTR res = Srmm_ModifyButton(&bbb); + lua_pushinteger(L, res); + + mir_free((void*)bbb.pszModuleName); + mir_free((void*)bbb.pwszText); + mir_free((void*)bbb.pwszTooltip); + + return 1; +} + +static int lua_RemoveButton(lua_State *L) +{ + ptrA szModuleName(mir_utf8decodeA(luaL_checkstring(L, 1))); + + BBButton mbb = {}; + mbb.pszModuleName = szModuleName; + mbb.dwButtonID = luaL_checkinteger(L, 2); + + INT_PTR res = Srmm_RemoveButton(&mbb); + lua_pushinteger(L, res); + + return 1; +} + +static luaL_Reg srmmApi[] = +{ + { "AddButton", lua_AddButton }, + { "ModifyButton", lua_ModifyButton }, + { "RemoveButton", lua_RemoveButton }, + + { NULL, NULL } +}; + +/***********************************************/ + +LUAMOD_API int luaopen_m_srmm(lua_State *L) +{ + luaL_newlib(L, srmmApi); + + MT(L, "CustomButtonClickData") + .Field(&CustomButtonClickData::pszModule, "Module", LUA_TSTRINGA) + .Field(&CustomButtonClickData::dwButtonId, "ButtonId", LUA_TINTEGER) + .Field(&CustomButtonClickData::hContact, "hContact", LUA_TINTEGER) + .Field(&CustomButtonClickData::flags, "Flags", LUA_TINTEGER); + + return 1; +} diff --git a/plugins/MirLua/src/mlua.cpp b/plugins/MirLua/src/mlua.cpp index 156e957a02..d3c835ee7d 100644 --- a/plugins/MirLua/src/mlua.cpp +++ b/plugins/MirLua/src/mlua.cpp @@ -21,6 +21,173 @@ CMLua::~CMLua() Unload(); } +/***********************************************/ + +static int mlua_print(lua_State *L) +{ + CMStringA data; + int nargs = lua_gettop(L); + for (int i = 1; i <= nargs; i++) + { + switch (lua_type(L, i)) + { + case LUA_TNIL: + data.Append("nil"); + break; + case LUA_TBOOLEAN: + data.AppendFormat("%s", lua_toboolean(L, i) ? "true" : "false"); + break; + case LUA_TNUMBER: + case LUA_TSTRING: + data.AppendFormat("%s", lua_tostring(L, i)); + break; + default: + data.AppendFormat("%s(0x%p)", luaL_typename(L, i), lua_topointer(L, i)); + break; + } + data.Append(", "); + } + if (data.GetLength() >= 1) + data.Delete(data.GetLength() - 2, 2); + + Log(data.GetBuffer()); + + return 0; +} + +static int mlua_toansi(lua_State *L) +{ + const char *value = luaL_checkstring(L, 1); + int codepage = luaL_optinteger(L, 2, Langpack_GetDefaultCodePage()); + + ptrA string(mir_strdup(value)); + lua_pushstring(L, mir_utf8decodecp(string, codepage, NULL)); + + return 1; +} + +static int mlua_toucs2(lua_State *L) +{ + const char *value = luaL_checkstring(L, 1); + + ptrW unicode(mir_utf8decodeW(value)); + size_t length = mir_wstrlen(unicode) * sizeof(wchar_t); + + ptrA string((char*)mir_calloc(length + 1)); + memcpy(string, unicode, length); + + lua_pushlstring(L, string, length + 1); + + return 1; +} + +static int mlua_topointer(lua_State *L) +{ + switch (lua_type(L, 1)) + { + case LUA_TBOOLEAN: + lua_pushlightuserdata(L, (void*)lua_toboolean(L, 1)); + break; + case LUA_TNUMBER: + if (lua_isinteger(L, 1)) + { + lua_Integer value = lua_tointeger(L, 1); + if (value > INTPTR_MAX) + { + const char *msg = lua_pushfstring(L, "%f is larger than %d", value, INTPTR_MAX); + return luaL_argerror(L, 1, msg); + } + lua_pushlightuserdata(L, (void*)value); + } + break; + case LUA_TSTRING: + lua_pushlightuserdata(L, (void*)lua_tostring(L, 1)); + break; + case LUA_TLIGHTUSERDATA: + lua_pushvalue(L, 1); + default: + return luaL_argerror(L, 1, luaL_typename(L, 1)); + } + + return 1; +} + +static int mlua_tonumber(lua_State *L) +{ + if (lua_islightuserdata(L, 1)) + { + lua_Integer value = (lua_Integer)lua_touserdata(L, 1); + lua_pushinteger(L, value); + return 1; + } + + int n = lua_gettop(L); + lua_pushvalue(L, lua_upvalueindex(1)); + lua_pushvalue(L, 1); + if (n == 2) + lua_pushvalue(L, 2); + luaM_pcall(L, n, 1); + + return 1; +} + +static int mlua_interpolate(lua_State *L) +{ + const char *string = luaL_checkstring(L, 1); + + char pattern[128]; + + 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 + { + int nargs = lua_gettop(L); + for (int i = 2; i <= nargs; i++) + { + const char *val = lua_tostring(L, i); + + mir_snprintf(pattern, "{%d}", i - 1); + string = luaL_gsub(L, string, pattern, val); + lua_pop(L, 1); + } + } + + lua_Debug ar; + + size_t level = 1; + + while (lua_getstack(L, level++, &ar)) + { + size_t i = 1; + while (const char *name = lua_getlocal(L, &ar, i++)) + { + const char *val = lua_tostring(L, -1); + if (val) + { + mir_snprintf(pattern, "${%s}", name); + string = luaL_gsub(L, string, pattern, val); + lua_pop(L, 1); + } + } + } + lua_pushstring(L, string); + + return 1; +} + +/***********************************************/ + void CMLua::SetPaths() { wchar_t path[MAX_PATH]; @@ -47,23 +214,23 @@ void CMLua::Load() SetPaths(); - lua_register(L, "print", luaM_print); - lua_register(L, "a", luaM_toansi); - lua_register(L, "u", luaM_toucs2); - lua_register(L, "topointer", luaM_topointer); + lua_register(L, "print", mlua_print); + lua_register(L, "a", mlua_toansi); + lua_register(L, "u", mlua_toucs2); + lua_register(L, "topointer", mlua_topointer); lua_getglobal(L, "tonumber"); - lua_setglobal(L, "_tonumber"); - lua_register(L, "tonumber", luaM_tonumber); + lua_pushcclosure(L, mlua_tonumber, 1); + lua_setglobal(L, "tonumber"); lua_pushstring(L, ""); lua_getmetatable(L, -1); lua_pushstring(L, "__mod"); - lua_pushcfunction(L, luaM_interpolate); + lua_pushcfunction(L, mlua_interpolate); lua_rawset(L, -3); lua_pushstring(L, "__index"); lua_rawget(L, -2); - lua_pushcfunction(L, luaM_interpolate); + lua_pushcfunction(L, mlua_interpolate); lua_setfield(L, -2, "interpolate"); lua_pop(L, 3); diff --git a/plugins/MirLua/src/mlua_metatable.h b/plugins/MirLua/src/mlua_metatable.h index b918971077..ddd67090d0 100644 --- a/plugins/MirLua/src/mlua_metatable.h +++ b/plugins/MirLua/src/mlua_metatable.h @@ -1,6 +1,7 @@ #ifndef _LUA_METATABLE_H_ #define _LUA_METATABLE_H_ +#include #include #include @@ -17,6 +18,7 @@ union MTFieldVal const char *string; const char *stringA; const wchar_t *stringW; + lua_CFunction function; }; struct MTField @@ -25,7 +27,6 @@ struct MTField MTFieldVal val; }; - class CMTField { public: @@ -50,6 +51,21 @@ public: } }; +class CMTFieldFunction : public CMTField +{ + lua_CFunction func; +public: + + CMTFieldFunction(lua_CFunction f) : func(f) {} + + virtual MTField GetValue(void *obj) + { + MTField tmp = { LUA_TFUNCTION }; + tmp.val.function = func; + return tmp; + } +}; + template class CMTFieldLambda : public CMTField { @@ -67,7 +83,6 @@ public: } }; - template class MT { @@ -77,10 +92,10 @@ private: static const char *name; static std::map fields; - static void Init(lua_State *L, T **obj) + static T* Init(lua_State *L) { luaL_checktype(L, 1, LUA_TLIGHTUSERDATA); - *obj = (T*)lua_touserdata(L, 1); + return (T*)lua_touserdata(L, 1); } static int Index(lua_State *L, T* /*obj*/) @@ -97,7 +112,7 @@ private: static int lua__new(lua_State *L) { T **udata = (T**)lua_newuserdata(L, sizeof(T*)); - Init(L, udata); + *udata = Init(L); if (*udata == NULL) { lua_pushnil(L); @@ -108,17 +123,6 @@ private: return 1; } - static int lua__call(lua_State *L) - { - int nargs = lua_gettop(L); - lua_pushcfunction(L, lua__new); - for (int i = 2; i <= nargs; i++) - lua_pushvalue(L, i); - luaM_pcall(L, nargs - 1, 1); - - return 1; - } - static int lua__bnot(lua_State *L) { T *obj = *(T**)luaL_checkudata(L, 1, MT::name); @@ -163,6 +167,9 @@ private: case LUA_TLIGHTUSERDATA: lua_pushlightuserdata(L, fieldVal.val.userdata); break; + case LUA_TFUNCTION: + lua_pushcfunction(L, fieldVal.val.function); + break; default: lua_pushnil(L); } @@ -230,8 +237,6 @@ public: MT::name = tname; luaL_newmetatable(L, MT::name); - lua_pushcfunction(L, lua__call); - lua_setfield(L, -2, "__call"); lua_pushcfunction(L, lua__index); lua_setfield(L, -2, "__index"); lua_pushcfunction(L, lua__bnot); @@ -247,7 +252,6 @@ public: lua_setfield(L, -2, "new"); lua_pushvalue(L, -1); lua_setglobal(L, MT::name); - luaL_setmetatable(L, MT::name); lua_pop(L, 1); } @@ -270,6 +274,12 @@ public: return *this; } + MT& Field(const lua_CFunction f, const char *name) + { + fields[name] = new CMTFieldFunction(f); + return *this; + } + static void Set(lua_State *L, T *obj) { if (obj == NULL) diff --git a/plugins/MirLua/src/mlua_module_loader.cpp b/plugins/MirLua/src/mlua_module_loader.cpp index c7e64a5b0a..a35801373a 100644 --- a/plugins/MirLua/src/mlua_module_loader.cpp +++ b/plugins/MirLua/src/mlua_module_loader.cpp @@ -37,6 +37,7 @@ void CMLuaModuleLoader::LoadModules() Preload(MLUA_OPTIONS, luaopen_m_options); Preload(MLUA_PROTOCOLS, luaopen_m_protocols); Preload(MLUA_SOUNDS, luaopen_m_sounds); + Preload(MLUA_SRMM, luaopen_m_srmm); } void CMLuaModuleLoader::Load(lua_State *L) diff --git a/plugins/MirLua/src/mlua_options.h b/plugins/MirLua/src/mlua_options.h index 624a1eefaa..5d36188604 100644 --- a/plugins/MirLua/src/mlua_options.h +++ b/plugins/MirLua/src/mlua_options.h @@ -1,6 +1,8 @@ #ifndef _LUA_OPTIONS_H_ #define _LUA_OPTIONS_H_ +#include + class CCtrlScriptList : public CCtrlListView { private: diff --git a/plugins/MirLua/src/mlua_script.cpp b/plugins/MirLua/src/mlua_script.cpp index f4cfef8c7c..280452d068 100644 --- a/plugins/MirLua/src/mlua_script.cpp +++ b/plugins/MirLua/src/mlua_script.cpp @@ -1,6 +1,6 @@ #include "stdafx.h" -#define SCRIPT "Script" +#define MT_SCRIPT "SCRIPT" CMLuaScript::CMLuaScript(lua_State *L, const wchar_t *path) : L(L), status(None), unloadRef(LUA_NOREF) @@ -26,31 +26,12 @@ CMLuaScript::~CMLuaScript() mir_free(moduleName); } -bool CMLuaScript::GetEnviroment(lua_State *L) -{ - lua_Debug ar; - if (lua_getstack(L, 1, &ar) == 0 || lua_getinfo(L, "f", &ar) == 0 || lua_iscfunction(L, -1)) - { - lua_pop(L, 1); - return false; - } - - const char *env = lua_getupvalue(L, -1, 1); - if (!env || mir_strcmp(env, "_ENV") != 0) - { - lua_pop(L, 1); - return false; - } - - return true; -} - CMLuaScript* CMLuaScript::GetScriptFromEnviroment(lua_State *L) { - if (!GetEnviroment(L)) + if (!luaM_getenv(L)) return NULL; - lua_getfield(L, -1, SCRIPT); + lua_rawgeti(L, -1, NULL); CMLuaScript *script = (CMLuaScript*)lua_touserdata(L, -1); lua_pop(L, 3); @@ -101,12 +82,14 @@ bool CMLuaScript::Load() return false; } - lua_createtable(L, 0, 2); + lua_createtable(L, 1, 1); + lua_pushlightuserdata(L, this); + lua_rawseti(L, -2, NULL); lua_pushvalue(L, -1); lua_setfield(L, -2, "_G"); - lua_pushlightuserdata(L, this); - lua_setfield(L, -2, "Script"); lua_createtable(L, 0, 2); + lua_pushliteral(L, MT_SCRIPT); + lua_setfield(L, -2, "__metatable"); lua_getglobal(L, "_G"); lua_setfield(L, -2, "__index"); lua_setmetatable(L, -2); diff --git a/plugins/MirLua/src/mlua_script.h b/plugins/MirLua/src/mlua_script.h index 042e78dadf..539a0123b8 100644 --- a/plugins/MirLua/src/mlua_script.h +++ b/plugins/MirLua/src/mlua_script.h @@ -21,14 +21,12 @@ private: wchar_t filePath[MAX_PATH]; Status status; - public: CMLuaScript(lua_State *L, const wchar_t *path); ~CMLuaScript(); static CMLuaScript* GetScriptFromEnviroment(lua_State *L); static int GetScriptIdFromEnviroment(lua_State *L); - static bool GetEnviroment(lua_State *L); int GetId() const; diff --git a/plugins/MirLua/src/mlua_utils.cpp b/plugins/MirLua/src/mlua_utils.cpp index f21bd8fcbf..9abbc6e492 100644 --- a/plugins/MirLua/src/mlua_utils.cpp +++ b/plugins/MirLua/src/mlua_utils.cpp @@ -48,8 +48,9 @@ void ObsoleteMethod(lua_State *L, const char *message) ShowNotification(MODULE, text, MB_OK | MB_ICONWARNING, NULL); } -void ReportError(const char *message) +void ReportError(lua_State *L) { + const char *message = lua_tostring(L, -1); Log(message); if (db_get_b(NULL, MODULE, "PopupOnError", 0)) ShowNotification(MODULE, message, MB_OK | MB_ICONERROR); @@ -57,8 +58,7 @@ void ReportError(const char *message) int luaM_atpanic(lua_State *L) { - ReportError(lua_tostring(L, -1)); - + ReportError(L); return 0; } @@ -66,196 +66,27 @@ int luaM_pcall(lua_State *L, int n, int r) { int res = lua_pcall(L, n, r, 0); if (res != LUA_OK) - ReportError(lua_tostring(L, -1)); + ReportError(L); return res; } -int luaM_print(lua_State *L) -{ - CMStringA data; - int nargs = lua_gettop(L); - for (int i = 1; i <= nargs; i++) - { - switch (lua_type(L, i)) - { - case LUA_TNIL: - data.Append("nil"); - break; - case LUA_TBOOLEAN: - data.AppendFormat("%s", lua_toboolean(L, i) ? "true" : "false"); - break; - case LUA_TNUMBER: - case LUA_TSTRING: - data.AppendFormat("%s", lua_tostring(L, i)); - break; - default: - data.AppendFormat("%s(0x%p)", luaL_typename(L, i), lua_topointer(L, i)); - break; - } - data.Append(", "); - } - if (data.GetLength() >= 1) - data.Delete(data.GetLength() - 2, 2); - - Log(data.GetBuffer()); - - return 0; -} - -int luaM_toansi(lua_State *L) -{ - const char *value = luaL_checkstring(L, 1); - int codepage = luaL_optinteger(L, 2, Langpack_GetDefaultCodePage()); - - ptrA string(mir_strdup(value)); - lua_pushstring(L, mir_utf8decodecp(string, codepage, NULL)); - - return 1; -} - -int luaM_toucs2(lua_State *L) +int luaM_getenv(lua_State *L) { - const char *value = luaL_checkstring(L, 1); - - ptrW unicode(mir_utf8decodeW(value)); - size_t length = mir_wstrlen(unicode) * sizeof(wchar_t); - - ptrA string((char*)mir_calloc(length + 1)); - memcpy(string, unicode, length); - - lua_pushlstring(L, string, length + 1); - - return 1; -} - -int luaM_topointer(lua_State *L) -{ - switch (lua_type(L, 1)) - { - case LUA_TBOOLEAN: - lua_pushlightuserdata(L, (void*)lua_toboolean(L, 1)); - break; - case LUA_TNUMBER: - { - if (lua_isinteger(L, 1)) - { - lua_Integer value = lua_tointeger(L, 1); - if (value > INTPTR_MAX) - { - const char *msg = lua_pushfstring(L, "%f is larger than %d", value, INTPTR_MAX); - return luaL_argerror(L, 1, msg); - } - lua_pushlightuserdata(L, (void*)value); - } - } - break; - case LUA_TSTRING: - lua_pushlightuserdata(L, (void*)lua_tostring(L, 1)); - break; - case LUA_TLIGHTUSERDATA: - lua_pushvalue(L, 1); - default: - return luaL_argerror(L, 1, luaL_typename(L, 1)); - } - - return 1; -} - -int luaM_tonumber(lua_State *L) -{ - if (lua_islightuserdata(L, 1)) - { - lua_Integer value = (lua_Integer)lua_touserdata(L, 1); - lua_pushinteger(L, value); - return 1; - } - - int n = lua_gettop(L); - lua_getglobal(L, "_tonumber"); - lua_pushvalue(L, 1); - if (n == 2) - lua_pushvalue(L, 2); - luaM_pcall(L, n, 1); - - return 1; -} - -UINT_PTR luaM_tomparam(lua_State *L, int idx) -{ - switch (lua_type(L, idx)) - { - case LUA_TBOOLEAN: - return lua_toboolean(L, idx); - case LUA_TSTRING: - return (UINT_PTR)lua_tostring(L, idx); - case LUA_TLIGHTUSERDATA: - return (UINT_PTR)lua_touserdata(L, idx); - case LUA_TNUMBER: - { - if (lua_isinteger(L, idx)) - { - lua_Integer value = lua_tointeger(L, idx); - return value <= INTPTR_MAX - ? (UINT_PTR)value - : NULL; - } - } - default: - return NULL; - } -} - -int luaM_interpolate(lua_State *L) -{ - const char *string = luaL_checkstring(L, 1); - - char pattern[128]; - - 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 + lua_Debug ar; + if (lua_getstack(L, 1, &ar) == 0 || + lua_getinfo(L, "f", &ar) == 0 || + lua_iscfunction(L, -1)) { - int nargs = lua_gettop(L); - for (int i = 2; i <= nargs; i++) - { - const char *val = lua_tostring(L, i); - - mir_snprintf(pattern, "{%d}", i - 1); - string = luaL_gsub(L, string, pattern, val); - lua_pop(L, 1); - } + lua_pop(L, 1); + return 0; } - lua_Debug ar; - - size_t level = 1; - - while (lua_getstack(L, level++, &ar)) + const char *env = lua_getupvalue(L, -1, 1); + if (!env || strcmp(env, "_ENV") != 0) { - size_t i = 1; - while (const char *name = lua_getlocal(L, &ar, i++)) - { - const char *val = lua_tostring(L, -1); - if (val) - { - mir_snprintf(pattern, "${%s}", name); - string = luaL_gsub(L, string, pattern, val); - lua_pop(L, 1); - } - } + lua_pop(L, 1); + return 0; } - lua_pushstring(L, string); return 1; } diff --git a/plugins/MirLua/src/stdafx.h b/plugins/MirLua/src/stdafx.h index dda365dd82..84924a7012 100644 --- a/plugins/MirLua/src/stdafx.h +++ b/plugins/MirLua/src/stdafx.h @@ -2,23 +2,15 @@ #define _COMMON_H_ #include -#include -#include #include -#include -#include - #include #include #include #include -#include #include -#include #include -#include #include #include #include @@ -33,7 +25,7 @@ #include #include -#include +#include #include "version.h" #include "resource.h" @@ -74,8 +66,7 @@ LUAMOD_API int (luaopen_m_chat)(lua_State *L); #define MLUA_CLIST "m_clist" LUAMOD_API int (luaopen_m_clist)(lua_State *L); -#define MLUA_DATABASE "m_database" -LUAMOD_API int (luaopen_m_database)(lua_State *L); +#include "m_database.h" #define MLUA_ICOLIB "m_icolib" LUAMOD_API int (luaopen_m_icolib)(lua_State *L); @@ -96,6 +87,9 @@ LUAMOD_API int (luaopen_m_options)(lua_State *L); #define MLUA_SOUNDS "m_sounds" LUAMOD_API int (luaopen_m_sounds)(lua_State *L); +#define MLUA_SRMM "m_srmm" +LUAMOD_API int (luaopen_m_srmm)(lua_State *L); + /* utils */ extern HNETLIBUSER hNetlib; @@ -109,17 +103,7 @@ void ObsoleteMethod(lua_State *L, const char *message); int luaM_atpanic(lua_State *L); int luaM_pcall(lua_State *L, int n = 0, int r = 0); -int luaM_print(lua_State *L); - -int luaM_toansi(lua_State *L); -int luaM_toucs2(lua_State *L); - -int luaM_topointer(lua_State *L); -int luaM_tonumber(lua_State *L); - -WPARAM luaM_tomparam(lua_State *L, int idx); - -int luaM_interpolate(lua_State *L); +int luaM_getenv(lua_State *L); bool luaM_toboolean(lua_State *L, int idx); diff --git a/plugins/MirLua/src/version.h b/plugins/MirLua/src/version.h index 4a4f9a797d..89028c524c 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 1 +#define __BUILD_NUM 2 #include -- cgit v1.2.3