extern "C" int __declspec(dllexport) Load(void) { mir_getLP(&pluginInfo); mir_getCLI(); HookEvent(ME_SYSTEM_MODULESLOADED, MirandaLoaded); Icon_Register(g_hInstance, MOD_NAME, iconList, _countof(iconList), "nas"); InitCommonControls(); InitOptions(); // must be called before we hook CallService if (db_get_b(NULL, MOD_NAME, DB_SETTINGSVER, 0) < 1) { // change all %nas_message% variables to %extratext% if it wasn't done before TCString Str = db_get_s(NULL, MOD_NAME, "PopupsFormat", _T("")); if (Str.GetLen()) db_set_ts(NULL, MOD_NAME, "PopupsFormat", Str.Replace(_T("nas_message"), _T("extratext"))); Str = db_get_s(NULL, MOD_NAME, "ReplyPrefix", _T("")); if (Str.GetLen()) db_set_ts(NULL, MOD_NAME, "ReplyPrefix", Str.Replace(_T("nas_message"), _T("extratext"))); } if (db_get_b(NULL, MOD_NAME, DB_SETTINGSVER, 0) < 2) { // disable autoreply for not-on-list contacts, as such contact may be a spam bot db_set_b(NULL, MOD_NAME, ContactStatusToDBSetting(0, DB_ENABLEREPLY, 0, INVALID_CONTACT_ID), 0); db_set_b(NULL, MOD_NAME, DB_SETTINGSVER, 2); } return 0; }
int CMPlugin::Load() { HookEvent(ME_SYSTEM_MODULESLOADED, MirandaLoaded); DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &g_hMainThread, THREAD_SET_CONTEXT, false, 0); InitOptions(); if (db_get_b(NULL, MODULENAME, DB_SETTINGSVER, 0) < 1) { TCString Str; Str = db_get_s(NULL, MODULENAME, DB_IGNORESUBSTRINGS, L""); if (Str.GetLen()) // fix incorrect regexp from v0.1.1.0 db_set_ws(NULL, MODULENAME, DB_IGNORESUBSTRINGS, Str.Replace(L"/Miranda[0-9A-F]{8}/", L"/[0-9A-F]{8}(\\W|$)/")); db_set_b(NULL, MODULENAME, DB_SETTINGSVER, 1); } return 0; }
extern "C" int __declspec(dllexport) Load(void) { mir_getLP( &pluginInfo ); HookEvent(ME_SYSTEM_MODULESLOADED, MirandaLoaded); DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &g_hMainThread, THREAD_SET_CONTEXT, false, 0); InitOptions(); if (db_get_b(NULL, MOD_NAME, DB_SETTINGSVER, 0) < 1) { TCString Str; Str = db_get_s(NULL, MOD_NAME, DB_IGNORESUBSTRINGS, _T("")); if (Str.GetLen()) // fix incorrect regexp from v0.1.1.0 db_set_ts(NULL, MOD_NAME, DB_IGNORESUBSTRINGS, Str.Replace(_T("/Miranda[0-9A-F]{8}/"), _T("/[0-9A-F]{8}(\\W|$)/"))); db_set_b(NULL, MOD_NAME, DB_SETTINGSVER, 1); } return 0; }
TCString VariablesEscape(TCString Str) { if (!Str.GetLen()) { return _T(""); } enum eState { ST_TEXT, ST_QUOTE }; eState State = ST_QUOTE; TCString Result(_T("`")); const TCHAR *p = Str; while (*p) { if (*p == '`') { if (State == ST_TEXT) { Result += _T("````"); State = ST_QUOTE; } else { Result += _T("``"); } } else { Result += *p; State = ST_TEXT; } p++; } if (State == ST_QUOTE) { Result.GetBuffer()[Result.GetLen() - 1] = '\0'; Result.ReleaseBuffer(); } else { Result += '`'; } return Result; }
int PcreCheck(TCString Str, int StartingID) { // StartingID specifies the pattern from which to start checking, i.e. the check starts from the next pattern after the one that has ID == StartingID int I; if (StartingID == -1) { I = 0; } else { for (I = 0; I < PcreCompileData.GetSize(); I++) { if (PcreCompileData[I].ID == StartingID) { I++; break; } } } for (; I < PcreCompileData.GetSize(); I++) { if (PcreCompileData[I].pPcre) { int Res = pcre16_exec(PcreCompileData[I].pPcre, PcreCompileData[I].pExtra, Str, Str.GetLen() - 1, 0, PCRE_NOTEMPTY | PCRE_NO_UTF8_CHECK, NULL, 0); if (Res >= 0) { return PcreCompileData[I].ID; } } else { if (_tcsstr(Str.ToLower(), PcreCompileData[I].Pattern.ToLower())) { return PcreCompileData[I].ID; } } } return -1; }
void CProtoSettings::SetMsgFormat(int Flags, TCString Message) { if (Flags & (SMF_TEMPORARY | SMF_PERSONAL) && g_AutoreplyOptPage.GetDBValueCopy(IDC_REPLYDLG_RESETCOUNTERWHENSAMEICON) && GetMsgFormat(Flags & (SMF_TEMPORARY | SMF_PERSONAL)) != (const TCHAR*)Message) ResetSettingsOnStatusChange(szProto); if (Flags & SMF_TEMPORARY) { _ASSERT(!Status || Status == g_ProtoStates[szProto].Status); g_ProtoStates[szProto].TempMsg = (szProto || Message != NULL) ? Message : CProtoSettings(NULL, Status).GetMsgFormat(GMF_LASTORDEFAULT); } if (Flags & SMF_PERSONAL) { // set a "personal" message for a protocol. also it's used to set global status message (hContact = NULL). // if Message == NULL, then we'll use the "default" message - i.e. it's either the global message for szProto != NULL (we delete the per-proto DB setting), or it's just a default message for a given status for szProto == NULL. g_ProtoStates[szProto].TempMsg.Unset(); CString DBSetting(ProtoStatusToDBSetting(DB_STATUSMSG, IDC_MOREOPTDLG_PERSTATUSPROTOMSGS)); if (Message != NULL) db_set_ts(NULL, MOD_NAME, DBSetting, Message); else { if (!szProto) db_set_ts(NULL, MOD_NAME, DBSetting, CProtoSettings(NULL, Status).GetMsgFormat(GMF_LASTORDEFAULT)); // global message can't be NULL; we can use an empty string instead if it's really necessary else db_unset(NULL, MOD_NAME, DBSetting); } } if (Flags & SMF_LAST) { COptPage MsgTreeData(g_MsgTreePage); COptItem_TreeCtrl *TreeCtrl = (COptItem_TreeCtrl*)MsgTreeData.Find(IDV_MSGTREE); TreeCtrl->DBToMem(CString(MOD_NAME)); int RecentGroupID = GetRecentGroupID(Status); if (RecentGroupID == -1) { // we didn't find the group, it also means that we're using per status messages; so we need to create it TreeCtrl->Value.AddElem(CTreeItem(Status ? pcli->pfnGetStatusModeDescription(Status, 0) : MSGTREE_RECENT_OTHERGROUP, g_Messages_RecentRootID, RecentGroupID = TreeCtrl->GenerateID(), TIF_GROUP)); TreeCtrl->SetModified(true); } int i; // try to find an identical message in the same group (to prevent saving multiple identical messages), // or at least if we'll find an identical message somewhere else, then we'll use its title for our new message TCString Title(_T("")); for (i = 0; i < TreeCtrl->Value.GetSize(); i++) { if (!(TreeCtrl->Value[i].Flags & TIF_GROUP) && TreeCtrl->Value[i].User_Str1 == (const TCHAR*)Message) { if (TreeCtrl->Value[i].ParentID == RecentGroupID) { // found it in the same group int GroupOrder = TreeCtrl->IDToOrder(RecentGroupID); TreeCtrl->Value.MoveElem(i, (GroupOrder >= 0) ? (GroupOrder + 1) : 0); // now move it to the top of recent messages list TreeCtrl->SetModified(true); break; // no reason to search for anything else } if (Title.IsEmpty()) // it's not in the same group, but at least we'll use its title Title = TreeCtrl->Value[i].Title; } } if (i == TreeCtrl->Value.GetSize()) { // we didn't find an identical message in the same group, so we'll add our new message here if (Title.IsEmpty()) { // didn't find a title for our message either if (Message.GetLen() > MRM_MAX_GENERATED_TITLE_LEN) Title = Message.Left(MRM_MAX_GENERATED_TITLE_LEN - 3) + _T("..."); else Title = Message; TCHAR *p = Title.GetBuffer(); while (*p) { // remove "garbage" if (!(p = _tcspbrk(p, _T("\r\n\t")))) break; *p++ = ' '; } Title.ReleaseBuffer(); } int GroupOrder = TreeCtrl->IDToOrder(RecentGroupID); TreeCtrl->Value.InsertElem(CTreeItem(Title, RecentGroupID, TreeCtrl->GenerateID(), 0, Message), (GroupOrder >= 0) ? (GroupOrder + 1) : 0); TreeCtrl->SetModified(true); } // now clean up here int MRMNum = 0; int MaxMRMNum = g_MoreOptPage.GetDBValueCopy(IDC_MOREOPTDLG_RECENTMSGSCOUNT); for (i = 0; i < TreeCtrl->Value.GetSize(); i++) { if (TreeCtrl->Value[i].ParentID == RecentGroupID) { // found a child of our group if (TreeCtrl->Value[i].Flags & TIF_GROUP || ++MRMNum > MaxMRMNum) { // what groups are doing here?! :)) TreeCtrl->Value.RemoveElem(i); TreeCtrl->SetModified(true); i--; } } } // if we're saving recent messages per status, then remove any messages that were left at the recent messages' root if (g_MoreOptPage.GetDBValueCopy(IDC_MOREOPTDLG_PERSTATUSMRM)) { for (i = 0; i < TreeCtrl->Value.GetSize(); i++) { if (TreeCtrl->Value[i].ParentID == g_Messages_RecentRootID) { if (!(TreeCtrl->Value[i].Flags & TIF_GROUP)) { TreeCtrl->Value.RemoveElem(i); TreeCtrl->SetModified(true); i--; } } } } TreeCtrl->MemToDB(CString(MOD_NAME)); } }
TCString CompileRegexp(TCString Regexp, int bAddAsUsualSubstring, int ID) { TCString Result(_T("")); sPcreCompileData s = {0}; int NewID = PcreCompileData.AddElem(s); PcreCompileData[NewID].ID = ID; if (hPcreDLL && !bAddAsUsualSubstring) { const char *Err; int ErrOffs; int Flags = PCRE_CASELESS; if (Regexp[0] == '/') { TCString OrigRegexp = Regexp; Regexp = Regexp.Right(Regexp.GetLen() - 1); TCHAR *pRegexpEnd = (TCHAR*)Regexp + Regexp.GetLen(); TCHAR *p = _tcsrchr(Regexp.GetBuffer(), '/'); if (!p) { Regexp = OrigRegexp; } else { *p = 0; Flags = 0; while (++p < pRegexpEnd) { switch (*p) { case 'i': Flags |= PCRE_CASELESS; break; case 'm': Flags |= PCRE_MULTILINE; break; case 's': Flags |= PCRE_DOTALL; break; case 'x': Flags |= PCRE_EXTENDED; break; case 'A': Flags |= PCRE_ANCHORED; break; case 'f': Flags |= PCRE_FIRSTLINE; break; case 'D': Flags |= PCRE_DOLLAR_ENDONLY; break; case 'U': Flags |= PCRE_UNGREEDY; break; case 'X': Flags |= PCRE_EXTRA; break; default: // Result += LogMessage(Translate("Warning, unknown pattern modifier '%c':\n"), *p ); break; } } } Regexp.ReleaseBuffer(); } PcreCompileData[NewID].pPcre = pcre_compile(WCHAR2UTF8(Regexp).GetData(), PCRE_UTF8 | PCRE_NO_UTF8_CHECK | Flags, &Err, &ErrOffs, NULL); if (PcreCompileData[NewID].pPcre) { PcreCompileData[NewID].pExtra = NULL; if (pcre_study) PcreCompileData[NewID].pExtra = pcre_study(PcreCompileData[NewID].pPcre, 0, &Err); } else { // Result += LogMessage(TranslateT("Syntax error in regexp\n%s\nat offset %d: %s."), (TCHAR*)Regexp, ErrOffs, (TCHAR*)ANSI2TCHAR(Err)) + _T("\n\n"); PcreCompileData[NewID].Pattern = Regexp; } } else PcreCompileData[NewID].Pattern = Regexp; return Result; }
INT_PTR srvVariablesHandler(WPARAM, LPARAM lParam) { ARGUMENTSINFO *ai = (ARGUMENTSINFO*)lParam; ai->flags = AIF_DONTPARSE; TCString Result; if (!mir_tstrcmp(ai->targv[0], VAR_AWAYSINCE_TIME)) { GetTimeFormat(LOCALE_USER_DEFAULT, 0, g_ProtoStates[VarParseData.szProto].AwaySince, (ai->argc > 1 && *ai->targv[1]) ? ai->targv[1] : _T("H:mm"), Result.GetBuffer(256), 256); Result.ReleaseBuffer(); } else if (!mir_tstrcmp(ai->targv[0], VAR_AWAYSINCE_DATE)) { GetDateFormat(LOCALE_USER_DEFAULT, 0, g_ProtoStates[VarParseData.szProto].AwaySince, (ai->argc > 1 && *ai->targv[1]) ? ai->targv[1] : NULL, Result.GetBuffer(256), 256); Result.ReleaseBuffer(); } else if (!mir_tstrcmp(ai->targv[0], VAR_STATDESC)) { Result = (VarParseData.Flags & VPF_XSTATUS) ? STR_XSTATUSDESC : pcli->pfnGetStatusModeDescription(g_ProtoStates[VarParseData.szProto].Status, 0); } else if (!mir_tstrcmp(ai->targv[0], VAR_MYNICK)) { if (g_MoreOptPage.GetDBValueCopy(IDC_MOREOPTDLG_MYNICKPERPROTO) && VarParseData.szProto) Result = db_get_s(NULL, VarParseData.szProto, "Nick", (TCHAR*)NULL); if (Result == NULL) Result = pcli->pfnGetContactDisplayName(NULL, 0); if (Result == NULL) Result = TranslateT("Stranger"); } else if (!mir_tstrcmp(ai->targv[0], VAR_REQUESTCOUNT)) { mir_sntprintf(Result.GetBuffer(16), 16, _T("%d"), db_get_w(ai->fi->hContact, MOD_NAME, DB_REQUESTCOUNT, 0)); Result.ReleaseBuffer(); } else if (!mir_tstrcmp(ai->targv[0], VAR_MESSAGENUM)) { mir_sntprintf(Result.GetBuffer(16), 16, _T("%d"), db_get_w(ai->fi->hContact, MOD_NAME, DB_MESSAGECOUNT, 0)); Result.ReleaseBuffer(); } else if (!mir_tstrcmp(ai->targv[0], VAR_TIMEPASSED)) { ULARGE_INTEGER ul_AwaySince, ul_Now; SYSTEMTIME st; GetLocalTime(&st); SystemTimeToFileTime(&st, (LPFILETIME)&ul_Now); SystemTimeToFileTime(g_ProtoStates[VarParseData.szProto].AwaySince, (LPFILETIME)&ul_AwaySince); ul_Now.QuadPart -= ul_AwaySince.QuadPart; ul_Now.QuadPart /= 10000000; // now it's in seconds Result.GetBuffer(256); if (ul_Now.LowPart >= 7200) // more than 2 hours mir_sntprintf(Result, 256, TranslateT("%d hours"), ul_Now.LowPart / 3600); else if (ul_Now.LowPart >= 120) // more than 2 minutes mir_sntprintf(Result, 256, TranslateT("%d minutes"), ul_Now.LowPart / 60); else mir_sntprintf(Result, 256, TranslateT("%d seconds"), ul_Now.LowPart); Result.ReleaseBuffer(); } else if (!mir_tstrcmp(ai->targv[0], VAR_PREDEFINEDMESSAGE)) { ai->flags = 0; // reset AIF_DONTPARSE flag if (ai->argc != 2) return NULL; COptPage MsgTreeData(g_MsgTreePage); COptItem_TreeCtrl *TreeCtrl = (COptItem_TreeCtrl*)MsgTreeData.Find(IDV_MSGTREE); TreeCtrl->DBToMem(CString(MOD_NAME)); for (int i = 0; i < TreeCtrl->Value.GetSize(); i++) { if (!(TreeCtrl->Value[i].Flags & TIF_GROUP) && !mir_tstrcmpi(TreeCtrl->Value[i].Title, ai->targv[1])) { Result = TreeCtrl->Value[i].User_Str1; break; } } if (Result == NULL) // if we didn't find a message with specified title return NULL; // return it now, as later we change NULL to "" } else if (!mir_tstrcmp(ai->targv[0], VAR_PROTOCOL)) { if (VarParseData.szProto) { CString AnsiResult; CallProtoService(VarParseData.szProto, PS_GETNAME, 256, (LPARAM)AnsiResult.GetBuffer(256)); AnsiResult.ReleaseBuffer(); Result = _A2T(AnsiResult); } if (Result == NULL) // if we didn't find a message with specified title return NULL; // return it now, as later we change NULL to "" } TCHAR *szResult = (TCHAR*)malloc((Result.GetLen() + 1) * sizeof(TCHAR)); if (!szResult) return NULL; mir_tstrcpy(szResult, (Result != NULL) ? Result : _T("")); return (INT_PTR)szResult; }