summaryrefslogtreecommitdiff
path: root/plugins/StopSpamMod
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/StopSpamMod')
-rwxr-xr-xplugins/StopSpamMod/Makefile24
-rwxr-xr-xplugins/StopSpamMod/README5
-rwxr-xr-xplugins/StopSpamMod/res/stopspam.rc244
-rwxr-xr-xplugins/StopSpamMod/src/eventhooker.cpp68
-rwxr-xr-xplugins/StopSpamMod/src/eventhooker.h52
-rwxr-xr-xplugins/StopSpamMod/src/globals.h20
-rwxr-xr-xplugins/StopSpamMod/src/headers.h46
-rwxr-xr-xplugins/StopSpamMod/src/include/utf8.h34
-rwxr-xr-xplugins/StopSpamMod/src/include/utf8/checked.h327
-rwxr-xr-xplugins/StopSpamMod/src/include/utf8/core.h329
-rwxr-xr-xplugins/StopSpamMod/src/include/utf8/unchecked.h228
-rwxr-xr-xplugins/StopSpamMod/src/init.cpp251
-rwxr-xr-xplugins/StopSpamMod/src/options.cpp475
-rwxr-xr-xplugins/StopSpamMod/src/options.h1
-rwxr-xr-xplugins/StopSpamMod/src/resource.h68
-rwxr-xr-xplugins/StopSpamMod/src/stopspam.cpp390
-rwxr-xr-xplugins/StopSpamMod/src/stopspam.h31
-rwxr-xr-xplugins/StopSpamMod/src/utilities.cpp551
-rwxr-xr-xplugins/StopSpamMod/src/utilities.h19
-rwxr-xr-xplugins/StopSpamMod/src/version.h6
-rwxr-xr-xplugins/StopSpamMod/stopspam_10.vcxproj244
-rwxr-xr-xplugins/StopSpamMod/stopspam_10.vcxproj.filters65
22 files changed, 3478 insertions, 0 deletions
diff --git a/plugins/StopSpamMod/Makefile b/plugins/StopSpamMod/Makefile
new file mode 100755
index 0000000000..4df12dca59
--- /dev/null
+++ b/plugins/StopSpamMod/Makefile
@@ -0,0 +1,24 @@
+CFLAGS=-Os -fomit-frame-pointer -pipe -march=i686 -mdll -mwin32 -mwindows -I../miranda-im/miranda/include -I/home/sss/temp/windows/libs/utf8cpp/include -D UNICODE -D _UNICODE -DBUILD_DLL
+CXXFLAGS=${CFLAGS}
+LDFLAGS=-shared -Wl,--subsystem,windows,--kill-at
+CPPFLAGS =
+CC=i686-pc-mingw32-gcc
+CXX=i686-pc-mingw32-g++
+STRIP=i686-pc-mingw32-strip
+WINDRES=i686-pc-mingw32-windres
+LD=i686-pc-mingw32-ld
+LNK_COMMON=-lkernel32 -lboost_thread_win32-mt -lboost_system-mt -lboost_random-mt -lboost_regex-mt
+MAINOBJS=eventhooker.o init.o options.o utilities.o stopspam.o
+RESOURCES=stopspam.rc
+
+all: main
+main: $(MAINOBJS)
+ $(WINDRES) -i $(RESOURCES) -o stopspam_res.o
+ $(CXX) $(MAINOBJS) stopspam_res.o $(LNK_COMMON) $(LDFLAGS) -o stopspam.dll
+ $(STRIP) stopspam.dll
+# upx -9 stopspam.dll
+clean:
+ rm *.o
+ rm stopspam.dll
+
+
diff --git a/plugins/StopSpamMod/README b/plugins/StopSpamMod/README
new file mode 100755
index 0000000000..4f317d214d
--- /dev/null
+++ b/plugins/StopSpamMod/README
@@ -0,0 +1,5 @@
+* Build Dependencies
+ 1. boost (http://www.boost.org/)
+ 2. c++ compiller (because of miranda have compiled with MSVC, only msvc compiled builds working fine (i have no success with mingw, please report your result :) ))
+* Runtime Dependencies
+ 1. MIranda IM at least 0.8 (custom builds should be compiled fine against 0.6, 0.7 miranda api)
diff --git a/plugins/StopSpamMod/res/stopspam.rc b/plugins/StopSpamMod/res/stopspam.rc
new file mode 100755
index 0000000000..fd5b505ee7
--- /dev/null
+++ b/plugins/StopSpamMod/res/stopspam.rc
@@ -0,0 +1,244 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "src/resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Русский (Россия) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_MESSAGES DIALOGEX 0, 0, 302, 225
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_POPUP | WS_SYSMENU
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ LTEXT "Question: (Ctrl-Enter for carriage return)",IDC_STATIC,0,5,156,8
+ EDITTEXT ID_QUESTION,0,17,300,57,ES_MULTILINE | ES_AUTOVSCROLL | WS_VSCROLL
+ PUSHBUTTON "Restore defaults",ID_RESTOREDEFAULTS,234,208,66,14,NOT WS_TABSTOP
+ LTEXT "Answer:",IDC_STATIC,0,82,270,8
+ EDITTEXT ID_ANSWER,0,94,300,14,ES_AUTOHSCROLL
+ LTEXT "Congratulation:",IDC_STATIC,0,112,270,8
+ EDITTEXT ID_CONGRATULATION,0,123,300,48,ES_MULTILINE | ES_AUTOVSCROLL | WS_VSCROLL
+ LTEXT "Auth. request reply:",IDC_STATIC,0,174,270,8
+ EDITTEXT ID_AUTHREPL,0,187,300,14,ES_AUTOHSCROLL
+ CONTROL "Vars",IDC_VARS,"MButtonClass",WS_TABSTOP,0,206,16,16
+END
+
+IDD_PROTO DIALOGEX 0, 0, 230, 173
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_SYSMENU
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ LTEXT "Available accounts:",IDC_STATIC,6,8,84,8
+ LISTBOX ID_ALLPROTO,6,20,84,138,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
+ PUSHBUTTON ">>>>",ID_ADDALL,96,26,36,14
+ PUSHBUTTON ">>",ID_ADD,96,44,36,14
+ PUSHBUTTON "<<",ID_REMOVE,96,62,36,14
+ PUSHBUTTON "<<<<",ID_REMOVEALL,96,80,36,14
+ LTEXT "Filtered accounts:",IDC_STATIC,138,8,85,8
+ LISTBOX ID_USEDPROTO,138,20,84,138,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
+END
+
+IDD_MAIN DIALOGEX 0, 0, 309, 219
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_SYSMENU
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ EDITTEXT ID_DESCRIPTION,12,7,290,82,ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | NOT WS_TABSTOP
+ LTEXT "Do not send more than ",IDC_STATIC,11,89,87,12,SS_CENTERIMAGE
+ EDITTEXT ID_MAXQUESTCOUNT,107,89,30,12,ES_AUTOHSCROLL | ES_NUMBER
+ LTEXT " questions to one contact (0 - for no limit)",IDC_STATIC,144,89,155,12,SS_CENTERIMAGE
+ CONTROL "Enable StopSpam-StopSpam infinite talk protection",ID_INFTALKPROT,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,106,290,10
+ CONTROL "Add contact permanently",ID_ADDPERMANENT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,118,290,8
+ CONTROL "Enable auth. requests blocking",ID_HANDLEAUTHREQ,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,130,290,8
+ CONTROL "Hide unanswered contacts and spammers from contact list",ID_HIDECONTACTS,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,140,290,10
+ CONTROL "Ignore spammers (do not write messages to history)",ID_IGNORESPAMMERS,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,151,290,10
+ CONTROL "Log spam to file",ID_LOGSPAMTOFILE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,162,290,10
+END
+
+IDD_ADVANCED DIALOGEX 0, 0, 309, 219
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_SYSMENU
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ CONTROL "Case insensitive answer checking",IDC_CASE_INSENSITIVE,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,66,279,10
+ CONTROL "Disable question in invisible mode",IDC_INVIS_DISABLE,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,77,287,10
+ CONTROL "Enable integration with DOS plugin",ID_DOS_INTEGRATION,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,89,287,8
+ CONTROL "Exclude contacts which we sending something from spam check",ID_EXCLUDE,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,33,287,8
+ CONTROL "Remove Excluded contacts after restart",ID_REMOVE_TMP,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,44,287,8
+ CONTROL "Add contacts to specified group:",ID_SPECIALGROUP,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,16,196,10
+ EDITTEXT ID_SPECIALGROUPNAME,217,15,79,12,ES_AUTOHSCROLL
+ CONTROL "Ignore URL in messages and auth requests",ID_IGNOREURL,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,100,287,10
+ CONTROL "Add contact to server list",IDC_ADDTOSRVLST,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,22,146,187,10
+ EDITTEXT IDC_AUTOADDGROUP,210,144,76,14,ES_AUTOHSCROLL
+ GROUPBOX "After congratulation (ICQ only)",IDC_STATIC,15,135,278,51
+ CONTROL "Automatically grant authorization",IDC_AUTOAUTH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,22,158,263,10
+ CONTROL "Request authorization from contacts which pass stopspam test",IDC_REQAUTH,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,22,170,267,10
+ CONTROL "Remove all tempory contacts after restart",ID_REMOVE_TMP_ALL,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,55,287,8
+ CONTROL "Use regex for answers checking",IDC_REGEX,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,111,287,10
+ CONTROL "Log Spammers to system history",IDC_HISTORY_LOG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,121,218,10
+ CONTROL "Use math expression in question",IDC_MATH_QUESTION,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,188,129,10
+ PUSHBUTTON "Details..",IDC_MATH_DETAILS,152,187,50,14
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_MESSAGES, DIALOG
+ BEGIN
+ RIGHTMARGIN, 300
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 222
+ END
+
+ IDD_PROTO, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 223
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 166
+ END
+
+ IDD_MAIN, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 302
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 212
+ END
+
+ IDD_ADVANCED, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 302
+ VERTGUIDE, 15
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 212
+ HORZGUIDE, 11
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 0,0,2,0
+ PRODUCTVERSION 0,7,0,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "000004b0"
+ BEGIN
+ VALUE "Comments", "Licensed under the terms of the GNU General Public License"
+ VALUE "CompanyName", " "
+ VALUE "FileDescription", "StopSpam plugin for Miranda IM"
+ VALUE "FileVersion", "0.0.2.0"
+ VALUE "InternalName", "stopspam"
+ VALUE "LegalCopyright", "Copyright © 2000-2010 Miranda IM Project. This software is released under the terms of the GNU General Public License."
+ VALUE "OriginalFilename", "stopspam.dll"
+ VALUE "ProductName", "StopSpam"
+ VALUE "ProductVersion", "0.7.0.0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0, 1200
+ END
+END
+
+#endif // Русский (Россия) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Английский (США) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Английский (США) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/plugins/StopSpamMod/src/eventhooker.cpp b/plugins/StopSpamMod/src/eventhooker.cpp
new file mode 100755
index 0000000000..5518577bac
--- /dev/null
+++ b/plugins/StopSpamMod/src/eventhooker.cpp
@@ -0,0 +1,68 @@
+/* eventhooker.cpp
+* Copyright (C) Miklashevsky Roman, sss, elzor
+*
+* 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; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include <list>
+#include "eventhooker.h"
+
+namespace miranda
+{
+ namespace
+ {
+ std::list<EventHooker*> eventHookerList;
+ }
+
+ EventHooker::EventHooker(std::string name, MIRANDAHOOK fun) : name_(name), fun_(fun), handle_(0)
+ {
+ eventHookerList.push_back(this);
+ }
+
+ EventHooker::~EventHooker()
+ {
+ eventHookerList.remove(this);
+ }
+
+ void EventHooker::Hook()
+ {
+ handle_ = HookEvent(name_.c_str(), fun_);
+ }
+
+ void EventHooker::Unhook()
+ {
+ if(handle_)
+ {
+ UnhookEvent(handle_);
+ handle_ = 0;
+ }
+ }
+
+ void EventHooker::HookAll()
+ {
+ for(std::list<EventHooker*>::iterator it = eventHookerList.begin(); it != eventHookerList.end(); ++it)
+ {
+ (*it)->Hook();
+ }
+ }
+
+ void EventHooker::UnhookAll()
+ {
+ for(std::list<EventHooker*>::iterator it = eventHookerList.begin(); it != eventHookerList.end(); ++it)
+ {
+ (*it)->Unhook();
+ }
+ }
+}
diff --git a/plugins/StopSpamMod/src/eventhooker.h b/plugins/StopSpamMod/src/eventhooker.h
new file mode 100755
index 0000000000..31640ffafa
--- /dev/null
+++ b/plugins/StopSpamMod/src/eventhooker.h
@@ -0,0 +1,52 @@
+/* eventhooker.h - Helper for hooking events in Miranda.
+* Copyright (C) Miklashevsky Roman, sss, elzor
+*
+* 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; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef EVENTHOOKER_H_C8EAA58A_7C4D_45f7_A88E_0E41FE93754D
+#define EVENTHOOKER_H_C8EAA58A_7C4D_45f7_A88E_0E41FE93754D
+
+#pragma warning( once : 4430 )
+
+#include <windows.h>
+#include <string>
+#include <newpluginapi.h>
+
+namespace miranda
+{
+
+#define MIRANDA_HOOK_EVENT(NAME, WPARAMNAME, LPARAMNAME) \
+ int NAME##_Handler(WPARAM,LPARAM);\
+ miranda::EventHooker NAME##_Hooker(NAME, NAME##_Handler);\
+ int NAME##_Handler(WPARAM WPARAMNAME, LPARAM LPARAMNAME)
+
+ struct EventHooker
+ {
+ EventHooker(std::string name, MIRANDAHOOK fun);
+ ~EventHooker();
+ void Hook();
+ void Unhook();
+ static void HookAll();
+ static void UnhookAll();
+ private:
+ std::string name_;
+ MIRANDAHOOK fun_;
+ HANDLE handle_;
+ };
+
+}
+
+#endif
diff --git a/plugins/StopSpamMod/src/globals.h b/plugins/StopSpamMod/src/globals.h
new file mode 100755
index 0000000000..790458e6bc
--- /dev/null
+++ b/plugins/StopSpamMod/src/globals.h
@@ -0,0 +1,20 @@
+#define pluginName "StopSpam" //const char* ?
+/*
+TCHAR const * defAnswer = _T("nospam");
+TCHAR const * defCongratulation =
+_T("Congratulations! You just passed human/robot test. Now you can write me a message.");
+char const * defProtoList = "ICQ\r\n";
+TCHAR const * infTalkProtPrefix = _T("StopSpam automatic message:\r\n");
+char const * answeredSetting = "Answered";
+char const * questCountSetting = "QuestionCount";
+TCHAR const * defAufrepl = _T("StopSpam: send a message and reply to a anti-spam bot question.");*/
+
+
+#ifdef _UNICODE
+typedef std::wstring tstring;
+#define PREF_TCHAR2 PREF_UTF
+#else
+typedef std::string tstring;
+#define PREF_TCHAR2 0
+#endif //_UNICODE
+
diff --git a/plugins/StopSpamMod/src/headers.h b/plugins/StopSpamMod/src/headers.h
new file mode 100755
index 0000000000..18993e70ef
--- /dev/null
+++ b/plugins/StopSpamMod/src/headers.h
@@ -0,0 +1,46 @@
+#include <windows.h>
+#include <stdio.h>
+#include <commctrl.h>
+#include <malloc.h>
+#include <time.h>
+#include <string>
+#include <sstream>
+#include<fstream>
+
+
+#include <newpluginapi.h>
+#include <m_database.h>
+#include <m_protosvc.h>
+#include <m_options.h>
+#include <m_utils.h>
+#include <m_langpack.h>
+#include <m_clistint.h>
+#include <m_skin.h>
+#include <m_button.h>
+#include <m_contacts.h>
+
+#include <m_variables.h>
+#include <m_folders.h>
+
+
+#include "globals.h"
+#include "stopspam.h"
+#include "options.h"
+#include "eventhooker.h"
+#include "version.h"
+#include "resource.h"
+#include "utilities.h"
+
+//boost
+#include <boost/thread.hpp>
+#include <boost/regex.hpp>
+#include <boost/algorithm/string.hpp>
+#include <boost/nondet_random.hpp>
+#include <boost/random/variate_generator.hpp>
+#include <boost/random/uniform_int.hpp>
+
+//utf8cpp
+#include <utf8.h>
+
+
+//#include <m_dos.h>
diff --git a/plugins/StopSpamMod/src/include/utf8.h b/plugins/StopSpamMod/src/include/utf8.h
new file mode 100755
index 0000000000..4e4451403f
--- /dev/null
+++ b/plugins/StopSpamMod/src/include/utf8.h
@@ -0,0 +1,34 @@
+// Copyright 2006 Nemanja Trifunovic
+
+/*
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+
+#ifndef UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731
+#define UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731
+
+#include "utf8/checked.h"
+#include "utf8/unchecked.h"
+
+#endif // header guard
diff --git a/plugins/StopSpamMod/src/include/utf8/checked.h b/plugins/StopSpamMod/src/include/utf8/checked.h
new file mode 100755
index 0000000000..3b00644444
--- /dev/null
+++ b/plugins/StopSpamMod/src/include/utf8/checked.h
@@ -0,0 +1,327 @@
+// Copyright 2006 Nemanja Trifunovic
+
+/*
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+
+#ifndef UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
+#define UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
+
+#include "core.h"
+#include <stdexcept>
+
+namespace utf8
+{
+ // Base for the exceptions that may be thrown from the library
+ class exception : public ::std::exception {
+ };
+
+ // Exceptions that may be thrown from the library functions.
+ class invalid_code_point : public exception {
+ uint32_t cp;
+ public:
+ invalid_code_point(uint32_t cp) : cp(cp) {}
+ virtual const char* what() const throw() { return "Invalid code point"; }
+ uint32_t code_point() const {return cp;}
+ };
+
+ class invalid_utf8 : public exception {
+ uint8_t u8;
+ public:
+ invalid_utf8 (uint8_t u) : u8(u) {}
+ virtual const char* what() const throw() { return "Invalid UTF-8"; }
+ uint8_t utf8_octet() const {return u8;}
+ };
+
+ class invalid_utf16 : public exception {
+ uint16_t u16;
+ public:
+ invalid_utf16 (uint16_t u) : u16(u) {}
+ virtual const char* what() const throw() { return "Invalid UTF-16"; }
+ uint16_t utf16_word() const {return u16;}
+ };
+
+ class not_enough_room : public exception {
+ public:
+ virtual const char* what() const throw() { return "Not enough space"; }
+ };
+
+ /// The library API - functions intended to be called by the users
+
+ template <typename octet_iterator>
+ octet_iterator append(uint32_t cp, octet_iterator result)
+ {
+ if (!utf8::internal::is_code_point_valid(cp))
+ throw invalid_code_point(cp);
+
+ if (cp < 0x80) // one octet
+ *(result++) = static_cast<uint8_t>(cp);
+ else if (cp < 0x800) { // two octets
+ *(result++) = static_cast<uint8_t>((cp >> 6) | 0xc0);
+ *(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
+ }
+ else if (cp < 0x10000) { // three octets
+ *(result++) = static_cast<uint8_t>((cp >> 12) | 0xe0);
+ *(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
+ *(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
+ }
+ else { // four octets
+ *(result++) = static_cast<uint8_t>((cp >> 18) | 0xf0);
+ *(result++) = static_cast<uint8_t>(((cp >> 12) & 0x3f) | 0x80);
+ *(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
+ *(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
+ }
+ return result;
+ }
+
+ template <typename octet_iterator, typename output_iterator>
+ output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out, uint32_t replacement)
+ {
+ while (start != end) {
+ octet_iterator sequence_start = start;
+ internal::utf_error err_code = utf8::internal::validate_next(start, end);
+ switch (err_code) {
+ case internal::UTF8_OK :
+ for (octet_iterator it = sequence_start; it != start; ++it)
+ *out++ = *it;
+ break;
+ case internal::NOT_ENOUGH_ROOM:
+ throw not_enough_room();
+ case internal::INVALID_LEAD:
+ utf8::append (replacement, out);
+ ++start;
+ break;
+ case internal::INCOMPLETE_SEQUENCE:
+ case internal::OVERLONG_SEQUENCE:
+ case internal::INVALID_CODE_POINT:
+ utf8::append (replacement, out);
+ ++start;
+ // just one replacement mark for the sequence
+ while (start != end && utf8::internal::is_trail(*start))
+ ++start;
+ break;
+ }
+ }
+ return out;
+ }
+
+ template <typename octet_iterator, typename output_iterator>
+ inline output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out)
+ {
+ static const uint32_t replacement_marker = utf8::internal::mask16(0xfffd);
+ return utf8::replace_invalid(start, end, out, replacement_marker);
+ }
+
+ template <typename octet_iterator>
+ uint32_t next(octet_iterator& it, octet_iterator end)
+ {
+ uint32_t cp = 0;
+ internal::utf_error err_code = utf8::internal::validate_next(it, end, cp);
+ switch (err_code) {
+ case internal::UTF8_OK :
+ break;
+ case internal::NOT_ENOUGH_ROOM :
+ throw not_enough_room();
+ case internal::INVALID_LEAD :
+ case internal::INCOMPLETE_SEQUENCE :
+ case internal::OVERLONG_SEQUENCE :
+ throw invalid_utf8(*it);
+ case internal::INVALID_CODE_POINT :
+ throw invalid_code_point(cp);
+ }
+ return cp;
+ }
+
+ template <typename octet_iterator>
+ uint32_t peek_next(octet_iterator it, octet_iterator end)
+ {
+ return utf8::next(it, end);
+ }
+
+ template <typename octet_iterator>
+ uint32_t prior(octet_iterator& it, octet_iterator start)
+ {
+ // can't do much if it == start
+ if (it == start)
+ throw not_enough_room();
+
+ octet_iterator end = it;
+ // Go back until we hit either a lead octet or start
+ while (utf8::internal::is_trail(*(--it)))
+ if (it == start)
+ throw invalid_utf8(*it); // error - no lead byte in the sequence
+ return utf8::peek_next(it, end);
+ }
+
+ /// Deprecated in versions that include "prior"
+ template <typename octet_iterator>
+ uint32_t previous(octet_iterator& it, octet_iterator pass_start)
+ {
+ octet_iterator end = it;
+ while (utf8::internal::is_trail(*(--it)))
+ if (it == pass_start)
+ throw invalid_utf8(*it); // error - no lead byte in the sequence
+ octet_iterator temp = it;
+ return utf8::next(temp, end);
+ }
+
+ template <typename octet_iterator, typename distance_type>
+ void advance (octet_iterator& it, distance_type n, octet_iterator end)
+ {
+ for (distance_type i = 0; i < n; ++i)
+ utf8::next(it, end);
+ }
+
+ template <typename octet_iterator>
+ typename std::iterator_traits<octet_iterator>::difference_type
+ distance (octet_iterator first, octet_iterator last)
+ {
+ typename std::iterator_traits<octet_iterator>::difference_type dist;
+ for (dist = 0; first < last; ++dist)
+ utf8::next(first, last);
+ return dist;
+ }
+
+ template <typename u16bit_iterator, typename octet_iterator>
+ octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result)
+ {
+ while (start != end) {
+ uint32_t cp = utf8::internal::mask16(*start++);
+ // Take care of surrogate pairs first
+ if (utf8::internal::is_lead_surrogate(cp)) {
+ if (start != end) {
+ uint32_t trail_surrogate = utf8::internal::mask16(*start++);
+ if (utf8::internal::is_trail_surrogate(trail_surrogate))
+ cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET;
+ else
+ throw invalid_utf16(static_cast<uint16_t>(trail_surrogate));
+ }
+ else
+ throw invalid_utf16(static_cast<uint16_t>(cp));
+
+ }
+ // Lone trail surrogate
+ else if (utf8::internal::is_trail_surrogate(cp))
+ throw invalid_utf16(static_cast<uint16_t>(cp));
+
+ result = utf8::append(cp, result);
+ }
+ return result;
+ }
+
+ template <typename u16bit_iterator, typename octet_iterator>
+ u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result)
+ {
+ while (start != end) {
+ uint32_t cp = utf8::next(start, end);
+ if (cp > 0xffff) { //make a surrogate pair
+ *result++ = static_cast<uint16_t>((cp >> 10) + internal::LEAD_OFFSET);
+ *result++ = static_cast<uint16_t>((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN);
+ }
+ else
+ *result++ = static_cast<uint16_t>(cp);
+ }
+ return result;
+ }
+
+ template <typename octet_iterator, typename u32bit_iterator>
+ octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result)
+ {
+ while (start != end)
+ result = utf8::append(*(start++), result);
+
+ return result;
+ }
+
+ template <typename octet_iterator, typename u32bit_iterator>
+ u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result)
+ {
+ while (start != end)
+ (*result++) = utf8::next(start, end);
+
+ return result;
+ }
+
+ // The iterator class
+ template <typename octet_iterator>
+ class iterator : public std::iterator <std::bidirectional_iterator_tag, uint32_t> {
+ octet_iterator it;
+ octet_iterator range_start;
+ octet_iterator range_end;
+ public:
+ iterator () {};
+ explicit iterator (const octet_iterator& octet_it,
+ const octet_iterator& range_start,
+ const octet_iterator& range_end) :
+ it(octet_it), range_start(range_start), range_end(range_end)
+ {
+ if (it < range_start || it > range_end)
+ throw std::out_of_range("Invalid utf-8 iterator position");
+ }
+ // the default "big three" are OK
+ octet_iterator base () const { return it; }
+ uint32_t operator * () const
+ {
+ octet_iterator temp = it;
+ return utf8::next(temp, range_end);
+ }
+ bool operator == (const iterator& rhs) const
+ {
+ if (range_start != rhs.range_start || range_end != rhs.range_end)
+ throw std::logic_error("Comparing utf-8 iterators defined with different ranges");
+ return (it == rhs.it);
+ }
+ bool operator != (const iterator& rhs) const
+ {
+ return !(operator == (rhs));
+ }
+ iterator& operator ++ ()
+ {
+ utf8::next(it, range_end);
+ return *this;
+ }
+ iterator operator ++ (int)
+ {
+ iterator temp = *this;
+ utf8::next(it, range_end);
+ return temp;
+ }
+ iterator& operator -- ()
+ {
+ utf8::prior(it, range_start);
+ return *this;
+ }
+ iterator operator -- (int)
+ {
+ iterator temp = *this;
+ utf8::prior(it, range_start);
+ return temp;
+ }
+ }; // class iterator
+
+} // namespace utf8
+
+#endif //header guard
+
+
diff --git a/plugins/StopSpamMod/src/include/utf8/core.h b/plugins/StopSpamMod/src/include/utf8/core.h
new file mode 100755
index 0000000000..693d388c07
--- /dev/null
+++ b/plugins/StopSpamMod/src/include/utf8/core.h
@@ -0,0 +1,329 @@
+// Copyright 2006 Nemanja Trifunovic
+
+/*
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+
+#ifndef UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
+#define UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
+
+#include <iterator>
+
+namespace utf8
+{
+ // The typedefs for 8-bit, 16-bit and 32-bit unsigned integers
+ // You may need to change them to match your system.
+ // These typedefs have the same names as ones from cstdint, or boost/cstdint
+ typedef unsigned char uint8_t;
+ typedef unsigned short uint16_t;
+ typedef unsigned int uint32_t;
+
+// Helper code - not intended to be directly called by the library users. May be changed at any time
+namespace internal
+{
+ // Unicode constants
+ // Leading (high) surrogates: 0xd800 - 0xdbff
+ // Trailing (low) surrogates: 0xdc00 - 0xdfff
+ const uint16_t LEAD_SURROGATE_MIN = 0xd800u;
+ const uint16_t LEAD_SURROGATE_MAX = 0xdbffu;
+ const uint16_t TRAIL_SURROGATE_MIN = 0xdc00u;
+ const uint16_t TRAIL_SURROGATE_MAX = 0xdfffu;
+ const uint16_t LEAD_OFFSET = LEAD_SURROGATE_MIN - (0x10000 >> 10);
+ const uint32_t SURROGATE_OFFSET = 0x10000u - (LEAD_SURROGATE_MIN << 10) - TRAIL_SURROGATE_MIN;
+
+ // Maximum valid value for a Unicode code point
+ const uint32_t CODE_POINT_MAX = 0x0010ffffu;
+
+ template<typename octet_type>
+ inline uint8_t mask8(octet_type oc)
+ {
+ return static_cast<uint8_t>(0xff & oc);
+ }
+ template<typename u16_type>
+ inline uint16_t mask16(u16_type oc)
+ {
+ return static_cast<uint16_t>(0xffff & oc);
+ }
+ template<typename octet_type>
+ inline bool is_trail(octet_type oc)
+ {
+ return ((utf8::internal::mask8(oc) >> 6) == 0x2);
+ }
+
+ template <typename u16>
+ inline bool is_lead_surrogate(u16 cp)
+ {
+ return (cp >= LEAD_SURROGATE_MIN && cp <= LEAD_SURROGATE_MAX);
+ }
+
+ template <typename u16>
+ inline bool is_trail_surrogate(u16 cp)
+ {
+ return (cp >= TRAIL_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX);
+ }
+
+ template <typename u16>
+ inline bool is_surrogate(u16 cp)
+ {
+ return (cp >= LEAD_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX);
+ }
+
+ template <typename u32>
+ inline bool is_code_point_valid(u32 cp)
+ {
+ return (cp <= CODE_POINT_MAX && !utf8::internal::is_surrogate(cp));
+ }
+
+ template <typename octet_iterator>
+ inline typename std::iterator_traits<octet_iterator>::difference_type
+ sequence_length(octet_iterator lead_it)
+ {
+ uint8_t lead = utf8::internal::mask8(*lead_it);
+ if (lead < 0x80)
+ return 1;
+ else if ((lead >> 5) == 0x6)
+ return 2;
+ else if ((lead >> 4) == 0xe)
+ return 3;
+ else if ((lead >> 3) == 0x1e)
+ return 4;
+ else
+ return 0;
+ }
+
+ template <typename octet_difference_type>
+ inline bool is_overlong_sequence(uint32_t cp, octet_difference_type length)
+ {
+ if (cp < 0x80) {
+ if (length != 1)
+ return true;
+ }
+ else if (cp < 0x800) {
+ if (length != 2)
+ return true;
+ }
+ else if (cp < 0x10000) {
+ if (length != 3)
+ return true;
+ }
+
+ return false;
+ }
+
+ enum utf_error {UTF8_OK, NOT_ENOUGH_ROOM, INVALID_LEAD, INCOMPLETE_SEQUENCE, OVERLONG_SEQUENCE, INVALID_CODE_POINT};
+
+ /// Helper for get_sequence_x
+ template <typename octet_iterator>
+ utf_error increase_safely(octet_iterator& it, octet_iterator end)
+ {
+ if (++it == end)
+ return NOT_ENOUGH_ROOM;
+
+ if (!utf8::internal::is_trail(*it))
+ return INCOMPLETE_SEQUENCE;
+
+ return UTF8_OK;
+ }
+
+ #define UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(IT, END) {utf_error ret = increase_safely(IT, END); if (ret != UTF8_OK) return ret;}
+
+ /// get_sequence_x functions decode utf-8 sequences of the length x
+ template <typename octet_iterator>
+ utf_error get_sequence_1(octet_iterator& it, octet_iterator end, uint32_t& code_point)
+ {
+ if (it == end)
+ return NOT_ENOUGH_ROOM;
+
+ code_point = utf8::internal::mask8(*it);
+
+ return UTF8_OK;
+ }
+
+ template <typename octet_iterator>
+ utf_error get_sequence_2(octet_iterator& it, octet_iterator end, uint32_t& code_point)
+ {
+ if (it == end)
+ return NOT_ENOUGH_ROOM;
+
+ code_point = utf8::internal::mask8(*it);
+
+ UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
+
+ code_point = ((code_point << 6) & 0x7ff) + ((*it) & 0x3f);
+
+ return UTF8_OK;
+ }
+
+ template <typename octet_iterator>
+ utf_error get_sequence_3(octet_iterator& it, octet_iterator end, uint32_t& code_point)
+ {
+ if (it == end)
+ return NOT_ENOUGH_ROOM;
+
+ code_point = utf8::internal::mask8(*it);
+
+ UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
+
+ code_point = ((code_point << 12) & 0xffff) + ((utf8::internal::mask8(*it) << 6) & 0xfff);
+
+ UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
+
+ code_point += (*it) & 0x3f;
+
+ return UTF8_OK;
+ }
+
+ template <typename octet_iterator>
+ utf_error get_sequence_4(octet_iterator& it, octet_iterator end, uint32_t& code_point)
+ {
+ if (it == end)
+ return NOT_ENOUGH_ROOM;
+
+ code_point = utf8::internal::mask8(*it);
+
+ UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
+
+ code_point = ((code_point << 18) & 0x1fffff) + ((utf8::internal::mask8(*it) << 12) & 0x3ffff);
+
+ UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
+
+ code_point += (utf8::internal::mask8(*it) << 6) & 0xfff;
+
+ UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
+
+ code_point += (*it) & 0x3f;
+
+ return UTF8_OK;
+ }
+
+ #undef UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR
+
+ template <typename octet_iterator>
+ utf_error validate_next(octet_iterator& it, octet_iterator end, uint32_t& code_point)
+ {
+ // Save the original value of it so we can go back in case of failure
+ // Of course, it does not make much sense with i.e. stream iterators
+ octet_iterator original_it = it;
+
+ uint32_t cp = 0;
+ // Determine the sequence length based on the lead octet
+ typedef typename std::iterator_traits<octet_iterator>::difference_type octet_difference_type;
+ const octet_difference_type length = utf8::internal::sequence_length(it);
+
+ // Get trail octets and calculate the code point
+ utf_error err = UTF8_OK;
+ switch (length) {
+ case 0:
+ return INVALID_LEAD;
+ case 1:
+ err = utf8::internal::get_sequence_1(it, end, cp);
+ break;
+ case 2:
+ err = utf8::internal::get_sequence_2(it, end, cp);
+ break;
+ case 3:
+ err = utf8::internal::get_sequence_3(it, end, cp);
+ break;
+ case 4:
+ err = utf8::internal::get_sequence_4(it, end, cp);
+ break;
+ }
+
+ if (err == UTF8_OK) {
+ // Decoding succeeded. Now, security checks...
+ if (utf8::internal::is_code_point_valid(cp)) {
+ if (!utf8::internal::is_overlong_sequence(cp, length)){
+ // Passed! Return here.
+ code_point = cp;
+ ++it;
+ return UTF8_OK;
+ }
+ else
+ err = OVERLONG_SEQUENCE;
+ }
+ else
+ err = INVALID_CODE_POINT;
+ }
+
+ // Failure branch - restore the original value of the iterator
+ it = original_it;
+ return err;
+ }
+
+ template <typename octet_iterator>
+ inline utf_error validate_next(octet_iterator& it, octet_iterator end) {
+ uint32_t ignored;
+ return utf8::internal::validate_next(it, end, ignored);
+ }
+
+} // namespace internal
+
+ /// The library API - functions intended to be called by the users
+
+ // Byte order mark
+ const uint8_t bom[] = {0xef, 0xbb, 0xbf};
+
+ template <typename octet_iterator>
+ octet_iterator find_invalid(octet_iterator start, octet_iterator end)
+ {
+ octet_iterator result = start;
+ while (result != end) {
+ utf8::internal::utf_error err_code = utf8::internal::validate_next(result, end);
+ if (err_code != internal::UTF8_OK)
+ return result;
+ }
+ return result;
+ }
+
+ template <typename octet_iterator>
+ inline bool is_valid(octet_iterator start, octet_iterator end)
+ {
+ return (utf8::find_invalid(start, end) == end);
+ }
+
+ template <typename octet_iterator>
+ inline bool starts_with_bom (octet_iterator it, octet_iterator end)
+ {
+ return (
+ ((it != end) && (utf8::internal::mask8(*it++)) == bom[0]) &&
+ ((it != end) && (utf8::internal::mask8(*it++)) == bom[1]) &&
+ ((it != end) && (utf8::internal::mask8(*it)) == bom[2])
+ );
+ }
+
+ //Deprecated in release 2.3
+ template <typename octet_iterator>
+ inline bool is_bom (octet_iterator it)
+ {
+ return (
+ (utf8::internal::mask8(*it++)) == bom[0] &&
+ (utf8::internal::mask8(*it++)) == bom[1] &&
+ (utf8::internal::mask8(*it)) == bom[2]
+ );
+ }
+} // namespace utf8
+
+#endif // header guard
+
+
diff --git a/plugins/StopSpamMod/src/include/utf8/unchecked.h b/plugins/StopSpamMod/src/include/utf8/unchecked.h
new file mode 100755
index 0000000000..b4547fad94
--- /dev/null
+++ b/plugins/StopSpamMod/src/include/utf8/unchecked.h
@@ -0,0 +1,228 @@
+// Copyright 2006 Nemanja Trifunovic
+
+/*
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+
+#ifndef UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
+#define UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
+
+#include "core.h"
+
+namespace utf8
+{
+ namespace unchecked
+ {
+ template <typename octet_iterator>
+ octet_iterator append(uint32_t cp, octet_iterator result)
+ {
+ if (cp < 0x80) // one octet
+ *(result++) = static_cast<uint8_t>(cp);
+ else if (cp < 0x800) { // two octets
+ *(result++) = static_cast<uint8_t>((cp >> 6) | 0xc0);
+ *(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
+ }
+ else if (cp < 0x10000) { // three octets
+ *(result++) = static_cast<uint8_t>((cp >> 12) | 0xe0);
+ *(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
+ *(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
+ }
+ else { // four octets
+ *(result++) = static_cast<uint8_t>((cp >> 18) | 0xf0);
+ *(result++) = static_cast<uint8_t>(((cp >> 12) & 0x3f)| 0x80);
+ *(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
+ *(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
+ }
+ return result;
+ }
+
+ template <typename octet_iterator>
+ uint32_t next(octet_iterator& it)
+ {
+ uint32_t cp = utf8::internal::mask8(*it);
+ typename std::iterator_traits<octet_iterator>::difference_type length = utf8::internal::sequence_length(it);
+ switch (length) {
+ case 1:
+ break;
+ case 2:
+ it++;
+ cp = ((cp << 6) & 0x7ff) + ((*it) & 0x3f);
+ break;
+ case 3:
+ ++it;
+ cp = ((cp << 12) & 0xffff) + ((utf8::internal::mask8(*it) << 6) & 0xfff);
+ ++it;
+ cp += (*it) & 0x3f;
+ break;
+ case 4:
+ ++it;
+ cp = ((cp << 18) & 0x1fffff) + ((utf8::internal::mask8(*it) << 12) & 0x3ffff);
+ ++it;
+ cp += (utf8::internal::mask8(*it) << 6) & 0xfff;
+ ++it;
+ cp += (*it) & 0x3f;
+ break;
+ }
+ ++it;
+ return cp;
+ }
+
+ template <typename octet_iterator>
+ uint32_t peek_next(octet_iterator it)
+ {
+ return utf8::unchecked::next(it);
+ }
+
+ template <typename octet_iterator>
+ uint32_t prior(octet_iterator& it)
+ {
+ while (utf8::internal::is_trail(*(--it))) ;
+ octet_iterator temp = it;
+ return utf8::unchecked::next(temp);
+ }
+
+ // Deprecated in versions that include prior, but only for the sake of consistency (see utf8::previous)
+ template <typename octet_iterator>
+ inline uint32_t previous(octet_iterator& it)
+ {
+ return utf8::unchecked::prior(it);
+ }
+
+ template <typename octet_iterator, typename distance_type>
+ void advance (octet_iterator& it, distance_type n)
+ {
+ for (distance_type i = 0; i < n; ++i)
+ utf8::unchecked::next(it);
+ }
+
+ template <typename octet_iterator>
+ typename std::iterator_traits<octet_iterator>::difference_type
+ distance (octet_iterator first, octet_iterator last)
+ {
+ typename std::iterator_traits<octet_iterator>::difference_type dist;
+ for (dist = 0; first < last; ++dist)
+ utf8::unchecked::next(first);
+ return dist;
+ }
+
+ template <typename u16bit_iterator, typename octet_iterator>
+ octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result)
+ {
+ while (start != end) {
+ uint32_t cp = utf8::internal::mask16(*start++);
+ // Take care of surrogate pairs first
+ if (utf8::internal::is_lead_surrogate(cp)) {
+ uint32_t trail_surrogate = utf8::internal::mask16(*start++);
+ cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET;
+ }
+ result = utf8::unchecked::append(cp, result);
+ }
+ return result;
+ }
+
+ template <typename u16bit_iterator, typename octet_iterator>
+ u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result)
+ {
+ while (start < end) {
+ uint32_t cp = utf8::unchecked::next(start);
+ if (cp > 0xffff) { //make a surrogate pair
+ *result++ = static_cast<uint16_t>((cp >> 10) + internal::LEAD_OFFSET);
+ *result++ = static_cast<uint16_t>((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN);
+ }
+ else
+ *result++ = static_cast<uint16_t>(cp);
+ }
+ return result;
+ }
+
+ template <typename octet_iterator, typename u32bit_iterator>
+ octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result)
+ {
+ while (start != end)
+ result = utf8::unchecked::append(*(start++), result);
+
+ return result;
+ }
+
+ template <typename octet_iterator, typename u32bit_iterator>
+ u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result)
+ {
+ while (start < end)
+ (*result++) = utf8::unchecked::next(start);
+
+ return result;
+ }
+
+ // The iterator class
+ template <typename octet_iterator>
+ class iterator : public std::iterator <std::bidirectional_iterator_tag, uint32_t> {
+ octet_iterator it;
+ public:
+ iterator () {};
+ explicit iterator (const octet_iterator& octet_it): it(octet_it) {}
+ // the default "big three" are OK
+ octet_iterator base () const { return it; }
+ uint32_t operator * () const
+ {
+ octet_iterator temp = it;
+ return utf8::unchecked::next(temp);
+ }
+ bool operator == (const iterator& rhs) const
+ {
+ return (it == rhs.it);
+ }
+ bool operator != (const iterator& rhs) const
+ {
+ return !(operator == (rhs));
+ }
+ iterator& operator ++ ()
+ {
+ ::std::advance(it, utf8::internal::sequence_length(it));
+ return *this;
+ }
+ iterator operator ++ (int)
+ {
+ iterator temp = *this;
+ ::std::advance(it, utf8::internal::sequence_length(it));
+ return temp;
+ }
+ iterator& operator -- ()
+ {
+ utf8::unchecked::prior(it);
+ return *this;
+ }
+ iterator operator -- (int)
+ {
+ iterator temp = *this;
+ utf8::unchecked::prior(it);
+ return temp;
+ }
+ }; // class iterator
+
+ } // namespace utf8::unchecked
+} // namespace utf8
+
+
+#endif // header guard
+
diff --git a/plugins/StopSpamMod/src/init.cpp b/plugins/StopSpamMod/src/init.cpp
new file mode 100755
index 0000000000..8bccf59052
--- /dev/null
+++ b/plugins/StopSpamMod/src/init.cpp
@@ -0,0 +1,251 @@
+/* Copyright (C) Miklashevsky Roman, sss, elzor
+*
+* 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; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#include "headers.h"
+
+
+
+BOOL gbDosServiceExist = 0;
+BOOL gbVarsServiceExist = 0;
+
+DWORD gbMaxQuestCount = 5;
+BOOL gbInfTalkProtection = 0;
+BOOL gbAddPermanent = 0;
+BOOL gbHandleAuthReq = 1;
+BOOL gbSpecialGroup = 0;
+BOOL gbHideContacts = 1;
+BOOL gbIgnoreContacts = 0;
+BOOL gbExclude = 1;
+BOOL gbDelExcluded = 0;
+BOOL gbDelAllTempory = 0;
+BOOL gbHistoryLog = 0;
+BOOL gbDosServiceIntegration = 0;
+BOOL gbCaseInsensitive = 0;
+BOOL gbRegexMatch = 0;
+BOOL gbInvisDisable = 0;
+BOOL gbIgnoreURL = 1;
+BOOL gbLogToFile=0;
+BOOL gbAutoAuth=0;
+BOOL gbAutoAddToServerList=0;
+BOOL gbAutoReqAuth=1;
+BOOL gbMathExpression = 0;
+
+HANDLE hStopSpamLogDirH=0;
+
+tstring gbSpammersGroup = _T("Spammers");
+tstring gbAutoAuthGroup = _T("NotSpammers");
+
+tstring gbQuestion;
+tstring gbAnswer;
+tstring gbCongratulation;
+std::wstring gbAuthRepl;
+extern char * pluginDescription;
+extern TCHAR const * defQuestion;
+extern int RemoveTmp(WPARAM,LPARAM);
+
+
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// returns plugin's extended information
+
+// {553811EE-DEB6-48b8-8902-A8A00C1FD679}
+#define MIID_STOPSPAM { 0x553811ee, 0xdeb6, 0x48b8, { 0x89, 0x2, 0xa8, 0xa0, 0xc, 0x1f, 0xd6, 0x79 } }
+
+PLUGININFOEX pluginInfoEx = {
+ sizeof(PLUGININFOEX),
+ 0,
+ PLUGIN_MAKE_VERSION(0, 0, 2, 0),
+ pluginDescription,
+ "Roman Miklashevsky, sss, Elzor",
+ "sss123next@list.ru",
+ "© 2004-2012 Roman Miklashevsky, A. Petkevich, Kosh&chka, sss, Elzor",
+ "http://sss.chaoslab.ru/tracker/mim_plugs/",
+ UNICODE_AWARE,
+ MIID_STOPSPAM
+};
+
+
+char *date()
+{
+ static char d[11];
+ char *tmp = __DATE__, m[4], mn[3] = "01";
+ m[0]=tmp[0];
+ m[1]=tmp[1];
+ m[2]=tmp[2];
+ if(strstr(m,"Jan"))
+ strcpy(mn,"01");
+ else if(strstr(m,"Feb"))
+ strcpy(mn,"02");
+ else if(strstr(m,"Mar"))
+ strcpy(mn,"03");
+ else if(strstr(m,"Apr"))
+ strcpy(mn,"04");
+ else if(strstr(m,"May"))
+ strcpy(mn,"05");
+ else if(strstr(m,"Jun"))
+ strcpy(mn,"06");
+ else if(strstr(m,"Jul"))
+ strcpy(mn,"07");
+ else if(strstr(m,"Aug"))
+ strcpy(mn,"08");
+ else if(strstr(m,"Sep"))
+ strcpy(mn,"09");
+ else if(strstr(m,"Oct"))
+ strcpy(mn,"10");
+ else if(strstr(m,"Nov"))
+ strcpy(mn,"11");
+ else if(strstr(m,"Dec"))
+ strcpy(mn,"12");
+ d[0]=tmp[7];
+ d[1]=tmp[8];
+ d[2]=tmp[9];
+ d[3]=tmp[10];
+ d[4]='.';
+ d[5]=mn[0];
+ d[6]=mn[1];
+ d[7]='.';
+ if (tmp[4] == ' ')
+ d[8] = '0';
+ else
+ d[8]=tmp[4];
+ d[9]=tmp[5];
+ return d;
+}
+
+
+extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion)
+{
+ if ( mirandaVersion < PLUGIN_MAKE_VERSION( 0, 7, 0, 1 ))
+ return NULL;
+ {
+ static char plugname[52];
+ strcpy(plugname, pluginName" mod [");
+ strcat(plugname, date());
+ strcat(plugname, " ");
+ strcat(plugname, __TIME__);
+ strcat(plugname, "]");
+ pluginInfoEx.shortName = plugname;
+ }
+
+ return &pluginInfoEx;
+}
+
+extern tstring DBGetContactSettingStringPAN(HANDLE hContact, char const * szModule, char const * szSetting, tstring errorValue);
+
+void InitVars()
+{
+ gbDosServiceIntegration = DBGetContactSettingByte(NULL, pluginName, "DOSIntegration", 0);
+ gbSpammersGroup = DBGetContactSettingStringPAN(NULL, pluginName, "SpammersGroup", _T("Spammers"));
+ gbAnswer = DBGetContactSettingStringPAN(NULL, pluginName, "answer", _T("nospam"));
+ gbCongratulation = DBGetContactSettingStringPAN(NULL, pluginName, "congratulation", _T("Congratulations! You just passed human/robot test. Now you can write me a message."));
+ gbInfTalkProtection = DBGetContactSettingByte(NULL, pluginName, "infTalkProtection", 0);
+ gbAddPermanent = DBGetContactSettingByte(NULL, pluginName, "addPermanent", 0);
+ gbMaxQuestCount = DBGetContactSettingDword(NULL, pluginName, "maxQuestCount", 5);
+ gbHandleAuthReq = DBGetContactSettingByte(NULL, pluginName, "handleAuthReq", 1);
+ gbQuestion = DBGetContactSettingStringPAN(NULL, pluginName, "question", defQuestion);
+ gbAnswer = DBGetContactSettingStringPAN(NULL, pluginName, "answer", _T("nospam"));
+ gbCongratulation = DBGetContactSettingStringPAN(NULL, pluginName, "congratulation", _T("Congratulations! You just passed human/robot test. Now you can write me a message."));
+ gbAuthRepl = DBGetContactSettingStringPAN(NULL, pluginName, "authrepl", _T("StopSpam: send a message and reply to a anti-spam bot question."));
+ gbSpecialGroup = DBGetContactSettingByte(NULL, pluginName, "SpecialGroup", 0);
+ gbHideContacts = DBGetContactSettingByte(NULL, pluginName, "HideContacts", 0);
+ gbIgnoreContacts = DBGetContactSettingByte(NULL, pluginName, "IgnoreContacts", 0);
+ gbExclude = DBGetContactSettingByte(NULL, pluginName, "ExcludeContacts", 1);
+ gbDelExcluded = DBGetContactSettingByte(NULL, pluginName, "DelExcluded", 0);
+ gbDelAllTempory = DBGetContactSettingByte(NULL, pluginName, "DelAllTempory", 0);
+ gbCaseInsensitive = DBGetContactSettingByte(NULL, pluginName, "CaseInsensitive", 0);
+ gbRegexMatch = DBGetContactSettingByte(NULL, pluginName, "RegexMatch", 0);
+ gbInvisDisable = DBGetContactSettingByte(NULL, pluginName, "DisableInInvis", 0);
+ gbIgnoreURL = DBGetContactSettingByte(NULL, pluginName, "IgnoreURL", 0);
+ gbAutoAuthGroup = DBGetContactSettingStringPAN(NULL, pluginName, "AutoAuthGroup", _T("Not Spammers"));
+ gbAutoAuth=DBGetContactSettingByte(NULL, pluginName, "AutoAuth", 0);
+ gbAutoAddToServerList=DBGetContactSettingByte(NULL, pluginName, "AutoAddToServerList", 0);
+ gbAutoReqAuth=DBGetContactSettingByte(NULL, pluginName, "AutoReqAuth", 0);
+ gbLogToFile=DBGetContactSettingByte(NULL, pluginName, "LogSpamToFile", 0);
+ gbHistoryLog = DBGetContactSettingByte(NULL, pluginName, "HistoryLog", 0);
+ gbMathExpression = DBGetContactSettingByte(NULL, pluginName, "MathExpression", 0);
+
+}
+
+static int OnSystemModulesLoaded(WPARAM wParam,LPARAM lParam)
+{
+/* if (ServiceExists(MS_DOS_SERVICE))
+ gbDosServiceExist = TRUE; */
+ if (ServiceExists(MS_VARS_FORMATSTRING))
+ gbVarsServiceExist = TRUE;
+ InitVars();
+ void CleanThread();
+ if(gbDelAllTempory || gbDelExcluded)
+ boost::thread *thr = new boost::thread(&CleanThread);
+ // Folders plugin support
+ if (ServiceExists(MS_FOLDERS_REGISTER_PATH))
+ {
+ hStopSpamLogDirH = (HANDLE) FoldersRegisterCustomPath("StopSpam", "StopSpam Logs",
+ PROFILE_PATH "\\" CURRENT_PROFILE "\\StopSpamLog");
+ }
+ return 0;
+}
+
+HANDLE hEventFilter = 0, hOptInitialise = 0, hSettingChanged = 0;
+
+
+BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
+{
+ /*if(DLL_PROCESS_ATTACH == fdwReason)
+ hInst=hinstDLL;
+ return TRUE;*/
+ hInst = hinstDLL;
+ return TRUE;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// returns plugin's interfaces information
+
+static const MUUID interfaces[] = { MIID_STOPSPAM, MIID_LAST };
+
+extern "C" __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void)
+{
+ return interfaces;
+}
+
+int hLangpack = 0;
+
+extern "C" int __declspec(dllexport) Load()
+{
+ mir_getLP(&pluginInfoEx);
+ CLISTMENUITEM mi;
+ CreateServiceFunction("/RemoveTmp", (MIRANDASERVICE)RemoveTmp);
+ HookEvent(ME_SYSTEM_MODULESLOADED, OnSystemModulesLoaded);
+ ZeroMemory(&mi,sizeof(mi));
+ mi.cbSize=sizeof(mi);
+ mi.position=-0x7FFFFFFF;
+ mi.flags=0;
+ mi.hIcon=LoadSkinnedIcon(SKINICON_OTHER_MIRANDA);
+ mi.pszName="Remove Temporary Contacts";
+ mi.pszService="/RemoveTmp";
+
+ Menu_AddMainMenuItem(&mi);
+
+ miranda::EventHooker::HookAll();
+ return 0;
+}
+
+extern "C" int __declspec(dllexport) Unload(void)
+{
+ miranda::EventHooker::UnhookAll();
+ return 0;
+}
diff --git a/plugins/StopSpamMod/src/options.cpp b/plugins/StopSpamMod/src/options.cpp
new file mode 100755
index 0000000000..76e448e84b
--- /dev/null
+++ b/plugins/StopSpamMod/src/options.cpp
@@ -0,0 +1,475 @@
+/* Copyright (C) Miklashevsky Roman, sss, elzor
+*
+* 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; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#define MIRANDA_VER 0x0800
+#include "headers.h"
+
+char * pluginDescription = "No more spam! Robots can't go! Only human beings invited!\r\n\r\n"
+"This plugin works pretty simple:\r\n"
+"While messages from users on your contact list go as there is no any anti-spam software, "
+"messages from unknown users are not delivered to you. "
+"But also they are not ignored, this plugin replies with a simple question, "
+"and if user gives the right answer plugin adds him to your contact list "
+"so that he can contact you.";
+TCHAR const * defQuestion =
+_T("Spammers made me to install small anti-spam system you are now speaking with.\r\n")
+_T("Please reply \"nospam\" without quotes and spaces if you want to contact me.");
+
+
+INT_PTR CALLBACK MainDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+
+ switch(msg)
+ {
+ case WM_INITDIALOG:
+ {
+ SetDlgItemTextA(hwnd, ID_DESCRIPTION, pluginDescription);
+ TranslateDialogDefault(hwnd);
+ SetDlgItemInt(hwnd, ID_MAXQUESTCOUNT, gbMaxQuestCount, FALSE);
+ SendDlgItemMessage(hwnd, ID_INFTALKPROT, BM_SETCHECK, gbInfTalkProtection ? BST_CHECKED : BST_UNCHECKED, 0);
+ SendDlgItemMessage(hwnd, ID_ADDPERMANENT, BM_SETCHECK, gbAddPermanent ? BST_CHECKED : BST_UNCHECKED, 0);
+ SendDlgItemMessage(hwnd, ID_HANDLEAUTHREQ, BM_SETCHECK, gbHandleAuthReq ? BST_CHECKED : BST_UNCHECKED, 0);
+ SendDlgItemMessage(hwnd, ID_HIDECONTACTS, BM_SETCHECK, gbHideContacts ? BST_CHECKED : BST_UNCHECKED, 0);
+ SendDlgItemMessage(hwnd, ID_IGNORESPAMMERS, BM_SETCHECK, gbIgnoreContacts ? BST_CHECKED : BST_UNCHECKED, 0);
+ SendDlgItemMessage(hwnd, ID_LOGSPAMTOFILE, BM_SETCHECK, gbLogToFile ? BST_CHECKED : BST_UNCHECKED, 0);
+ }
+ return TRUE;
+ case WM_COMMAND:{
+ switch (LOWORD(wParam))
+ {
+ case ID_MAXQUESTCOUNT:
+ {
+ if (EN_CHANGE != HIWORD(wParam) || (HWND)lParam != GetFocus())
+ return FALSE;
+ break;
+ }
+ }
+ SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
+ }
+ break;
+ case WM_NOTIFY:
+ {
+ NMHDR* nmhdr = (NMHDR*)lParam;
+ switch (nmhdr->code)
+ {
+ case PSN_APPLY:
+ {
+ DBWriteContactSettingDword(NULL, pluginName, "maxQuestCount", gbMaxQuestCount =
+ GetDlgItemInt(hwnd, ID_MAXQUESTCOUNT, NULL, FALSE));
+ DBWriteContactSettingByte(NULL, pluginName, "infTalkProtection", gbInfTalkProtection =
+ BST_CHECKED == SendDlgItemMessage(hwnd, ID_INFTALKPROT, BM_GETCHECK, 0, 0));
+ DBWriteContactSettingByte(NULL, pluginName, "addPermanent", gbAddPermanent =
+ BST_CHECKED == SendDlgItemMessage(hwnd, ID_ADDPERMANENT, BM_GETCHECK, 0, 0));
+ DBWriteContactSettingByte(NULL, pluginName, "handleAuthReq", gbHandleAuthReq =
+ BST_CHECKED == SendDlgItemMessage(hwnd, ID_HANDLEAUTHREQ, BM_GETCHECK, 0, 0));
+ DBWriteContactSettingByte(NULL, pluginName, "HideContacts", gbHideContacts =
+ BST_CHECKED == SendDlgItemMessage(hwnd, ID_HIDECONTACTS, BM_GETCHECK, 0, 0));
+ DBWriteContactSettingByte(NULL, pluginName, "IgnoreContacts", gbIgnoreContacts =
+ BST_CHECKED == SendDlgItemMessage(hwnd, ID_IGNORESPAMMERS, BM_GETCHECK, 0, 0));
+ DBWriteContactSettingByte(NULL, pluginName, "LogSpamToFile", gbLogToFile =
+ BST_CHECKED == SendDlgItemMessage(hwnd, ID_LOGSPAMTOFILE, BM_GETCHECK, 0, 0));
+ }
+ return TRUE;
+ }
+ }
+ break;
+ }
+ return FALSE;
+}
+
+INT_PTR CALLBACK MessagesDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+
+ switch(msg)
+ {
+ case WM_INITDIALOG:
+ {
+ TranslateDialogDefault(hwnd);
+ SetDlgItemText(hwnd, ID_QUESTION, gbQuestion.c_str());
+ SetDlgItemText(hwnd, ID_ANSWER, gbAnswer.c_str());
+ SetDlgItemText(hwnd, ID_CONGRATULATION, gbCongratulation.c_str());
+ SetDlgItemText(hwnd, ID_AUTHREPL, gbAuthRepl.c_str());
+ EnableWindow(GetDlgItem(hwnd, ID_ANSWER), !gbMathExpression);
+ variables_skin_helpbutton(hwnd, IDC_VARS);
+ gbVarsServiceExist?EnableWindow(GetDlgItem(hwnd, IDC_VARS),1):EnableWindow(GetDlgItem(hwnd, IDC_VARS),0);
+ }
+ return TRUE;
+ case WM_COMMAND:
+ {
+ switch(LOWORD(wParam))
+ {
+ case ID_QUESTION:
+ case ID_ANSWER:
+ case ID_AUTHREPL:
+ case ID_CONGRATULATION:
+ {
+ if (EN_CHANGE != HIWORD(wParam) || (HWND)lParam != GetFocus())
+ return FALSE;
+ break;
+ }
+ case ID_RESTOREDEFAULTS:
+ SetDlgItemText(hwnd, ID_QUESTION, TranslateTS(defQuestion));
+ SetDlgItemText(hwnd, ID_ANSWER, TranslateTS(_T("nospam")));
+ SetDlgItemText(hwnd, ID_AUTHREPL, TranslateTS(_T("StopSpam: send a message and reply to a anti-spam bot question.")));
+ SetDlgItemText(hwnd, ID_CONGRATULATION, TranslateTS(_T("Congratulations! You just passed human/robot test. Now you can write me a message.")));
+ SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
+ return TRUE;
+ case IDC_VARS:
+ variables_showhelp(hwnd, msg, VHF_FULLDLG|VHF_SETLASTSUBJECT, NULL, NULL);
+ return TRUE;
+ }
+ SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
+ }
+ break;
+ case WM_NOTIFY:
+ {
+ NMHDR* nmhdr = (NMHDR*)lParam;
+ switch (nmhdr->code)
+ {
+ case PSN_APPLY:
+ {
+ DBWriteContactSettingTString(NULL, pluginName, "question",
+ GetDlgItemString(hwnd, ID_QUESTION).c_str());
+ gbQuestion = DBGetContactSettingStringPAN(NULL, pluginName, "question", defQuestion);
+ DBWriteContactSettingTString(NULL, pluginName, "answer",
+ GetDlgItemString(hwnd, ID_ANSWER).c_str());
+ gbAnswer = DBGetContactSettingStringPAN(NULL, pluginName, "answer", _T("nospam"));
+ DBWriteContactSettingTString(NULL, pluginName, "authrepl",
+ GetDlgItemString(hwnd, ID_AUTHREPL).c_str());
+ gbAuthRepl = DBGetContactSettingStringPAN(NULL, pluginName, "authrepl", _T("StopSpam: send a message and reply to a anti-spam bot question."));
+ DBWriteContactSettingTString(NULL, pluginName, "congratulation",
+ GetDlgItemString(hwnd, ID_CONGRATULATION).c_str());
+ gbCongratulation = DBGetContactSettingStringPAN(NULL, pluginName, "congratulation", _T("Congratulations! You just passed human/robot test. Now you can write me a message."));
+ }
+ return TRUE;
+ }
+ }
+ break;
+ }
+ return FALSE;
+}
+
+INT_PTR CALLBACK ProtoDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+
+ switch(msg)
+ {
+ case WM_INITDIALOG:
+ {
+ TranslateDialogDefault(hwnd);
+ int n;
+ PROTOCOLDESCRIPTOR** pppd;
+ if(!CallService(MS_PROTO_ENUMPROTOCOLS, (LPARAM)&n, (WPARAM)&pppd))
+ for(int i = 0; i < n; ++i)
+ {
+ SendDlgItemMessageA(hwnd, (ProtoInList(pppd[i]->szName) ? ID_USEDPROTO : ID_ALLPROTO),
+ LB_ADDSTRING, 0, (LPARAM)pppd[i]->szName);
+ }
+ }
+ return TRUE;
+ case WM_COMMAND:
+ switch(LOWORD(wParam))
+ {
+ case ID_ADD:
+ {
+ WPARAM n = (WPARAM)SendDlgItemMessage(hwnd, ID_ALLPROTO, LB_GETCURSEL, 0, 0);
+ if(LB_ERR != n)
+ {
+ size_t len = SendDlgItemMessage(hwnd, ID_ALLPROTO, LB_GETTEXTLEN, n, 0);
+ if(LB_ERR != len)
+ {
+ TCHAR * buf = new TCHAR[len + 1];
+ SendDlgItemMessage(hwnd, ID_ALLPROTO, LB_GETTEXT, n, (LPARAM)buf);
+ SendDlgItemMessage(hwnd, ID_USEDPROTO, LB_ADDSTRING, 0, (LPARAM)buf);
+ delete []buf;
+ SendDlgItemMessage(hwnd, ID_ALLPROTO, LB_DELETESTRING, n, 0);
+ }
+ }
+ }
+ break;
+ case ID_REMOVE:
+ {
+ WPARAM n = (WPARAM)SendDlgItemMessage(hwnd, ID_USEDPROTO, LB_GETCURSEL, 0, 0);
+ if(LB_ERR != n)
+ {
+ size_t len = SendDlgItemMessage(hwnd, ID_USEDPROTO, LB_GETTEXTLEN, n, 0);
+ if(LB_ERR != len)
+ {
+ TCHAR * buf = new TCHAR[len + 1];
+ SendDlgItemMessage(hwnd, ID_USEDPROTO, LB_GETTEXT, n, (LPARAM)buf);
+ SendDlgItemMessage(hwnd, ID_ALLPROTO, LB_ADDSTRING, 0, (LPARAM)buf);
+ delete []buf;
+ SendDlgItemMessage(hwnd, ID_USEDPROTO, LB_DELETESTRING, n, 0);
+ }
+ }
+ }
+ break;
+ case ID_ADDALL:
+ for(;;)
+ {
+ LRESULT count = SendDlgItemMessage(hwnd, ID_ALLPROTO, LB_GETCOUNT, 0, 0);
+ if(!count || LB_ERR == count)
+ break;
+ SendDlgItemMessage(hwnd, ID_ALLPROTO, LB_SETCURSEL, 0, 0);
+ SendMessage(hwnd, WM_COMMAND, ID_ADD, 0);
+ }
+ break;
+ case ID_REMOVEALL:
+ for(;;)
+ {
+ LRESULT count = SendDlgItemMessage(hwnd, ID_USEDPROTO, LB_GETCOUNT, 0, 0);
+ if(!count || LB_ERR == count)
+ break;
+ SendDlgItemMessage(hwnd, ID_USEDPROTO, LB_SETCURSEL, 0, 0);
+ SendMessage(hwnd, WM_COMMAND, ID_REMOVE, 0);
+ }
+ break;
+ default:
+ return FALSE;
+ }
+ SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
+ return TRUE;
+ case WM_NOTIFY:
+ {
+ NMHDR* nmhdr = (NMHDR*)lParam;
+ switch (nmhdr->code)
+ {
+ case PSN_APPLY:
+ {
+ LRESULT count = SendDlgItemMessage(hwnd, ID_USEDPROTO, LB_GETCOUNT, 0, 0);
+ std::ostringstream out;
+ for(int i = 0; i < count; ++i)
+ {
+ size_t len = SendDlgItemMessageA(hwnd, ID_USEDPROTO, LB_GETTEXTLEN, i, 0);
+ if(LB_ERR != len)
+ {
+ char * buf = new char[len + 1];
+ SendDlgItemMessageA(hwnd, ID_USEDPROTO, LB_GETTEXT, i, (LPARAM)buf);
+ out << buf << "\r\n";
+ delete []buf;
+ }
+ }
+ DBWriteContactSettingString(NULL, pluginName, "protoList", out.str().c_str());
+ }
+ return TRUE;
+ }
+ }
+ break;
+ }
+ return FALSE;
+}
+
+INT_PTR CALLBACK AdvancedDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+
+ switch(msg)
+ {
+ case WM_INITDIALOG:
+ {
+ TranslateDialogDefault(hwnd);
+ SendDlgItemMessage(hwnd, IDC_INVIS_DISABLE, BM_SETCHECK, gbInvisDisable ? BST_CHECKED : BST_UNCHECKED, 0);
+ SendDlgItemMessage(hwnd, IDC_CASE_INSENSITIVE, BM_SETCHECK, gbCaseInsensitive ? BST_CHECKED : BST_UNCHECKED, 0);
+ gbDosServiceExist?EnableWindow(GetDlgItem(hwnd, ID_DOS_INTEGRATION),1):EnableWindow(GetDlgItem(hwnd, ID_DOS_INTEGRATION),0);
+ SendDlgItemMessage(hwnd, ID_DOS_INTEGRATION, BM_SETCHECK, gbDosServiceIntegration ? BST_CHECKED : BST_UNCHECKED, 0);
+ SetDlgItemText(hwnd, ID_SPECIALGROUPNAME, gbSpammersGroup.c_str());
+ SendDlgItemMessage(hwnd, ID_SPECIALGROUP, BM_SETCHECK, gbSpecialGroup ? BST_CHECKED : BST_UNCHECKED, 0);
+ SendDlgItemMessage(hwnd, ID_EXCLUDE, BM_SETCHECK, gbExclude ? BST_CHECKED : BST_UNCHECKED, 0);
+ SendDlgItemMessage(hwnd, ID_REMOVE_TMP, BM_SETCHECK, gbDelExcluded ? BST_CHECKED : BST_UNCHECKED, 0);
+ SendDlgItemMessage(hwnd, ID_REMOVE_TMP_ALL, BM_SETCHECK, gbDelAllTempory ? BST_CHECKED : BST_UNCHECKED, 0);
+ SendDlgItemMessage(hwnd, ID_IGNOREURL, BM_SETCHECK, gbIgnoreURL ? BST_CHECKED : BST_UNCHECKED, 0);
+ SendDlgItemMessage(hwnd, IDC_AUTOAUTH, BM_SETCHECK, gbAutoAuth ? BST_CHECKED : BST_UNCHECKED, 0);
+ SendDlgItemMessage(hwnd, IDC_ADDTOSRVLST, BM_SETCHECK, gbAutoAddToServerList ? BST_CHECKED : BST_UNCHECKED, 0);
+ SendDlgItemMessage(hwnd, IDC_REQAUTH, BM_SETCHECK, gbAutoReqAuth ? BST_CHECKED : BST_UNCHECKED, 0);
+ SendDlgItemMessage(hwnd, IDC_REGEX, BM_SETCHECK, gbRegexMatch ? BST_CHECKED : BST_UNCHECKED, 0);
+ SendDlgItemMessage(hwnd, IDC_HISTORY_LOG, BM_SETCHECK, gbHistoryLog ? BST_CHECKED : BST_UNCHECKED, 0);
+ SendDlgItemMessage(hwnd, IDC_MATH_QUESTION, BM_SETCHECK, gbMathExpression ? BST_CHECKED : BST_UNCHECKED, 0 );
+
+ SetDlgItemText(hwnd, IDC_AUTOADDGROUP, gbAutoAuthGroup.c_str());
+ }
+ return TRUE;
+ case WM_COMMAND:{
+ switch (LOWORD(wParam))
+ {
+ case IDC_MATH_DETAILS:
+ {
+ MessageBox(NULL, TranslateT("If math expression is turned on you can use following expression in message text:\nXX+XX-X/X*X\neach X will be replaced by one ruandom number and answer will be expression result\nMessage must contain only one expression without spaces"), _T("Info"), MB_OK);
+ }
+ break;
+ case IDC_INVIS_DISABLE:
+ case IDC_CASE_INSENSITIVE:
+ case ID_DOS_INTEGRATION:
+ case ID_SPECIALGROUPNAME:
+ case ID_SPECIALGROUP:
+ case ID_EXCLUDE:
+ case ID_REMOVE_TMP:
+ case ID_REMOVE_TMP_ALL:
+ case ID_IGNOREURL:
+ case IDC_AUTOAUTH:
+ case IDC_ADDTOSRVLST:
+ case IDC_REQAUTH:
+ case IDC_AUTOADDGROUP:
+ case IDC_REGEX:
+ case IDC_HISTORY_LOG:
+ SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
+ break;
+
+ }
+ }
+ break;
+ case WM_NOTIFY:
+ {
+ NMHDR* nmhdr = (NMHDR*)lParam;
+ switch (nmhdr->code)
+ {
+ case PSN_APPLY:
+ {
+ DBWriteContactSettingByte(NULL, pluginName, "CaseInsensitive", gbCaseInsensitive =
+ BST_CHECKED == SendDlgItemMessage(hwnd, IDC_CASE_INSENSITIVE, BM_GETCHECK, 0, 0));
+ DBWriteContactSettingByte(NULL, pluginName, "DisableInInvis", gbInvisDisable =
+ BST_CHECKED == SendDlgItemMessage(hwnd, IDC_INVIS_DISABLE, BM_GETCHECK, 0, 0));
+ DBWriteContactSettingByte(NULL, pluginName, "DOSIntegration", gbDosServiceIntegration =
+ BST_CHECKED == SendDlgItemMessage(hwnd, ID_DOS_INTEGRATION, BM_GETCHECK, 0, 0));
+ {
+ static tstring NewGroupName, CurrentGroupName;
+ NewGroupName = GetDlgItemString(hwnd, ID_SPECIALGROUPNAME);
+ CurrentGroupName = gbSpammersGroup = DBGetContactSettingStringPAN(NULL, pluginName, "SpammersGroup", _T("0"));
+ if(wcscmp(CurrentGroupName.c_str(), NewGroupName.c_str()) != 0)
+ {
+ int GroupNumber = 0;
+ BYTE GroupExist = 0;
+ TCHAR szValue[96] = {0};
+ char szNumber[32] = {0};
+ extern int CreateCListGroup(TCHAR* szGroupName);
+ strcpy(szNumber, "0");
+ while(strcmp(DBGetContactSettingStringPAN_A(NULL, "CListGroups", szNumber, "0").c_str(), "0") != 0)
+ {
+ _itoa(GroupNumber, szNumber, 10);
+ wcscpy(szValue, DBGetContactSettingStringPAN(NULL, "CListGroups", szNumber, _T("0")).c_str());
+ if(wcscmp(NewGroupName.c_str(), szValue + 1) == 0)
+ {
+ GroupExist = 1;
+ break;
+ }
+ GroupNumber++;
+ }
+ DBWriteContactSettingTString(NULL,pluginName, "SpammersGroup", NewGroupName.c_str());
+ gbSpammersGroup = DBGetContactSettingStringPAN(NULL,pluginName,"SpammersGroup", _T("Spammers"));
+ if(!GroupExist && gbSpecialGroup)
+ CreateCListGroup((TCHAR*)gbSpammersGroup.c_str());
+ }
+ }
+ DBWriteContactSettingByte(NULL, pluginName, "SpecialGroup", gbSpecialGroup =
+ BST_CHECKED == SendDlgItemMessage(hwnd, ID_SPECIALGROUP, BM_GETCHECK, 0, 0));
+ DBWriteContactSettingByte(NULL, pluginName, "ExcludeContacts", gbExclude =
+ BST_CHECKED == SendDlgItemMessage(hwnd, ID_EXCLUDE, BM_GETCHECK, 0, 0));
+ DBWriteContactSettingByte(NULL, pluginName, "DelExcluded", gbDelExcluded =
+ BST_CHECKED == SendDlgItemMessage(hwnd, ID_REMOVE_TMP, BM_GETCHECK, 0, 0));
+ DBWriteContactSettingByte(NULL, pluginName, "DelAllTempory", gbDelAllTempory =
+ BST_CHECKED == SendDlgItemMessage(hwnd, ID_REMOVE_TMP_ALL, BM_GETCHECK, 0, 0));
+ DBWriteContactSettingByte(NULL, pluginName, "IgnoreURL", gbIgnoreURL =
+ BST_CHECKED == SendDlgItemMessage(hwnd, ID_IGNOREURL, BM_GETCHECK, 0, 0));
+
+ DBWriteContactSettingByte(NULL, pluginName, "AutoAuth", gbAutoAuth =
+ BST_CHECKED == SendDlgItemMessage(hwnd, IDC_AUTOAUTH, BM_GETCHECK, 0, 0));
+ DBWriteContactSettingByte(NULL, pluginName, "AutoAddToServerList", gbAutoAddToServerList =
+ BST_CHECKED == SendDlgItemMessage(hwnd, IDC_ADDTOSRVLST, BM_GETCHECK, 0, 0));
+ DBWriteContactSettingByte(NULL, pluginName, "AutoReqAuth", gbAutoReqAuth =
+ BST_CHECKED == SendDlgItemMessage(hwnd, IDC_REQAUTH, BM_GETCHECK, 0, 0));
+ DBWriteContactSettingByte(NULL, pluginName, "RegexMatch", gbRegexMatch =
+ BST_CHECKED == SendDlgItemMessage(hwnd, IDC_REGEX, BM_GETCHECK, 0, 0));
+ DBWriteContactSettingByte(NULL, pluginName, "HistoryLog", gbHistoryLog =
+ BST_CHECKED == SendDlgItemMessage(hwnd, IDC_HISTORY_LOG, BM_GETCHECK, 0, 0));
+ DBWriteContactSettingByte(NULL, pluginName, "MathExpression", gbMathExpression =
+ BST_CHECKED == SendDlgItemMessage(hwnd, IDC_MATH_QUESTION, BM_GETCHECK, 0, 0));
+
+ {
+ static tstring NewAGroupName, CurrentAGroupName;
+ NewAGroupName = GetDlgItemString(hwnd, IDC_AUTOADDGROUP);
+ CurrentAGroupName = gbAutoAuthGroup = DBGetContactSettingStringPAN(NULL, pluginName, "AutoAuthGroup", _T("0"));
+ if(wcscmp(CurrentAGroupName.c_str(), NewAGroupName.c_str()) != 0)
+ {
+ int GroupNumber = 0;
+ BYTE GroupExist = 0;
+ TCHAR szValue[96] = {0};
+ char szNumber[32] = {0};
+ extern int CreateCListGroup(TCHAR* szGroupName);
+ strcpy(szNumber, "0");
+ while(strcmp(DBGetContactSettingStringPAN_A(NULL, "CListGroups", szNumber, "0").c_str(), "0") != 0)
+ {
+ _itoa(GroupNumber, szNumber, 10);
+ wcscpy(szValue, DBGetContactSettingStringPAN(NULL, "CListGroups", szNumber, _T("0")).c_str());
+ if(wcscmp(NewAGroupName.c_str(), szValue + 1) == 0)
+ {
+ GroupExist = 1;
+ break;
+ }
+ GroupNumber++;
+ }
+ DBWriteContactSettingTString(NULL,pluginName, "AutoAuthGroup", NewAGroupName.c_str());
+ gbAutoAuthGroup = DBGetContactSettingStringPAN(NULL,pluginName,"AutoAuthGroup", _T("Not Spammers"));
+ if(!GroupExist && gbAutoAddToServerList)
+ CreateCListGroup((TCHAR*)gbAutoAuthGroup.c_str());
+ }
+ }
+
+ }
+ return TRUE;
+ }
+ }
+ break;
+ }
+ return FALSE;
+}
+
+
+HINSTANCE hInst;
+MIRANDA_HOOK_EVENT(ME_OPT_INITIALISE, w, l)
+{
+ OPTIONSDIALOGPAGE odp = {0};
+ odp.cbSize = sizeof(odp);
+ odp.ptszGroup = _T("Message Sessions");
+ odp.ptszTitle = _T(pluginName);
+ odp.position = -1;
+ odp.hInstance = hInst;
+ odp.flags = ODPF_TCHAR;
+
+ odp.ptszTab = _T("Main");
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_MAIN);
+ odp.pfnDlgProc = MainDlgProc;
+ Options_AddPage(w, &odp);
+
+
+ odp.ptszTab = _T("Messages");
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_MESSAGES);
+ odp.pfnDlgProc = MessagesDlgProc;
+ Options_AddPage(w, &odp);
+
+ odp.ptszTab = _T("Protocols");
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_PROTO);
+ odp.pfnDlgProc = ProtoDlgProc;
+ Options_AddPage(w, &odp);
+
+ odp.ptszTab = _T("Advanced");
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_ADVANCED);
+ odp.pfnDlgProc = AdvancedDlgProc;
+ odp.flags = odp.flags|ODPF_EXPERTONLY;
+ Options_AddPage(w, &odp);
+
+ return 0;
+}
+
diff --git a/plugins/StopSpamMod/src/options.h b/plugins/StopSpamMod/src/options.h
new file mode 100755
index 0000000000..e32791e98b
--- /dev/null
+++ b/plugins/StopSpamMod/src/options.h
@@ -0,0 +1 @@
+extern HINSTANCE hInst; \ No newline at end of file
diff --git a/plugins/StopSpamMod/src/resource.h b/plugins/StopSpamMod/src/resource.h
new file mode 100755
index 0000000000..05f1ba3267
--- /dev/null
+++ b/plugins/StopSpamMod/src/resource.h
@@ -0,0 +1,68 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by stopspam.rc
+//
+#define IDD_MESSAGES 101
+#define IDD_MAIN 103
+#define ID_DESCRIPTION 1001
+#define ID_QUESTION 1002
+#define ID_ANSWER 1003
+#define ID_CONGRATULATION 1004
+#define ID_RESTOREDEFAULTS 1005
+#define ID_ADD 1005
+#define ID_ANSWER2 1007
+#define ID_AUTHREPL 1007
+#define ID_ALLPROTO 1008
+#define IDD_PROTO 1008
+#define ID_MAXQUESTCOUNT 1008
+#define ID_REMOVE 1009
+#define ID_SPECIALGROUPNAME 1009
+#define IDD_ADVANCED 1009
+#define ID_USEDPROTO 1010
+#define ID_REMOVEALL 1011
+#define ID_ADDALL 1012
+#define ID_INFTALKPROT 1013
+#define ID_ADDPERMANENT 1014
+#define ID_ADDPERMANENT2 1015
+#define ID_HANDLEAUTHREQ 1015
+#define ID_DOS_INTEGRATION 1016
+#define ID_SPECIALGROUP 1017
+#define IDC_BUTTON1 1017
+#define IDC_VARS 1017
+#define ID_HIDECONTACTS 1018
+#define IDC_CASE_INSENSITIVE 1018
+#define ID_IGNORESPAMMERS 1019
+#define IDC_CHECK2 1019
+#define IDC_INVIS_DISABLE 1019
+#define ID_REMOVE_TMP 1020
+#define IDC_CUSTOM1 1020
+#define ID_REMOVE_TMP2 1021
+#define ID_EXCLUDE 1021
+#define ID_ADDPERMANENT3 1022
+#define ID_DEL_NO_IN_LIST 1022
+#define IDC_ADDTOSRVLST 1022
+#define ID_IGNOREURL 1023
+#define IDC_EDIT1 1024
+#define IDC_AUTOADDGROUP 1024
+#define IDC_AUTOAUTH 1025
+#define IDC_REQAUTH 1026
+#define IDC_LOGSPAMTOFILE 1027
+#define ID_REMOVE_TMP_ALL 1027
+#define ID_LOGSPAMTOFILE 1027
+#define IDC_REGEX 1028
+#define IDC_CHECK1 1029
+#define IDC_HISTORY_LOG 1029
+#define IDC_MATH_QUESTION 1030
+#define IDC_BUTTON2 1031
+#define IDC_MATH_DETAILS 1031
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 104
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1032
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/plugins/StopSpamMod/src/stopspam.cpp b/plugins/StopSpamMod/src/stopspam.cpp
new file mode 100755
index 0000000000..5c13ec6056
--- /dev/null
+++ b/plugins/StopSpamMod/src/stopspam.cpp
@@ -0,0 +1,390 @@
+/* Copyright (C) Miklashevsky Roman, sss, elzor
+*
+* 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; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#include "headers.h"
+
+
+MIRANDA_HOOK_EVENT(ME_DB_CONTACT_ADDED, w, l)
+{
+ return 0;
+}
+
+
+MIRANDA_HOOK_EVENT(ME_DB_EVENT_ADDED, wParam, lParam)
+{
+ HANDLE hContact = (HANDLE)wParam;
+ HANDLE hDbEvent = (HANDLE)lParam;
+
+ DBEVENTINFO dbei = {0};
+ dbei.cbSize = sizeof(dbei);
+ dbei.cbBlob = CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)hDbEvent, 0);
+ if(-1 == dbei.cbBlob)
+ return 0;
+
+ dbei.pBlob = new BYTE[dbei.cbBlob];
+ CallService(MS_DB_EVENT_GET, lParam, (LPARAM)&dbei);
+
+ // if event is in protocol that is not despammed
+ if(!ProtoInList(dbei.szModule)) {
+ delete dbei.pBlob;
+ return 0;
+ }
+
+ // event is an auth request
+ if(gbHandleAuthReq)
+ {
+ if(!(dbei.flags & DBEF_SENT) && !(dbei.flags & DBEF_READ) && dbei.eventType == EVENTTYPE_AUTHREQUEST)
+ {
+ HANDLE hcntct;
+ hcntct=*((PHANDLE)(dbei.pBlob+sizeof(DWORD)));
+
+ // if request is from unknown or not marked Answered contact
+ int a = DBGetContactSettingByte(hcntct, "CList", "NotOnList", 0);
+ int b = !DBGetContactSettingByte(hcntct, pluginName, "Answered", 0);
+
+ if(a && b)//
+ {
+ // ...send message
+
+ if(gbHideContacts)
+ DBWriteContactSettingByte(hcntct, "CList", "Hidden", 1);
+ if(gbSpecialGroup)
+ DBWriteContactSettingTString(hcntct, "CList", "Group", gbSpammersGroup.c_str());
+ BYTE msg = 1;
+ if(gbIgnoreURL){
+ TCHAR* EventText = ReqGetText(&dbei); //else return NULL
+ msg=!IsUrlContains(EventText);
+ mir_free(EventText);
+ };
+ if(gbInvisDisable)
+ {
+ if(CallProtoService(dbei.szModule, PS_GETSTATUS, 0, 0) == ID_STATUS_INVISIBLE)
+ msg = 0;
+ else if(DBGetContactSettingWord(hContact,dbei.szModule,"ApparentMode",0) == ID_STATUS_OFFLINE)
+ msg = 0; //is it useful ?
+ }
+ if(msg)
+ {
+ char * buff=mir_utf8encodeW(variables_parse(gbAuthRepl, hcntct).c_str());
+ CallContactService(hcntct, PSS_MESSAGE, PREF_UTF, (LPARAM) buff);
+ mir_free(buff);
+ };
+ delete dbei.pBlob;
+ return 1;
+ }
+ }
+ }
+ delete dbei.pBlob;
+ return 0;
+}
+
+MIRANDA_HOOK_EVENT(ME_DB_EVENT_FILTER_ADD, w, l)
+{
+ HANDLE hContact = (HANDLE)w;
+ if(!l) //fix potential DEP crash
+ return 0;
+ DBEVENTINFO * dbei = (DBEVENTINFO*)l;
+
+ // if event is in protocol that is not despammed
+ if(!ProtoInList(dbei->szModule))
+ {
+ // ...let the event go its way
+ return 0;
+ }
+ //do not check excluded contact
+
+ if(DBGetContactSettingByte(hContact, pluginName, "Answered", 0))
+ return 0;
+ if(DBGetContactSettingByte(hContact, pluginName, "Excluded", 0))
+ {
+ if(!DBGetContactSettingByte(hContact, "CList", "NotOnList", 0))
+ DBDeleteContactSetting(hContact, pluginName, "Excluded");
+ return 0;
+ }
+ //we want block not only messages, i seen many types other eventtype flood
+ if(dbei->flags & DBEF_READ)
+ // ...let the event go its way
+ return 0;
+ //mark contact which we trying to contact for exclude from check
+ if((dbei->flags & DBEF_SENT) && DBGetContactSettingByte(hContact, "CList", "NotOnList", 0)
+ && (!gbMaxQuestCount || DBGetContactSettingDword(hContact, pluginName, "QuestionCount", 0) < gbMaxQuestCount) && gbExclude)
+ {
+ DBWriteContactSettingByte(hContact, pluginName, "Excluded", 1);
+ return 0;
+ }
+ // if message is from known or marked Answered contact
+ if(!DBGetContactSettingByte(hContact, "CList", "NotOnList", 0))
+ // ...let the event go its way
+ return 0;
+ // if message is corrupted or empty it cannot be an answer.
+ if(!dbei->cbBlob || !dbei->pBlob)
+ // reject processing of the event
+ return 1;
+
+ tstring message;
+
+ if(dbei->flags & DBEF_UTF)
+ {
+ wchar_t* msg_u;
+ char* msg_a = mir_strdup(( char* )dbei->pBlob );
+ mir_utf8decode( msg_a, &msg_u );
+ message = msg_u;
+ }
+ else
+ message = mir_a2u((char*)(dbei->pBlob));
+
+ // if message contains right answer...
+
+ BYTE msg = 1;
+ if(gbInvisDisable)
+ {
+ if(CallProtoService(dbei->szModule, PS_GETSTATUS, 0, 0) == ID_STATUS_INVISIBLE)
+ msg = 0;
+ else if(DBGetContactSettingWord(hContact,dbei->szModule,"ApparentMode",0) == ID_STATUS_OFFLINE)
+ msg = 0; //is it useful ?
+ }
+ bool answered = false;
+ if(gbMathExpression)
+ {
+ if(boost::algorithm::all(message, boost::is_digit()))
+ {
+ int msg = _ttoi(message.c_str());
+ int math_answer = DBGetContactSettingDword(hContact, pluginName, "MathAnswer", 0);
+ if(msg && math_answer)
+ answered = (msg == math_answer);
+ }
+ }
+ else if(!gbRegexMatch)
+ answered = gbCaseInsensitive?(!Stricmp(message.c_str(), (variables_parse(gbAnswer, hContact).c_str()))):( !_tcscmp(message.c_str(), (variables_parse(gbAnswer, hContact).c_str())));
+ else
+ {
+ if(gbCaseInsensitive)
+ {
+ std::string check(toUTF8(variables_parse(gbAnswer, hContact))), msg(toUTF8(message));
+ boost::algorithm::to_upper(check);
+ boost::algorithm::to_upper(msg);
+ boost::regex expr(check);
+ answered = boost::regex_search(msg.begin(), msg.end(), expr);
+ }
+ else
+ {
+ std::string check(toUTF8(variables_parse(gbAnswer, hContact))), msg(toUTF8(message));
+ boost::regex expr(check);
+ answered = boost::regex_search(msg.begin(), msg.end(), expr);
+ }
+ }
+ if(answered)
+ {
+ // unhide contact
+ DBDeleteContactSetting(hContact, "CList", "Hidden");
+
+ DBDeleteContactSetting(hContact, pluginName, "MathAnswer");
+
+ // mark contact as Answered
+ DBWriteContactSettingByte(hContact, pluginName, "Answered", 1);
+
+ //add contact permanently
+ if(gbAddPermanent) //do not use this )
+ DBDeleteContactSetting(hContact, "CList", "NotOnList");
+
+ // send congratulation
+ if(msg)
+ {
+ tstring prot=DBGetContactSettingStringPAN(NULL,dbei->szModule,"AM_BaseProto", _T(""));
+ // for notICQ protocols or disable auto auth. reqwest
+ if((Stricmp(_T("ICQ"),prot.c_str()))||(!gbAutoReqAuth))
+ {
+#ifdef _UNICODE
+ char * buf=mir_utf8encodeW(variables_parse(gbCongratulation, hContact).c_str());
+ CallContactService(hContact, PSS_MESSAGE, PREF_UTF, (LPARAM)buf);
+ mir_free(buf);
+#else
+ CallContactService(hContact, PSS_MESSAGE, 0, (LPARAM)GetCongratulation().c_str());
+#endif
+ };
+ // Note: For ANSI can be not work
+ if(!Stricmp(_T("ICQ"),prot.c_str())){
+ // grand auth.
+ if(gbAutoAuth)
+ CallProtoService(dbei->szModule, "/GrantAuth", w, 0);
+ // add contact to server list and local group
+ if(gbAutoAddToServerList)
+ {
+ DBWriteContactSettingTString(hContact, "CList", "Group", gbAutoAuthGroup.c_str());
+ CallProtoService(dbei->szModule, "/AddServerContact", w, 0);
+ DBDeleteContactSetting(hContact, "CList", "NotOnList");
+ };
+ // auto auth. reqwest with send congratulation
+ if(gbAutoReqAuth)
+ CallContactService(hContact,PSS_AUTHREQUESTW,0, (LPARAM)variables_parse(gbCongratulation, hContact).c_str());
+ }
+ }
+ return 0;
+ }
+ // URL contains check
+ msg=(msg&&gbIgnoreURL)?(!IsUrlContains((TCHAR *) message.c_str())):msg;
+ // if message message does not contain infintite talk protection prefix
+ // and question count for this contact is less then maximum
+ if(msg)
+ {
+ if((!gbInfTalkProtection || tstring::npos==message.find(_T("StopSpam automatic message:\r\n")))
+ && (!gbMaxQuestCount || DBGetContactSettingDword(hContact, pluginName, "QuestionCount", 0) < gbMaxQuestCount))
+ {
+ // send question
+ tstring q;
+ if(gbInfTalkProtection)
+ q += _T("StopSpam automatic message:\r\n");
+ if(gbMathExpression)
+ { //parse math expression in question
+ tstring tmp_question = gbQuestion;
+ std::list<int> args;
+ std::list<TCHAR> actions;
+ tstring::size_type p1 = gbQuestion.find(_T("X")), p2 = 0;
+ const tstring expr_chars = _T("X+-/*"), expr_acts = _T("+-/*");
+ while(p1 < gbQuestion.length() && p1 != tstring::npos && expr_chars.find(gbQuestion[p1]) != tstring::npos)
+ {
+ std::string arg;
+ p2 = p1;
+#ifdef UNICODE
+ for(p1 = gbQuestion.find(_T("X"), p1); (p1 < gbQuestion.length()) && (gbQuestion[p1] == L'X'); ++p1)
+#else
+ for(p1 = gbQuestion.find(_T("X"), p1); gbQuestion[p1] == 'X'; ++p1)
+#endif
+ arg += get_random_num(1);
+#ifdef UNICODE
+ tmp_question.replace(p2, arg.size(), toUTF16(arg));
+#else
+ tmp_question.replace(p2, arg.size(), arg);
+#endif
+ args.push_back(atoi(arg.c_str()));
+ if((p1 < gbQuestion.length()) && (p1 != tstring::npos) && (expr_acts.find(gbQuestion[p1]) != tstring::npos))
+ actions.push_back(gbQuestion[p1]);
+ ++p1;
+ }
+ int math_answer = 0;
+ math_answer = args.front();
+ args.pop_front();
+ while(!args.empty())
+ {
+ if(!actions.empty())
+ {
+ switch(actions.front())
+ {
+ case _T('+'):
+ {
+ math_answer += args.front();
+ args.pop_front();
+ }
+ break;
+ case _T('-'):
+ {
+ math_answer -= args.front();
+ args.pop_front();
+ }
+ break;
+ case _T('/'):
+ {
+ math_answer /= args.front();
+ args.pop_front();
+ }
+ break;
+ case _T('*'):
+ {
+ math_answer *= args.front();
+ args.pop_front();
+ }
+ break;
+ }
+ actions.pop_front();
+ }
+ else
+ break;
+ }
+ DBWriteContactSettingDword(hContact, pluginName, "MathAnswer", math_answer);
+ q += variables_parse(tmp_question, hContact);
+ }
+ else
+ q += variables_parse(gbQuestion, hContact);
+
+#ifdef _UNICODE
+ char * buf=mir_utf8encodeW(q.c_str());
+ CallContactService(hContact, PSS_MESSAGE, PREF_UTF, (LPARAM)buf);
+ mir_free(buf);
+#else
+ CallContactService(hContact, PSS_MESSAGE, 0, (LPARAM)q.c_str());
+#endif
+
+ // increment question count
+ DWORD questCount = DBGetContactSettingDword(hContact, pluginName, "QuestionCount", 0);
+ DBWriteContactSettingDword(hContact, pluginName, "QuestionCount", questCount + 1);
+ }
+ else
+ {
+/* if (gbDosServiceExist)
+ {
+ if(gbDosServiceIntegration)
+ {
+ int i;
+ i = rand()%255*13;
+ CallService(MS_DOS_SERVICE, (WPARAM)hContact, (LPARAM)i);
+ }
+ } */
+ if(gbIgnoreContacts)
+ {
+ DBWriteContactSettingDword(hContact, "Ignore", "Mask1", 0x0000007F);
+ }
+ }
+ }
+ if(gbHideContacts)
+ DBWriteContactSettingByte(hContact, "CList", "Hidden", 1);
+ if(gbSpecialGroup)
+ DBWriteContactSettingTString(hContact, "CList", "Group", gbSpammersGroup.c_str());
+ DBWriteContactSettingByte(hContact, "CList", "NotOnList", 1);
+
+ // save first message from contact
+ if (DBGetContactSettingDword(hContact, pluginName, "QuestionCount", 0)<2){
+ dbei->flags |= DBEF_READ;
+ CallService(MS_DB_EVENT_ADD, (WPARAM)hContact, (LPARAM)dbei);
+ };
+ // reject processing of the event
+ LogSpamToFile(hContact, message);
+ return 1;
+}
+
+
+MIRANDA_HOOK_EVENT(ME_DB_CONTACT_SETTINGCHANGED, w, l)
+{
+ HANDLE hContact = (HANDLE)w;
+ DBCONTACTWRITESETTING * cws = (DBCONTACTWRITESETTING*)l;
+
+ // if CList/NotOnList is being deleted then remove answeredSetting
+ if(strcmp(cws->szModule, "CList"))
+ return 0;
+ if(strcmp(cws->szSetting, "NotOnList"))
+ return 0;
+ if(!cws->value.type)
+ {
+ DBDeleteContactSetting(hContact, pluginName, "Answered");
+ DBDeleteContactSetting(hContact, pluginName, "QuestionCount");
+ }
+
+ return 0;
+}
+
+
+
diff --git a/plugins/StopSpamMod/src/stopspam.h b/plugins/StopSpamMod/src/stopspam.h
new file mode 100755
index 0000000000..94300b9713
--- /dev/null
+++ b/plugins/StopSpamMod/src/stopspam.h
@@ -0,0 +1,31 @@
+
+extern BOOL gbDosServiceExist;
+extern BOOL gbVarsServiceExist;
+extern DWORD gbMaxQuestCount;
+extern BOOL gbInfTalkProtection;
+extern BOOL gbAddPermanent;
+extern BOOL gbHandleAuthReq;
+extern BOOL gbSpecialGroup;
+extern BOOL gbHideContacts;
+extern BOOL gbIgnoreContacts;
+extern BOOL gbExclude;
+extern BOOL gbDelExcluded;
+extern BOOL gbDosServiceIntegration;
+extern BOOL gbDelNotInList;
+extern BOOL gbCaseInsensitive;
+extern BOOL gbRegexMatch;
+extern BOOL gbHistoryLog;
+extern BOOL gbInvisDisable;
+extern BOOL gbIgnoreURL;
+extern BOOL gbMathExpression;
+extern tstring gbSpammersGroup;
+extern tstring gbQuestion;
+extern tstring gbAnswer;
+extern tstring gbCongratulation;
+extern std::wstring gbAuthRepl;
+extern BOOL gbAutoAuth;
+extern BOOL gbAutoAddToServerList;
+extern BOOL gbAutoReqAuth;
+extern tstring gbAutoAuthGroup;
+extern BOOL gbLogToFile;
+extern BOOL gbDelAllTempory;
diff --git a/plugins/StopSpamMod/src/utilities.cpp b/plugins/StopSpamMod/src/utilities.cpp
new file mode 100755
index 0000000000..3685091b25
--- /dev/null
+++ b/plugins/StopSpamMod/src/utilities.cpp
@@ -0,0 +1,551 @@
+/* Copyright (C) Miklashevsky Roman, sss, elzor
+*
+* 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; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#include "headers.h"
+
+tstring DBGetContactSettingStringPAN(HANDLE hContact, char const * szModule, char const * szSetting, tstring errorValue)
+{
+ DBVARIANT dbv;
+ //if(DBGetContactSetting(hContact, szModule, szSetting, &dbv))
+ if(DBGetContactSettingTString(hContact, szModule, szSetting, &dbv))
+ return errorValue;
+// if(DBVT_TCHAR == dbv.type )
+ errorValue = dbv.ptszVal;
+ DBFreeVariant(&dbv);
+ return errorValue;
+}
+
+std::string DBGetContactSettingStringPAN_A(HANDLE hContact, char const * szModule, char const * szSetting, std::string errorValue)
+{
+ DBVARIANT dbv;
+ //if(DBGetContactSetting(hContact, szModule, szSetting, &dbv))
+ if(DBGetContactSettingString(hContact, szModule, szSetting, &dbv))
+ return errorValue;
+// if(DBVT_ASCIIZ == dbv.type )
+ errorValue = dbv.pszVal;
+ DBFreeVariant(&dbv);
+ return errorValue;
+}
+
+tstring &GetDlgItemString(HWND hwnd, int id)
+{
+ HWND h = GetDlgItem(hwnd, id);
+ int len = GetWindowTextLength(h);
+ TCHAR * buf = new TCHAR[len + 1];
+ GetWindowText(h, buf, len + 1);
+ static tstring s;
+ s = buf;
+ delete []buf;
+ return s;
+}
+
+std::string &GetProtoList()
+{
+ static std::string s;
+ return s = DBGetContactSettingStringPAN_A(NULL, pluginName, "protoList", "ICQ\r\n");
+}
+
+
+bool ProtoInList(std::string proto)
+{
+ return std::string::npos != GetProtoList().find(proto + "\r\n");
+}
+
+int CreateCListGroup(TCHAR* szGroupName)
+{
+ int hGroup;
+ CLIST_INTERFACE *clint = NULL;
+
+ if (ServiceExists(MS_CLIST_RETRIEVE_INTERFACE))
+ clint = (CLIST_INTERFACE*)CallService(MS_CLIST_RETRIEVE_INTERFACE, 0, 0);
+
+ hGroup = CallService(MS_CLIST_GROUPCREATE, 0, 0);
+
+ TCHAR* usTmp = szGroupName;
+
+ clint->pfnRenameGroup(hGroup, usTmp);
+
+ return hGroup;
+}
+
+void DeleteCListGroupsByName(TCHAR* szGroupName)
+{
+ int GroupNumber = 0;
+ TCHAR szValue[96] = {0};
+ char szNumber[32] = {0};
+ strcpy(szNumber, "0");
+ BYTE ConfirmDelete=DBGetContactSettingByte(NULL, "CList", "ConfirmDelete", SETTING_CONFIRMDELETE_DEFAULT);
+ if(ConfirmDelete)
+ DBWriteContactSettingByte(NULL, "CList", "ConfirmDelete",0);
+ while(strcmp(DBGetContactSettingStringPAN_A(NULL, "CListGroups", szNumber, "0").c_str(), "0") != 0)
+ {
+ wcscpy(szValue, DBGetContactSettingStringPAN(NULL, "CListGroups", szNumber, _T("0")).c_str());
+ if(wcscmp(szGroupName, szValue + 1) == 0)
+ CallService(MS_CLIST_GROUPDELETE,(WPARAM)(HANDLE)GroupNumber+1,0); // bug or ??? @_@
+ GroupNumber++;
+#if defined(_MSC_VER) && _MSC_VER >= 1300
+ _itoa_s(GroupNumber, szNumber, sizeof(szNumber), 10);
+#else
+ _itoa(GroupNumber, szNumber, 10);
+#endif
+ };
+ if(ConfirmDelete)
+ DBWriteContactSettingByte(NULL, "CList", "ConfirmDelete",ConfirmDelete);
+}
+
+/*
+void RemoveExcludedUsers()
+{
+ HANDLE hContact;
+ hContact_entry *first, *plist, *tmp;
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ first = new hContact_entry;
+ plist = first;
+ plist->hContact = INVALID_HANDLE_VALUE;
+ if(hContact)
+ {
+ do{
+ if(DBGetContactSettingByte(hContact, "CList", "NotOnList", 0) && DBGetContactSettingByte(hContact, pluginName, "Excluded", 0))
+ {
+ plist->hContact = hContact;
+ plist->next = new hContact_entry;
+ plist = plist->next;
+ plist->hContact = INVALID_HANDLE_VALUE;
+ }
+ }while(hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hContact, 0));
+
+ plist = first;
+ while(plist->hContact != INVALID_HANDLE_VALUE)
+ {
+ std::string proto=DBGetContactSettingStringPAN_A(plist->hContact,"Protocol","p","");
+ UINT status = CallProtoService(proto.c_str(), PS_GETSTATUS, 0, 0);
+
+ if(status>= ID_STATUS_CONNECTING && status <= ID_STATUS_OFFLINE){
+ LogSpamToFile(plist->hContact, _T("Mark for delete"));
+ DBWriteContactSettingByte(plist->hContact,"CList","Delete", 1);
+ }else{
+ LogSpamToFile(plist->hContact, _T("Deleted"));
+ CallService(MS_DB_CONTACT_DELETE, (WPARAM)plist->hContact, 0);
+ };
+ tmp = plist;
+ plist = plist->next;
+ delete tmp;
+ }
+ delete plist;
+ }
+}
+
+void RemoveTemporaryUsers()
+{
+ HANDLE hContact;
+ hContact_entry *first, *plist, *tmp;
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ first = new hContact_entry;
+ plist = first;
+ plist->hContact = INVALID_HANDLE_VALUE;
+ if(hContact)
+ {
+ do{
+ if(DBGetContactSettingByte(hContact, "CList", "NotOnList", 0)||
+ (_T("Not In List")== DBGetContactSettingStringPAN(hContact,"CList","Group",_T("")))
+ )
+ {
+ plist->hContact = hContact;
+ plist->next = new hContact_entry;
+ plist = plist->next;
+ plist->hContact = INVALID_HANDLE_VALUE;
+ }
+ }while(hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hContact, 0));
+
+ plist = first;
+ while(plist->hContact != INVALID_HANDLE_VALUE)
+ {
+ std::string proto=DBGetContactSettingStringPAN_A(plist->hContact,"Protocol","p","");
+ UINT status = CallProtoService(proto.c_str(), PS_GETSTATUS, 0, 0);
+
+ if(status>= ID_STATUS_CONNECTING && status <= ID_STATUS_OFFLINE){
+ LogSpamToFile(plist->hContact, _T("Mark for delete"));
+ DBWriteContactSettingByte(plist->hContact,"CList","Delete", 1);
+ }else{
+ LogSpamToFile(plist->hContact, _T("Deleted"));
+ CallService(MS_DB_CONTACT_DELETE, (WPARAM)plist->hContact, 0);
+ };
+
+ tmp = plist;
+ plist = plist->next;
+ delete tmp;
+ }
+ delete plist;
+ };
+ DeleteCListGroupsByName(_T("Not In List"));
+}*/
+int RemoveTmp(WPARAM,LPARAM)
+{
+ void CleanThread();
+ CleanThread();
+ return 0;
+}
+tstring variables_parse(tstring const &tstrFormat, HANDLE hContact){
+ if (gbVarsServiceExist) {
+ FORMATINFO fi;
+ TCHAR *tszParsed;
+ tstring tstrResult;
+
+ ZeroMemory(&fi, sizeof(fi));
+ fi.cbSize = sizeof(fi);
+ fi.tszFormat = _tcsdup(tstrFormat.c_str());
+ fi.hContact = hContact;
+ fi.flags |= FIF_TCHAR;
+ tszParsed = (TCHAR *)CallService(MS_VARS_FORMATSTRING, (WPARAM)&fi, 0);
+ free(fi.tszFormat);
+ if (tszParsed) {
+ tstrResult = tszParsed;
+ CallService(MS_VARS_FREEMEMORY, (WPARAM)tszParsed, 0);
+ return tstrResult;
+ }
+ }
+ return tstrFormat;
+}
+
+// case-insensitive _tcscmp
+//by nullbie as i remember...
+#define NEWTSTR_MALLOC(A) (A==NULL)?NULL:_tcscpy((TCHAR*)mir_alloc(sizeof(TCHAR)*(_tcslen(A)+1)),A)
+const int Stricmp(const TCHAR *str, const TCHAR *substr)
+{
+ int i = 0;
+
+ TCHAR *str_up = NEWTSTR_MALLOC(str);
+ TCHAR *substr_up = NEWTSTR_MALLOC(substr);
+
+ CharUpperBuff(str_up, lstrlen(str_up));
+ CharUpperBuff(substr_up, lstrlen(substr_up));
+
+ i = _tcscmp(str_up, substr_up);
+
+ mir_free(str_up);
+ mir_free(substr_up);
+
+ return i;
+}
+
+TCHAR* ReqGetText(DBEVENTINFO* dbei)
+{
+ if ( !dbei->pBlob )
+ return 0;
+
+ char * ptr=(char *)&dbei->pBlob[sizeof(DWORD)*2];
+ int len=dbei->cbBlob-sizeof(DWORD)*2;
+ int i=0;
+
+ while(len&&(i<4))
+ {
+ if(!ptr[0]) i++;
+ ptr++;
+ len--;
+ };
+
+ if(len)
+ {
+ char * tstr=(char *)mir_alloc(len+1);
+ memcpy(tstr, ptr, len);
+ tstr[len]=0;
+ WCHAR* msg = NULL;
+ msg=(dbei->flags&DBEF_UTF)?mir_utf8decodeW(tstr):mir_a2u(tstr);
+ mir_free(tstr);
+ return (TCHAR *)msg;
+ };
+ return 0;
+}
+
+
+BOOL IsUrlContains(TCHAR * Str)
+{
+ const int CountUrl=11;
+ const TCHAR URL[CountUrl][5]=
+ {
+ _T("http"),
+ _T("www"),
+ _T(".ru"),
+ _T(".com"),
+ _T(".de"),
+ _T(".cz"),
+ _T(".org"),
+ _T(".net"),
+ _T(".su"),
+ _T(".ua"),
+ _T(".tv")
+ };
+
+ if(Str&&_tcslen(Str)>0) {
+ TCHAR *StrLower = NEWTSTR_MALLOC(Str);
+ CharLowerBuff(StrLower, lstrlen(StrLower));
+ for (int i=0; i<CountUrl; i++)
+ if(_tcsstr (StrLower, URL[i]))
+ {
+ mir_free(StrLower);
+ return 1;
+ }
+ mir_free(StrLower);
+ }
+ return 0;
+}
+
+tstring GetContactUid(HANDLE hContact, tstring Protocol)
+{
+ tstring Uid;
+ TCHAR dUid[32]={0};
+ char aUid[32]={0};
+ char *szProto = mir_utf8encodeW(Protocol.c_str());
+ CONTACTINFO ci;
+ ZeroMemory((void *)&ci, sizeof(ci));
+
+ ci.hContact = hContact;
+ ci.szProto = szProto;
+ ci.cbSize = sizeof(ci);
+
+ ci.dwFlag = CNF_DISPLAYUID | CNF_TCHAR;
+ if (!CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM) & ci)) {
+ switch (ci.type) {
+ case CNFT_ASCIIZ:
+ Uid=ci.pszVal;
+ mir_free((void *)ci.pszVal);
+ break;
+ case CNFT_DWORD:
+#if defined(_MSC_VER) && _MSC_VER >= 1300
+
+ _itoa_s(ci.dVal,aUid,32,10);
+#else
+ _itoa(ci.dVal,aUid,10);
+
+#endif
+ OemToChar(aUid, dUid);
+ Uid=dUid;
+ break;
+ default:
+ Uid=_T("");
+ break;
+ };
+ }
+ mir_free(szProto);
+ return Uid;
+}
+
+
+void LogSpamToFile(HANDLE hContact, tstring message)
+{
+
+ if (!gbLogToFile) return;
+
+ tstring LogStrW, LogTime, LogProtocol, LogContactId, LogContactName;
+ std::string filename;
+ std::fstream file;
+
+ UINT cbName=255;
+ char* pszName = (char *)mir_alloc(cbName);
+ extern HANDLE hStopSpamLogDirH;
+
+ if (FoldersGetCustomPath(hStopSpamLogDirH, pszName, cbName, ""))
+ CallService(MS_DB_GETPROFILEPATH,(WPARAM) cbName, (LPARAM)pszName);
+ filename=pszName;
+ filename=filename+"\\stopspam_mod.log";
+ mir_free(pszName);
+
+ file.open(filename.c_str(),std::ios::out |std::ios::app);
+
+ // Time Log line
+ time_t time_now;
+ tm *TimeNow;
+ time(&time_now);
+ TimeNow = localtime(&time_now);
+ LogTime=_wasctime( TimeNow );
+ // Time Log line
+
+ // Name, UID and Protocol Log line
+ LogProtocol=DBGetContactSettingStringPAN(hContact,"Protocol","p",_T(""));
+ LogContactName=(TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM) hContact, GCDNF_TCHAR);
+ LogContactId=(LogProtocol==_T(""))?_T(""):GetContactUid(hContact,LogProtocol);
+ // Name, UID and Protocol Log line
+
+ LogStrW=_T("[")+LogTime.substr(0,LogTime.length()-1)+_T("] ")+
+ LogContactId+_T(" - ")+
+ LogContactName+_T(" (")+
+ LogProtocol+_T("): ")+
+ message+_T("\n");
+
+ char * buf=mir_u2a(LogStrW.c_str());
+ file.write(buf,LogStrW.length());
+ mir_free(buf);
+
+ file.close();
+
+}
+
+boost::mutex clean_mutex;
+
+void CleanProtocolTmpThread(std::string proto)
+{
+ while(true)
+ {
+ UINT status = CallProtoService(proto.c_str(), PS_GETSTATUS, 0, 0);
+ if(status > ID_STATUS_OFFLINE)
+ break;
+ boost::this_thread::sleep(boost::posix_time::seconds(2));
+ }
+ std::list<HANDLE> contacts;
+ for(HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); hContact; hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0))
+ {
+ char *proto_tmp = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ if(proto_tmp)
+ if(!strcmp(proto.c_str(), proto_tmp))
+ if(DBGetContactSettingByte(hContact, "CList", "NotOnList", 0)|| (_T("Not In List")== DBGetContactSettingStringPAN(hContact,"CList","Group",_T(""))))
+ contacts.push_back(hContact);
+ }
+ boost::this_thread::sleep(boost::posix_time::seconds(5));
+ clean_mutex.lock();
+ std::list<HANDLE>::iterator end = contacts.end();
+ for(std::list<HANDLE>::iterator i = contacts.begin(); i != end; ++i)
+ {
+ LogSpamToFile(*i, _T("Deleted"));
+ HistoryLogFunc(*i, "Deleted");
+ CallService(MS_DB_CONTACT_DELETE, (WPARAM)*i, 0);
+ }
+ clean_mutex.unlock();
+}
+
+void CleanProtocolExclThread(std::string proto)
+{
+ while(true)
+ {
+ UINT status = CallProtoService(proto.c_str(), PS_GETSTATUS, 0, 0);
+ if(status > ID_STATUS_OFFLINE)
+ break;
+ boost::this_thread::sleep(boost::posix_time::seconds(2));
+ }
+ std::list<HANDLE> contacts;
+ for(HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); hContact; hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0))
+ {
+ char *proto_tmp = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ if(proto_tmp)
+ if(!strcmp(proto.c_str(), proto_tmp))
+ if(DBGetContactSettingByte(hContact, "CList", "NotOnList", 0) && DBGetContactSettingByte(hContact, pluginName, "Excluded", 0))
+ contacts.push_back(hContact);
+ }
+ boost::this_thread::sleep(boost::posix_time::seconds(5));
+ clean_mutex.lock();
+ std::list<HANDLE>::iterator end = contacts.end();
+ for(std::list<HANDLE>::iterator i = contacts.begin(); i != end; ++i)
+ {
+ LogSpamToFile(*i, _T("Deleted"));
+ HistoryLogFunc(*i, "Deleted");
+ CallService(MS_DB_CONTACT_DELETE, (WPARAM)*i, 0);
+ }
+ clean_mutex.unlock();
+}
+
+
+void CleanThread()
+{
+ std::list<std::string> protocols;
+ int count = 0;
+ PROTOACCOUNT **accounts;
+ ProtoEnumAccounts(&count, &accounts);
+ for(int i = 0; i < count; i++)
+ {
+ if(!strstr(accounts[i]->szModuleName, "MetaContacts") && !strstr(accounts[i]->szModuleName, "Weather")) //not real protocols
+ protocols.push_back(accounts[i]->szModuleName);
+ }
+ std::list<std::string>::iterator end = protocols.end();
+ for(std::list<std::string>::iterator i = protocols.begin(); i != end; ++i)
+ {
+ if(gbDelAllTempory)
+ boost::thread *thr = new boost::thread(boost::bind(&CleanProtocolTmpThread, *i));
+ if(gbDelExcluded)
+ boost::thread *thr = new boost::thread(boost::bind(&CleanProtocolExclThread, *i));
+ }
+}
+void HistoryLog(HANDLE hContact, char *data, int event_type, int flags)
+{
+ DBEVENTINFO Event = {0};
+ Event.cbSize = sizeof(Event);
+ Event.szModule = pluginName;
+ Event.eventType = event_type;
+ Event.flags = flags | DBEF_UTF;
+ Event.timestamp = (DWORD)time(NULL);
+ Event.cbBlob = strlen(data)+1;
+ Event.pBlob = (PBYTE)_strdup(data);
+ CallService(MS_DB_EVENT_ADD, (WPARAM)(HANDLE)hContact,(LPARAM)&Event);
+}
+void HistoryLogFunc(HANDLE hContact, std::string message)
+{
+ if(gbHistoryLog)
+ {
+ if(hContact == INVALID_HANDLE_VALUE)
+ return;
+ std::string msg = message;
+ msg.append("\n");
+ msg.append("Protocol: ").append((char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0)).append(" Contact: ");
+ msg.append(toUTF8((TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM) hContact, GCDNF_TCHAR))).append(" ID: ");
+ msg.append(toUTF8(GetContactUid(hContact,toUTF16((char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0)))));
+ HistoryLog(NULL, (char*)msg.c_str(), EVENTTYPE_MESSAGE, DBEF_READ);
+ }
+}
+
+std::string toUTF8(std::wstring str)
+{
+ std::string ustr;
+ try{
+ utf8::utf16to8(str.begin(), str.end(), back_inserter(ustr));
+ }
+ catch(const std::exception &e)
+ {
+ //TODO: handle utf8cpp exceptions
+ }
+ return ustr;
+}
+
+std::string toUTF8(std::string str)
+{
+ return toUTF8(toUTF16(str));
+}
+
+
+std::wstring toUTF16(std::string str) //convert as much as possible
+{
+ std::wstring ustr;
+ std::string tmpstr;
+ try{
+ utf8::replace_invalid(str.begin(), str.end(), back_inserter(tmpstr));
+ utf8::utf8to16(tmpstr.begin(), tmpstr.end(), back_inserter(ustr));
+ }
+ catch(const std::exception &e)
+ {
+ //TODO: handle utf8cpp exceptions
+ }
+ return ustr;
+}
+
+std::string get_random_num(int length)
+{
+ std::string chars("123456789");
+ std::string data;
+ boost::random_device rng;
+ boost::variate_generator<boost::random_device&, boost::uniform_int<>> gen(rng, boost::uniform_int<>(0, chars.length()-1));
+ for(int i = 0; i < length; ++i)
+ data += chars[gen()];
+ return data;
+}
diff --git a/plugins/StopSpamMod/src/utilities.h b/plugins/StopSpamMod/src/utilities.h
new file mode 100755
index 0000000000..62a3ef5750
--- /dev/null
+++ b/plugins/StopSpamMod/src/utilities.h
@@ -0,0 +1,19 @@
+tstring DBGetContactSettingStringPAN(HANDLE hContact, char const * szModule, char const * szSetting, tstring errorValue);
+std::string DBGetContactSettingStringPAN_A(HANDLE hContact, char const * szModule, char const * szSetting, std::string errorValue);
+tstring &GetDlgItemString(HWND hwnd, int id);
+std::string &GetProtoList();
+bool ProtoInList(std::string proto);
+void RemoveExcludedUsers();
+tstring variables_parse(tstring const &tstrFormat, HANDLE hContact);
+const int Stricmp(const TCHAR *str, const TCHAR *substr);
+//const int Stristr(const TCHAR *str, const TCHAR *substr);
+TCHAR* ReqGetText(DBEVENTINFO* dbei);
+BOOL IsUrlContains(TCHAR * Str);
+void DeleteCListGroupsByName(TCHAR* szGroupName);
+tstring GetContactUid(HANDLE hContact, std::string Protocol);
+void LogSpamToFile(HANDLE hContact, tstring message);
+std::string toUTF8(std::wstring str);
+std::string toUTF8(std::string str);
+std::wstring toUTF16(std::string str);
+void HistoryLogFunc(HANDLE hContact, std::string message);
+std::string get_random_num(int length); \ No newline at end of file
diff --git a/plugins/StopSpamMod/src/version.h b/plugins/StopSpamMod/src/version.h
new file mode 100755
index 0000000000..1641ff5c9c
--- /dev/null
+++ b/plugins/StopSpamMod/src/version.h
@@ -0,0 +1,6 @@
+#ifndef VERSION_H_CAA3B062_9BEE_40e6_A9F9_20BBF467731B
+#define VERSION_H_CAA3B062_9BEE_40e6_A9F9_20BBF467731B
+
+#define SUBWCREV (0)
+
+#endif
diff --git a/plugins/StopSpamMod/stopspam_10.vcxproj b/plugins/StopSpamMod/stopspam_10.vcxproj
new file mode 100755
index 0000000000..a412f624a1
--- /dev/null
+++ b/plugins/StopSpamMod/stopspam_10.vcxproj
@@ -0,0 +1,244 @@
+п»ї<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectName>stopspam</ProjectName>
+ <ProjectGuid>{3E6CEC79-5E93-4607-B10E-498586ECF6A6}</ProjectGuid>
+ <RootNamespace>stopspam</RootNamespace>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\Plugins\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Configuration)/Plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\Obj\$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)/Plugins\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Configuration)/Plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)/Obj/$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Configuration)/Obj/$(ProjectName)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <PreBuildEvent>
+ <Command>
+ </Command>
+ </PreBuildEvent>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;STOPSPAM_EXPORTS;%(PreprocessorDefinitions);_UNICODE;UNICODE;_CRT_SECURE_NO_DEPRECATE</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)$(ProjectName).dll</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>c:\debug\stopspam.pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>$(OutDir)stopspam.lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <AdditionalLibraryDirectories>X:\temp\windows\libs\Boost\lib;$(SolutionDir)\lib</AdditionalLibraryDirectories>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <PreBuildEvent>
+ <Command>
+ </Command>
+ </PreBuildEvent>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>X:\temp\windows\libs\boost;X:\temp\windows\libs\utf8cpp\include;X:\install\git\miranda\miranda-im\miranda\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;STOPSPAM_EXPORTS;%(PreprocessorDefinitions);_UNICODE;UNICODE;_CRT_SECURE_NO_DEPRECATE</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)$(ProjectName).dll</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)stopspam.pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>$(OutDir)stopspam.lib</ImportLibrary>
+ <AdditionalLibraryDirectories>X:\temp\windows\libs\boost\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <PreBuildEvent>
+ <Command>
+ </Command>
+ </PreBuildEvent>
+ <ClCompile>
+ <Optimization>MinSpace</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>X:\install\git\miranda\miranda_ng_svn\plugins\stopspam_mod\src\include;X:\temp\windows\libs\Boost\include;..\..\include;..\..\plugins\ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;STOPSPAM_EXPORTS;%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>
+ </DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AssemblyDebug>true</AssemblyDebug>
+ <SubSystem>NotSet</SubSystem>
+ <OptimizeReferences>
+ </OptimizeReferences>
+ <EnableCOMDATFolding>
+ </EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>
+ </ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <AdditionalLibraryDirectories>X:\temp\windows\libs\Boost\lib32;%(AdditionalLibraryDirectories);$(SolutionDir)\lib</AdditionalLibraryDirectories>
+ </Link>
+ <PostBuildEvent>
+ <Command>
+ </Command>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <PreBuildEvent>
+ <Command>
+ </Command>
+ </PreBuildEvent>
+ <ClCompile>
+ <Optimization>MinSpace</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>C:\Program Files\boost\boost_1_34_1\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;STOPSPAM_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>
+ </DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)$(ProjectName).dll</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AssemblyDebug>true</AssemblyDebug>
+ <SubSystem>NotSet</SubSystem>
+ <OptimizeReferences>
+ </OptimizeReferences>
+ <EnableCOMDATFolding>
+ </EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>
+ </ImportLibrary>
+ </Link>
+ <PostBuildEvent>
+ <Command>
+ </Command>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClInclude Include="src\eventhooker.h" />
+ <ClInclude Include="src\globals.h" />
+ <ClInclude Include="src\headers.h" />
+ <ClInclude Include="src\options.h" />
+ <ClInclude Include="src\resource.h" />
+ <ClInclude Include="src\stopspam.h" />
+ <ClInclude Include="src\utilities.h" />
+ <ClInclude Include="src\version.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="src\eventhooker.cpp" />
+ <ClCompile Include="src\init.cpp" />
+ <ClCompile Include="src\options.cpp" />
+ <ClCompile Include="src\stopspam.cpp" />
+ <ClCompile Include="src\utilities.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="res\stopspam.rc" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/plugins/StopSpamMod/stopspam_10.vcxproj.filters b/plugins/StopSpamMod/stopspam_10.vcxproj.filters
new file mode 100755
index 0000000000..ae17f570aa
--- /dev/null
+++ b/plugins/StopSpamMod/stopspam_10.vcxproj.filters
@@ -0,0 +1,65 @@
+п»ї<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="src\eventhooker.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\globals.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\headers.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\options.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\resource.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\stopspam.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\utilities.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\version.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="src\eventhooker.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\init.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\options.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\stopspam.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\utilities.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="res\stopspam.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file