/* * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM * * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna * * This code is inspired by article of RichardS at http://www.codeproject.com/Articles/11508/Integrating-Lua-into-C * * This file is part of SAR. * * SAR is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SAR is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SAR. If not, see . */ #include "stdafx.h" #include "SarLuaScript.h" #include "../miranda32/m_protomod.h" #include "../miranda32/m_protosvc.h" extern INT g_nCurrentMode; extern CMessagesHandler *g_pMessHandler; wchar_t* Utf8toUtf16(CHAR * szStrIn, UINT & nSize); char* Utf16toUtf8(LPCWSTR lpwszStrIn, UINT & nSize); CSarLuaScript::CSarLuaScript(CLuaBridge & luaBridge) : CLuaScript(luaBridge) { m_nFuncBaseIndex = RegisterFunction("SendMessage"); RegisterFunction("GetMyStatus"); RegisterFunction("SetMyStatus"); RegisterFunction("Wait"); RegisterFunction("FindUser"); RegisterFunction("SetVariable"); RegisterFunction("GetVariable"); } CSarLuaScript::~CSarLuaScript(void) { } int CSarLuaScript::ScriptCalling(CLuaBridge & luaBridge, int nFncNumber) { switch (nFncNumber - m_nFuncBaseIndex) { case 0: return SendMessage(luaBridge); case 1: return GetMyStatus(luaBridge); case 2: return SetMyStatus(luaBridge); case 3: return Wait(luaBridge); case 4: return FindUser(luaBridge); case 5: return SetVariable(luaBridge); case 6: return GetVariable(luaBridge); } return FALSE; } int CSarLuaScript::SendMessage(CLuaBridge & luaBridge) { lua_State *pFunctionContext = (lua_State*)luaBridge; UINT nMessageLen = lua_strlen(pFunctionContext, -1); const char * szMessage = lua_tostring(pFunctionContext, -1); int hUserToken = (int)lua_tonumber(pFunctionContext, -2); if (szMessage == NULL) { return FALSE; } int nRetVal = 0; #ifdef _UNICODE /*/// as I am in unicode, I have to convert all strings from utf8 to utf16 :) wchar_t * szwMessage = Utf8toUtf16((char*)szMessage, nMessageLen);*/ nRetVal = CallContactService((HANDLE)hUserToken, PSS_MESSAGE, PREF_UTF, reinterpret_cast(szMessage)); /*free(szwMessage);*/ #else nRetVal = CallContactService((HANDLE)hUserToken, PSS_MESSAGE, 0, reinterpret_cast(szMessage)); #endif return FALSE; } int CSarLuaScript::GetMyStatus(CLuaBridge & luaBridge) { lua_State *pFunctionContext = (lua_State*)luaBridge; int nStatusMode = CallService(MS_CLIST_GETSTATUSMODE, (WPARAM)0, (LPARAM)0); nStatusMode = g_nCurrentMode; switch (nStatusMode) { case ID_STATUS_ONLINE: AddParam("Online"); break; case ID_STATUS_OFFLINE: AddParam("Offline"); break; case ID_STATUS_AWAY: AddParam("Away"); break; case ID_STATUS_DND: AddParam("DND"); break; case ID_STATUS_NA: AddParam("NA"); break; case ID_STATUS_OCCUPIED: AddParam("Occupied"); break; case ID_STATUS_FREECHAT: AddParam("FreeChat"); break; case ID_STATUS_INVISIBLE: AddParam("Invisible"); break; case ID_STATUS_ONTHEPHONE: AddParam("OnThePhone"); break; case ID_STATUS_OUTTOLUNCH: AddParam("OutToLunch"); break; default: AddParam("Unknown"); break; } return TRUE; } int CSarLuaScript::SetMyStatus(CLuaBridge & luaBridge) { int nNewStatus = 0; lua_State *pFunctionContext = (lua_State*)luaBridge; const char * szStatus = lua_tostring(pFunctionContext, -1); if (szStatus == NULL) { return FALSE; } if (strcmp(szStatus, "Online") == 0) { nNewStatus = ID_STATUS_ONLINE; } else if (strcmp(szStatus, "Offline") == 0) { nNewStatus = ID_STATUS_OFFLINE; } else if (strcmp(szStatus, "Away") == 0) { nNewStatus = ID_STATUS_AWAY; } else if (strcmp(szStatus, "DND") == 0) { nNewStatus = ID_STATUS_DND; } else if (strcmp(szStatus, "NA") == 0) { nNewStatus = ID_STATUS_NA; } else if (strcmp(szStatus, "Occupied") == 0) { nNewStatus = ID_STATUS_OCCUPIED; } else if (strcmp(szStatus, "FreeChat") == 0) { nNewStatus = ID_STATUS_FREECHAT; } else if (strcmp(szStatus, "Invisible") == 0) { nNewStatus = ID_STATUS_INVISIBLE; } else if (strcmp(szStatus, "OnThePhone") == 0) { nNewStatus = ID_STATUS_ONTHEPHONE; } else if (strcmp(szStatus, "OutToLunch") == 0) { nNewStatus = ID_STATUS_OUTTOLUNCH; } CallService(MS_CLIST_SETSTATUSMODE, (WPARAM)nNewStatus, (LPARAM)0); return FALSE; } typedef map MapOfStrings; MapOfStrings g_MapOfVariables; int CSarLuaScript::SetVariable(CLuaBridge & luaBridge) { lua_State *pFunctionContext = (lua_State*)luaBridge; UINT nNameLength = lua_strlen(pFunctionContext, -2); const char * szName = lua_tostring(pFunctionContext, -2); UINT nVariableLength = lua_strlen(pFunctionContext, -1); const char * szVariable = lua_tostring(pFunctionContext, -1); if (szName == NULL || szVariable == NULL) { return FALSE; } wchar_t * szwName = Utf8toUtf16((char*)szName, nNameLength); wchar_t * szwVariable = Utf8toUtf16((char*)szVariable, nVariableLength); if (szwName && szwVariable) { g_MapOfVariables[szwName] = szwVariable; } if (szwName) { free(szwName); } if (szwVariable) { free(szwVariable); } return FALSE; } int CSarLuaScript::GetVariable(CLuaBridge & luaBridge) { lua_State *pFunctionContext = (lua_State*)luaBridge; UINT nNameLength = lua_strlen(pFunctionContext, -1); const char * szName = lua_tostring(pFunctionContext, -1); if (szName == NULL) { return FALSE; } wchar_t * szwName = Utf8toUtf16((char*)szName, nNameLength); if (szwName) { MapOfStrings::iterator it = g_MapOfVariables.find(szwName); if (it != g_MapOfVariables.end()) { UINT nSize = 0; char * szUtf = Utf16toUtf8(it->second.c_str(), nSize); if (szUtf != NULL) { AddParam(szUtf); free(szUtf); free(szwName); return TRUE; } } } if (szwName) { free(szwName); } return FALSE; } int CSarLuaScript::Wait(CLuaBridge & luaBridge) { lua_State *pFunctionContext = (lua_State*)luaBridge; int nSleepInterval = (int)lua_tonumber(pFunctionContext, -1); Sleep(1000 * nSleepInterval); return FALSE; } int CSarLuaScript::FindUser(CLuaBridge & luaBridge) { lua_State *pFunctionContext = (lua_State*)luaBridge; const CHAR * szUser = (CHAR*)lua_tostring(pFunctionContext, -2); const CHAR * szProtocol = (CHAR*)lua_tostring(pFunctionContext, -1); if (szProtocol == NULL || szUser == NULL) { return FALSE; } HANDLE hContact = reinterpret_cast(CallService(MS_DB_CONTACT_FINDFIRST, 0, 0)); CHAR* szContactName = NULL; CHAR* szProto = NULL; DWORD wId = 0; while (hContact != NULL) { szContactName = reinterpret_cast(CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, GCDNF_NOMYHANDLE)); szProto = (CHAR*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); if (szProto && szContactName) { if ( (strcmp(szUser, szContactName)) == 0 && (strcmp(szProto, szProtocol) == 0)) { AddParam((int)hContact); return TRUE; } } hContact = reinterpret_cast (CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM) hContact, 0)); } return FALSE; } void CSarLuaScript::HandleReturns(CLuaBridge & luaBridge, const char *szFunc) { }