#include "stdafx.h" HANDLE hRecvMessage = NULL; static int lua_GetProtocol(lua_State *L) { const char *name = NULL; switch (lua_type(L, 1)) { case LUA_TNUMBER: { const char *proto = GetContactProto(lua_tonumber(L, 1)); PROTOACCOUNT *pa = Proto_GetAccount(proto); if (pa) name = pa->szProtoName; } break; case LUA_TSTRING: name = lua_tostring(L, 1); break; default: luaL_argerror(L, 1, luaL_typename(L, 1)); } PROTOCOLDESCRIPTOR *pd = Proto_IsProtocolLoaded(name); if (pd) MT::Set(L, pd); else lua_pushnil(L); return 1; } static int lua_ProtocolIterator(lua_State *L) { int i = lua_tointeger(L, lua_upvalueindex(1)); int count = lua_tointeger(L, lua_upvalueindex(2)); PROTOCOLDESCRIPTOR **protos = (PROTOCOLDESCRIPTOR**)lua_touserdata(L, lua_upvalueindex(3)); if (i < count) { lua_pushinteger(L, (i + 1)); lua_replace(L, lua_upvalueindex(1)); MT::Set(L, protos[i]); } else lua_pushnil(L); return 1; } static int lua_Protocols(lua_State *L) { int count; PROTOCOLDESCRIPTOR **protos; Proto_EnumProtocols(&count, &protos); lua_pushinteger(L, 0); lua_pushinteger(L, count); lua_pushlightuserdata(L, protos); lua_pushcclosure(L, lua_ProtocolIterator, 3); return 1; } static int lua_CallService(lua_State *L) { const char *module = NULL; switch (lua_type(L, 1)) { case LUA_TNUMBER: module = GetContactProto(lua_tonumber(L, 1)); break; case LUA_TSTRING: module = lua_tostring(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(module, service, wParam, lParam); lua_pushinteger(L, res); return 1; } static int lua_ChainSend(lua_State *L) { MCONTACT hContact = luaL_checknumber(L, 1); const char *service = luaL_checkstring(L, 2); WPARAM wParam = (WPARAM)luaM_tomparam(L, 3); LPARAM lParam = (LPARAM)luaM_tomparam(L, 4); CCSDATA ccs = { hContact, service, wParam, lParam }; INT_PTR res = Proto_ChainSend(0, &ccs); lua_pushinteger(L, res); return 1; } static int lua_ChainRecv(lua_State *L) { MCONTACT hContact = luaL_checknumber(L, 1); const char *service = luaL_checkstring(L, 2); WPARAM wParam = (WPARAM)luaM_tomparam(L, 3); LPARAM lParam = (LPARAM)luaM_tomparam(L, 4); CCSDATA ccs = { hContact, service, wParam, lParam }; INT_PTR res = Proto_ChainRecv(0, &ccs); lua_pushinteger(L, res); return 1; } /***********************************************/ static int lua_GetAccount(lua_State *L) { const char *name = NULL; switch (lua_type(L, 1)) { case LUA_TNUMBER: name = GetContactProto(lua_tonumber(L, 1)); break; case LUA_TSTRING: name = lua_tostring(L, 1); break; default: luaL_argerror(L, 1, luaL_typename(L, 1)); } PROTOACCOUNT *pa = Proto_GetAccount(name); if (pa) MT::Set(L, pa); else lua_pushnil(L); return 1; } static int lua_AccountIterator(lua_State *L) { int i = lua_tointeger(L, lua_upvalueindex(1)); int count = lua_tointeger(L, lua_upvalueindex(2)); PROTOACCOUNT **accounts = (PROTOACCOUNT**)lua_touserdata(L, lua_upvalueindex(3)); if (i < count) { lua_pushinteger(L, (i + 1)); lua_replace(L, lua_upvalueindex(1)); MT::Set(L, accounts[i]); } else lua_pushnil(L); return 1; } static int lua_Accounts(lua_State *L) { int count; PROTOACCOUNT **accounts; Proto_EnumAccounts(&count, &accounts); lua_pushinteger(L, 0); lua_pushinteger(L, count); lua_pushlightuserdata(L, accounts); lua_pushcclosure(L, lua_AccountIterator, 3); return 1; } /***********************************************/ INT_PTR FilterRecvMessage(WPARAM wParam, LPARAM lParam) { int res = NotifyEventHooks(hRecvMessage, wParam, lParam); if (res) return res; Proto_ChainRecv(wParam, (CCSDATA*)lParam); return 0; } /***********************************************/ 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 }, { NULL, NULL } }; /***********************************************/ LUAMOD_API int luaopen_m_protocols(lua_State *L) { luaL_newlib(L, protocolsApi); MT(L, "PROTOCOLDESCRIPTOR") .Field(&PROTOCOLDESCRIPTOR::szName, "Name", LUA_TSTRINGA) .Field(&PROTOCOLDESCRIPTOR::type, "Type", LUA_TINTEGER); MT(L, "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); MT(L, "ACKDATA") .Field(&ACKDATA::szModule, "Module", LUA_TSTRINGA) .Field(&ACKDATA::hContact, "hContact", LUA_TINTEGER) .Field(&ACKDATA::type, "Type", LUA_TINTEGER) .Field(&ACKDATA::result, "Result", LUA_TINTEGER) .Field(&ACKDATA::hProcess, "hProcess", LUA_TLIGHTUSERDATA) .Field(&ACKDATA::lParam, "lParam", LUA_TLIGHTUSERDATA); MT(L, "CCSDATA") .Field(&CCSDATA::hContact, "hContact", LUA_TINTEGER) .Field(&CCSDATA::szProtoService, "Service", LUA_TSTRINGA) .Field([](CCSDATA *ccd) { return (void*)ccd->wParam; }, "wParam", LUA_TLIGHTUSERDATA) .Field([](CCSDATA *ccd) { return (void*)ccd->lParam; }, "lParam", LUA_TLIGHTUSERDATA); MT(L, "PROTORECVEVENT") .Field(&PROTORECVEVENT::timestamp, "Timestamp", LUA_TINTEGER) .Field(&PROTORECVEVENT::flags, "Flags", LUA_TINTEGER) .Field(&PROTORECVEVENT::szMessage, "Message", LUA_TSTRING); return 1; }