diff options
Diffstat (limited to 'miranda-wine/protocols/MSN/msn_chat.cpp')
-rw-r--r-- | miranda-wine/protocols/MSN/msn_chat.cpp | 335 |
1 files changed, 335 insertions, 0 deletions
diff --git a/miranda-wine/protocols/MSN/msn_chat.cpp b/miranda-wine/protocols/MSN/msn_chat.cpp new file mode 100644 index 0000000..fae3574 --- /dev/null +++ b/miranda-wine/protocols/MSN/msn_chat.cpp @@ -0,0 +1,335 @@ +/*
+Plugin of Miranda IM for communicating with users of the MSN Messenger protocol.
+Copyright (c) 2003-5 George Hazan.
+Copyright (c) 2002-3 Richard Hughes (original version).
+
+Miranda IM: the free icq client for MS Windows
+Copyright (C) 2000-2002 Richard Hughes, Roland Rabien & Tristan Van de Vreede
+
+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 "msn_global.h"
+#include "../../include/m_history.h"
+
+static LONG sttChatID = 0;
+extern HANDLE hInitChat;
+
+int MSN_ChatInit( WPARAM wParam, LPARAM lParam )
+{
+ ThreadData *info = (ThreadData*)wParam;
+ GCWINDOW gcw = {0};
+ GCDEST gcd = {0};
+ GCEVENT gce = {0};
+
+ InterlockedIncrement( &sttChatID );
+ ltoa( sttChatID, info->mChatID, 10 );
+
+ info->mJoinedContacts = ( HANDLE* )realloc(info->mJoinedContacts, sizeof(HANDLE)*(++info->mJoinedCount));
+ info->mJoinedContacts[info->mJoinedCount - 1] = info->mJoinedContacts[0];
+ info->mJoinedContacts[0] = ( HANDLE )-sttChatID;
+
+ char szName[ 512 ];
+ char tEmail[ MSN_MAX_EMAIL_LEN ], tNick[ 1024 ];
+ mir_snprintf( szName, sizeof( szName ), "%s%s", Translate("MSN Chat #"), info->mChatID );
+
+ gcw.cbSize = sizeof(GCWINDOW);
+ gcw.iType = GCW_CHATROOM;
+ gcw.pszModule = msnProtocolName;
+ gcw.pszName = szName;
+ gcw.pszID = info->mChatID;
+ gcw.pszStatusbarText = NULL;
+ gcw.bDisableNickList = FALSE;
+ MSN_CallService(MS_GC_NEWCHAT, NULL, (LPARAM)&gcw);
+
+ gce.cbSize = sizeof(GCEVENT);
+ gcd.pszModule = msnProtocolName;
+ gcd.pszID = info->mChatID;
+ gcd.iType = GC_EVENT_ADDGROUP;
+ gce.pDest = &gcd;
+ gce.pszStatus = Translate("Me");
+ MSN_CallService(MS_GC_EVENT, NULL, (LPARAM)&gce);
+
+ gcd.iType = GC_EVENT_JOIN;
+ gce.pszStatus, Translate("Me");
+ MSN_GetStaticString( "Nick", NULL, tNick, sizeof tNick );
+ gce.pszNick = tNick;
+ MSN_GetStaticString( "e-mail", NULL, tEmail, sizeof tEmail );
+ gce.pszUID = tEmail;
+ gce.time = 0;
+ gce.bIsMe = TRUE;
+ gce.bAddToLog = FALSE;
+ MSN_CallService(MS_GC_EVENT, NULL, (LPARAM)&gce);
+
+ gcd.iType = GC_EVENT_ADDGROUP;
+ gce.pDest = &gcd;
+ gce.pszStatus = Translate("Others");
+ MSN_CallService(MS_GC_EVENT, NULL, (LPARAM)&gce);
+
+ gce.cbSize = sizeof(GCEVENT);
+ gcd.iType = GC_EVENT_CONTROL;
+ gce.pDest = &gcd;
+ MSN_CallService(MS_GC_EVENT, WINDOW_INITDONE, (LPARAM)&gce);
+ MSN_CallService(MS_GC_EVENT, WINDOW_ONLINE, (LPARAM)&gce);
+ MSN_CallService(MS_GC_EVENT, WINDOW_VISIBLE, (LPARAM)&gce);
+ return 0;
+}
+
+void MSN_ChatStart(ThreadData* info) {
+ if ( info->mChatID[0] == 0 ) {
+ NotifyEventHooks( hInitChat, (WPARAM)info, 0 );
+
+ // add all participants onto the list
+ GCDEST gcd = {0};
+ gcd.pszModule = msnProtocolName;
+ gcd.pszID = info->mChatID;
+ gcd.iType = GC_EVENT_JOIN;
+
+ GCEVENT gce = {0};
+ gce.cbSize = sizeof(GCEVENT);
+ gce.pDest = &gcd;
+ gce.pszStatus = Translate("Others");
+ gce.time = time(NULL);
+ gce.bIsMe = FALSE;
+ gce.bAddToLog = TRUE;
+
+ for ( int j=0; j < info->mJoinedCount; j++ ) {
+ if (( long )info->mJoinedContacts[j] > 0 ) {
+ gce.pszNick = MSN_GetContactName( info->mJoinedContacts[j] );
+
+ char tEmail[ MSN_MAX_EMAIL_LEN ];
+ if ( !MSN_GetStaticString( "e-mail", info->mJoinedContacts[j], tEmail, sizeof tEmail )) {
+ gce.pszUID = tEmail;
+ MSN_CallService( MS_GC_EVENT, NULL, ( LPARAM )&gce );
+ } } } }
+}
+
+void KillChatSession(char* id, GCHOOK* gch) {
+ GCDEST gcd = {0};
+ GCEVENT gce = {0};
+ gce.cbSize = sizeof(GCEVENT);
+ gce.pDest = &gcd;
+ gcd.pszModule = gch->pDest->pszModule;
+ gcd.pszID = gch->pDest->pszID;
+ gcd.iType = GC_EVENT_CONTROL;
+ MSN_CallService(MS_GC_EVENT, WINDOW_OFFLINE, (LPARAM)&gce);
+ MSN_CallService(MS_GC_EVENT, WINDOW_TERMINATE, (LPARAM)&gce);
+}
+
+void InviteUser(ThreadData* info) {
+ HMENU tMenu = ::CreatePopupMenu();
+ HANDLE hContact = ( HANDLE )MSN_CallService( MS_DB_CONTACT_FINDFIRST, 0, 0 );
+
+ // add the heading
+ ::AppendMenu(tMenu, MF_STRING|MF_GRAYED|MF_DISABLED, (UINT_PTR)0, TranslateT("&Invite user..."));
+ ::AppendMenu(tMenu, MF_SEPARATOR, (UINT_PTR)1, NULL);
+
+ // generate a list of contact
+ while ( hContact != NULL ) {
+ if ( !lstrcmpA( msnProtocolName, ( char* )MSN_CallService( MS_PROTO_GETCONTACTBASEPROTO, ( WPARAM )hContact,0 ))) {
+ if (DBGetContactSettingByte(hContact, msnProtocolName, "ChatRoom", 0) == 0) {
+ if (MSN_GetWord(hContact, "Status", ID_STATUS_OFFLINE) != ID_STATUS_OFFLINE) {
+ BOOL alreadyInSession = FALSE;
+ for ( int j=0; j < info->mJoinedCount; j++ ) {
+ if (info->mJoinedContacts[j] == hContact) {
+ alreadyInSession = TRUE;
+ break;
+ }
+ }
+ if (!alreadyInSession)
+ ::AppendMenu(tMenu, MF_STRING, (UINT_PTR)hContact, MSN_GetContactNameT(hContact));
+ }
+ } }
+ hContact = ( HANDLE )MSN_CallService( MS_DB_CONTACT_FINDNEXT,( WPARAM )hContact, 0 );
+ }
+
+ HWND tWindow = CreateWindow(_T("EDIT"),_T(""),0,1,1,1,1,NULL,NULL,hInst,NULL);
+
+ POINT pt;
+ ::GetCursorPos ( &pt );
+ HANDLE hInvitedUser = (HANDLE)::TrackPopupMenu( tMenu, TPM_NONOTIFY | TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD, pt.x, pt.y, 0, tWindow, NULL );
+ ::DestroyMenu( tMenu );
+ ::DestroyWindow( tWindow );
+
+ if ( !hInvitedUser )
+ return;
+
+ char tEmail[ MSN_MAX_EMAIL_LEN ];
+ if ( !MSN_GetStaticString( "e-mail", ( HANDLE )hInvitedUser, tEmail, sizeof( tEmail ))) {
+ info->sendPacket( "CAL", tEmail );
+ MSN_ChatStart(info);
+} }
+
+int MSN_GCEventHook(WPARAM wParam,LPARAM lParam) {
+ GCHOOK *gch = (GCHOOK*) lParam;
+ char S[512] = "";
+
+ if(gch) {
+ if (!lstrcmpiA(gch->pDest->pszModule, msnProtocolName)) {
+ char *p = new char[lstrlenA(gch->pDest->pszID)+1];
+ lstrcpyA(p, gch->pDest->pszID);
+ switch (gch->pDest->iType) {
+ case GC_USER_TERMINATE: {
+ int chatID = atoi( p );
+ ThreadData* thread = MSN_GetThreadByContact((HANDLE)-chatID);
+ if ( thread != NULL ) {
+ // open up srmm dialog when quit while 1 person left
+ if ( thread->mJoinedCount == 1 ) {
+ // switch back to normal session
+ thread->mJoinedContacts[0] = thread->mJoinedContacts[1];
+ thread->mJoinedContacts = ( HANDLE* )realloc( thread->mJoinedContacts, sizeof( HANDLE ) );
+ MSN_CallService(MS_MSG_SENDMESSAGE, (WPARAM)thread->mJoinedContacts[0], 0);
+ thread->mChatID[0] = 0;
+ }
+ else thread->sendPacket( "OUT", NULL );
+ }
+ break;
+ }
+ case GC_USER_MESSAGE:
+ if ( gch && gch->pszText && lstrlenA( gch->pszText ) > 0 ) {
+ rtrim( gch->pszText ); // remove the ending linebreak
+
+ { char* pszMsg = UnEscapeChatTags( NEWSTR_ALLOCA( gch->pszText ));
+
+ CCSDATA ccs = {0};
+ ccs.hContact = (HANDLE)-atoi(p);
+ ccs.wParam = 0;
+ ccs.lParam = (LPARAM)pszMsg;
+ CallProtoService(msnProtocolName, PSS_MESSAGE, (WPARAM)0, (LPARAM)&ccs);
+ }
+
+ GCDEST gcd = {0};
+ GCEVENT gce = {0};
+
+ gcd.pszModule = msnProtocolName;
+ gcd.pszID = p;
+ gcd.iType = GC_EVENT_MESSAGE;
+
+ char tEmail[ MSN_MAX_EMAIL_LEN ], tNick[ 1024 ];
+ gce.cbSize = sizeof(GCEVENT);
+ gce.pDest = &gcd;
+ MSN_GetStaticString( "Nick", NULL, tNick, sizeof tNick );
+ gce.pszNick = tNick;
+ MSN_GetStaticString( "e-mail", NULL, tEmail, sizeof tEmail );
+ gce.pszUID = tEmail;
+ gce.time = time(NULL);
+ gce.pszText = gch->pszText;
+ gce.bAddToLog = TRUE;
+ gce.bIsMe = TRUE;
+ MSN_CallService(MS_GC_EVENT, NULL, (LPARAM)&gce);
+ }
+ break;
+ case GC_USER_CHANMGR: {
+ int chatID = atoi(p);
+ ThreadData* thread = MSN_GetThreadByContact((HANDLE)-chatID);
+ if ( thread != NULL ) {
+ InviteUser(thread);
+ }
+ break;
+ }
+ case GC_USER_PRIVMESS: {
+ HANDLE hContact = MSN_HContactFromEmail((char*)gch->pszUID, NULL, 0, 0);
+ MSN_CallService(MS_MSG_SENDMESSAGE, (WPARAM)hContact, 0);
+ break;
+ }
+ case GC_USER_LOGMENU:
+ switch(gch->dwData) {
+ case 10: {
+ int chatID = atoi(p);
+ ThreadData* thread = MSN_GetThreadByContact((HANDLE)-chatID);
+ if ( thread != NULL ) {
+ InviteUser(thread);
+ }
+ break;
+ }
+ case 20:
+ KillChatSession(p, gch);
+ break;
+ }
+ break;
+ case GC_USER_NICKLISTMENU: {
+ HANDLE hContact = MSN_HContactFromEmail((char*)gch->pszUID, NULL, 0, 0);
+
+ switch(gch->dwData) {
+ case 10:
+ MSN_CallService(MS_USERINFO_SHOWDIALOG, (WPARAM)hContact, 0);
+ break;
+ case 20:
+ MSN_CallService(MS_HISTORY_SHOWCONTACTHISTORY, (WPARAM)hContact, 0);
+ break;
+ case 110:
+ KillChatSession(p, gch);
+ break;
+ }
+ break;
+ }
+/* haven't implemented in chat.dll
+ case GC_USER_TYPNOTIFY: {
+ int chatID = atoi(p);
+ ThreadData* thread = MSN_GetThreadByContact((HANDLE)-chatID);
+ for ( int j=0; j < thread->mJoinedCount; j++ ) {
+ if (( long )thread->mJoinedContacts[j] > 0 )
+ CallService(MS_PROTO_SELFISTYPING, (WPARAM) thread->mJoinedContacts[j], (LPARAM) PROTOTYPE_SELFTYPING_ON);
+ }
+ break;
+ }
+*/
+ default:
+ break;
+ }
+ delete[]p;
+ }
+
+ }
+ return 0;
+}
+
+int MSN_GCMenuHook(WPARAM wParam,LPARAM lParam) {
+ GCMENUITEMS *gcmi= (GCMENUITEMS*) lParam;
+
+ if ( gcmi ) {
+ if (!lstrcmpiA(gcmi->pszModule, msnProtocolName)) {
+ if(gcmi->Type == MENU_ON_LOG) {
+ static struct gc_item Item[] = {
+ {Translate("&Invite user..."), 10, MENU_ITEM, FALSE},
+ {Translate("&Leave chat session"), 20, MENU_ITEM, FALSE}
+ };
+ gcmi->nItems = sizeof(Item)/sizeof(Item[0]);
+ gcmi->Item = &Item[0];
+ }
+ if(gcmi->Type == MENU_ON_NICKLIST) {
+ char tEmail[ MSN_MAX_EMAIL_LEN ];
+ MSN_GetStaticString( "e-mail", NULL, tEmail, sizeof tEmail );
+ if (!lstrcmpA(tEmail, (char *)gcmi->pszUID)) {
+ static struct gc_item Item[] = {
+ {Translate("User &details"), 10, MENU_ITEM, FALSE},
+ {Translate("User &history"), 20, MENU_ITEM, FALSE},
+ {Translate(""), 100, MENU_SEPARATOR, FALSE},
+ {Translate("&Leave chat session"), 110, MENU_ITEM, FALSE}
+ };
+ gcmi->nItems = sizeof(Item)/sizeof(Item[0]);
+ gcmi->Item = &Item[0];
+ }
+ else {
+ static struct gc_item Item[] = {
+ {Translate("User &details"), 10, MENU_ITEM, FALSE},
+ {Translate("User &history"), 20, MENU_ITEM, FALSE}
+ };
+ gcmi->nItems = sizeof(Item)/sizeof(Item[0]);
+ gcmi->Item = &Item[0];
+ } } } }
+
+ return 0;
+}
|