From 48540940b6c28bb4378abfeb500ec45a625b37b6 Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Tue, 15 May 2012 10:38:20 +0000 Subject: initial commit git-svn-id: http://svn.miranda-ng.org/main/trunk@2 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/MSN/msn_msgqueue.cpp | 204 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 204 insertions(+) create mode 100644 protocols/MSN/msn_msgqueue.cpp (limited to 'protocols/MSN/msn_msgqueue.cpp') diff --git a/protocols/MSN/msn_msgqueue.cpp b/protocols/MSN/msn_msgqueue.cpp new file mode 100644 index 0000000000..eeafdfea2f --- /dev/null +++ b/protocols/MSN/msn_msgqueue.cpp @@ -0,0 +1,204 @@ +/* +Plugin of Miranda IM for communicating with users of the MSN Messenger protocol. +Copyright (c) 2006-2012 Boris Krasnovskiy. +Copyright (c) 2003-2005 George Hazan. +Copyright (c) 2002-2003 Richard Hughes (original version). + +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, see . +*/ + +#include "msn_global.h" +#include "msn_proto.h" + +//a few little functions to manage queuing send message requests until the +//connection is established + +void CMsnProto::MsgQueue_Init(void) +{ + msgQueueSeq = 1; + InitializeCriticalSection(&csMsgQueue); +} + +void CMsnProto::MsgQueue_Uninit(void) +{ + MsgQueue_Clear(); + DeleteCriticalSection(&csMsgQueue); +} + +int CMsnProto::MsgQueue_Add(const char* wlid, int msgType, const char* msg, int msgSize, filetransfer* ft, int flags, STRLIST *cnt) +{ + EnterCriticalSection(&csMsgQueue); + + MsgQueueEntry* E = new MsgQueueEntry; + msgQueueList.insert(E); + + int seq = msgQueueSeq++; + + E->wlid = mir_strdup(wlid); + E->msgSize = msgSize; + E->msgType = msgType; + if (msgSize <= 0) + E->message = mir_strdup(msg); + else + memcpy(E->message = (char*)mir_alloc(msgSize), msg, msgSize); + E->ft = ft; + E->cont = cnt; + E->seq = seq; + E->flags = flags; + E->allocatedToThread = 0; + E->ts = time(NULL); + + LeaveCriticalSection(&csMsgQueue); + return seq; +} + +// shall we create another session? +const char* CMsnProto::MsgQueue_CheckContact(const char* wlid, time_t tsc) +{ + EnterCriticalSection(&csMsgQueue); + + time_t ts = time(NULL); + const char* ret = NULL; + for (int i=0; i < msgQueueList.getCount(); i++) + { + if (_stricmp(msgQueueList[i].wlid, wlid) == 0 && (tsc == 0 || (ts - msgQueueList[i].ts) < tsc)) + { + ret = wlid; + break; + } + } + + LeaveCriticalSection(&csMsgQueue); + return ret; +} + +//for threads to determine who they should connect to +const char* CMsnProto::MsgQueue_GetNextRecipient(void) +{ + EnterCriticalSection(&csMsgQueue); + + const char* ret = NULL; + for (int i=0; i < msgQueueList.getCount(); i++) + { + MsgQueueEntry& E = msgQueueList[i]; + if (!E.allocatedToThread) + { + E.allocatedToThread = 1; + ret = E.wlid; + + while(++i < msgQueueList.getCount()) + if (_stricmp(msgQueueList[i].wlid, ret) == 0) + msgQueueList[i].allocatedToThread = 1; + + break; + } + } + + LeaveCriticalSection(&csMsgQueue); + return ret; +} + +//deletes from list. Must mir_free() return value +bool CMsnProto::MsgQueue_GetNext(const char* wlid, MsgQueueEntry& retVal) +{ + int i; + + EnterCriticalSection(&csMsgQueue); + for(i=0; i < msgQueueList.getCount(); i++) + if (_stricmp(msgQueueList[i].wlid, wlid) == 0) + break; + + bool res = i != msgQueueList.getCount(); + if (res) + { + retVal = msgQueueList[i]; + msgQueueList.remove(i); + } + LeaveCriticalSection(&csMsgQueue); + return res; +} + +int CMsnProto::MsgQueue_NumMsg(const char* wlid) +{ + int res = 0; + EnterCriticalSection(&csMsgQueue); + + for(int i=0; i < msgQueueList.getCount(); i++) + res += (_stricmp(msgQueueList[i].wlid, wlid) == 0); + + LeaveCriticalSection(&csMsgQueue); + return res; +} + +void CMsnProto::MsgQueue_Clear(const char* wlid, bool msg) +{ + int i; + + EnterCriticalSection(&csMsgQueue); + if (wlid == NULL) + { + + for(i=0; i < msgQueueList.getCount(); i++) + { + const MsgQueueEntry& E = msgQueueList[i]; + if (E.msgSize == 0) + { + HANDLE hContact = MSN_HContactFromEmail(E.wlid); + SendBroadcast(hContact, ACKTYPE_MESSAGE, ACKRESULT_FAILED, + (HANDLE)E.seq, (LPARAM)MSN_Translate("Message delivery failed")); + } + mir_free(E.message); + mir_free(E.wlid); + if (E.cont) delete E.cont; + } + msgQueueList.destroy(); + + msgQueueSeq = 1; + } + else + { + for(i=0; i < msgQueueList.getCount(); i++) + { + time_t ts = time(NULL); + const MsgQueueEntry& E = msgQueueList[i]; + if (_stricmp(msgQueueList[i].wlid, wlid) == 0 && (!msg || E.msgSize == 0)) + { + bool msgfnd = E.msgSize == 0 && E.ts < ts; + int seq = E.seq; + + mir_free(E.message); + mir_free(E.wlid); + if (E.cont) delete E.cont; + msgQueueList.remove(i); + + if (msgfnd) + { + LeaveCriticalSection(&csMsgQueue); + HANDLE hContact = MSN_HContactFromEmail(wlid); + SendBroadcast(hContact, ACKTYPE_MESSAGE, ACKRESULT_FAILED, (HANDLE)seq, + (LPARAM)MSN_Translate("Message delivery failed")); + i = 0; + EnterCriticalSection(&csMsgQueue); + } + } + } + } + LeaveCriticalSection(&csMsgQueue); +} + +void __cdecl CMsnProto::MsgQueue_AllClearThread(void* arg) +{ + MsgQueue_Clear((char*)arg); + mir_free(arg); +} -- cgit v1.2.3