diff options
Diffstat (limited to 'main.c')
-rw-r--r-- | main.c | 1190 |
1 files changed, 595 insertions, 595 deletions
@@ -1,595 +1,595 @@ -/*
-
-"Spam Filter"-Plugin for Miranda IM
-
-Copyright 2003-2006 Heiko Herkenrath
-
-This program 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 2
-of the License, or (at your option) any later version.
-
-This program 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 this program ("SpamFilter-License.txt"); if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-
-// -- Includes
-#include "common.h"
-
-
-HINSTANCE hInst;
-PLUGINLINK *pluginLink;
-
-
-
-
-// -- Plugin Info
-PLUGININFOEX pluginInfo = {
- sizeof(PLUGININFOEX),
- "Spam Filter Mod (Unicode)",
- PLUGIN_VERSION,
- "Filters out advertisment messages, messages sent by robots and other disliked messages such as hoax messages.", // Gets translated automatically
- "Heiko Herkenrath",
- "", // PLUGIN_EMAIL will get set later
- "© 2003-2006 Heiko Herkenrath",
- "",
- 1,
- 0, // Does not replace anything built-in
- { 0xecb1c450, 0xf71a, 0x425d, { 0xab, 0x63, 0xed, 0x17, 0x5a, 0x86, 0x23, 0x84 } }
-};
-
-// -- Variables: Events/Hooks
-HANDLE hHookModulesLoaded;
-
-// -----------------------------------------
-
-
-static void ThreadInstallation(void* arg)
-{
- WCHAR* szFileName = 0;
-
- if (Miranda_Terminated()) return;
-
- // Install Files
- {
- // Spam Definitions
- // Move "Spam Filter" subdirectory to Miranda IM folder.
- // Since the Plugins directory should only contain DLLs and no additional data files
- GetDefinitionsPath(szFileName, FALSE, NULL);
- PInstallFile(DATA_SUBDIRECTORY, szFileName);
-
- // Documentation
- PConstructLocalPath(szFileName, CSIDL_EXT_EXECUTABLE, DOCS_SUBDIRECTORY, NULL, NULL);
- PInstallFile(_T("SpamFilter-Readme.txt"), szFileName);
- PInstallFile(_T("SpamFilter-License.txt"), szFileName);
- PInstallFile(_T("SpamFilter-SDK.zip"), szFileName);
- PInstallFile(_T("SpamFilter-Translation.txt"), szFileName); // normally in SDK
- PInstallFile(_T("SpamFilter-Developer.txt"), szFileName); // normally in SDK
- PInstallFile(_T("m_spamfilter.h"), szFileName); // normally in SDK
- PInstallFile(_T("m_spamfilter.inc"), szFileName); // normally in SDK
-
- PInstallFile(_T("SpamDefinitions-*.txt"), szFileName); // additional SpamDefs installed
-
- PInstallFile(_T("PCRE-License.txt"), szFileName);
-
- // Sounds
- PConstructLocalPath(szFileName, CSIDL_EXT_EXECUTABLE, SOUNDS_SUBDIRECTORY, NULL, NULL);
- PInstallFile(DEFAULT_ADVERTISMENT_SOUNDFILE, szFileName);
- PInstallFile(DEFAULT_DISLIKEDMESSAGE_SOUNDFILE, szFileName);
- PInstallFile(DEFAULT_ROBOT_SOUNDFILE, szFileName);
-
- // DLLs (non-plugin)
- PInstallDLLFile(_T("pcre.dll"), TRUE, TRUE);
-
- // InstallScript.xml
- PConstructLocalPath(szFileName, CSIDL_EXT_MODULE, NULL, _T("InstallScript.xml"), NULL);
- DeleteFile(szFileName);
- }
-
- if (Miranda_Terminated()) return;
-
- // Add default list items
- {
- STRINGLIST* pslWords = SLNewList();
-
- // Create default bad words
- if (!IsSpamDefinitionDataPresent(SDID_CUSTOM_BADWORDS))
- {
- SLAddItem(pslWords, TranslateT("Automated message"));
- SetSpamDefinitionData(pslWords, SDID_CUSTOM_BADWORDS, NULL);
-
- SLClearList(pslWords);
- }
-
- // Create default good words
- if (!IsSpamDefinitionDataPresent(SDID_CUSTOM_GOODWORDS))
- {
- SLAddItem(pslWords, TranslateT("Miranda IM"));
- SetSpamDefinitionData(pslWords, SDID_CUSTOM_GOODWORDS, NULL);
-
- SLClearList(pslWords);
- }
-
- // Create default disliked message words
- if (!IsSpamDefinitionDataPresent(SDID_CUSTOM_DISLIKEDWORDS))
- {
- SLAddItem(pslWords, TranslateT("Please forward"));
- SetSpamDefinitionData(pslWords, SDID_CUSTOM_DISLIKEDWORDS, NULL);
- }
-
- SLFreeList(pslWords);
- }
-
- if (Miranda_Terminated()) return;
-
- // On First Run
- if (DBGetContactSettingDword(NULL, DB_MODULE_NAME, DB_SETTING_FIRSTRUNDONE, 0) != PLUGIN_VERSION) // no use of "<"!
- {
- // Import bad words v1.0.4.0 -> v2.0.0.0 (DB->FILE converter)
- {
- STRINGLIST* pslBadWords = NULL;
- STRINGLIST* pslDefaultBadWords = NULL;
- int i;
- char szSetting[7+MAX_INT_LENGTH+1];
- DBVARIANT dbv;
-
- // Get old bad words out of database
- for (i=0;; i++) // no break condition
- {
- mir_snprintf(szSetting, ARRAYSIZE(szSetting), "BadWord%i", i);
-
- if (DBGetContactSettingTString(NULL, "SpamFilter", szSetting, &dbv) != 0)
- break;
-
- // Load default list when needed
- if (!pslBadWords)
- {
- pslDefaultBadWords = SLNewList();
- pslBadWords = SLNewList();
-
- // Load default bad words
- GetSpamDefinitionData(pslDefaultBadWords, SDID_BADWORDS);
-
- // Load bad words already in file
- GetSpamDefinitionData(pslBadWords, SDID_CUSTOM_BADWORDS);
- }
-
- if (!SLIsItem(pslDefaultBadWords, dbv.ptszVal, FALSE) && !SLIsItem(pslBadWords, dbv.ptszVal, FALSE))
- SLAddItem(pslBadWords, dbv.ptszVal);
-
- DBFreeVariant(&dbv);
-
- // Delete old setting (important! else it will reimport every version change)
- DBDeleteContactSetting(NULL, "SpamFilter", szSetting);
- }
-
- // Save old and new bad words
- if (pslBadWords) {
- SetSpamDefinitionData(pslBadWords, SDID_CUSTOM_BADWORDS, NULL);
- SLFreeList(pslBadWords);
- }
- if (pslDefaultBadWords)
- SLFreeList(pslDefaultBadWords);
- }
-
- if (Miranda_Terminated()) return;
-
- // Import old spammers in database of v2.0.1.0 (DB->DB converter)
- {
- WCHAR* pszSuffix = _T(" (Spammer)"); // readonly allocated
- WCHAR* pszSuffixT = TranslateTS(pszSuffix);
- WCHAR* pszUserName;
- HANDLE hContact;
- BOOL bIsOldSpammer;
-
- if (pszSuffix)
- {
- for (hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0); hContact; hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hContact,0))
- {
- // Skip if not hidden
- if (!DBGetContactSettingByte(hContact, "CList", "Hidden", 0))
- continue;
-
- // Skip if is already "new" spammer
- if (CallService(MS_SPAMFILTER_CONTACT_ISSPAMMER, (WPARAM)hContact, 0))
- continue;
-
- pszUserName = (WCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, (LPARAM)GCDNF_UNICODE);
-
- // Find suffix
- bIsOldSpammer = FALSE;
- if (lstrlen(pszUserName) > lstrlen(pszSuffix))
- if (StrCmp(pszUserName+lstrlen(pszUserName)-lstrlen(pszSuffix), pszSuffix) == 0)
- bIsOldSpammer = TRUE;
- if (lstrlen(pszUserName) > lstrlen(pszSuffixT))
- if (StrCmp(pszUserName+lstrlen(pszUserName)-lstrlen(pszSuffixT), pszSuffixT) == 0)
- bIsOldSpammer = TRUE;
-
- if (bIsOldSpammer)
- CallService(MS_SPAMFILTER_CONTACT_SETASSPAMMER, (WPARAM)hContact, (LPARAM)SCASF_NO_NOTIFY|SCASF_NO_REMOVE_HISTORY|SCASF_NO_DENY_AUTHREQUESTS);
- }
- }
-
- }
-
- if (Miranda_Terminated()) return;
-
- // Import Spam Definition Data previous to v2.5.0.0 (ANSI->UTF8 converter)
- {
- // own-badwords.sfw
- PConstructLocalPath(szFileName, CSIDL_EXT_MIRANDAPROFILE, _T("Spam Filter"), _T("own-badwords.sfw"), NULL);
- mir_utf8encodeW(szFileName); // current codepage
-
- // own-goodwords.sfw
- PConstructLocalPath(szFileName, CSIDL_EXT_MIRANDAPROFILE, _T("Spam Filter"), _T("own-goodwords.sfw"), NULL);
- mir_utf8encodeW(szFileName); // current codepage
-
- // own-dislikedwords.sfw
- PConstructLocalPath(szFileName, CSIDL_EXT_MIRANDAPROFILE, _T("Spam Filter"), _T("own-dislikedwords.sfw"), NULL);
- mir_utf8encodeW(szFileName); // current codepage
-
- // BadWords\*.sfw
- PConstructLocalPath(szFileName, CSIDL_EXT_EXECUTABLE, _T("Spam Filter\\BadWords"), _T("Chinese (Traditional).sfw"), NULL);
- mir_utf8encodeW(szFileName); // big5 codepage (Chinese) [PRC and Singapore have other codepages]
- PConstructLocalPath(szFileName, CSIDL_EXT_EXECUTABLE, _T("Spam Filter\\BadWords"), _T("Russian.sfw"), NULL);
- mir_utf8encodeW(szFileName); // cp-1251 codepage (Russian)
- PConstructLocalPath(szFileName, CSIDL_EXT_EXECUTABLE, _T("Spam Filter\\BadWords"), _T("English.sfw"), NULL);
- mir_utf8encodeW(szFileName); // English, German, French, Portuguese codepage (European)
- PConstructLocalPath(szFileName, CSIDL_EXT_EXECUTABLE, _T("Spam Filter\\BadWords"), _T("German.sfw"), NULL);
- mir_utf8encodeW(szFileName); // English, German, French, Portuguese codepage (European)
- PConstructLocalPath(szFileName, CSIDL_EXT_EXECUTABLE, _T("Spam Filter\\BadWords"), _T("French.sfw"), NULL);
- mir_utf8encodeW(szFileName); // English, German, French, Portuguese codepage (European)
- PConstructLocalPath(szFileName, CSIDL_EXT_EXECUTABLE, _T("Spam Filter\\BadWords"), _T("Portuguese (Brazil).sfw"), NULL);
- mir_utf8encodeW(szFileName); // English, German, French, Portuguese codepage (European)
- PConstructLocalPath(szFileName, CSIDL_EXT_EXECUTABLE, _T("Spam Filter\\BadWords"), _T("*.sfw"), NULL);
- mir_utf8encodeW(szFileName); // customized reminder
-
- // HoaxTexts\*.sft
- PConstructLocalPath(szFileName, CSIDL_EXT_EXECUTABLE, _T("Spam Filter\\HoaxTexts"), _T("Example.sft"), NULL);
- mir_utf8encodeW(szFileName); // English, German, French, Portuguese codepage (European)
- PConstructLocalPath(szFileName, CSIDL_EXT_EXECUTABLE, _T("Spam Filter\\HoaxTexts"), _T("Example.sft"), NULL);
- mir_utf8encodeW(szFileName); // customized reminder
-
- // Teasers\*.sft
- PConstructLocalPath(szFileName, CSIDL_EXT_EXECUTABLE, _T("Spam Filter\\Teasers"), _T("English.sft"), NULL);
- mir_utf8encodeW(szFileName); // English, German, French, Portuguese codepage (European)
- PConstructLocalPath(szFileName, CSIDL_EXT_EXECUTABLE, _T("Spam Filter\\Teasers"), _T("German.sft"), NULL);
- mir_utf8encodeW(szFileName); // English, German, French, Portuguese codepage (European)
- PConstructLocalPath(szFileName, CSIDL_EXT_EXECUTABLE, _T("Spam Filter\\Teasers"), _T("*.sft"), NULL);
- mir_utf8encodeW(szFileName); // reminder customized
-
- // Urls\*.sfc
- PConstructLocalPath(szFileName, CSIDL_EXT_EXECUTABLE, _T("Spam Filter\\Urls"), _T("*.sfc"), NULL);
- mir_utf8encodeW(szFileName); // url strings are all English
-
- // PhoneNumbers\*.sfc
- PConstructLocalPath(szFileName, CSIDL_EXT_EXECUTABLE, _T("Spam Filter\\PhoneNumbers"), _T("Russian.sfc"), NULL);
- mir_utf8encodeW(szFileName); // cp-1251 codepage (Russian)
- PConstructLocalPath(szFileName, CSIDL_EXT_EXECUTABLE, _T("Spam Filter\\PhoneNumbers"), _T("German.sfc"), NULL);
- mir_utf8encodeW(szFileName); // English, German, French, Portuguese codepage (European)
- PConstructLocalPath(szFileName, CSIDL_EXT_EXECUTABLE, _T("Spam Filter\\PhoneNumbers"), _T("*.sfc"), NULL);
- mir_utf8encodeW(szFileName); // reminder customizd
-
- // Spammers\*.sfc
- PConstructLocalPath(szFileName, CSIDL_EXT_EXECUTABLE, _T("Spam Filter\\Spammers"), _T("Russian.sfc"), NULL);
- mir_utf8encodeW(szFileName); // cp-1251 codepage (Russian)
- PConstructLocalPath(szFileName, CSIDL_EXT_EXECUTABLE, _T("Spam Filter\\Spammers"), _T("*.sfc"), NULL);
- mir_utf8encodeW(szFileName); // reminder customized
-
- // format_text.sfc
- PConstructLocalPath(szFileName, CSIDL_EXT_EXECUTABLE, _T("Spam Filter"), _T("format_text.sfc"), NULL);
- mir_utf8encodeW(szFileName); // was English only
-
- // format_numbers.sfc
- PConstructLocalPath(szFileName, CSIDL_EXT_EXECUTABLE, _T("Spam Filter"), _T("format_numbers.sfc"), NULL);
- mir_utf8encodeW(szFileName); // was English only
-
- // separators.sfc
- PConstructLocalPath(szFileName, CSIDL_EXT_EXECUTABLE, _T("Spam Filter"), _T("separators.sfc"), NULL);
- mir_utf8encodeW(szFileName); // was English only
- }
-
- if (Miranda_Terminated()) return;
-
- if (DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENTFILTER, (BYTE)DEFAULT_SETTING_ADVERTISMENTFILTER) || DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ROBOTFILTER, (BYTE)DEFAULT_SETTING_ROBOTFILTER))
- {
- CallService(MS_IGNORE_UNIGNORE, (WPARAM)NULL, (LPARAM)IGNOREEVENT_MESSAGE);
- CallService(MS_IGNORE_UNIGNORE, (WPARAM)NULL, (LPARAM)IGNOREEVENT_URL);
- CallService(MS_IGNORE_UNIGNORE, (WPARAM)NULL, (LPARAM)IGNOREEVENT_FILE);
- CallService(MS_IGNORE_UNIGNORE, (WPARAM)NULL, (LPARAM)IGNOREEVENT_AUTHORIZATION);
-
- CallService(MS_IGNORE_IGNORE, (WPARAM)NULL, (LPARAM)IGNOREEVENT_USERONLINE);
-
- {
- DBVARIANT dbv;
-
- if (DBGetContactSetting(NULL, "SRMM", "UnknownTyping", &dbv) == 0) // If existant
- {
- if (dbv.type == DBVT_BYTE)
- DBWriteContactSettingByte(NULL, "SRMM", "UnknownTyping", 0);
- DBFreeVariant(&dbv);
- }
- }
- }
-
- // Disable "old"/other spam plugins (if installed) to avoid conflicts and user confusion
- // (All features of them included in Spam Filter)
- if (GetModuleHandle(_T("SpamBlock")))
- DBWriteContactSettingByte(NULL, "PluginDisable", "spamblock.dll", 1);
- if (GetModuleHandle(_T("SpamBlockPlus")))
- DBWriteContactSettingByte(NULL, "PluginDisable", "spamblockplus.dll", 1);
- if (GetModuleHandle(_T("spamreturner")))
- DBWriteContactSettingByte(NULL, "PluginDisable", "spamreturner.dll", 1);
- if (GetModuleHandle(_T("stopspam"))) {
- DBWriteContactSettingByte(NULL, "PluginDisable", "stopspam.dll", 1);
- DBWriteContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ROBOTFILTER, (BYTE)TRUE);
- }
- if (GetModuleHandle(_T("ignorecontact")))
- DBWriteContactSettingByte(NULL, "PluginDisable", "ignorecontact.dll", 1);
-
- #if defined (UNICODE)
- DBWriteContactSettingByte(NULL, "PluginDisable", "spamfilter.dll", 1);
- #else
- DBWriteContactSettingByte(NULL, "PluginDisable", "spamfilterw.dll", 1);
- #endif
-
- // FirstRunDone
- DBWriteContactSettingDword(NULL, DB_MODULE_NAME, DB_SETTING_FIRSTRUNDONE, PLUGIN_VERSION);
- }
-}
-
-
-__declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion)
-{
- if (mirandaVersion < NEEDED_MIRANDA_VERSION)
- {
- // No Translate() here! (langpack service not yet loaded, no need anyway)
- MessageBoxEx(NULL, _T("The Spam Filter plugin can not be loaded. It requires Miranda IM ")_T(NEEDED_MIRANDA_VERSION_STR)_T(" or later."), _T("Spam Filter Plugin"), MB_OK|MB_ICONERROR|MB_SETFOREGROUND|MB_TOPMOST|MB_TASKMODAL, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US));
- return NULL;
- }
-
- return &pluginInfo;
-}
-static const MUUID interfaces[] = {MIID_SERVICEMODE, MIID_LAST};
-__declspec(dllexport) const MUUID* MirandaPluginInterfaces(void)
-{
- return interfaces;
-}
-
-
-
-BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
-{
- hInst = hinstDLL;
-
- return TRUE;
-}
-
-
-
-static int AllModulesLoaded(WPARAM wParam, LPARAM lParam)
-{
- AssignAllContacts();
-
- // Custom Profile Folder Plugin support (as early as possible!)
- InitFolders();
-
- // Definition file cache (after folder)
- InitSpamDefinitions();
-
- // Load regular expressions DLL
- // Important: Not in Load() to allow other plugins to update/replace the DLL in their Load()
- InitRegExp();
-
- // Trigger Plugin support
- InitTrigger();
-
- // Add message types for filter
- {
- int i, iProtoCount = 0;
- WCHAR szProtoNameBuf[256];
- WCHAR* pszProtoName;
- DWORD dwProtoCaps, dwProtoCaps4;
- HICON hProtoIcon;
- PROTOCOLDESCRIPTOR** appd = NULL;
-
- if (CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM)&iProtoCount, (LPARAM)&appd) == 0)
- {
- for (i=0; i<iProtoCount; i++)
- {
- if (appd[i]->type != PROTOTYPE_PROTOCOL) continue;
-
- // Get capabilities
- dwProtoCaps = CallProtoService(appd[i]->szName, PS_GETCAPS, (WPARAM)PFLAGNUM_1, 0);
- if ((int)dwProtoCaps == CALLSERVICE_NOTFOUND) continue;
- dwProtoCaps4 = CallProtoService(appd[i]->szName, PS_GETCAPS, (WPARAM)PFLAGNUM_4, 0);
-
- // Get icon
- hProtoIcon = (HICON)CallProtoService(appd[i]->szName, PS_LOADICON, PLI_PROTOCOL|PLIF_SMALL, 0);
- if ((int)hProtoIcon == CALLSERVICE_NOTFOUND) hProtoIcon = NULL;
-
- // Get readable name
- #if defined(UNICODE)
- if (CallProtoService(appd[i]->szName, PS_GETNAME"W", ARRAYSIZE(szProtoNameBuf), (LPARAM)szProtoNameBuf) == 0) {
- pszProtoName = szProtoNameBuf;
- } else if (CallProtoService(appd[i]->szName, PS_GETNAME, ARRAYSIZE(szProtoNameBuf), (LPARAM)szProtoNameBuf) == 0) {
- pszProtoName = (WCHAR*)mir_utf8encodeW(szProtoNameBuf);
- } else {
- pszProtoName = (WCHAR*)mir_utf8encodeW((WCHAR*)appd[i]->szName);
- }
- #else
- if (CallProtoService(appd[i]->szName, PS_GETNAME, ARRAYSIZE(szProtoNameBuf), (LPARAM)szProtoNameBuf) == 0) {
- pszProtoName = szProtoNameBuf;
- } else {
- pszProtoName = appd[i]->szName;
- }
- #endif
-
- // Authorization Requests (flag supported and display module installed)
- if (dwProtoCaps&PF1_AUTHREQ)
- SFRegisterMessageType(appd[i]->szName, pszProtoName, hProtoIcon, SFMT_AUTHREQUEST, TranslateT("Authorization Request"), (HICON)-SKINICON_OTHER_MIRANDA, 100, ((dwProtoCaps4&PF4_FORCEAUTH) ? MTDF_DEFAULTDISABLED : 0));
-
- // YouWereAdded Notification (flag supported and display module installed)
- if (dwProtoCaps&PF1_ADDED)
- SFRegisterMessageType(appd[i]->szName, pszProtoName, hProtoIcon, SFMT_ADDED, TranslateT("Added Notification"), (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(210), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED), 110, ((dwProtoCaps4&PF4_FORCEADDED) ? MTDF_DEFAULTDISABLED : 0));
-
- // Special support for ICQ (workaround, quite hacky)
- if (StrCmpA(appd[i]->szName, "ICQ") == 0)
- {
- // WebPager (display module installed: WebPager Plugin)
- if (ServiceExists("WebPager/ReceiveWebPager"))
- SFRegisterMessageType(appd[i]->szName, pszProtoName, hProtoIcon, "WebPager", TranslateT("WebPager"), GetModuleHandle(_T("WebPager")) ? (HICON)LoadImage(GetModuleHandle(_T("WebPager")), MAKEINTRESOURCE(101), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED) : NULL, 200, 0);
-
- // EmailExpress (display module installed: EmailExpress Plugin)
- if (ServiceExists("EmailExpress/ReceiveEmailExpress"))
- SFRegisterMessageType(appd[i]->szName, pszProtoName, hProtoIcon, "EmailExpress", TranslateT("EmailExpress"), GetModuleHandle(_T("EmailExpress")) ? (HICON)LoadImage(GetModuleHandle(_T("EmailExpress")), MAKEINTRESOURCE(102), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED) : NULL, 210, 0);
- }
-
- // Instant Messages (flag supported and display module installed)
- if ((dwProtoCaps&PF1_IMRECV) && ServiceExists(MS_MSG_SENDMESSAGE))
- SFRegisterMessageType(appd[i]->szName, pszProtoName, hProtoIcon, SFMT_MESSAGE, TranslateT("Message"), (HICON)-SKINICON_EVENT_MESSAGE, 300, ((dwProtoCaps&PF1_IMSEND) ? 0 : MTDF_DEFAULTDISABLED));
-
- // URLs (flag supported and display module installed)
- if ((dwProtoCaps&PF1_URLRECV) && ServiceExists(MS_URL_SENDURL))
- SFRegisterMessageType(appd[i]->szName, pszProtoName, hProtoIcon, SFMT_URL, TranslateT("URL"), (HICON)-SKINICON_EVENT_URL, 400, ((dwProtoCaps&PF1_URLSEND) ? 0 : MTDF_DEFAULTDISABLED));
-
- // File Transfers (flag supported and display module installed)
- if ((dwProtoCaps&PF1_FILERECV) && ServiceExists(MS_FILE_SENDFILE))
- SFRegisterMessageType(appd[i]->szName, pszProtoName, hProtoIcon, SFMT_FILE, TranslateT("File"), (HICON)-SKINICON_EVENT_FILE, 500, ((dwProtoCaps&PF1_FILESEND) ? 0 : MTDF_DEFAULTDISABLED));
-
- // Contact Transfers (flag supported and display module installed)
- if ((dwProtoCaps&PF1_CONTACTRECV) && ServiceExists(MS_CONTACTS_SEND))
- SFRegisterMessageType(appd[i]->szName, pszProtoName, hProtoIcon, SFMT_CONTACTS, TranslateT("Contacts"), GetModuleHandle(_T("contacts")) ? (HICON)LoadImage(GetModuleHandle(_T("contacts")), MAKEINTRESOURCE(109), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED) : NULL, 600, ((dwProtoCaps&PF1_CONTACTSEND) ? 0 : MTDF_DEFAULTDISABLED));
-
-
- if (hProtoIcon) DestroyIcon(hProtoIcon); // must be destroyed
-
- #if defined(UNICODE)
- if (pszProtoName != szProtoNameBuf)
- mir_free(pszProtoName);
- #endif
- }
- }
- }
-
- // Options
- InitOptions();
-
- // Add sounds
- SkinAddNewSoundBundled(DB_SOUND_ADVERTISMENT_SETTING, Translate("Spam Filter"), Translate("Advertisment Alert"), DEFAULT_ADVERTISMENT_SOUNDFILE);
- SkinAddNewSoundBundled(DB_SOUND_DISLIKEDMESSAGE_SETTING, Translate("Spam Filter"), Translate("Disliked Message Alert"), DEFAULT_DISLIKEDMESSAGE_SOUNDFILE);
- SkinAddNewSoundBundled(DB_SOUND_ROBOT_SETTING, Translate("Spam Filter"), Translate("Robot Alert"), DEFAULT_ROBOT_SOUNDFILE);
-
- // Add known database modules (Support for DBEditor++)
- if (ServiceExists("DBEditorpp/RegisterModule"))
- {
- const char* apszModuleNames[] = {DB_MODULE_NAME, DB_MODULE_NAME_MSGTYPES, DB_MODULE_NAME_PRESPAMMERS};
- CallService("DBEditorpp/RegisterModule", (WPARAM)apszModuleNames, (LPARAM)ARRAYSIZE(apszModuleNames));
- }
-
- // Support for own variables in Variables-Plugin
- InitVariables();
-
- // Init CList extra image (for spammers)
- InitExtraImg();
-
- // Support for Popup/PopupPlus Plugin
- if (IsPopupAvailable(FALSE))
- {
- BOOL bFilterActive = DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENTFILTER, DEFAULT_SETTING_ADVERTISMENTFILTER) || DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_DISLIKEDMESSAGEFILTER, DEFAULT_SETTING_DISLIKEDMESSAGEFILTER);
- BOOL bPopupsActive = DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_POPUP, DEFAULT_SETTING_POPUP);
-
- InitPopup();
-
- // Init popup menu item
- SetPopupMenuItem(bPopupsActive, !bFilterActive);
-
- // Add colors
- SkinAddNewColor(DB_COLOR_POPUPBACKGROUND_SETTING, Translate("Spam Filter"), Translate("Popup Background"), RGB(213,209,208), FALSE);
- SkinAddNewColor(DB_COLOR_POPUPTEXT_SETTING, Translate("Spam Filter"), Translate("Popup Text"), RGB(193,0,38), FALSE);
- }
-
- // Init contact menu item
- InitMenuItems();
-
- // SpamFilter fully loaded
- NotifyModuleLoaded();
- return 0;
-}
-
-
-__declspec(dllexport) int Load(PLUGINLINK* link)
-{
- pluginLink = (PLUGINLINK*)link;;
-
- hwndSpamFilterOpt = NULL;
- hwndAdvertismentFilter = NULL;
- hwndRobotFilter = NULL;
- hwndDislikedMessagesFilter = NULL;
- hwndSpamDefinitionsInfo = NULL;
- hwndSpammersInfo = NULL;
-
- if (!ServiceExists(MS_DB_CONTACT_GETSETTING_STR))
- {
- // No Translate() here
- MessageBoxEx(NULL, _T("The Spam Filter plugin requires database driver (db3x) 0.5.1.0 or later."), _T("Spam Filter Plugin"), MB_OK|MB_ICONERROR|MB_SETFOREGROUND|MB_TOPMOST|MB_TASKMODAL, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US));
- return 1;
- }
-
- // Load Unicode version only for Unicode core
- {
- char szVer[128];
- if (CallService(MS_SYSTEM_GETVERSIONTEXT, (WPARAM)ARRAYSIZE(szVer), (LPARAM)szVer) == 0)
- if (!StrStrA(szVer, "Unicode")) {
- OutputDebugString(_T("Spam Filter: No Unicode core, Unicode version not loaded.\r\n"));
- return 1;
- }
- }
-
- // Get Miranda's simple memory problems catcher
-
- memset(&memoryManagerInterface,0,sizeof(memoryManagerInterface));
- memoryManagerInterface.cbSize = sizeof(memoryManagerInterface);
- CallService(MS_SYSTEM_GET_MMI, 0, (LPARAM)&memoryManagerInterface);
- mir_getUTFI( &utfi );
-
- // Init SpamFilter-API
- InitServices();
-
- // Establish the filter protocol
- InitSpamCheck();
-
- // Installation (making sure files are placed correctly)
- forkthread(ThreadInstallation, 0, NULL);
- hHookModulesLoaded = HookEvent(ME_SYSTEM_MODULESLOADED, AllModulesLoaded);
- if (!hHookModulesLoaded) CallService(MS_SPAMFILTER_SHOWERROR, SFSE_CRITICAL_ERROR, 0);
-
- return 0;
-}
-
-
-__declspec(dllexport) int Unload(void)
-{
- if (hHookModulesLoaded) UnhookEvent(hHookModulesLoaded);
- UninitExtraImg();
- UninitMenuItems();
- UninitOptions();
- UninitPopup();
- UninitSpamCheck();
- UninitVariables();
- UninitServices();
- UninitRegExp();
- UninitSpamDefinitions();
- UninitTrigger();
- UninitFolders();
- return 0;
-}
-
-
+/* + +"Spam Filter"-Plugin for Miranda IM + +Copyright 2003-2006 Heiko Herkenrath + +This program 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 2 +of the License, or (at your option) any later version. + +This program 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 this program ("SpamFilter-License.txt"); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + + +// -- Includes +#include "common.h" + + +HINSTANCE hInst; +PLUGINLINK *pluginLink; + + + + +// -- Plugin Info +PLUGININFOEX pluginInfo = { + sizeof(PLUGININFOEX), + "Spam Filter Mod (Unicode)", + PLUGIN_VERSION, + "Filters out advertisment messages, messages sent by robots and other disliked messages such as hoax messages.", // Gets translated automatically + "Heiko Herkenrath", + "", // PLUGIN_EMAIL will get set later + "© 2003-2006 Heiko Herkenrath", + "", + 1, + 0, // Does not replace anything built-in + { 0xecb1c450, 0xf71a, 0x425d, { 0xab, 0x63, 0xed, 0x17, 0x5a, 0x86, 0x23, 0x84 } } +}; + +// -- Variables: Events/Hooks +HANDLE hHookModulesLoaded; + +// ----------------------------------------- + + +static void ThreadInstallation(void* arg) +{ + WCHAR* szFileName = 0; + + if (Miranda_Terminated()) return; + + // Install Files + { + // Spam Definitions + // Move "Spam Filter" subdirectory to Miranda IM folder. + // Since the Plugins directory should only contain DLLs and no additional data files + GetDefinitionsPath(szFileName, FALSE, NULL); + PInstallFile(DATA_SUBDIRECTORY, szFileName); + + // Documentation + PConstructLocalPath(szFileName, CSIDL_EXT_EXECUTABLE, DOCS_SUBDIRECTORY, NULL, NULL); + PInstallFile(_T("SpamFilter-Readme.txt"), szFileName); + PInstallFile(_T("SpamFilter-License.txt"), szFileName); + PInstallFile(_T("SpamFilter-SDK.zip"), szFileName); + PInstallFile(_T("SpamFilter-Translation.txt"), szFileName); // normally in SDK + PInstallFile(_T("SpamFilter-Developer.txt"), szFileName); // normally in SDK + PInstallFile(_T("m_spamfilter.h"), szFileName); // normally in SDK + PInstallFile(_T("m_spamfilter.inc"), szFileName); // normally in SDK + + PInstallFile(_T("SpamDefinitions-*.txt"), szFileName); // additional SpamDefs installed + + PInstallFile(_T("PCRE-License.txt"), szFileName); + + // Sounds + PConstructLocalPath(szFileName, CSIDL_EXT_EXECUTABLE, SOUNDS_SUBDIRECTORY, NULL, NULL); + PInstallFile(DEFAULT_ADVERTISMENT_SOUNDFILE, szFileName); + PInstallFile(DEFAULT_DISLIKEDMESSAGE_SOUNDFILE, szFileName); + PInstallFile(DEFAULT_ROBOT_SOUNDFILE, szFileName); + + // DLLs (non-plugin) + PInstallDLLFile(_T("pcre.dll"), TRUE, TRUE); + + // InstallScript.xml + PConstructLocalPath(szFileName, CSIDL_EXT_MODULE, NULL, _T("InstallScript.xml"), NULL); + DeleteFile(szFileName); + } + + if (Miranda_Terminated()) return; + + // Add default list items + { + STRINGLIST* pslWords = SLNewList(); + + // Create default bad words + if (!IsSpamDefinitionDataPresent(SDID_CUSTOM_BADWORDS)) + { + SLAddItem(pslWords, TranslateT("Automated message")); + SetSpamDefinitionData(pslWords, SDID_CUSTOM_BADWORDS, NULL); + + SLClearList(pslWords); + } + + // Create default good words + if (!IsSpamDefinitionDataPresent(SDID_CUSTOM_GOODWORDS)) + { + SLAddItem(pslWords, TranslateT("Miranda IM")); + SetSpamDefinitionData(pslWords, SDID_CUSTOM_GOODWORDS, NULL); + + SLClearList(pslWords); + } + + // Create default disliked message words + if (!IsSpamDefinitionDataPresent(SDID_CUSTOM_DISLIKEDWORDS)) + { + SLAddItem(pslWords, TranslateT("Please forward")); + SetSpamDefinitionData(pslWords, SDID_CUSTOM_DISLIKEDWORDS, NULL); + } + + SLFreeList(pslWords); + } + + if (Miranda_Terminated()) return; + + // On First Run + if (DBGetContactSettingDword(NULL, DB_MODULE_NAME, DB_SETTING_FIRSTRUNDONE, 0) != PLUGIN_VERSION) // no use of "<"! + { + // Import bad words v1.0.4.0 -> v2.0.0.0 (DB->FILE converter) + { + STRINGLIST* pslBadWords = NULL; + STRINGLIST* pslDefaultBadWords = NULL; + int i; + char szSetting[7+MAX_INT_LENGTH+1]; + DBVARIANT dbv; + + // Get old bad words out of database + for (i=0;; i++) // no break condition + { + mir_snprintf(szSetting, ARRAYSIZE(szSetting), "BadWord%i", i); + + if (DBGetContactSettingTString(NULL, "SpamFilter", szSetting, &dbv) != 0) + break; + + // Load default list when needed + if (!pslBadWords) + { + pslDefaultBadWords = SLNewList(); + pslBadWords = SLNewList(); + + // Load default bad words + GetSpamDefinitionData(pslDefaultBadWords, SDID_BADWORDS); + + // Load bad words already in file + GetSpamDefinitionData(pslBadWords, SDID_CUSTOM_BADWORDS); + } + + if (!SLIsItem(pslDefaultBadWords, dbv.ptszVal, FALSE) && !SLIsItem(pslBadWords, dbv.ptszVal, FALSE)) + SLAddItem(pslBadWords, dbv.ptszVal); + + DBFreeVariant(&dbv); + + // Delete old setting (important! else it will reimport every version change) + DBDeleteContactSetting(NULL, "SpamFilter", szSetting); + } + + // Save old and new bad words + if (pslBadWords) { + SetSpamDefinitionData(pslBadWords, SDID_CUSTOM_BADWORDS, NULL); + SLFreeList(pslBadWords); + } + if (pslDefaultBadWords) + SLFreeList(pslDefaultBadWords); + } + + if (Miranda_Terminated()) return; + + // Import old spammers in database of v2.0.1.0 (DB->DB converter) + { + WCHAR* pszSuffix = _T(" (Spammer)"); // readonly allocated + WCHAR* pszSuffixT = TranslateTS(pszSuffix); + WCHAR* pszUserName; + HANDLE hContact; + BOOL bIsOldSpammer; + + if (pszSuffix) + { + for (hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0); hContact; hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hContact,0)) + { + // Skip if not hidden + if (!DBGetContactSettingByte(hContact, "CList", "Hidden", 0)) + continue; + + // Skip if is already "new" spammer + if (CallService(MS_SPAMFILTER_CONTACT_ISSPAMMER, (WPARAM)hContact, 0)) + continue; + + pszUserName = (WCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, (LPARAM)GCDNF_UNICODE); + + // Find suffix + bIsOldSpammer = FALSE; + if (lstrlen(pszUserName) > lstrlen(pszSuffix)) + if (StrCmp(pszUserName+lstrlen(pszUserName)-lstrlen(pszSuffix), pszSuffix) == 0) + bIsOldSpammer = TRUE; + if (lstrlen(pszUserName) > lstrlen(pszSuffixT)) + if (StrCmp(pszUserName+lstrlen(pszUserName)-lstrlen(pszSuffixT), pszSuffixT) == 0) + bIsOldSpammer = TRUE; + + if (bIsOldSpammer) + CallService(MS_SPAMFILTER_CONTACT_SETASSPAMMER, (WPARAM)hContact, (LPARAM)SCASF_NO_NOTIFY|SCASF_NO_REMOVE_HISTORY|SCASF_NO_DENY_AUTHREQUESTS); + } + } + + } + + if (Miranda_Terminated()) return; + + // Import Spam Definition Data previous to v2.5.0.0 (ANSI->UTF8 converter) + { + // own-badwords.sfw + PConstructLocalPath(szFileName, CSIDL_EXT_MIRANDAPROFILE, _T("Spam Filter"), _T("own-badwords.sfw"), NULL); + mir_utf8encodeW(szFileName); // current codepage + + // own-goodwords.sfw + PConstructLocalPath(szFileName, CSIDL_EXT_MIRANDAPROFILE, _T("Spam Filter"), _T("own-goodwords.sfw"), NULL); + mir_utf8encodeW(szFileName); // current codepage + + // own-dislikedwords.sfw + PConstructLocalPath(szFileName, CSIDL_EXT_MIRANDAPROFILE, _T("Spam Filter"), _T("own-dislikedwords.sfw"), NULL); + mir_utf8encodeW(szFileName); // current codepage + + // BadWords\*.sfw + PConstructLocalPath(szFileName, CSIDL_EXT_EXECUTABLE, _T("Spam Filter\\BadWords"), _T("Chinese (Traditional).sfw"), NULL); + mir_utf8encodeW(szFileName); // big5 codepage (Chinese) [PRC and Singapore have other codepages] + PConstructLocalPath(szFileName, CSIDL_EXT_EXECUTABLE, _T("Spam Filter\\BadWords"), _T("Russian.sfw"), NULL); + mir_utf8encodeW(szFileName); // cp-1251 codepage (Russian) + PConstructLocalPath(szFileName, CSIDL_EXT_EXECUTABLE, _T("Spam Filter\\BadWords"), _T("English.sfw"), NULL); + mir_utf8encodeW(szFileName); // English, German, French, Portuguese codepage (European) + PConstructLocalPath(szFileName, CSIDL_EXT_EXECUTABLE, _T("Spam Filter\\BadWords"), _T("German.sfw"), NULL); + mir_utf8encodeW(szFileName); // English, German, French, Portuguese codepage (European) + PConstructLocalPath(szFileName, CSIDL_EXT_EXECUTABLE, _T("Spam Filter\\BadWords"), _T("French.sfw"), NULL); + mir_utf8encodeW(szFileName); // English, German, French, Portuguese codepage (European) + PConstructLocalPath(szFileName, CSIDL_EXT_EXECUTABLE, _T("Spam Filter\\BadWords"), _T("Portuguese (Brazil).sfw"), NULL); + mir_utf8encodeW(szFileName); // English, German, French, Portuguese codepage (European) + PConstructLocalPath(szFileName, CSIDL_EXT_EXECUTABLE, _T("Spam Filter\\BadWords"), _T("*.sfw"), NULL); + mir_utf8encodeW(szFileName); // customized reminder + + // HoaxTexts\*.sft + PConstructLocalPath(szFileName, CSIDL_EXT_EXECUTABLE, _T("Spam Filter\\HoaxTexts"), _T("Example.sft"), NULL); + mir_utf8encodeW(szFileName); // English, German, French, Portuguese codepage (European) + PConstructLocalPath(szFileName, CSIDL_EXT_EXECUTABLE, _T("Spam Filter\\HoaxTexts"), _T("Example.sft"), NULL); + mir_utf8encodeW(szFileName); // customized reminder + + // Teasers\*.sft + PConstructLocalPath(szFileName, CSIDL_EXT_EXECUTABLE, _T("Spam Filter\\Teasers"), _T("English.sft"), NULL); + mir_utf8encodeW(szFileName); // English, German, French, Portuguese codepage (European) + PConstructLocalPath(szFileName, CSIDL_EXT_EXECUTABLE, _T("Spam Filter\\Teasers"), _T("German.sft"), NULL); + mir_utf8encodeW(szFileName); // English, German, French, Portuguese codepage (European) + PConstructLocalPath(szFileName, CSIDL_EXT_EXECUTABLE, _T("Spam Filter\\Teasers"), _T("*.sft"), NULL); + mir_utf8encodeW(szFileName); // reminder customized + + // Urls\*.sfc + PConstructLocalPath(szFileName, CSIDL_EXT_EXECUTABLE, _T("Spam Filter\\Urls"), _T("*.sfc"), NULL); + mir_utf8encodeW(szFileName); // url strings are all English + + // PhoneNumbers\*.sfc + PConstructLocalPath(szFileName, CSIDL_EXT_EXECUTABLE, _T("Spam Filter\\PhoneNumbers"), _T("Russian.sfc"), NULL); + mir_utf8encodeW(szFileName); // cp-1251 codepage (Russian) + PConstructLocalPath(szFileName, CSIDL_EXT_EXECUTABLE, _T("Spam Filter\\PhoneNumbers"), _T("German.sfc"), NULL); + mir_utf8encodeW(szFileName); // English, German, French, Portuguese codepage (European) + PConstructLocalPath(szFileName, CSIDL_EXT_EXECUTABLE, _T("Spam Filter\\PhoneNumbers"), _T("*.sfc"), NULL); + mir_utf8encodeW(szFileName); // reminder customizd + + // Spammers\*.sfc + PConstructLocalPath(szFileName, CSIDL_EXT_EXECUTABLE, _T("Spam Filter\\Spammers"), _T("Russian.sfc"), NULL); + mir_utf8encodeW(szFileName); // cp-1251 codepage (Russian) + PConstructLocalPath(szFileName, CSIDL_EXT_EXECUTABLE, _T("Spam Filter\\Spammers"), _T("*.sfc"), NULL); + mir_utf8encodeW(szFileName); // reminder customized + + // format_text.sfc + PConstructLocalPath(szFileName, CSIDL_EXT_EXECUTABLE, _T("Spam Filter"), _T("format_text.sfc"), NULL); + mir_utf8encodeW(szFileName); // was English only + + // format_numbers.sfc + PConstructLocalPath(szFileName, CSIDL_EXT_EXECUTABLE, _T("Spam Filter"), _T("format_numbers.sfc"), NULL); + mir_utf8encodeW(szFileName); // was English only + + // separators.sfc + PConstructLocalPath(szFileName, CSIDL_EXT_EXECUTABLE, _T("Spam Filter"), _T("separators.sfc"), NULL); + mir_utf8encodeW(szFileName); // was English only + } + + if (Miranda_Terminated()) return; + + if (DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENTFILTER, (BYTE)DEFAULT_SETTING_ADVERTISMENTFILTER) || DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ROBOTFILTER, (BYTE)DEFAULT_SETTING_ROBOTFILTER)) + { + CallService(MS_IGNORE_UNIGNORE, (WPARAM)NULL, (LPARAM)IGNOREEVENT_MESSAGE); + CallService(MS_IGNORE_UNIGNORE, (WPARAM)NULL, (LPARAM)IGNOREEVENT_URL); + CallService(MS_IGNORE_UNIGNORE, (WPARAM)NULL, (LPARAM)IGNOREEVENT_FILE); + CallService(MS_IGNORE_UNIGNORE, (WPARAM)NULL, (LPARAM)IGNOREEVENT_AUTHORIZATION); + + CallService(MS_IGNORE_IGNORE, (WPARAM)NULL, (LPARAM)IGNOREEVENT_USERONLINE); + + { + DBVARIANT dbv; + + if (DBGetContactSetting(NULL, "SRMM", "UnknownTyping", &dbv) == 0) // If existant + { + if (dbv.type == DBVT_BYTE) + DBWriteContactSettingByte(NULL, "SRMM", "UnknownTyping", 0); + DBFreeVariant(&dbv); + } + } + } + + // Disable "old"/other spam plugins (if installed) to avoid conflicts and user confusion + // (All features of them included in Spam Filter) + if (GetModuleHandle(_T("SpamBlock"))) + DBWriteContactSettingByte(NULL, "PluginDisable", "spamblock.dll", 1); + if (GetModuleHandle(_T("SpamBlockPlus"))) + DBWriteContactSettingByte(NULL, "PluginDisable", "spamblockplus.dll", 1); + if (GetModuleHandle(_T("spamreturner"))) + DBWriteContactSettingByte(NULL, "PluginDisable", "spamreturner.dll", 1); + if (GetModuleHandle(_T("stopspam"))) { + DBWriteContactSettingByte(NULL, "PluginDisable", "stopspam.dll", 1); + DBWriteContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ROBOTFILTER, (BYTE)TRUE); + } + if (GetModuleHandle(_T("ignorecontact"))) + DBWriteContactSettingByte(NULL, "PluginDisable", "ignorecontact.dll", 1); + + #if defined (UNICODE) + DBWriteContactSettingByte(NULL, "PluginDisable", "spamfilter.dll", 1); + #else + DBWriteContactSettingByte(NULL, "PluginDisable", "spamfilterw.dll", 1); + #endif + + // FirstRunDone + DBWriteContactSettingDword(NULL, DB_MODULE_NAME, DB_SETTING_FIRSTRUNDONE, PLUGIN_VERSION); + } +} + + +__declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) +{ + if (mirandaVersion < NEEDED_MIRANDA_VERSION) + { + // No Translate() here! (langpack service not yet loaded, no need anyway) + MessageBoxEx(NULL, _T("The Spam Filter plugin can not be loaded. It requires Miranda IM ")_T(NEEDED_MIRANDA_VERSION_STR)_T(" or later."), _T("Spam Filter Plugin"), MB_OK|MB_ICONERROR|MB_SETFOREGROUND|MB_TOPMOST|MB_TASKMODAL, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US)); + return NULL; + } + + return &pluginInfo; +} +static const MUUID interfaces[] = {MIID_SERVICEMODE, MIID_LAST}; +__declspec(dllexport) const MUUID* MirandaPluginInterfaces(void) +{ + return interfaces; +} + + + +BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved) +{ + hInst = hinstDLL; + + return TRUE; +} + + + +static int AllModulesLoaded(WPARAM wParam, LPARAM lParam) +{ + AssignAllContacts(); + + // Custom Profile Folder Plugin support (as early as possible!) + InitFolders(); + + // Definition file cache (after folder) + InitSpamDefinitions(); + + // Load regular expressions DLL + // Important: Not in Load() to allow other plugins to update/replace the DLL in their Load() + InitRegExp(); + + // Trigger Plugin support + InitTrigger(); + + // Add message types for filter + { + int i, iProtoCount = 0; + WCHAR szProtoNameBuf[256]; + WCHAR* pszProtoName; + DWORD dwProtoCaps, dwProtoCaps4; + HICON hProtoIcon; + PROTOCOLDESCRIPTOR** appd = NULL; + + if (CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM)&iProtoCount, (LPARAM)&appd) == 0) + { + for (i=0; i<iProtoCount; i++) + { + if (appd[i]->type != PROTOTYPE_PROTOCOL) continue; + + // Get capabilities + dwProtoCaps = CallProtoService(appd[i]->szName, PS_GETCAPS, (WPARAM)PFLAGNUM_1, 0); + if ((int)dwProtoCaps == CALLSERVICE_NOTFOUND) continue; + dwProtoCaps4 = CallProtoService(appd[i]->szName, PS_GETCAPS, (WPARAM)PFLAGNUM_4, 0); + + // Get icon + hProtoIcon = (HICON)CallProtoService(appd[i]->szName, PS_LOADICON, PLI_PROTOCOL|PLIF_SMALL, 0); + if ((int)hProtoIcon == CALLSERVICE_NOTFOUND) hProtoIcon = NULL; + + // Get readable name + #if defined(UNICODE) + if (CallProtoService(appd[i]->szName, PS_GETNAME"W", ARRAYSIZE(szProtoNameBuf), (LPARAM)szProtoNameBuf) == 0) { + pszProtoName = szProtoNameBuf; + } else if (CallProtoService(appd[i]->szName, PS_GETNAME, ARRAYSIZE(szProtoNameBuf), (LPARAM)szProtoNameBuf) == 0) { + pszProtoName = (WCHAR*)mir_utf8encodeW(szProtoNameBuf); + } else { + pszProtoName = (WCHAR*)mir_utf8encodeW((WCHAR*)appd[i]->szName); + } + #else + if (CallProtoService(appd[i]->szName, PS_GETNAME, ARRAYSIZE(szProtoNameBuf), (LPARAM)szProtoNameBuf) == 0) { + pszProtoName = szProtoNameBuf; + } else { + pszProtoName = appd[i]->szName; + } + #endif + + // Authorization Requests (flag supported and display module installed) + if (dwProtoCaps&PF1_AUTHREQ) + SFRegisterMessageType(appd[i]->szName, pszProtoName, hProtoIcon, SFMT_AUTHREQUEST, TranslateT("Authorization Request"), (HICON)-SKINICON_OTHER_MIRANDA, 100, ((dwProtoCaps4&PF4_FORCEAUTH) ? MTDF_DEFAULTDISABLED : 0)); + + // YouWereAdded Notification (flag supported and display module installed) + if (dwProtoCaps&PF1_ADDED) + SFRegisterMessageType(appd[i]->szName, pszProtoName, hProtoIcon, SFMT_ADDED, TranslateT("Added Notification"), (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(210), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED), 110, ((dwProtoCaps4&PF4_FORCEADDED) ? MTDF_DEFAULTDISABLED : 0)); + + // Special support for ICQ (workaround, quite hacky) + if (StrCmpA(appd[i]->szName, "ICQ") == 0) + { + // WebPager (display module installed: WebPager Plugin) + if (ServiceExists("WebPager/ReceiveWebPager")) + SFRegisterMessageType(appd[i]->szName, pszProtoName, hProtoIcon, "WebPager", TranslateT("WebPager"), GetModuleHandle(_T("WebPager")) ? (HICON)LoadImage(GetModuleHandle(_T("WebPager")), MAKEINTRESOURCE(101), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED) : NULL, 200, 0); + + // EmailExpress (display module installed: EmailExpress Plugin) + if (ServiceExists("EmailExpress/ReceiveEmailExpress")) + SFRegisterMessageType(appd[i]->szName, pszProtoName, hProtoIcon, "EmailExpress", TranslateT("EmailExpress"), GetModuleHandle(_T("EmailExpress")) ? (HICON)LoadImage(GetModuleHandle(_T("EmailExpress")), MAKEINTRESOURCE(102), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED) : NULL, 210, 0); + } + + // Instant Messages (flag supported and display module installed) + if ((dwProtoCaps&PF1_IMRECV) && ServiceExists(MS_MSG_SENDMESSAGE)) + SFRegisterMessageType(appd[i]->szName, pszProtoName, hProtoIcon, SFMT_MESSAGE, TranslateT("Message"), (HICON)-SKINICON_EVENT_MESSAGE, 300, ((dwProtoCaps&PF1_IMSEND) ? 0 : MTDF_DEFAULTDISABLED)); + + // URLs (flag supported and display module installed) + if ((dwProtoCaps&PF1_URLRECV) && ServiceExists(MS_URL_SENDURL)) + SFRegisterMessageType(appd[i]->szName, pszProtoName, hProtoIcon, SFMT_URL, TranslateT("URL"), (HICON)-SKINICON_EVENT_URL, 400, ((dwProtoCaps&PF1_URLSEND) ? 0 : MTDF_DEFAULTDISABLED)); + + // File Transfers (flag supported and display module installed) + if ((dwProtoCaps&PF1_FILERECV) && ServiceExists(MS_FILE_SENDFILE)) + SFRegisterMessageType(appd[i]->szName, pszProtoName, hProtoIcon, SFMT_FILE, TranslateT("File"), (HICON)-SKINICON_EVENT_FILE, 500, ((dwProtoCaps&PF1_FILESEND) ? 0 : MTDF_DEFAULTDISABLED)); + + // Contact Transfers (flag supported and display module installed) + if ((dwProtoCaps&PF1_CONTACTRECV) && ServiceExists(MS_CONTACTS_SEND)) + SFRegisterMessageType(appd[i]->szName, pszProtoName, hProtoIcon, SFMT_CONTACTS, TranslateT("Contacts"), GetModuleHandle(_T("contacts")) ? (HICON)LoadImage(GetModuleHandle(_T("contacts")), MAKEINTRESOURCE(109), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED) : NULL, 600, ((dwProtoCaps&PF1_CONTACTSEND) ? 0 : MTDF_DEFAULTDISABLED)); + + + if (hProtoIcon) DestroyIcon(hProtoIcon); // must be destroyed + + #if defined(UNICODE) + if (pszProtoName != szProtoNameBuf) + mir_free(pszProtoName); + #endif + } + } + } + + // Options + InitOptions(); + + // Add sounds + SkinAddNewSoundBundled(DB_SOUND_ADVERTISMENT_SETTING, Translate("Spam Filter"), Translate("Advertisment Alert"), DEFAULT_ADVERTISMENT_SOUNDFILE); + SkinAddNewSoundBundled(DB_SOUND_DISLIKEDMESSAGE_SETTING, Translate("Spam Filter"), Translate("Disliked Message Alert"), DEFAULT_DISLIKEDMESSAGE_SOUNDFILE); + SkinAddNewSoundBundled(DB_SOUND_ROBOT_SETTING, Translate("Spam Filter"), Translate("Robot Alert"), DEFAULT_ROBOT_SOUNDFILE); + + // Add known database modules (Support for DBEditor++) + if (ServiceExists("DBEditorpp/RegisterModule")) + { + const char* apszModuleNames[] = {DB_MODULE_NAME, DB_MODULE_NAME_MSGTYPES, DB_MODULE_NAME_PRESPAMMERS}; + CallService("DBEditorpp/RegisterModule", (WPARAM)apszModuleNames, (LPARAM)ARRAYSIZE(apszModuleNames)); + } + + // Support for own variables in Variables-Plugin + InitVariables(); + + // Init CList extra image (for spammers) + InitExtraImg(); + + // Support for Popup/PopupPlus Plugin + if (IsPopupAvailable(FALSE)) + { + BOOL bFilterActive = DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_ADVERTISMENTFILTER, DEFAULT_SETTING_ADVERTISMENTFILTER) || DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_DISLIKEDMESSAGEFILTER, DEFAULT_SETTING_DISLIKEDMESSAGEFILTER); + BOOL bPopupsActive = DBGetContactSettingByte(NULL, DB_MODULE_NAME, DB_SETTING_POPUP, DEFAULT_SETTING_POPUP); + + InitPopup(); + + // Init popup menu item + SetPopupMenuItem(bPopupsActive, !bFilterActive); + + // Add colors + SkinAddNewColor(DB_COLOR_POPUPBACKGROUND_SETTING, Translate("Spam Filter"), Translate("Popup Background"), RGB(213,209,208), FALSE); + SkinAddNewColor(DB_COLOR_POPUPTEXT_SETTING, Translate("Spam Filter"), Translate("Popup Text"), RGB(193,0,38), FALSE); + } + + // Init contact menu item + InitMenuItems(); + + // SpamFilter fully loaded + NotifyModuleLoaded(); + return 0; +} + + +__declspec(dllexport) int Load(PLUGINLINK* link) +{ + pluginLink = (PLUGINLINK*)link;; + + hwndSpamFilterOpt = NULL; + hwndAdvertismentFilter = NULL; + hwndRobotFilter = NULL; + hwndDislikedMessagesFilter = NULL; + hwndSpamDefinitionsInfo = NULL; + hwndSpammersInfo = NULL; + + if (!ServiceExists(MS_DB_CONTACT_GETSETTING_STR)) + { + // No Translate() here + MessageBoxEx(NULL, _T("The Spam Filter plugin requires database driver (db3x) 0.5.1.0 or later."), _T("Spam Filter Plugin"), MB_OK|MB_ICONERROR|MB_SETFOREGROUND|MB_TOPMOST|MB_TASKMODAL, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US)); + return 1; + } + + // Load Unicode version only for Unicode core + { + char szVer[128]; + if (CallService(MS_SYSTEM_GETVERSIONTEXT, (WPARAM)ARRAYSIZE(szVer), (LPARAM)szVer) == 0) + if (!StrStrA(szVer, "Unicode")) { + OutputDebugString(_T("Spam Filter: No Unicode core, Unicode version not loaded.\r\n")); + return 1; + } + } + + // Get Miranda's simple memory problems catcher + + memset(&memoryManagerInterface,0,sizeof(memoryManagerInterface)); + memoryManagerInterface.cbSize = sizeof(memoryManagerInterface); + CallService(MS_SYSTEM_GET_MMI, 0, (LPARAM)&memoryManagerInterface); + mir_getUTFI( &utfi ); + + // Init SpamFilter-API + InitServices(); + + // Establish the filter protocol + InitSpamCheck(); + + // Installation (making sure files are placed correctly) + forkthread(ThreadInstallation, 0, NULL); + hHookModulesLoaded = HookEvent(ME_SYSTEM_MODULESLOADED, AllModulesLoaded); + if (!hHookModulesLoaded) CallService(MS_SPAMFILTER_SHOWERROR, SFSE_CRITICAL_ERROR, 0); + + return 0; +} + + +__declspec(dllexport) int Unload(void) +{ + if (hHookModulesLoaded) UnhookEvent(hHookModulesLoaded); + UninitExtraImg(); + UninitMenuItems(); + UninitOptions(); + UninitPopup(); + UninitSpamCheck(); + UninitVariables(); + UninitServices(); + UninitRegExp(); + UninitSpamDefinitions(); + UninitTrigger(); + UninitFolders(); + return 0; +} + + |