/* "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; itype != 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; }