From 66526765714b08969548a414d3fa87dbe333242d Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Sat, 28 Jul 2012 19:25:08 +0000 Subject: "!Deprecated" folders moved from root directory to plugins git-svn-id: http://svn.miranda-ng.org/main/trunk@1230 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/!NotAdopted/SmartAutoReplier/SAR.cpp | 462 +++++++++++++++++++++++++++ 1 file changed, 462 insertions(+) create mode 100644 plugins/!NotAdopted/SmartAutoReplier/SAR.cpp (limited to 'plugins/!NotAdopted/SmartAutoReplier/SAR.cpp') diff --git a/plugins/!NotAdopted/SmartAutoReplier/SAR.cpp b/plugins/!NotAdopted/SmartAutoReplier/SAR.cpp new file mode 100644 index 0000000000..a2617b496b --- /dev/null +++ b/plugins/!NotAdopted/SmartAutoReplier/SAR.cpp @@ -0,0 +1,462 @@ +/* + * Smart Auto Replier (SAR) - auto replier plugin for Miranda IM + * + * Copyright (C) 2004 - 2012 by Volodymyr M. Shcherbyna + * + * 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 "resource.h" + +/// these dlg are necessary here.. +#include "gui\settingsdlgholder.h" +#include "gui\EditReplyDlg.h" +#include "gui\addruledlg.h" + +#include "../updater/m_updater.h" + +/// let's advertise myselft and this plugin ;) +#define ICQPROTONAME "SAR" +#if defined( _UNICODE ) +#define ICQPROTODECRSHORT "Smart Auto Replier" +#else +#define ICQPROTODECRSHORT "Smart Auto Replier" +#endif +#define ICQPROTODECR "Plugin is able to reply on all incoming messages, making possible use of rules that are applied to specific contacts. Plugin allows to use Lua scripts as a rules, thus allowing user to make virtually any type of customizations." +#define DEVNAME "Volodymyr M. Shcherbyna" +#define DEVMAIL "volodymyr@shcherbyna.com" +#define DEVCOPYRIGHT "© 2004-2012 Volodymyr M. Shcherbyna, www.shcherbyna.com" +#define DEVWWW "http://www.shcherbyna.com/forum/viewforum.php?f=8" +#define GLOB_HOOKS 3 + +/// global menu items strings... +#define MENU_ITEM_DISABLE_CAPTION TranslateTS(TEXT("Disable Smart Auto Replier")) +#define MENU_ITEM_ENABLE_CAPTION TranslateTS(TEXT("Enable Smart Auto Replier")) + +//#define +/// global data... +HINSTANCE hInst = NULL; /// hinstance +PLUGINLINK *pluginLink = NULL; /// ptr to plugin object +CMessagesHandler *g_pMessHandler = NULL; /// ptr to "main" global manager object +CSettingsDlgHolder *g_pSettingsDlg = NULL; +static HANDLE g_hHook[GLOB_HOOKS] = {NULL}; /// global hooks +CLISTMENUITEM g_mi = {NULL}; /// handle to menu item that is used to switch on/off plugin +CLISTMENUITEM g_miAUR2This = {NULL}; /// handle to menu item that is used to add user to aur +bool g_bEnableMItem = true; /// flag for menu item.. +HANDLE g_hMenuItem; /// global handle to menu service +CCrushLog CRUSHLOGOBJ; /// global object that handles all crushes +LPTSTR g_strPluginName = TEXT(ICQPROTONAME); /// global string that represents plugin name... +INT g_nCurrentMode = 0; /// current mode of a protocol == i duno which exactly protocol... +HANDLE g_hAUR2User = NULL; /// handle to proto service of "autoreply to this user" + +struct MM_INTERFACE mmi; + +/// forming an info structure +PLUGININFOEX pluginInfo = +{ + sizeof(PLUGININFOEX), + ICQPROTODECRSHORT, + PLUGIN_MAKE_VERSION(2, 0, 0, 3), + ICQPROTODECR, + DEVNAME, + DEVMAIL, + DEVCOPYRIGHT, + DEVWWW, + UNICODE_AWARE, + 0, +//#if defined( _UNICODE ) +// // {B9C9AC38-9D81-45D3-A9D7-67A7D8EA9D29} +// { 0xb9c9ac38, 0x9d81, 0x45d3, { 0xa9, 0xd7, 0x67, 0xa7, 0xd8, 0xea, 0x9d, 0x29 } } +//#else + // {9E536082-017E-423B-BF4F-DEDFEB9B3B60} + { 0x9e536082, 0x17e, 0x423b, { 0xbf, 0x4f, 0xde, 0xdf, 0xeb, 0x9b, 0x3b, 0x60 } } +//#endif +}; + +/// mapping into mirandaim.exe +BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved) +{ +BEGIN_PROTECT_AND_LOG_CODE + hInst = hinstDLL; + DisableThreadLibraryCalls(hinstDLL); + return TRUE; +END_PROTECT_AND_LOG_CODE +} + +__declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) +{ + return &pluginInfo; +} + +extern "C" __declspec(dllexport) const MUUID interfaces[] = {MIID_CHAT, MIID_SRMM, MIID_LAST}; + +__declspec(dllexport) const MUUID * MirandaPluginInterfaces(void) +{ + return interfaces; +} + +/// handler of event when the options are choosed +static int OptionsInitialized(WPARAM wp, LPARAM lp) +{ +BEGIN_PROTECT_AND_LOG_CODE + LPTSTR lpszGroup = TranslateTS(TEXT("Plugins")); + OPTIONSDIALOGPAGE optsDialog = {0}; + optsDialog.cbSize = sizeof(OPTIONSDIALOGPAGE); + optsDialog.hInstance = hInst; + optsDialog.position = 910000000; + optsDialog.pszTemplate = (char*)MAKEINTRESOURCE(IDD_SDLGHOLDER); + TCHAR szMax[MAX_PATH] = {0}; + _tcscpy(szMax, TranslateTS(TEXT(ICQPROTODECRSHORT))); + +#ifdef _UNICODE + optsDialog.ptszGroup = lpszGroup; + optsDialog.ptszTitle = szMax; +#else + optsDialog.pszTitle = (char*)szMax; + optsDialog.pszGroup = lpszGroup; +#endif + optsDialog.pfnDlgProc = (DLGPROC)&CSettingsDlgHolder::FakeDlgProc; + optsDialog.flags = ODPF_BOLDGROUPS/*|ODPF_EXPERTONLY*/; /// some lames are scaring that option... +#ifdef _UNICODE + optsDialog.flags |= ODPF_UNICODE; +#endif + + g_pSettingsDlg->m_bDestroying = false; + CallService(MS_OPT_ADDPAGE, wp, reinterpret_cast(&optsDialog)); +END_PROTECT_AND_LOG_CODE + return FALSE; +} + +/// pre building menu item for a contact.. +static int AURContactPreBuildMenu(WPARAM wParam, LPARAM lParam) +{ + LPTSTR lpContactName = g_pMessHandler->GetContactName(reinterpret_cast(wParam)); + CRulesStorage & storage = g_pMessHandler->getSettings().getStorage(); + bool bval = storage.RuleIsRegistered(lpContactName); + + if (bval) + { + g_miAUR2This.flags = CMIM_FLAGS | CMIF_GRAYED; + } + else + { + g_miAUR2This.flags = CMIM_FLAGS; + } + + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)g_hAUR2User, (LPARAM)&g_miAUR2This); + + return 0; +} + +/// handler of clicking on menu item +/// aur to this user... +static int AUR2User(WPARAM wParam, LPARAM lParam) +{ + CAddRuleDlg dlg; + RULE_ITEM item; + item.ContactName = g_pMessHandler->GetContactName(reinterpret_cast(wParam)); + //item.ReplyAction = " "; + item.ReplyText = SETTINGS_DEF_MESSAGE_RULE; + TCHAR rulename[MAX_PATH * 5] = {0}; + _tcscat(rulename, TEXT("reply to ")); + _tcscat(rulename, item.ContactName); + item.RuleName = rulename; + + dlg.m_baur2thisMode = true; + dlg.m_item = item; + dlg.DoModal(); + if (dlg.m_bAddedOk) + { /// already added... + OnRefreshSettings(); + } + + return 0; +} + +/// handler of clicking on menu item enablr/disable plugin... +static int PluginMenuCommand(WPARAM wParam, LPARAM lParam) +{ +BEGIN_PROTECT_AND_LOG_CODE + if (!g_pMessHandler) + return 0; + + if (g_bEnableMItem) + {/// lets handle enabling of AUR feature + g_pMessHandler->MakeAction(true); /// this will enable plugin + } + else + {/// lets handle disabling of AUR feature + g_pMessHandler->MakeAction(false); /// this will disable plugin + } + + /// put here stuff to do + TCHAR sz[MAX_PATH] = {0}; + _tcscpy(sz, (g_bEnableMItem == true ? MENU_ITEM_DISABLE_CAPTION : MENU_ITEM_ENABLE_CAPTION)); + g_mi.pszName = (char*)TranslateTS(sz); + g_mi.flags = CMIM_NAME; + +#ifdef _UNICODE + g_mi.flags |= CMIF_UNICODE; +#endif + +#ifdef _DEBUG + int nretval = +#endif + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)g_hMenuItem, (LPARAM)&g_mi); + + g_bEnableMItem = !g_bEnableMItem; +END_PROTECT_AND_LOG_CODE + return 0; +} + +/// handler that is invoked when mode is changed +static int OnStatusModeChanged(WPARAM wp, LPARAM lp) +{ +BEGIN_PROTECT_AND_LOG_CODE + g_nCurrentMode = static_cast(wp); + if (!g_pMessHandler) + return FALSE; + + bool bNonOnOffLine = (wp != ID_STATUS_ONLINE && + wp != ID_STATUS_OFFLINE && + wp != ID_STATUS_FREECHAT); + + REPLYER_SETTINGS & s = g_pMessHandler->getSettings().getSettings(); + COMMON_RULE_ITEM & r = g_pMessHandler->getSettings().getStorage().getCommonRule(); + + if (!bNonOnOffLine && s.bDisableWhenModeIsSet) + { + if (s.bEnabled) /// plugin is enabled... we have a chance to disable it + { + bool bDisableIt = false; + + if (s.ModeDisValue == 0) + bDisableIt = true; + else if (s.ModeDisValue == 1 && wp == ID_STATUS_ONLINE) + bDisableIt = true; + else if (s.ModeDisValue == 2 && wp == ID_STATUS_FREECHAT) + bDisableIt = true; + + if (bDisableIt) + { /// disable plugin... + PluginMenuCommand(0, 0); + } + } + return FALSE; + } + + if (s.bShowAURDlgWhenModeChanges) + { + CEditReplyDlg dlg; + dlg.m_commRule = r; + + dlg.DoModal(); + if (dlg.m_bAllOk) + { + r = dlg.m_commRule; + } + } + if (s.bEnableWhenModeIsSet) + { + if (!s.bEnabled) + { + bool bEnable = false; + if (s.ModeValue == 0 && bNonOnOffLine) + bEnable = true; + else if (s.ModeValue == 1 && wp == ID_STATUS_DND) + bEnable = true; + else if (s.ModeValue == 2 && wp == ID_STATUS_NA) + bEnable = true; + else if (s.ModeValue == 3 && wp == ID_STATUS_AWAY) + bEnable = true; + else if (s.ModeValue == 4 && wp == ID_STATUS_OCCUPIED) + bEnable = true; + + if (bEnable) /// enabling plugin... (I realize that enabling and disabling is made via ass but i am lazy today) + PluginMenuCommand(0, 0); + } + } + + return FALSE; +END_PROTECT_AND_LOG_CODE + return FALSE; +} + +#ifndef _DEBUG +LPTOP_LEVEL_EXCEPTION_FILTER UnhandledExceptionFilter( + LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter +) +{ + LPTOP_LEVEL_EXCEPTION_FILTER f = {0}; +BEGIN_PROTECT_AND_LOG_CODE + throw f; /// show msgbox to user and store inf to file +END_PROTECT_AND_LOG_CODE + return f; /// let compiler shut ups... +} +#endif + +int OnModulesLoaded(WPARAM wParam, LPARAM lParam) +{ + Update update = {0}; // for c you'd use memset or ZeroMemory... + char szVersion[16]; + + update.cbSize = sizeof(Update); + + update.szComponentName = pluginInfo.shortName; + update.pbVersion = (BYTE*)CreateVersionStringPluginEx(&pluginInfo, szVersion); + update.cpbVersion = strlen((char*)update.pbVersion); + + // these are the three lines that matter - the archive, the page containing the version string, and the text (or data) + // before the version that we use to locate it on the page + // (note that if the update URL and the version URL point to standard file listing entries, the backend xml + // data will be used to check for updates rather than the actual web page - this is not true for beta urls) + //update.szUpdateURL = "http://www.shcherbyna.com/files/sar/SAR.zip"; + //update.szVersionURL = "http://www.shcherbyna.com/files/sar/SAR.html"; + + update.szUpdateURL = "http://addons.miranda-im.org/details.php?action=viewfile&id=1609"; + + //update.pbVersionPrefix = (BYTE *)"SAR version "; + + //update.cpbVersionPrefix = strlen((char *)update.pbVersionPrefix); + + // do the same for the beta versions of the above struct members if you wish to allow beta updates from another URL + + CallService(MS_UPDATE_REGISTER, 0, (WPARAM)&update); + + // Alternatively, to register a plugin with e.g. file ID 2254 on the file listing... + // CallService(MS_UPDATE_REGISTERFL, (WPARAM)2254, (LPARAM)&pluginInfo); + + return 0; +} + +/// loading plugin +extern "C" int __declspec(dllexport) Load(PLUGINLINK *link) +{ +#ifndef _DEBUG + SetUnhandledExceptionFilter(UnhandledExceptionFilter); +#endif +#ifdef _DEBUG + //MessageBox (NULL, __FUNCTION__, __FILE__, MB_OK); +#endif + + CCrushLog::Init(); /// crushes manager should be inited first + int nRetVal = 0; +BEGIN_PROTECT_AND_LOG_CODE + pluginLink = link; + +#ifndef _DEBUG + /// creates help file near plugin + /// if it is absent... + /// note: originally help is in recources of plugin + //CheckForHelpFile(); +#endif + /// main manager... + g_pMessHandler = new CMessagesHandler(); + g_pSettingsDlg = new CSettingsDlgHolder(); + + if (g_pMessHandler) + { /// is inited + REPLYER_SETTINGS & s = g_pMessHandler->getSettings().getSettings(); + if (s.bDisableWhenMirandaIsOn) + { + s.bEnabled = false; + } + else + { + if (s.bEnabled) + g_pMessHandler->HookEvents(); + } + + /// hook main events + //HookEvent(MS_AWAYMSG_SHOWAWAYMSG, OnShow + g_hHook[0] = HookEvent(ME_OPT_INITIALISE, OptionsInitialized); + g_hHook[1] = HookEvent(ME_CLIST_STATUSMODECHANGE, OnStatusModeChanged); + g_hHook[2] = HookEvent(ME_SYSTEM_MODULESLOADED, OnModulesLoaded); + + /// Yushenko Tak, Yanukovich - Mudak. (Orange revolution) + /// this was written in 2004-2005 in Kiev :) + + /// create menu item for disabling / enabling plugin + CreateServiceFunction("AUR/MenuCommand", PluginMenuCommand); + ZeroMemory(&g_mi, sizeof(g_mi)); + g_mi.cbSize = sizeof(g_mi); + g_mi.position = -0x7FFFFFFF; + g_mi.flags = 0; + g_mi.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_SAR_ICON)); //LoadSkinnedIcon(IDI_AUR_ICON/*SKINICON_OTHER_MIRANDA*/); + bool bVal = g_pMessHandler->getSettings().getSettings().bEnabled; + TCHAR sz[MAX_PATH] = {0}; + _tcscpy(sz, bVal ? MENU_ITEM_DISABLE_CAPTION : MENU_ITEM_ENABLE_CAPTION); +#ifdef _UNICODE + g_mi.ptszName = TranslateTS(sz); + g_mi.flags = CMIF_UNICODE; +#else + g_mi.pszName = (char*)TranslateTS(sz); +#endif + g_mi.pszService = "AUR/MenuCommand"; + + g_hMenuItem = (HANDLE)CallService(MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM)&g_mi); + g_bEnableMItem = !bVal; + + /// creating menu item for a contact + ZeroMemory(&g_miAUR2This, sizeof(g_miAUR2This)); + g_miAUR2This.cbSize = sizeof(g_miAUR2This); + g_miAUR2This.position = -2000010000; + g_miAUR2This.flags = 0; + g_miAUR2This.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_SAR_ICON)); + g_miAUR2This.pszContactOwner = NULL; +#ifdef _UNICODE + g_miAUR2This.ptszName = TranslateTS(TEXT("&Smart Auto Reply to this user ...")); + g_miAUR2This.flags = CMIF_UNICODE; +#else + g_miAUR2This.pszName = TranslateTS(TEXT("&Smart Auto Reply to this user ...")); +#endif + CreateServiceFunction("AUR/AURToThis", AUR2User); + g_miAUR2This.pszService = "AUR/AURToThis"; + g_hAUR2User = (HANDLE)CallService(MS_CLIST_ADDCONTACTMENUITEM, 0, (LPARAM)&g_miAUR2This); + HookEvent(ME_CLIST_PREBUILDCONTACTMENU, AURContactPreBuildMenu); + } + + CallService(MS_SYSTEM_GET_MMI, 0, (LPARAM)&mmi); + +END_PROTECT_AND_LOG_CODE + return FALSE; +} + +/// unloading plugin +extern "C" int __declspec(dllexport) Unload(void) +{ +BEGIN_PROTECT_AND_LOG_CODE + for (size_t i = 0; i < GLOB_HOOKS; i++) + UnhookEvent(g_hHook[i]); + + if (g_pSettingsDlg) + { + if (g_pSettingsDlg->IsWindow()) + g_pSettingsDlg->DestroyWindow(); + delete g_pSettingsDlg; + } + if (g_pMessHandler) + { /// unhook manager's events... + g_pMessHandler->UnHookEvents(); + delete g_pMessHandler; /// call dtor + g_pMessHandler = NULL; + } +END_PROTECT_AND_LOG_CODE + + CCrushLog::DeInit(); /// destroy crushes manager obj + return FALSE; +} -- cgit v1.2.3