From 7ad4550af9bf16f3a6212edfc1f425082065b095 Mon Sep 17 00:00:00 2001 From: watcherhd Date: Mon, 13 Jun 2011 08:59:23 +0000 Subject: added NewAwaySysMod git-svn-id: http://miranda-plugins.googlecode.com/svn/trunk@137 e753b5eb-9565-29b2-b5c5-2cc6f99dfbcb --- NewAwaySysMod/Client.cpp | 232 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 232 insertions(+) create mode 100644 NewAwaySysMod/Client.cpp (limited to 'NewAwaySysMod/Client.cpp') diff --git a/NewAwaySysMod/Client.cpp b/NewAwaySysMod/Client.cpp new file mode 100644 index 0000000..e37d3ee --- /dev/null +++ b/NewAwaySysMod/Client.cpp @@ -0,0 +1,232 @@ +/* + New Away System - plugin for Miranda IM + Copyright (c) 2005-2007 Chervov Dmitry + Copyright (c) 2004-2005 Iksaif Entertainment + Copyright (c) 2002-2003 Goblineye Entertainment + + 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 "Common.h" +#include "MsgTree.h" +#include "Properties.h" + +#define PARSE_INTERVAL 10000 + +HANDLE g_hTerminateUpdateMsgsThread = NULL; +HANDLE g_hUpdateMsgsThread = NULL; + +void __cdecl UpdateMsgsThreadProc(void *) +{ + int ProtoCount; + PROTOCOLDESCRIPTOR **proto; + CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM)&ProtoCount, (LPARAM)&proto); + int I; + while (WaitForSingleObject(g_hTerminateUpdateMsgsThread, 0) == WAIT_TIMEOUT && !Miranda_Terminated()) + { + DWORD MinUpdateTimeDifference = g_MoreOptPage.GetDBValueCopy(IDC_MOREOPTDLG_UPDATEMSGSPERIOD) * 1000; // in milliseconds + for (I = 0; I < ProtoCount; I++) + { + if (proto[I]->type == PROTOTYPE_PROTOCOL && CallProtoService(proto[I]->szName, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_MODEMSGSEND && !IsAnICQProto(proto[I]->szName)) + { + int Status = CallProtoService(proto[I]->szName, PS_GETSTATUS, 0, 0); + if (Status < ID_STATUS_OFFLINE || Status > ID_STATUS_OUTTOLUNCH) + { + Status = g_ProtoStates[proto[I]->szName].Status; + } + if (CallProtoService(proto[I]->szName, PS_GETCAPS, PFLAGNUM_3, 0) & Proto_Status2Flag(Status) && g_ProtoStates[proto[I]->szName].CurStatusMsg.GetUpdateTimeDifference() >= MinUpdateTimeDifference) + { + TCString CurMsg(GetDynamicStatMsg(INVALID_HANDLE_VALUE, proto[I]->szName)); + if ((TCString)g_ProtoStates[proto[I]->szName].CurStatusMsg != (const TCHAR*)CurMsg) // if the message has changed + { + g_ProtoStates[proto[I]->szName].CurStatusMsg = CurMsg; + CallAllowedPS_SETAWAYMSG(proto[I]->szName, Status, (char*)TCHAR2ANSI(CurMsg)); + } + } + } + } + SleepEx(PARSE_INTERVAL, true); + } +} + + +static void __stdcall DummyAPCFunc(DWORD) +{ + return; +} + + +void InitUpdateMsgs() +{ + int UpdateMsgs = g_MoreOptPage.GetDBValueCopy(IDC_MOREOPTDLG_UPDATEMSGS); + if (g_hUpdateMsgsThread && !UpdateMsgs) + { + _ASSERT(WaitForSingleObject(g_hUpdateMsgsThread, 0) == WAIT_TIMEOUT); + SetEvent(g_hTerminateUpdateMsgsThread); + QueueUserAPC(DummyAPCFunc, g_hUpdateMsgsThread, 0); // wake up the thread, as it's most probably in SleepEx() now + WaitForSingleObject(g_hUpdateMsgsThread, INFINITE); + g_hUpdateMsgsThread = NULL; + CloseHandle(g_hTerminateUpdateMsgsThread); + } else if (!g_hUpdateMsgsThread && UpdateMsgs) + { + g_hTerminateUpdateMsgsThread = CreateEvent(NULL, TRUE, FALSE, NULL); + g_hUpdateMsgsThread = (HANDLE)mir_forkthread(UpdateMsgsThreadProc, NULL); + } +} + + +void ChangeProtoMessages(char* szProto, int iMode, TCString &Msg) +{ + TCString CurMsg(Msg); + if (szProto) + { + if (Msg == NULL) + { + CurMsg = GetDynamicStatMsg(INVALID_HANDLE_VALUE, szProto); + } + CallAllowedPS_SETAWAYMSG(szProto, iMode, (char*)TCHAR2ANSI(CurMsg)); + g_ProtoStates[szProto].CurStatusMsg = CurMsg; + } else // change message of all protocols + { + int ProtoCount; + PROTOCOLDESCRIPTOR **proto; + CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM)&ProtoCount, (LPARAM)&proto); + int I; + for (I = 0; I < ProtoCount; I++) + { + if (proto[I]->type == PROTOTYPE_PROTOCOL && !DBGetContactSettingByte(NULL, proto[I]->szName, "LockMainStatus", 0)) + { + if (Msg == NULL) + { + CurMsg = GetDynamicStatMsg(INVALID_HANDLE_VALUE, proto[I]->szName); + } + CallAllowedPS_SETAWAYMSG(proto[I]->szName, iMode, (char*)TCHAR2ANSI(CurMsg)); + g_ProtoStates[proto[I]->szName].CurStatusMsg = CurMsg; + } + } + } + static struct + { + int Status; + char *Setting; + } StatusSettings[] = { + ID_STATUS_OFFLINE, "Off", + ID_STATUS_ONLINE, "On", + ID_STATUS_AWAY, "Away", + ID_STATUS_NA, "Na", + ID_STATUS_DND, "Dnd", + ID_STATUS_OCCUPIED, "Occupied", + ID_STATUS_FREECHAT, "FreeChat", + ID_STATUS_INVISIBLE, "Inv", + ID_STATUS_ONTHEPHONE, "Otp", + ID_STATUS_OUTTOLUNCH, "Otl", + ID_STATUS_IDLE, "Idl" + }; + int I; + for (I = 0; I < lengthof(StatusSettings); I++) + { + if (iMode == StatusSettings[I].Status) + { + DBWriteContactSettingTString(NULL, "SRAway", CString(StatusSettings[I].Setting) + "Msg", CurMsg); + DBWriteContactSettingTString(NULL, "SRAway", CString(StatusSettings[I].Setting) + "Default", CurMsg); // TODO: make it more accurate, and change not only here, but when changing status messages through UpdateMsgsTimerFunc too; and when changing messages through AutoAway() ? + break; + } + } +// InitUpdateMsgs(); +} + + +int GetRecentGroupID(int iMode) +{ // returns an ID of a group where recent messages are stored, accordingly to current settings and status mode. + // -1 if the group is not found +// COptPage MoreOptData(g_MoreOptPage); + COptPage MsgTreeData(g_MsgTreePage); + COptItem_TreeCtrl *TreeCtrl = (COptItem_TreeCtrl*)MsgTreeData.Find(IDV_MSGTREE); + TreeCtrl->DBToMem(CString(MOD_NAME)); + int Order; + if (g_MoreOptPage.GetDBValueCopy(IDC_MOREOPTDLG_PERSTATUSMRM)) + { + for (Order = 0; Order < TreeCtrl->Value.GetSize(); Order++) // find a group named accordingly to the current status + { + if (TreeCtrl->Value[Order].ParentID == g_Messages_RecentRootID && TreeCtrl->Value[Order].Flags & TIF_GROUP && !_tcsicmp(TreeCtrl->Value[Order].Title, iMode ? (TCHAR*)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, iMode, GCMDF_TCHAR) : MSGTREE_RECENT_OTHERGROUP)) + { + return TreeCtrl->Value[Order].ID; + } + } + } else // simply use Recent Messages category + { + return g_Messages_RecentRootID; + } + return -1; +} + + +int ICQStatusToGeneralStatus(int bICQStat) +{ + switch (bICQStat) + { + case MTYPE_AUTOONLINE: return ID_STATUS_ONLINE; + case MTYPE_AUTOAWAY: return ID_STATUS_AWAY; + case MTYPE_AUTONA: return ID_STATUS_NA; + case MTYPE_AUTODND: return ID_STATUS_DND; + case MTYPE_AUTOBUSY: return ID_STATUS_OCCUPIED; + case MTYPE_AUTOFFC: return ID_STATUS_FREECHAT; + default: 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; +} -- cgit v1.2.3