summaryrefslogtreecommitdiff
path: root/protocols/AimOscar/chat.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/AimOscar/chat.cpp')
-rw-r--r--protocols/AimOscar/chat.cpp343
1 files changed, 343 insertions, 0 deletions
diff --git a/protocols/AimOscar/chat.cpp b/protocols/AimOscar/chat.cpp
new file mode 100644
index 0000000000..1c9f329486
--- /dev/null
+++ b/protocols/AimOscar/chat.cpp
@@ -0,0 +1,343 @@
+/*
+Plugin of Miranda IM for communicating with users of the AIM protocol.
+Copyright (c) 2008-2009 Boris Krasnovskiy
+
+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 <http://www.gnu.org/licenses/>.
+*/
+#include "aim.h"
+
+static const COLORREF crCols[16] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+
+void CAimProto::chat_register(void)
+{
+ GCREGISTER gcr = {0};
+ gcr.cbSize = sizeof(gcr);
+ gcr.dwFlags = GC_TYPNOTIF | GC_CHANMGR | GC_TCHAR;
+ gcr.iMaxText = 0;
+ gcr.nColors = 16;
+ gcr.pColors = (COLORREF*)crCols;
+ gcr.ptszModuleDispName = m_tszUserName;
+ gcr.pszModule = m_szModuleName;
+ CallServiceSync(MS_GC_REGISTER, 0, (LPARAM)&gcr);
+
+ HookProtoEvent(ME_GC_EVENT, &CAimProto::OnGCEvent);
+ HookProtoEvent(ME_GC_BUILDMENU, &CAimProto::OnGCMenuHook );
+}
+
+void CAimProto::chat_start(const char* id, unsigned short exchange)
+{
+ TCHAR* idt = mir_a2t(id);
+
+ GCSESSION gcw = {0};
+ gcw.cbSize = sizeof(gcw);
+ gcw.dwFlags = GC_TCHAR;
+ gcw.iType = GCW_CHATROOM;
+ gcw.pszModule = m_szModuleName;
+ gcw.ptszName = idt;
+ gcw.ptszID = idt;
+ CallServiceSync(MS_GC_NEWSESSION, 0, (LPARAM)&gcw);
+
+ GCDEST gcd = { m_szModuleName, { NULL }, GC_EVENT_ADDGROUP };
+ gcd.ptszID = idt;
+
+ GCEVENT gce = {0};
+ gce.cbSize = sizeof(gce);
+ gce.dwFlags = GC_TCHAR;
+ gce.pDest = &gcd;
+ gce.ptszStatus = TranslateT("Me");
+ CallServiceSync(MS_GC_EVENT, 0, (LPARAM)&gce);
+
+ gcd.iType = GC_EVENT_ADDGROUP;
+ gce.ptszStatus = TranslateT("Others");
+ CallServiceSync(MS_GC_EVENT, 0, (LPARAM)&gce);
+
+ gcd.iType = GC_EVENT_CONTROL;
+ CallServiceSync(MS_GC_EVENT, SESSION_INITDONE, (LPARAM)&gce);
+ CallServiceSync(MS_GC_EVENT, SESSION_ONLINE, (LPARAM)&gce);
+ CallServiceSync(MS_GC_EVENT, WINDOW_VISIBLE, (LPARAM)&gce);
+
+ setWord(find_chat_contact(id), "Exchange", exchange);
+
+ mir_free(idt);
+}
+
+void CAimProto::chat_event(const char* id, const char* sn, int evt, const TCHAR* msg)
+{
+ TCHAR* idt = mir_a2t(id);
+ TCHAR* snt = mir_a2t(sn);
+
+ HANDLE hContact = contact_from_sn(sn);
+ TCHAR* nick = hContact ? (TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,
+ WPARAM(hContact), GCDNF_TCHAR) : snt;
+
+ GCDEST gcd = { m_szModuleName, { NULL }, evt };
+ gcd.ptszID = idt;
+
+ GCEVENT gce = {0};
+ gce.cbSize = sizeof(gce);
+ gce.dwFlags = GC_TCHAR | GCEF_ADDTOLOG;
+ gce.pDest = &gcd;
+ gce.ptszNick = nick;
+ gce.ptszUID = snt;
+ gce.bIsMe = _stricmp(sn, username) == 0;
+ gce.ptszStatus = gce.bIsMe ? TranslateT("Me") : TranslateT("Others");
+ gce.ptszText = msg;
+ gce.time = time(NULL);
+ CallServiceSync(MS_GC_EVENT, 0, (LPARAM)&gce);
+
+ mir_free(snt);
+ mir_free(idt);
+}
+
+void CAimProto::chat_leave(const char* id)
+{
+ TCHAR* idt = mir_a2t(id);
+
+ GCDEST gcd = { m_szModuleName, { NULL }, GC_EVENT_CONTROL };
+ gcd.ptszID = idt;
+
+ GCEVENT gce = {0};
+ gce.cbSize = sizeof(GCEVENT);
+ gce.dwFlags = GC_TCHAR;
+ gce.pDest = &gcd;
+ CallServiceSync(MS_GC_EVENT, SESSION_OFFLINE, (LPARAM)&gce);
+ CallServiceSync(MS_GC_EVENT, SESSION_TERMINATE, (LPARAM)&gce);
+
+ mir_free(idt);
+}
+
+
+int CAimProto::OnGCEvent(WPARAM wParam,LPARAM lParam)
+{
+ GCHOOK *gch = (GCHOOK*) lParam;
+ if (!gch) return 1;
+
+ if (strcmp(gch->pDest->pszModule, m_szModuleName)) return 0;
+
+ char* id = mir_t2a(gch->pDest->ptszID);
+ chat_list_item* item = find_chat_by_id(id);
+
+ if (item == NULL) return 0;
+
+ switch (gch->pDest->iType)
+ {
+ case GC_SESSION_TERMINATE:
+ aim_sendflap(item->hconn,0x04,0,NULL,item->seqno);
+ Netlib_Shutdown(item->hconn);
+ break;
+
+ case GC_USER_MESSAGE:
+ if (gch->ptszText && _tcslen(gch->ptszText))
+ {
+ char* msg = mir_utf8encodeT(gch->ptszText);
+ aim_chat_send_message(item->hconn, item->seqno, msg);
+ mir_free(msg);
+ }
+ break;
+ case GC_USER_CHANMGR:
+ DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_CHATROOM_INVITE), NULL, invite_to_chat_dialog,
+ LPARAM(new invite_chat_param(item->id, this)));
+ break;
+
+ case GC_USER_PRIVMESS:
+ {
+ char* sn = mir_t2a(gch->ptszUID);
+ HANDLE hContact = contact_from_sn(sn);
+ mir_free(sn);
+ CallService(MS_MSG_SENDMESSAGE, (WPARAM)hContact, 0);
+ }
+ break;
+
+ case GC_USER_LOGMENU:
+ switch(gch->dwData)
+ {
+ case 10:
+ DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_CHATROOM_INVITE), NULL, invite_to_chat_dialog,
+ LPARAM(new invite_chat_param(item->id, this)));
+ break;
+
+ case 20:
+ chat_leave(id);
+ break;
+ }
+ break;
+
+ case GC_USER_NICKLISTMENU:
+ {
+ char *sn = mir_t2a(gch->ptszUID);
+ HANDLE hContact = contact_from_sn(sn);
+ mir_free(sn);
+
+ switch (gch->dwData)
+ {
+ case 10:
+ CallService(MS_USERINFO_SHOWDIALOG, (WPARAM)hContact, 0);
+ break;
+
+ case 20:
+ CallService(MS_HISTORY_SHOWCONTACTHISTORY, (WPARAM)hContact, 0);
+ break;
+
+ case 110:
+ chat_leave(id);
+ break;
+ }
+ }
+ break;
+
+ case GC_USER_TYPNOTIFY:
+ break;
+ }
+ mir_free(id);
+
+ return 0;
+}
+
+int CAimProto::OnGCMenuHook(WPARAM wParam,LPARAM lParam)
+{
+ GCMENUITEMS *gcmi= (GCMENUITEMS*) lParam;
+
+ if ( gcmi == NULL || _stricmp(gcmi->pszModule, m_szModuleName )) return 0;
+
+ if ( gcmi->Type == MENU_ON_LOG )
+ {
+ static const struct gc_item Items[] = {
+ { TranslateT("&Invite user..."), 10, MENU_ITEM, FALSE },
+ { TranslateT("&Leave chat session"), 20, MENU_ITEM, FALSE }
+ };
+ gcmi->nItems = SIZEOF(Items);
+ gcmi->Item = (gc_item*)Items;
+ }
+ else if ( gcmi->Type == MENU_ON_NICKLIST )
+ {
+ char* sn = mir_t2a(gcmi->pszUID);
+ if ( !strcmp(username, sn))
+ {
+ static const struct gc_item Items[] = {
+ { TranslateT("User &details"), 10, MENU_ITEM, FALSE },
+ { TranslateT("User &history"), 20, MENU_ITEM, FALSE },
+ { _T(""), 100, MENU_SEPARATOR, FALSE },
+ { TranslateT("&Leave chat session"), 110, MENU_ITEM, FALSE }
+ };
+ gcmi->nItems = SIZEOF(Items);
+ gcmi->Item = (gc_item*)Items;
+ }
+ else {
+ static const struct gc_item Items[] = {
+ { TranslateT("User &details"), 10, MENU_ITEM, FALSE },
+ { TranslateT("User &history"), 20, MENU_ITEM, FALSE }
+ };
+ gcmi->nItems = SIZEOF(Items);
+ gcmi->Item = (gc_item*)Items;
+ }
+ mir_free(sn);
+ }
+
+ return 0;
+}
+
+
+void __cdecl CAimProto::chatnav_request_thread( void* param )
+{
+ chatnav_param* par = (chatnav_param*)param;
+
+ if (wait_conn(hChatNavConn, hChatNavEvent, 0x0d))
+ {
+ if (par->isroom)
+ aim_chatnav_create(hChatNavConn, chatnav_seqno, par->id, par->exchange);
+ else
+ aim_chatnav_room_info(hChatNavConn, chatnav_seqno, par->id, par->exchange, par->instance);
+ }
+ delete par;
+}
+
+chat_list_item* CAimProto::find_chat_by_cid(unsigned short cid)
+{
+ chat_list_item* item = NULL;
+ for(int i=0; i<chat_rooms.getCount(); ++i)
+ {
+ if (chat_rooms[i].cid == cid)
+ {
+ item = &chat_rooms[i];
+ break;
+ }
+ }
+ return item;
+}
+
+chat_list_item* CAimProto::find_chat_by_id(char* id)
+{
+ chat_list_item* item = NULL;
+ for(int i=0; i<chat_rooms.getCount(); ++i)
+ {
+ if (strcmp(chat_rooms[i].id, id) == 0)
+ {
+ item = &chat_rooms[i];
+ break;
+ }
+ }
+ return item;
+}
+
+chat_list_item* CAimProto::find_chat_by_conn(HANDLE conn)
+{
+ chat_list_item* item = NULL;
+ for(int i=0; i<chat_rooms.getCount(); ++i)
+ {
+ if (chat_rooms[i].hconn == conn)
+ {
+ item = &chat_rooms[i];
+ break;
+ }
+ }
+ return item;
+}
+
+void CAimProto::remove_chat_by_ptr(chat_list_item* item)
+{
+ for(int i=0; i<chat_rooms.getCount(); ++i)
+ {
+ if (&chat_rooms[i] == item)
+ {
+ chat_rooms.remove(i);
+ break;
+ }
+ }
+}
+
+void CAimProto::shutdown_chat_conn(void)
+{
+ for(int i=0; i<chat_rooms.getCount(); ++i)
+ {
+ chat_list_item& item = chat_rooms[i];
+ if (item.hconn)
+ {
+ aim_sendflap(item.hconn,0x04,0,NULL,item.seqno);
+ Netlib_Shutdown(item.hconn);
+ }
+ }
+}
+
+void CAimProto::close_chat_conn(void)
+{
+ for(int i=0; i<chat_rooms.getCount(); ++i)
+ {
+ chat_list_item& item = chat_rooms[i];
+ if (item.hconn)
+ {
+ Netlib_CloseHandle(item.hconn);
+ item.hconn = NULL;
+ }
+ }
+} \ No newline at end of file