summaryrefslogtreecommitdiff
path: root/irc_mod/services.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'irc_mod/services.cpp')
-rw-r--r--irc_mod/services.cpp2515
1 files changed, 2515 insertions, 0 deletions
diff --git a/irc_mod/services.cpp b/irc_mod/services.cpp
new file mode 100644
index 0000000..3953e80
--- /dev/null
+++ b/irc_mod/services.cpp
@@ -0,0 +1,2515 @@
+/*
+IRC plugin for Miranda IM
+
+Copyright (C) 2003 Jörgen Persson
+
+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 "irc.h"
+
+CIrcSessionInfo si;
+HANDLE g_hModulesLoaded = NULL;
+HANDLE g_hSystemPreShutdown = NULL;
+HANDLE g_hContactDblClick = NULL;
+HANDLE g_hEventDblClick = NULL;
+HANDLE g_hContactDeleted = NULL;
+HANDLE g_hIconsChanged = NULL;
+HANDLE g_hUserInfoInit = NULL;
+HANDLE g_hMenuCreation = NULL;
+HANDLE g_hGCUserEvent = NULL;
+HANDLE g_hGCMenuBuild = NULL;
+HANDLE g_hOptionsInit = NULL;
+HANDLE hContactMenu1 = NULL;
+HANDLE hContactMenu2 = NULL;
+HANDLE hContactMenu3 = NULL;
+HANDLE hMenuQuick = NULL;
+HANDLE hMenuJoin = NULL;
+HANDLE hMenuNick = NULL;
+HANDLE hMenuList = NULL;
+HANDLE hMenuServer = NULL;
+HANDLE hMenuAvatar = NULL;
+HANDLE hMenuConsole = NULL;
+HANDLE hNetlib = NULL;
+HANDLE hNetlibDCC = NULL;
+HWND join_hWnd = NULL;
+HWND quickconn_hWnd = NULL;
+volatile bool bChatInstalled = FALSE;
+bool bMbotInstalled = FALSE;
+extern HWND nick_hWnd;
+extern HWND list_hWnd ;
+int RetryCount =0;
+int PortCount =0;
+DWORD bConnectRequested = 0;
+DWORD bConnectThreadRunning = 0;
+extern bool bTempDisableCheck ;
+extern bool bTempForceCheck ;
+extern bool bPerformDone;
+int iTempCheckTime = 0;
+int OldStatus= ID_STATUS_OFFLINE;
+int GlobalStatus = ID_STATUS_OFFLINE;
+UINT_PTR RetryTimer = 0;
+String StatusMessage ="";
+
+extern CIrcSession g_ircSession;
+extern char * IRCPROTONAME;
+extern char * ALTIRCPROTONAME;
+extern char * pszServerFile;
+extern char * pszPerformFile;
+extern char * pszIgnoreFile;
+extern PREFERENCES* prefs;
+extern CRITICAL_SECTION cs;
+extern CRITICAL_SECTION m_gchook;
+extern bool nickflag;
+extern String sUserModes;
+extern String sUserModePrefixes;
+extern String sChannelPrefixes;
+extern String sChannelModes;
+extern String WhoisAwayReply ;
+extern char mirandapath[MAX_PATH];
+extern MM_INTERFACE mmi;
+GETEVENTFUNC pfnAddEvent = 0;
+
+// Nudge
+extern HANDLE hIRCNudge;
+
+// PopUp
+bool whois_popup=true;
+
+// Updater
+extern PLUGININFO pluginInfo;
+
+// xStatus
+HANDLE hHookUserMenu = NULL;
+HANDLE hUserMenuXStatus = NULL;
+
+// IcoLib
+HANDLE hHookIconsChanged = NULL;
+
+VOID CALLBACK RetryTimerProc(HWND hwnd,UINT uMsg,UINT idEvent,DWORD dwTime);
+int Service_SetMyAvatar(WPARAM wParam, LPARAM lParam);
+
+static void InitMenus(void)
+{
+ CLISTMENUITEM mi = { 0 };
+ char temp[MAXMODULELABELLENGTH];
+
+ ZeroMemory(&mi, sizeof(mi));
+ mi.cbSize = sizeof(mi);
+ if (bChatInstalled)
+ {
+ mi.pszName = Translate("&Quick connect");
+ mi.hIcon = LoadIconEx(IDI_QUICK,"quick",GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON));
+ wsprintf(temp,"%s/QuickConnectMenu", IRCPROTONAME);
+ mi.pszService = temp;
+ mi.popupPosition = 500090000;
+ mi.pszPopupName = ALTIRCPROTONAME;
+ hMenuQuick= (void *)CallService(MS_CLIST_ADDMAINMENUITEM, (WPARAM)0, (LPARAM)&mi);
+
+ mi.pszName = Translate("&Join a channel");
+ mi.hIcon = LoadIconEx(IDI_JOIN,"join",GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON));
+ wsprintf(temp,"%s/JoinChannelMenu", IRCPROTONAME);
+ mi.pszService = temp;
+ mi.popupPosition = 500090001;
+ mi.pszPopupName = ALTIRCPROTONAME;
+ hMenuJoin = (void *)CallService(MS_CLIST_ADDMAINMENUITEM, (WPARAM)0, (LPARAM)&mi);
+
+ mi.pszName = Translate("&Change your nickname");
+ mi.hIcon = LoadIconEx(IDI_WHOIS,"whois",GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON));
+ wsprintf(temp,"%s/ChangeNickMenu", IRCPROTONAME);
+ mi.pszService = temp;
+ mi.popupPosition = 500090002;
+ mi.pszPopupName = ALTIRCPROTONAME;
+ hMenuNick = (void *)CallService(MS_CLIST_ADDMAINMENUITEM, (WPARAM)0, (LPARAM)&mi);
+
+ mi.pszName = Translate("Show the &list of available channels");
+ mi.hIcon = LoadIconEx(IDI_LIST,"list",GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON));
+ wsprintf(temp,"%s/ShowListMenu", IRCPROTONAME);
+ mi.pszService = temp;
+ mi.popupPosition = 500090003;
+ mi.pszPopupName = ALTIRCPROTONAME;
+ hMenuList = (void *)CallService(MS_CLIST_ADDMAINMENUITEM, (WPARAM)0, (LPARAM)&mi);
+
+ mi.pszName = Translate("&Show the server window");
+ mi.hIcon = LoadIconEx(IDI_SERVER,"server",GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON));
+ wsprintf(temp,"%s/ShowServerMenu", IRCPROTONAME);
+ mi.pszService = temp;
+ mi.popupPosition = 500090004;
+ mi.pszPopupName = ALTIRCPROTONAME;
+ hMenuServer = (void *)CallService(MS_CLIST_ADDMAINMENUITEM, (WPARAM)0, (LPARAM)&mi);
+
+ if(prefs->AvatarsEnabled)
+ {
+ mi.pszName = Translate("Set proto picture");
+ mi.hIcon = LoadIconEx(IDI_AVATAR,"avatar",GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON));
+ wsprintf(temp,"%s/SetAvatarMenu", IRCPROTONAME);
+ mi.pszService = temp;
+ mi.popupPosition = 500090005;
+ mi.pszPopupName = ALTIRCPROTONAME;
+ hMenuAvatar = (void *)CallService(MS_CLIST_ADDMAINMENUITEM, (WPARAM)0, (LPARAM)&mi);
+ }
+ }
+
+ mi.pszName = Translate("&Leave the channel");
+ mi.hIcon = LoadIconEx(IDI_DELETE,"delete",GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON));
+ wsprintf(temp,"%s/Menu1ChannelMenu", IRCPROTONAME);
+ mi.pszService = temp;
+ mi.pszContactOwner = IRCPROTONAME;
+ mi.popupPosition = 500090000;
+ hContactMenu1 = (void *)CallService(MS_CLIST_ADDCONTACTMENUITEM, (WPARAM)0, (LPARAM)&mi);
+
+ mi.pszName = Translate("&User details");
+ mi.hIcon = LoadIconEx(IDI_WHOIS,"whois",GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON));
+ wsprintf(temp,"%s/Menu2ChannelMenu", IRCPROTONAME);
+ mi.pszService = temp;
+ mi.pszContactOwner = IRCPROTONAME;
+ mi.popupPosition = 500090001;
+ hContactMenu2 = (void *)CallService(MS_CLIST_ADDCONTACTMENUITEM, (WPARAM)0, (LPARAM)&mi);
+
+ mi.pszName = Translate("&Ignore");
+ mi.hIcon = LoadIconEx(IDI_BLOCK,"block",GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON));
+ wsprintf(temp,"%s/Menu3ChannelMenu", IRCPROTONAME);
+ mi.pszService = temp;
+ mi.pszContactOwner = IRCPROTONAME;
+ mi.popupPosition = 500090002;
+ hContactMenu3 = (void *)CallService(MS_CLIST_ADDCONTACTMENUITEM, (WPARAM)0, (LPARAM)&mi);
+
+ mi.pszName = IRCTranslate("Show custom status details");
+ mi.hIcon = NULL; // dynamically updated
+ wsprintf(temp,"%s%s", IRCPROTONAME, MS_XSTATUS_SHOWDETAILS);
+ mi.pszService = temp;
+ mi.flags=CMIF_NOTOFFLINE;
+ mi.popupPosition = 500090003;
+ hUserMenuXStatus = (HANDLE)CallService(MS_CLIST_ADDCONTACTMENUITEM, 0, (LPARAM)&mi);
+
+ CLISTMENUITEM clmi;
+ memset( &clmi, 0, sizeof( clmi ));
+ clmi.cbSize = sizeof( clmi );
+ clmi.flags = CMIM_FLAGS|CMIF_GRAYED;
+ CallService( MS_CLIST_MODIFYMENUITEM, ( WPARAM )hMenuJoin, ( LPARAM )&clmi );
+ CallService( MS_CLIST_MODIFYMENUITEM, ( WPARAM )hMenuList, ( LPARAM )&clmi );
+ CallService( MS_CLIST_MODIFYMENUITEM, ( WPARAM )hMenuNick, ( LPARAM )&clmi );
+ if(!prefs->UseServer)
+ CallService( MS_CLIST_MODIFYMENUITEM, ( WPARAM )hMenuServer, ( LPARAM )&clmi );
+ return;
+}
+
+static int Service_FileAllow(WPARAM wParam,LPARAM lParam)
+{
+ CCSDATA *ccs = (CCSDATA *) lParam;
+ DCCINFO * di = (DCCINFO *) ccs->wParam;;
+
+ if (g_ircSession)
+ {
+ String sFile = (String)(char *)ccs->lParam + di->sFile;
+ di->sFileAndPath = sFile;
+ di->sPath = (char *)ccs->lParam;
+
+ CDccSession * dcc = new CDccSession(di);
+
+ g_ircSession.AddDCCSession(di, dcc);
+
+ dcc->Connect();
+
+ }
+ else
+ delete di;
+ return ccs->wParam;
+
+}
+
+static int Service_FileDeny(WPARAM wParam,LPARAM lParam)
+{
+ CCSDATA *ccs = (CCSDATA *) lParam;
+ DCCINFO * di = (DCCINFO *) ccs->wParam;
+
+ delete di;
+
+ return 0;
+}
+
+static int Service_FileCancel(WPARAM wParam,LPARAM lParam)
+{
+ CCSDATA *ccs = (CCSDATA *) lParam;
+ DCCINFO *di = (DCCINFO *) ccs->wParam;
+
+ CDccSession * dcc = g_ircSession.FindDCCSession(di);
+
+ if (dcc)
+ {
+ InterlockedExchange(&dcc->dwWhatNeedsDoing, (long)FILERESUME_CANCEL);
+ SetEvent(dcc->hEvent);
+ dcc->Disconnect();
+ }
+
+ return 0;
+}
+
+static int Service_FileSend(WPARAM wParam,LPARAM lParam)
+{
+ CCSDATA *ccs = (CCSDATA *) lParam;
+ char **files = (char **) ccs->lParam;
+ DCCINFO * dci = NULL;
+ int iPort = 0;
+ int index= 0;
+ DWORD size = 0;
+
+ // do not send to channels :-P
+ if(DBGetContactSettingByte(ccs->hContact, IRCPROTONAME, "ChatRoom", 0) != 0)
+ return 0;
+
+ // stop if it is an active type filetransfer and the user's IP is not known
+ unsigned long ulAdr = 0;
+ if (prefs->ManualHost)
+ ulAdr = ConvertIPToInteger(prefs->MySpecifiedHostIP);
+ else
+ ulAdr = ConvertIPToInteger(prefs->IPFromServer?prefs->MyHost:prefs->MyLocalHost);
+
+ if(!prefs->DCCPassive && !ulAdr)
+ {
+ DoEvent(GC_EVENT_INFORMATION, 0, g_ircSession.GetInfo().sNick.c_str(), Translate("DCC ERROR: Unable to automatically resolve external IP"), NULL, NULL, NULL, true, false);
+ return 0;
+ }
+
+ if(files[index])
+ {
+
+ //get file size
+ FILE * hFile = NULL;
+ while (files[index] && hFile == 0)
+ {
+ hFile = fopen ( files[index] , "rb" );
+ if(hFile)
+ {
+ fseek (hFile , 0 , SEEK_END);
+ size = ftell (hFile);
+ rewind (hFile);
+ fclose(hFile);
+ break;
+ }
+ index++;
+ }
+
+ if(size == 0)
+ {
+ DoEvent(GC_EVENT_INFORMATION, 0, g_ircSession.GetInfo().sNick.c_str(), Translate("DCC ERROR: No valid files specified"), NULL, NULL, NULL, true, false);
+ return 0;
+ }
+
+
+ DBVARIANT dbv;
+ if (!DBGetContactSetting(ccs->hContact, IRCPROTONAME, "Nick", &dbv) && dbv.type == DBVT_ASCIIZ)
+ {
+ // set up a basic DCCINFO struct and pass it to a DCC object
+ dci = new DCCINFO;
+ dci->sFileAndPath = files[index];
+
+ int i = dci->sFileAndPath.rfind("\\", dci->sFileAndPath.length());
+ if (i != string::npos)
+ {
+ dci->sPath = dci->sFileAndPath.substr(0, i+1);
+ dci->sFile = dci->sFileAndPath.substr(i+1, dci->sFileAndPath.length());
+ }
+
+ String sFileWithQuotes = dci->sFile;
+
+ // if spaces in the filename surround witrh quotes
+ if (sFileWithQuotes.find(' ', 0) != string::npos)
+ {
+ sFileWithQuotes.insert(0, "\"");
+ sFileWithQuotes.insert(sFileWithQuotes.length(), "\"");
+ }
+
+ dci->hContact = ccs->hContact;
+ dci->sContactName = dbv.pszVal;
+ dci->iType = DCC_SEND;
+ dci->bReverse = prefs->DCCPassive?true:false;
+ dci->bSender = true;
+ dci->dwSize = size;
+
+ // create new dcc object
+ CDccSession * dcc = new CDccSession(dci);
+
+ // keep track of all objects created
+ g_ircSession.AddDCCSession(dci, dcc);
+
+ // need to make sure that %'s are doubled to avoid having chat interpret as color codes
+ String sFileCorrect = ReplaceString(dci->sFile, "%", "%%");
+
+ // is it an reverse filetransfer (receiver acts as server)
+ if(dci->bReverse)
+ {
+ char szTemp[256];
+ PostIrcMessage("/CTCP %s DCC SEND %s 200 0 %u %u", dci->sContactName.c_str(), sFileWithQuotes.c_str(), dci->dwSize, dcc->iToken);
+
+ mir_snprintf(szTemp, sizeof(szTemp), Translate("DCC reversed file transfer request sent to %s [%s]"), dci->sContactName.c_str(), sFileCorrect.c_str());
+ DoEvent(GC_EVENT_INFORMATION, 0, g_ircSession.GetInfo().sNick.c_str(), szTemp, NULL, NULL, NULL, true, false);
+
+ mir_snprintf(szTemp, sizeof(szTemp), "/NOTICE %s I am sending the file \'\002%s\002\' (%u kB) to you, please accept it. [Reverse transfer]", dci->sContactName.c_str(), sFileCorrect.c_str(), dci->dwSize/1024);
+ if(prefs->SendNotice)
+ PostIrcMessage(szTemp);
+
+ }
+ else // ... normal filetransfer.
+ {
+
+ iPort = dcc->Connect();
+
+ if(iPort)
+ {
+ char szTemp[256];
+ PostIrcMessage("/CTCP %s DCC SEND %s %u %u %u", dci->sContactName.c_str(), sFileWithQuotes.c_str(), ulAdr, iPort, dci->dwSize);
+
+ mir_snprintf(szTemp, sizeof(szTemp), Translate("DCC file transfer request sent to %s [%s]"), dci->sContactName.c_str(), sFileCorrect.c_str());
+ DoEvent(GC_EVENT_INFORMATION, 0, g_ircSession.GetInfo().sNick.c_str(), szTemp, NULL, NULL, NULL, true, false);
+
+ mir_snprintf(szTemp, sizeof(szTemp), "/NOTICE %s I am sending the file \'\002%s\002\' (%u kB) to you, please accept it. [IP: %s]", dci->sContactName.c_str(), sFileCorrect.c_str(), dci->dwSize/1024, ConvertIntegerToIP(ulAdr));
+
+ if(prefs->SendNotice)
+ PostIrcMessage(szTemp);
+ }
+ else
+ DoEvent(GC_EVENT_INFORMATION, 0, g_ircSession.GetInfo().sNick.c_str(), Translate("DCC ERROR: Unable to bind local port"), NULL, NULL, NULL, true, false);
+ }
+
+ // fix for sending multiple files
+ index++;
+ while(files[index])
+ {
+ hFile = NULL;
+ hFile = fopen ( files[index] , "rb" );
+ if(hFile)
+ {
+ fclose(hFile);
+ PostIrcMessage("/DCC SEND %s %s", dci->sContactName.c_str(), files[index]);
+ }
+ index++;
+ }
+
+
+ DBFreeVariant(&dbv);
+
+ }
+ }
+
+ if(dci)
+ return (int)(HANDLE) dci;
+ return NULL;
+}
+
+static int Service_FileReceive(WPARAM wParam,LPARAM lParam)
+{
+ DBEVENTINFO dbei;
+ CCSDATA *ccs = (CCSDATA *) lParam;
+ PROTORECVEVENT *pre = (PROTORECVEVENT *) ccs->lParam;
+ char *szDesc, *szFile;
+
+ DBDeleteContactSetting(ccs->hContact, "CList", "Hidden");
+ szFile = pre->szMessage + sizeof(DWORD);
+ szDesc = szFile + strlen(szFile) + 1;
+ ZeroMemory(&dbei, sizeof(dbei));
+ dbei.cbSize = sizeof(dbei);
+ dbei.szModule = IRCPROTONAME;
+ dbei.timestamp = pre->timestamp;
+ dbei.flags = pre->flags & (PREF_CREATEREAD ? DBEF_READ : 0);
+ dbei.eventType = EVENTTYPE_FILE;
+ dbei.cbBlob = sizeof(DWORD) + strlen(szFile) + strlen(szDesc) + 2;
+ dbei.pBlob = (PBYTE) pre->szMessage;
+ CallService(MS_DB_EVENT_ADD, (WPARAM) ccs->hContact, (LPARAM) &dbei);
+
+ return 0;
+}
+
+static int Service_FileResume(WPARAM wParam,LPARAM lParam)
+{
+ DCCINFO * di = (DCCINFO *) wParam;
+ PROTOFILERESUME * pfr = (PROTOFILERESUME *) lParam;
+
+ long i = (long)pfr->action;
+
+ CDccSession * dcc = g_ircSession.FindDCCSession(di);
+ if(dcc)
+ {
+ InterlockedExchange(&dcc->dwWhatNeedsDoing, i);
+ if(pfr->action == FILERESUME_RENAME)
+ {
+ char * szTemp = strdup(pfr->szFilename);
+ InterlockedExchange((volatile long*)&dcc->NewFileName, (long)szTemp);
+ }
+ if(pfr->action == FILERESUME_RESUME)
+ {
+ DWORD dwPos = 0;
+ String sFile;
+ char * pszTemp = NULL;;
+ FILE * hFile = NULL;
+
+ hFile = fopen(di->sFileAndPath.c_str(), "rb");
+ if(hFile)
+ {
+ fseek(hFile,0,SEEK_END);
+ dwPos = ftell(hFile);
+ rewind (hFile);
+ fclose(hFile); hFile = NULL;
+ }
+
+ String sFileWithQuotes = di->sFile;
+
+ // if spaces in the filename surround witrh quotes
+ if (sFileWithQuotes.find(' ', 0) != string::npos)
+ {
+ sFileWithQuotes.insert(0, "\"");
+ sFileWithQuotes.insert(sFileWithQuotes.length(), "\"");
+ }
+
+
+ if (di->bReverse)
+ PostIrcMessage("/PRIVMSG %s \001DCC RESUME %s 0 %u %s\001", di->sContactName.c_str(), sFileWithQuotes.c_str(), dwPos, dcc->di->sToken.c_str());
+ else
+ PostIrcMessage("/PRIVMSG %s \001DCC RESUME %s %u %u\001", di->sContactName.c_str(), sFileWithQuotes.c_str(), di->iPort, dwPos);
+
+ return 0;
+ }
+
+
+ SetEvent(dcc->hEvent);
+ }
+ return 0;
+}
+
+static int Service_EventDoubleclicked(WPARAM wParam,LPARAM lParam)
+{
+ if (!lParam)
+ return 0;
+
+ CLISTEVENT* pcle = (CLISTEVENT*)lParam;
+
+ if(DBGetContactSettingByte((HANDLE) pcle->hContact, IRCPROTONAME, "DCC", 0) != 0)
+ {
+ char szTemp[500];
+ DCCINFO * pdci = (DCCINFO *) pcle->lParam;
+ HWND hWnd = CreateDialogParam(g_hInstance,MAKEINTRESOURCE(IDD_MESSAGEBOX),NULL,MessageboxWndProc, (LPARAM)pdci);
+ mir_snprintf(szTemp, sizeof(szTemp), Translate("%s (%s) is requesting a client-to-client chat connection."), pdci->sContactName.c_str(), pdci->sHostmask.c_str() );
+ SetDlgItemText(hWnd,IDC_TEXT, szTemp);
+ ShowWindow(hWnd, SW_SHOW);
+ return 1;
+ }
+ return 0;
+}
+
+int Service_UserDeletedContact(WPARAM wp, LPARAM lp)
+{
+ DBVARIANT dbv;
+ HANDLE hContact = (HANDLE) wp;
+
+ if (!hContact)
+ return 0;
+ if (!DBGetContactSetting((HANDLE)wp, IRCPROTONAME, "Nick", &dbv) && dbv.type == DBVT_ASCIIZ )
+ {
+ int type = DBGetContactSettingByte(hContact, IRCPROTONAME, "ChatRoom", 0);
+ if ( type != 0)
+ {
+
+ GCEVENT gce = {0};
+ GCDEST gcd = {0};
+ String S = "";
+ if(type == GCW_CHATROOM)
+ S = MakeWndID(dbv.pszVal);
+ if(type == GCW_SERVER)
+ S = "Network log";
+ gce.cbSize = sizeof(GCEVENT);
+ gce.dwItemData = 0;
+ gcd.iType = GC_EVENT_CONTROL;
+ gcd.pszModule = IRCPROTONAME;
+ gce.pDest = &gcd;
+ gcd.pszID = (char *)S.c_str();
+ int i = CallChatEvent( SESSION_TERMINATE, (LPARAM)&gce);
+ if (i && type == GCW_CHATROOM)
+ PostIrcMessage( "/PART %s", dbv.pszVal);
+ }
+ else
+ {
+ BYTE bDCC = DBGetContactSettingByte((HANDLE)wp, IRCPROTONAME, "DCC", 0) ;
+ if(bDCC)
+ {
+ CDccSession * dcc = g_ircSession.FindDCCSession((HANDLE)wp);
+ if(dcc)
+ dcc->Disconnect();
+ }
+ }
+
+
+
+ DBFreeVariant(&dbv);
+ }
+ return 0;
+}
+
+static int Service_Menu1Command(WPARAM wp, LPARAM lp)
+{
+ DBVARIANT dbv;
+
+ if (!wp )
+ return 0;
+ if (!DBGetContactSetting((HANDLE)wp, IRCPROTONAME, "Nick", &dbv) && dbv.type == DBVT_ASCIIZ )
+ {
+ int type = DBGetContactSettingByte((HANDLE)wp, IRCPROTONAME, "ChatRoom", 0);
+ if ( type != 0)
+ {
+ GCEVENT gce = {0};
+ GCDEST gcd = {0};
+ String S = "";
+ if(type == GCW_CHATROOM)
+ S = MakeWndID(dbv.pszVal);
+ if(type == GCW_SERVER)
+ S = "Network log";
+ gcd.iType = GC_EVENT_CONTROL;
+ gcd.pszID = (char *)S.c_str();
+ gcd.pszModule = IRCPROTONAME;
+ gce.cbSize = sizeof(GCEVENT);
+ gce.pDest = &gcd;
+ CallChatEvent( WINDOW_VISIBLE, (LPARAM)&gce);
+ }
+ else
+ CallService(MS_MSG_SENDMESSAGE, (WPARAM)wp, 0);
+ }
+ return 0;
+}
+
+static int Service_Menu2Command(WPARAM wp, LPARAM lp)
+{
+ DBVARIANT dbv;
+
+ if (!wp )
+ return 0;
+ if (!DBGetContactSetting((HANDLE)wp, IRCPROTONAME, "Nick", &dbv) && dbv.type == DBVT_ASCIIZ )
+ {
+ int type = DBGetContactSettingByte((HANDLE)wp, IRCPROTONAME, "ChatRoom", 0);
+ if ( type != 0)
+ {
+ if (type == GCW_CHATROOM)
+ PostIrcMessage( "/PART %s", dbv.pszVal);
+
+ GCEVENT gce = {0};
+ GCDEST gcd = {0};
+ String S = "";
+ if(type == GCW_CHATROOM)
+ S = MakeWndID(dbv.pszVal);
+ if(type == GCW_SERVER)
+ S = "Network log";
+ gce.cbSize = sizeof(GCEVENT);
+ gcd.iType = GC_EVENT_CONTROL;
+ gcd.pszModule = IRCPROTONAME;
+ gce.pDest = &gcd;
+ gcd.pszID = (char *)S.c_str();
+ CallChatEvent( SESSION_TERMINATE, (LPARAM)&gce);
+ }
+ else
+ {
+ BYTE bDCC = DBGetContactSettingByte((HANDLE)wp, IRCPROTONAME, "DCC", 0) ;
+ if(bDCC)
+ {
+ CDccSession * dcc = g_ircSession.FindDCCSession((HANDLE)wp);
+ if(dcc)
+ dcc->Disconnect();
+ }
+ else
+ {
+ PostIrcMessage( "/WHOIS %s", dbv.pszVal);
+ whois_popup = true;
+ }
+ }
+ DBFreeVariant(&dbv);
+ }
+ return 0;
+}
+
+static int Service_Menu3Command(WPARAM wp, LPARAM lp)
+{
+ if (!wp )
+ return 0;
+ HANDLE hContact = (HANDLE) wp;
+ DBVARIANT dbv;
+ if (!DBGetContactSetting(hContact, IRCPROTONAME, "Nick", &dbv) && dbv.type == DBVT_ASCIIZ )
+ {
+ if (DBGetContactSettingByte((HANDLE)wp, IRCPROTONAME, "ChatRoom", 0) ==0)
+ {
+ char * host = NULL;
+ DBVARIANT dbv1;
+ if (!DBGetContactSetting((HANDLE) wp, IRCPROTONAME, "Host", &dbv1) && dbv1.type == DBVT_ASCIIZ) host = dbv1.pszVal;
+
+ if (host)
+ {
+ String S;
+ if(prefs->IgnoreChannelDefault)
+ S = "+qnidcm";
+ else
+ S = "+qnidc";
+ PostIrcMessage( "/IGNORE %%question=\"%s\",\"%s\",\"*!*@%s\" %s",Translate("Please enter the hostmask (nick!user@host) \nNOTE! Contacts on your contact list are never ignored"), Translate("Ignore"), host, S.c_str());
+
+ }
+
+ if (host)
+ DBFreeVariant(&dbv1);
+ }
+ else
+ {
+ PostIrcMessageWnd(dbv.pszVal, NULL, "/CHANNELMANAGER");
+ }
+ DBFreeVariant(&dbv);
+ }
+ return 0;
+}
+
+static int Service_JoinMenuCommand(WPARAM wp, LPARAM lp)
+{
+ if (!join_hWnd)
+ join_hWnd = CreateDialog(g_hInstance, MAKEINTRESOURCE(IDD_NICK), NULL, JoinWndProc);
+ SetDlgItemText(join_hWnd, IDC_CAPTION, Translate("Join channel"));
+ SetWindowText(GetDlgItem(join_hWnd, IDC_TEXT), Translate("Please enter a channel to join"));
+ SendMessage(GetDlgItem(join_hWnd, IDC_ENICK), EM_SETSEL, 0,MAKELPARAM(0,-1));
+ ShowWindow(join_hWnd, SW_SHOW);
+ SetActiveWindow(join_hWnd);
+ return 0;
+}
+
+static int Service_QuickConnectMenuCommand(WPARAM wp, LPARAM lp)
+{
+ if (!quickconn_hWnd)
+ quickconn_hWnd = CreateDialog(g_hInstance, MAKEINTRESOURCE(IDD_QUICKCONN), NULL, QuickWndProc);
+
+ SetWindowText(quickconn_hWnd, Translate("Quick connect"));
+ SetWindowText(GetDlgItem(quickconn_hWnd, IDC_TEXT), Translate("Please select IRC network and enter the password if needed"));
+ SetWindowText(GetDlgItem(quickconn_hWnd, IDC_CAPTION), Translate("Quick connect"));
+ SendMessage(quickconn_hWnd, WM_SETICON, ICON_BIG,(LPARAM)LoadIconEx(IDI_QUICK,"quick",GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON)));
+ ShowWindow(quickconn_hWnd, SW_SHOW);
+ SetActiveWindow(quickconn_hWnd);
+ return 0;
+}
+
+static int Service_ShowListMenuCommand(WPARAM wp, LPARAM lp)
+{
+ PostIrcMessage( "/LIST");
+ return 0;
+}
+
+static int Service_ShowServerMenuCommand(WPARAM wp, LPARAM lp)
+{
+ GCEVENT gce = {0};
+ GCDEST gcd = {0};
+ gcd.iType = GC_EVENT_CONTROL;
+ gcd.pszID = "Network log";
+ gcd.pszModule = IRCPROTONAME;
+ gce.cbSize = sizeof(GCEVENT);
+ gce.pDest = &gcd;
+ CallChatEvent( WINDOW_VISIBLE, (LPARAM)&gce);
+
+ return 0;
+}
+
+static int Service_ChangeNickMenuCommand(WPARAM wp, LPARAM lp)
+{
+ if (!nick_hWnd)
+ nick_hWnd = CreateDialog(g_hInstance,MAKEINTRESOURCE(IDD_NICK), NULL, NickWndProc);
+
+ SetDlgItemText(nick_hWnd, IDC_CAPTION, Translate("Change nick name"));
+ SetWindowText(GetDlgItem(nick_hWnd, IDC_TEXT), Translate("Please enter a unique nickname"));
+ SetWindowText(GetDlgItem(nick_hWnd, IDC_ENICK), g_ircSession.GetInfo().sNick.c_str());
+ SendMessage(GetDlgItem(nick_hWnd, IDC_ENICK), CB_SETEDITSEL, 0,MAKELPARAM(0,-1));
+ ShowWindow(nick_hWnd, SW_SHOW);
+ SetActiveWindow(nick_hWnd);
+
+ return 0;
+}
+
+static int Service_SetAvatarMenuCommand(WPARAM wp, LPARAM lp)
+{
+ char* szDest = (char*)SAFE_MALLOC(MAX_PATH+0x10);
+ char str[MAX_PATH];
+ char szFilter[512];
+ OPENFILENAME ofn = {0};
+
+ str[0] = 0;
+ CallService(MS_UTILS_GETBITMAPFILTERSTRINGS,sizeof(szFilter),(LPARAM)szFilter);
+ ofn.lStructSize = sizeof(OPENFILENAME);
+ ofn.lpstrFilter = szFilter;
+ ofn.lpstrFile = szDest;
+ ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
+ ofn.nMaxFile = MAX_PATH;
+ ofn.nMaxFileTitle = MAX_PATH;
+ ofn.lpstrDefExt = "jpg";
+ if(GetOpenFileName(&ofn))
+ Service_SetMyAvatar(NULL, (LPARAM)szDest);
+ else
+ Service_SetMyAvatar(NULL, NULL);
+
+ return 0;
+}
+
+static void DoChatFormatting(char * pszText)
+{
+ char * p1 = pszText;
+ int iFG = -1;
+ int iRemoveChars;
+ char InsertThis[50];
+
+ while(*p1 != '\0')
+ {
+ iRemoveChars = 0;
+ mir_snprintf(InsertThis, sizeof(InsertThis), "");
+
+ if (*p1 == '%')
+ {
+ switch (p1[1])
+ {
+ case 'B':
+ case 'b':
+ mir_snprintf(InsertThis, sizeof(InsertThis), "\002");
+ iRemoveChars = 2;
+ break;
+ case 'I':
+ case 'i':
+ mir_snprintf(InsertThis, sizeof(InsertThis), "\026");
+ iRemoveChars = 2;
+ break;
+ case 'U':
+ case 'u':
+ mir_snprintf(InsertThis, sizeof(InsertThis), "\037");
+ iRemoveChars = 2;
+ break;
+ case 'c':
+ {
+ char szTemp[3];
+ mir_snprintf(InsertThis, sizeof(InsertThis), "\003");
+
+ iRemoveChars = 2;
+
+ lstrcpyn(szTemp, p1 + 2, 3);
+ iFG = atoi(szTemp);
+ }break;
+ case 'C':
+ if(p1[2] =='%' && p1[3] == 'F')
+ {
+ mir_snprintf(InsertThis, sizeof(InsertThis), "\00399,99");
+ iRemoveChars = 4;
+ }
+ else
+ {
+ mir_snprintf(InsertThis, sizeof(InsertThis), "\00399");
+ iRemoveChars = 2;
+ }
+ iFG = -1;
+ break;
+ case 'f':
+ {
+ char szTemp[3];
+ if(p1 - 3 >= pszText && p1[-3] == '\003')
+ mir_snprintf(InsertThis, sizeof(InsertThis), ",");
+ else if( iFG >= 0 )
+ mir_snprintf(InsertThis, sizeof(InsertThis), "\003%u,", iFG);
+ else
+ mir_snprintf(InsertThis, sizeof(InsertThis), "\00399,");
+
+ iRemoveChars = 2;
+
+ lstrcpyn(szTemp, p1 + 2, 3);
+ }break;
+
+ case 'F':
+ if(iFG >= 0)
+ mir_snprintf(InsertThis, sizeof(InsertThis), "\003%u,99", iFG);
+ else
+ mir_snprintf(InsertThis, sizeof(InsertThis), "\00399,99");
+ iRemoveChars = 2;
+ break;
+
+ case '%':
+ mir_snprintf(InsertThis, sizeof(InsertThis), "%%");
+ iRemoveChars = 2;
+ break;
+ default:
+ iRemoveChars = 2;
+ break;
+
+ }
+ MoveMemory(p1 + lstrlen(InsertThis) , p1 + iRemoveChars, lstrlen(p1) - iRemoveChars +1);
+ CopyMemory(p1, InsertThis, lstrlen(InsertThis));
+ if(iRemoveChars || lstrlen(InsertThis))
+ p1 += lstrlen(InsertThis);
+ else
+ p1++;
+
+ }
+ else
+ p1++;
+
+ }
+
+
+}
+
+int Service_SendUserIsTyping(WPARAM wParam, LPARAM lParam)
+{
+ int nResult = 1;
+ HANDLE hContact = (HANDLE)wParam;
+
+ if (hContact && GlobalStatus != ID_STATUS_OFFLINE && DBGetContactSettingWord(hContact,IRCPROTONAME, "Status", ID_STATUS_OFFLINE) != ID_STATUS_OFFLINE && DBGetContactSettingByte(NULL,IRCPROTONAME, "TypingEnabled", 0))
+ {
+ switch (lParam)
+ {
+ case PROTOTYPE_SELFTYPING_ON:
+ sendTypingNotification(hContact, MTN_BEGUN);
+ nResult = 0;
+ break;
+
+ case PROTOTYPE_SELFTYPING_OFF:
+ sendTypingNotification(hContact, MTN_FINISHED);
+ nResult = 0;
+ break;
+
+ default:
+ break;
+ }
+ }
+ return nResult;
+}
+
+static int Service_SendNudge( WPARAM wParam, LPARAM lParam )
+{
+/*
+ DBVARIANT dbv;
+ DBCONTACTGETSETTING dcs;
+ dcs.szModule=IRCPROTONAME;
+ dcs.szSetting="Nick";
+ dcs.pValue=&dbv;
+ dbv.type=DBVT_ASCIIZ;
+ CallService(MS_DB_CONTACT_GETSETTING,(WPARAM)wParam,(LPARAM)&dcs);
+ if(ServiceExists(MS_NUDGE_SEND))
+ PostIrcMessage( "/PRIVMSG %s \001NUDGE\001", dbv.pszVal);
+ DBFreeVariant(&dbv);
+*/
+
+ if(ServiceExists(MS_NUDGE_SEND))
+ PostIrcMessage( "/PRIVMSG %s \001NUDGE\001", IRCGetContactSettingString((HANDLE)wParam, "Nick", ""));
+ return 0;
+}
+
+int Service_GCEventHook(WPARAM wParam,LPARAM lParam)
+{
+ GCHOOK *gchook= (GCHOOK*) lParam;
+ GCHOOK *gchtemp = NULL;
+ GCHOOK *gch = NULL;
+ String S = "";
+
+ EnterCriticalSection(&m_gchook);
+
+ // handle the hook
+ if(gchook)
+ {
+ if (!lstrcmpi(gchook->pDest->pszModule, IRCPROTONAME))
+ {
+
+ // first see if the scripting module should modify or stop this event
+ if(bMbotInstalled && prefs->ScriptingEnabled && wParam == NULL)
+ {
+ gchtemp = (GCHOOK *)mmi.mmi_malloc(sizeof(GCHOOK));
+ gchtemp->pDest = (GCDEST *)mmi.mmi_malloc(sizeof(GCDEST));
+ gchtemp->pDest->iType = gchook->pDest->iType;
+ gchtemp->dwData = gchook->dwData;
+
+ if(gchook->pDest->pszID)
+ {
+ char * pTemp = NULL;
+ gchtemp->pDest->pszID = (char *)mmi.mmi_malloc(lstrlen(gchook->pDest->pszID) + 1);
+ lstrcpyn(gchtemp->pDest->pszID, gchook->pDest->pszID, lstrlen(gchook->pDest->pszID) + 1);
+ pTemp = strchr(gchtemp->pDest->pszID, ' ');
+ if(pTemp)
+ *pTemp = '\0';
+
+ }else gchtemp->pDest->pszID = NULL;
+
+ if(gchook->pDest->pszModule)
+ {
+ gchtemp->pDest->pszModule = (char *)mmi.mmi_malloc(lstrlen(gchook->pDest->pszModule) + 1);
+ lstrcpyn(gchtemp->pDest->pszModule, gchook->pDest->pszModule, lstrlen(gchook->pDest->pszModule) + 1);
+ }else gchtemp->pDest->pszModule = NULL;
+
+ if(gchook->pszText)
+ {
+ gchtemp->pszText = (char *)mmi.mmi_malloc(lstrlen(gchook->pszText) + 1);
+ lstrcpyn(gchtemp->pszText, gchook->pszText, lstrlen(gchook->pszText) + 1);
+ }else gchtemp->pszText = NULL;
+
+ if(gchook->pszUID)
+ {
+ gchtemp->pszUID = (char *)mmi.mmi_malloc(lstrlen(gchook->pszUID) + 1);
+ lstrcpyn(gchtemp->pszUID, gchook->pszUID, lstrlen(gchook->pszUID) + 1);
+ }else gchtemp->pszUID = NULL;
+
+ if( Scripting_TriggerMSPGuiOut(gchtemp) && gchtemp)
+ gch = gchtemp;
+ else
+ gch = NULL;
+
+ }
+ else
+ gch = gchook;
+
+ if(gch)
+ {
+ char * p1 = new char[lstrlen(gch->pDest->pszID)+1];
+ lstrcpy(p1, gch->pDest->pszID);
+ char * p2 = strstr(p1, " - ");
+ if(p2)
+ {
+ *p2 = '\0';
+ }
+ switch (gch->pDest->iType)
+ {
+ case GC_SESSION_TERMINATE:
+ FreeWindowItemData(p1, (CHANNELINFO*)gch->dwData);
+ break;
+ case GC_USER_MESSAGE:
+ if(gch && gch->pszText && lstrlen(gch->pszText)> 0)
+ {
+ char * pszText = new char[lstrlen(gch->pszText)+1000];
+ lstrcpy(pszText, gch->pszText);
+ DoChatFormatting(pszText);
+ PostIrcMessageWnd(p1, NULL, pszText);
+ delete []pszText;
+ }
+ break;
+ case GC_USER_CHANMGR:
+ PostIrcMessageWnd(p1, NULL, "/CHANNELMANAGER");
+ break;
+ case GC_USER_PRIVMESS:
+ char szTemp[4000];
+ mir_snprintf(szTemp, sizeof(szTemp), "/QUERY %s", gch->pszUID);
+ PostIrcMessageWnd(p1, NULL, szTemp);
+ break;
+ case GC_USER_LOGMENU:
+ switch(gch->dwData)
+ {
+ case 1:
+ PostIrcMessageWnd(p1, NULL, "/CHANNELMANAGER");
+ break;
+ case 2:
+ {
+ PostIrcMessage( "/PART %s", p1);
+ GCEVENT gce = {0};
+ GCDEST gcd = {0};
+ S = MakeWndID(p1);
+ gce.cbSize = sizeof(GCEVENT);
+ gcd.iType = GC_EVENT_CONTROL;
+ gcd.pszModule = IRCPROTONAME;
+ gce.pDest = &gcd;
+ gcd.pszID = (char *)S.c_str();
+ CallChatEvent( SESSION_TERMINATE, (LPARAM)&gce);
+ }break;
+ case 3:
+ PostIrcMessageWnd(p1, NULL, "/SERVERSHOW");
+ break;
+ default:break;
+ }break;
+ case GC_USER_NICKLISTMENU:
+ switch(gch->dwData)
+ {
+ case 1:
+ PostIrcMessage( "/MODE %s +o %s", p1, gch->pszUID);
+ break;
+ case 2:
+ PostIrcMessage( "/MODE %s -o %s", p1, gch->pszUID);
+ break;
+ case 3:
+ PostIrcMessage( "/MODE %s +v %s", p1, gch->pszUID);
+ break;
+ case 4:
+ PostIrcMessage( "/MODE %s -v %s", p1, gch->pszUID);
+ break;
+ case 5:
+ PostIrcMessage( "/KICK %s %s", p1, gch->pszUID);
+ break;
+ case 6:
+ PostIrcMessage( "/KICK %s %s %%question=\"%s\",\"%s\",\"%s\"", p1, gch->pszUID, Translate("Please enter the reason"), Translate("Kick"), Translate("Jerk") );
+ break;
+ case 7:
+ DoUserhostWithReason(1, "B" + (String)p1, true, "%s", gch->pszUID);
+ break;
+ case 8:
+ DoUserhostWithReason(1, "K" + (String)p1, true, "%s", gch->pszUID);
+ break;
+ case 9:
+ DoUserhostWithReason(1, "L" + (String)p1, true, "%s", gch->pszUID);
+ break;
+ case 10:
+ PostIrcMessage( "/WHOIS %s", gch->pszUID);
+ break;
+// case 11:
+// DoUserhostWithReason(1, "I", true, "%s", gch->pszUID);
+// break;
+// case 12:
+// DoUserhostWithReason(1, "J", true, "%s", gch->pszUID);
+// break;
+ case 13:
+ PostIrcMessage( "/DCC CHAT %s", gch->pszUID);
+ break;
+ case 14:
+ PostIrcMessage( "/DCC SEND %s", gch->pszUID);
+ break;
+ case 15:
+ DoUserhostWithReason(1, "I", true, "%s", gch->pszUID);
+ break;
+ case 16:
+ PostIrcMessage( "/MODE %s +h %s", p1, gch->pszUID);
+ break;
+ case 17:
+ PostIrcMessage( "/MODE %s -h %s", p1, gch->pszUID);
+ break;
+ case 30:
+ {
+ PROTOSEARCHRESULT psr;
+ ZeroMemory(&psr, sizeof(psr));
+ psr.cbSize = sizeof(psr);
+ psr.nick = (char *)gch->pszUID;
+ ADDCONTACTSTRUCT acs;
+ ZeroMemory(&acs, sizeof(acs));
+ acs.handleType =HANDLE_SEARCHRESULT;
+ acs.szProto = IRCPROTONAME;
+ acs.psr = &psr;
+ CallService(MS_ADDCONTACT_SHOW, (WPARAM)NULL, (LPARAM)&acs);
+ }break;
+ break;
+ default:break;
+ }break;
+ default:break;
+ }
+
+ delete[]p1;
+ }
+ }
+
+ }
+ if (gchtemp)
+ {
+ if(gchtemp->pszUID)
+ mmi.mmi_free(gchtemp->pszUID);
+ if(gchtemp->pszText)
+ mmi.mmi_free(gchtemp->pszText);
+ if(gchtemp->pDest->pszID)
+ mmi.mmi_free(gchtemp->pDest->pszID);
+ if(gchtemp->pDest->pszModule)
+ mmi.mmi_free(gchtemp->pDest->pszModule);
+ mmi.mmi_free(gchtemp->pDest);
+ mmi.mmi_free(gchtemp);
+ }
+ LeaveCriticalSection(&m_gchook);
+ return 0;
+}
+
+static int Service_GCMenuHook(WPARAM wParam,LPARAM lParam)
+{
+ GCMENUITEMS *gcmi= (GCMENUITEMS*) lParam;
+ if(gcmi)
+ {
+ if (!lstrcmpi(gcmi->pszModule, IRCPROTONAME))
+ {
+ if(gcmi->Type == MENU_ON_LOG)
+ {
+ if(lstrcmpi(gcmi->pszID, "Network log"))
+ {
+ static struct gc_item Item[] = {
+ {Translate("Channel &settings"), 1, MENU_ITEM, FALSE},
+ {Translate("&Leave the channel"), 2, MENU_ITEM, FALSE},
+ {Translate("Show the server &window"), 3, MENU_ITEM, FALSE}};
+ gcmi->nItems = sizeof(Item)/sizeof(Item[0]);
+ gcmi->Item = &Item[0];
+ }
+ else
+ gcmi->nItems = 0;
+ }
+ if(gcmi->Type == MENU_ON_NICKLIST)
+ {
+ struct CONTACT_TYPE user ={(char *)gcmi->pszUID, NULL, NULL, false, false, false};
+ HANDLE hContact = CList_FindContact(&user);
+ BOOL bFlag = FALSE;
+
+ if (hContact && DBGetContactSettingByte(hContact,"CList", "NotOnList", 0) == 0)
+ bFlag = TRUE;
+
+ static struct gc_item Item[] = {
+ {Translate("&WhoIs info"), 10, MENU_ITEM, FALSE},
+ {Translate("&Control"), 0, MENU_NEWPOPUP, FALSE},
+ {Translate("Give &Op"), 1, MENU_POPUPITEM, FALSE},
+ {Translate("Take O&p"), 2, MENU_POPUPITEM, FALSE},
+ {Translate("Give &Halfop"), 16, MENU_POPUPITEM, FALSE},
+ {Translate("Take H&alfop"), 17, MENU_POPUPITEM, FALSE},
+ {Translate("Give &Voice"), 3, MENU_POPUPITEM, FALSE},
+ {Translate("Take V&oice"), 4, MENU_POPUPITEM, FALSE},
+ {"", 0, MENU_POPUPSEPARATOR, FALSE},
+ {Translate("&Kick"), 5, MENU_POPUPITEM, FALSE},
+ {Translate("Ki&ck (reason)"), 6, MENU_POPUPITEM, FALSE},
+ {Translate("&Ban"), 7, MENU_POPUPITEM, FALSE},
+ {Translate("Ban'&n kick"), 8, MENU_POPUPITEM, FALSE},
+ {Translate("Ban'n kick (&reason)"), 9, MENU_POPUPITEM, FALSE},
+ {Translate("&Direct Connection"), 0, MENU_NEWPOPUP, FALSE},
+ {Translate("Request &Chat"), 13, MENU_POPUPITEM, FALSE},
+ {Translate("Send &File"), 14, MENU_POPUPITEM, FALSE},
+ {Translate("Add to &ignore list"), 15, MENU_ITEM, FALSE},
+ {"", 12, MENU_SEPARATOR, FALSE},
+ {Translate("&Add User"), 30, MENU_ITEM, bFlag}
+ };
+ gcmi->nItems = sizeof(Item)/sizeof(Item[0]);
+ gcmi->Item = &Item[0];
+ gcmi->Item[gcmi->nItems-1].bDisabled = bFlag;
+
+ unsigned long ulAdr = 0;
+ if (prefs->ManualHost)
+ ulAdr = ConvertIPToInteger(prefs->MySpecifiedHostIP);
+ else
+ ulAdr = ConvertIPToInteger(prefs->IPFromServer?prefs->MyHost:prefs->MyLocalHost);
+
+ bool bDcc = ulAdr == 0 ?false:true;
+
+ gcmi->Item[14].bDisabled = !bDcc;
+ gcmi->Item[15].bDisabled = !bDcc;
+ gcmi->Item[16].bDisabled = !bDcc;
+
+ bool bHalfop = strchr(sUserModes.c_str(), 'h') == NULL?false:true;
+ gcmi->Item[5].bDisabled = !bHalfop;
+ gcmi->Item[4].bDisabled = !bHalfop;
+
+ }
+ }
+ }
+ return 0;
+}
+
+static int Service_SystemPreShutdown(WPARAM wParam,LPARAM lParam)
+{
+
+ EnterCriticalSection(&cs);
+
+ if (prefs->Perform && g_ircSession)
+ {
+ if(DoPerform("Event: Disconnect"))
+ Sleep(200);
+ }
+
+ g_ircSession.DisconnectAllDCCSessions(true);
+
+ if (g_ircSession)
+ g_ircSession.Disconnect();
+ if (list_hWnd)
+ SendMessage(list_hWnd, WM_CLOSE, 0, 0);
+ if (nick_hWnd)
+ SendMessage(nick_hWnd, WM_CLOSE, 0, 0);
+ if (join_hWnd)
+ SendMessage(join_hWnd, WM_CLOSE, 0, 0);
+ LeaveCriticalSection(&cs);
+
+ return 0;
+}
+
+static int Service_MenuPreBuild(WPARAM wParam,LPARAM lParam)
+{
+ DBVARIANT dbv;
+ char *szProto;
+ CLISTMENUITEM clmi;
+ HANDLE hContact = (HANDLE) wParam;
+
+ if (!hContact)
+ return 0;
+ memset( &clmi, 0, sizeof( clmi ));
+ clmi.cbSize = sizeof( clmi );
+ clmi.flags = CMIM_FLAGS|CMIM_NAME|CMIM_ICON;
+
+ szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) wParam, 0);
+ if (szProto && !lstrcmpi(szProto, IRCPROTONAME))
+ {
+ if(DBGetContactSettingByte(hContact, IRCPROTONAME, "ChatRoom", 0) == GCW_CHATROOM)
+ {
+ clmi.hIcon = LoadIconEx(IDI_PART,"part",GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON));
+ clmi.pszName = Translate("&Leave channel");
+ CallService( MS_CLIST_MODIFYMENUITEM, ( WPARAM )hContactMenu2, ( LPARAM )&clmi );
+
+ clmi.hIcon = LoadIconEx(IDI_MANAGER,"manager",GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON));
+ clmi.pszName = Translate("Channel &settings");
+ CallService( MS_CLIST_MODIFYMENUITEM, ( WPARAM )hContactMenu3, ( LPARAM )&clmi );
+
+ clmi.hIcon = LoadIconEx(IDI_SHOW,"show",GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON));
+ clmi.pszName = Translate("&Show channel");
+ CallService( MS_CLIST_MODIFYMENUITEM, ( WPARAM )hContactMenu1, ( LPARAM )&clmi );
+
+ }
+ else if(DBGetContactSettingByte(hContact, IRCPROTONAME, "ChatRoom", 0) == GCW_SERVER)
+ {
+ clmi.hIcon = LoadIconEx(IDI_SERVER,"server",GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON));
+ clmi.pszName = Translate("&Show server");
+ CallService( MS_CLIST_MODIFYMENUITEM, ( WPARAM )hContactMenu1, ( LPARAM )&clmi );
+
+ clmi.flags = CMIM_FLAGS|CMIF_HIDDEN;
+ CallService( MS_CLIST_MODIFYMENUITEM, ( WPARAM )hContactMenu2, ( LPARAM )&clmi );
+ CallService( MS_CLIST_MODIFYMENUITEM, ( WPARAM )hContactMenu3, ( LPARAM )&clmi );
+
+
+ }
+ else if (!DBGetContactSetting((void *)wParam, IRCPROTONAME, "Default", &dbv)&& dbv.type == DBVT_ASCIIZ)
+ {
+ BYTE bDcc = DBGetContactSettingByte((HANDLE) wParam, IRCPROTONAME, "DCC", 0) ;
+
+ clmi.flags = CMIM_FLAGS|CMIF_HIDDEN;
+
+ CallService( MS_CLIST_MODIFYMENUITEM, ( WPARAM )hContactMenu1, ( LPARAM )&clmi );
+ clmi.flags = CMIM_NAME|CMIM_ICON | CMIM_FLAGS;
+
+ if(bDcc)
+ {
+ if(DBGetContactSettingWord((void *)wParam, IRCPROTONAME, "Status", ID_STATUS_OFFLINE) == ID_STATUS_OFFLINE)
+ clmi.flags = CMIM_NAME|CMIM_ICON | CMIM_FLAGS |CMIF_HIDDEN;
+ clmi.hIcon = LoadIconEx(IDI_DELETE,"delete",GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON));
+ clmi.pszName = Translate("Di&sconnect");
+ CallService( MS_CLIST_MODIFYMENUITEM, ( WPARAM )hContactMenu2, ( LPARAM )&clmi );
+ }
+ else
+ {
+ if(!g_ircSession)
+ clmi.flags = CMIM_NAME|CMIM_ICON | CMIM_FLAGS |CMIF_HIDDEN;
+ clmi.hIcon = LoadIconEx(IDI_WHOIS,"whois",GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON));
+ clmi.pszName = Translate("&WhoIs info");
+ CallService( MS_CLIST_MODIFYMENUITEM, ( WPARAM )hContactMenu2, ( LPARAM )&clmi );
+
+ }
+
+ if(!g_ircSession || bDcc)
+ clmi.flags = CMIM_NAME|CMIM_ICON | CMIM_FLAGS |CMIF_HIDDEN;
+ else
+ clmi.flags = CMIM_NAME|CMIM_ICON | CMIM_FLAGS;
+
+ clmi.hIcon = LoadIconEx(IDI_BLOCK,"block",GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON));
+ if (DBGetContactSettingWord((HANDLE)wParam, IRCPROTONAME, "Status", ID_STATUS_OFFLINE) !=ID_STATUS_OFFLINE)
+ {
+ char * host = NULL;
+ DBVARIANT dbv3;
+ if (!DBGetContactSetting((HANDLE) wParam, IRCPROTONAME, "Host", &dbv3) && dbv3.type == DBVT_ASCIIZ) host = dbv3.pszVal;
+
+ if (host)
+ {
+ clmi.pszName = Translate("&Add to ignore list");
+ }
+ else
+ clmi.flags = CMIM_NAME|CMIM_ICON | CMIM_FLAGS |CMIF_HIDDEN;
+
+ if (host)
+ DBFreeVariant(&dbv3);
+
+ }
+ else
+ clmi.flags = CMIM_NAME|CMIM_ICON | CMIM_FLAGS |CMIF_HIDDEN;
+ CallService( MS_CLIST_MODIFYMENUITEM, ( WPARAM )hContactMenu3, ( LPARAM )&clmi );
+ DBFreeVariant(&dbv);
+ }
+
+ }
+
+ return 0;
+}
+
+static int Service_GetCaps(WPARAM wParam,LPARAM lParam)
+{
+ if(wParam==PFLAGNUM_1)
+ return PF1_BASICSEARCH | PF1_MODEMSG | PF1_FILE |PF1_CANRENAMEFILE | PF1_PEER2PEER | PF1_IM;
+ if(wParam==PFLAGNUM_2)
+ return PF2_ONLINE|PF2_SHORTAWAY;
+ if(wParam==PFLAGNUM_3)
+ return PF2_SHORTAWAY;
+ if(wParam==PFLAGNUM_4)
+ return PF4_NOCUSTOMAUTH | PF4_SUPPORTTYPING;
+ if(wParam==PFLAG_UNIQUEIDTEXT)
+ return (int) Translate("Nickname");
+ if(wParam==PFLAG_MAXLENOFMESSAGE)
+ return 400;
+ if(wParam==PFLAG_UNIQUEIDSETTING)
+ return (int) "Default";
+return 0;
+}
+
+static int Service_GetName(WPARAM wParam,LPARAM lParam)
+{
+ lstrcpyn((char *) lParam, ALTIRCPROTONAME, wParam);
+ return 0;
+}
+
+static int Service_LoadIcon(WPARAM wParam,LPARAM lParam)
+{
+
+ switch(wParam&0xFFFF) {
+ case PLI_PROTOCOL:
+ return (int)LoadImage(g_hInstance,MAKEINTRESOURCE(IDI_MAIN),IMAGE_ICON,16,16,LR_SHARED);
+ default: return (int)(HICON)NULL;
+ }
+ return 0;
+}
+
+static void __cdecl AckBasicSearch(void * pszNick)
+{
+ PROTOSEARCHRESULT psr;
+ ZeroMemory(&psr, sizeof(psr));
+ psr.cbSize = sizeof(psr);
+ psr.nick = (char *)pszNick;
+ ProtoBroadcastAck(IRCPROTONAME, NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE) 1, (LPARAM) & psr);
+ ProtoBroadcastAck(IRCPROTONAME, NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE) 1, 0);
+}
+
+static int Service_BasicSearch(WPARAM wParam,LPARAM lParam)
+{
+ static char buf[50];
+ if (lParam) {
+ lstrcpyn(buf, (const char *)lParam, 50);
+ if (OldStatus != ID_STATUS_OFFLINE && OldStatus != ID_STATUS_CONNECTING
+ && lstrlen(buf) >0 && !IsChannel(buf))
+ {
+ forkthread(AckBasicSearch, 0, &buf );
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static int Service_AddToList(WPARAM wParam,LPARAM lParam)
+{
+ HANDLE hContact;
+ PROTOSEARCHRESULT *psr = (PROTOSEARCHRESULT *) lParam;
+ CONTACT user ={(char *)psr->nick, NULL, NULL, true, false, false};
+
+ if (OldStatus == ID_STATUS_OFFLINE || OldStatus == ID_STATUS_CONNECTING)
+ return 0;
+ hContact = CList_AddContact(&user, true, false);
+
+ if (hContact)
+ {
+ DBVARIANT dbv1;
+
+ if(DBGetContactSettingByte(hContact, IRCPROTONAME, "AdvancedMode", 0) == 0)
+ DoUserhostWithReason(1, ((String)"S" + psr->nick).c_str(), true, psr->nick);
+ else
+ {
+ if (!DBGetContactSetting(hContact, IRCPROTONAME, "UWildcard", &dbv1) && dbv1.type == DBVT_ASCIIZ)
+ {
+ DoUserhostWithReason(2, ((String)"S" + dbv1.pszVal).c_str(), true, dbv1.pszVal);
+ DBFreeVariant(&dbv1);
+ }
+ else
+ {
+ DoUserhostWithReason(2, ((String)"S" + psr->nick).c_str(), true, psr->nick);
+ }
+ }
+
+ }
+ return (int) hContact;
+}
+
+static void __cdecl ConnectServerThread(LPVOID di)
+{
+ EnterCriticalSection(&cs);
+ InterlockedIncrement((volatile long *) &bConnectThreadRunning);
+ InterlockedIncrement((volatile long *) &bConnectRequested);
+ while ( !Miranda_Terminated() && bConnectRequested > 0 )
+ {
+ while(bConnectRequested > 0)
+ InterlockedDecrement((volatile long *) &bConnectRequested);
+ if (g_ircSession)
+ {
+ Sleep(200);
+ g_ircSession.Disconnect();
+ }
+ g_ircSession.GetInfo().bNickFlag = false;
+ int Temp = OldStatus;
+ OldStatus = ID_STATUS_CONNECTING;
+ nickflag = false;
+ ProtoBroadcastAck(IRCPROTONAME,NULL,ACKTYPE_STATUS,ACKRESULT_SUCCESS,(HANDLE)Temp,ID_STATUS_CONNECTING);
+ Sleep(100);
+ g_ircSession.Connect(si);
+ if (g_ircSession)
+ {
+
+ KillChatTimer(RetryTimer);
+
+ if(lstrlen(prefs->MySpecifiedHost))
+ {
+ IPRESOLVE * ipr = new IPRESOLVE;
+ ipr->iType = IP_MANUAL;
+ ipr->pszAdr = prefs->MySpecifiedHost;
+ forkthread(ResolveIPThread, NULL, ipr);
+ }
+ }
+ else
+ {
+ Temp = OldStatus;
+ OldStatus = ID_STATUS_OFFLINE;
+ ProtoBroadcastAck(IRCPROTONAME,NULL,ACKTYPE_STATUS,ACKRESULT_SUCCESS,(HANDLE)Temp,ID_STATUS_OFFLINE);
+ Sleep(100);
+ }
+ }
+ InterlockedDecrement((volatile long *) &bConnectThreadRunning);
+ LeaveCriticalSection(&cs);
+ return;
+}
+
+static void __cdecl DisconnectServerThread(LPVOID di)
+{
+ EnterCriticalSection(&cs);
+ KillChatTimer(RetryTimer);
+ if (g_ircSession)
+ g_ircSession.Disconnect();
+ LeaveCriticalSection(&cs);
+ return;
+}
+
+void ConnectToServer(void)
+{
+ PortCount= StrToInt(prefs->PortStart);
+ si.sServer = GetWord(prefs->ServerName, 0);
+ si.iPort = PortCount;
+ si.sNick = prefs->Nick;
+ si.sUserID = prefs->UserID;
+ si.sFullName = prefs->Name;
+ si.sPassword = prefs->Password;
+ si.bIdentServer = ((prefs->Ident) ? (true) : (false));
+ si.iIdentServerPort = StrToInt(prefs->IdentPort);
+ si.sIdentServerType = prefs->IdentSystem;
+ si.sNetwork = prefs->Network;
+ si.iSSL = prefs->iSSL;
+ RetryCount = 1;
+ KillChatTimer(RetryTimer);
+ if (prefs->Retry)
+ {
+ if (StrToInt(prefs->RetryWait)<10)
+ lstrcpy(prefs->RetryWait, "10");
+ SetChatTimer(RetryTimer, StrToInt(prefs->RetryWait)*1000, RetryTimerProc);
+ }
+ bPerformDone = false;
+ bTempDisableCheck = false;
+ bTempForceCheck = false;
+ iTempCheckTime = 0;
+ sChannelPrefixes = "&#";
+ sUserModes = "ov";
+ sUserModePrefixes = "@+";
+ sChannelModes = "btnimklps";
+
+
+ if (!bConnectThreadRunning)
+ {
+ forkthread(ConnectServerThread, 0, NULL );
+ }
+ else if (bConnectRequested < 1)
+ InterlockedIncrement((volatile long *) &bConnectRequested);
+
+ char szTemp[300];
+ mir_snprintf(szTemp, sizeof(szTemp), "\0033%s \002%s\002 (%s: %u)", Translate("Connecting to"), si.sNetwork.c_str(), si.sServer.c_str(), si.iPort);
+ DoEvent(GC_EVENT_INFORMATION, "Network log", NULL, szTemp, NULL, NULL, NULL, true, false);
+
+ return;
+}
+
+void DisconnectFromServer(void)
+{
+ GCEVENT gce = {0};
+ GCDEST gcd = {0};
+
+ if (prefs->Perform && g_ircSession) {
+ DoPerform("Event: Disconnect");
+ }
+
+ gcd.iType = GC_EVENT_CONTROL;
+ gcd.pszID = NULL; // all windows
+ gcd.pszModule = IRCPROTONAME;
+ gce.cbSize = sizeof(GCEVENT);
+ gce.pDest = &gcd;
+
+ CallChatEvent( SESSION_TERMINATE, (LPARAM)&gce);
+ forkthread(DisconnectServerThread, 0, NULL );
+
+ return;
+}
+
+static int Service_SetStatus(WPARAM wParam,LPARAM lParam)
+{
+
+ if (!bChatInstalled)
+ {
+ MIRANDASYSTRAYNOTIFY msn;
+ msn.cbSize = sizeof(MIRANDASYSTRAYNOTIFY);
+ msn.szProto = IRCPROTONAME;
+ msn.szInfoTitle = Translate("Information");
+ msn.szInfo = Translate("This protocol is dependent on another plugin named \'Chat\'\nPlease download it from the Miranda IM website!");
+ msn.dwInfoFlags = NIIF_ERROR;
+ msn.uTimeout = 15000;
+ CallService(MS_CLIST_SYSTRAY_NOTIFY, (WPARAM)NULL,(LPARAM) &msn);
+ return 0;
+ }
+ if (wParam != ID_STATUS_OFFLINE && lstrlen(prefs->Network) <1)
+ {
+ if (lstrlen(prefs->Nick) > 0 && !prefs->DisableDefaultServer)
+ {
+ HWND hwnd=CreateDialog(g_hInstance,MAKEINTRESOURCE(IDD_QUICKCONN),NULL,QuickWndProc);
+ SetWindowText(hwnd, "Miranda IRC");
+ SetWindowText(GetDlgItem(hwnd, IDC_TEXT), Translate("Please choose an IRC-network to go online. This network will be the default."));
+ SetWindowText(GetDlgItem(hwnd, IDC_CAPTION), Translate("Default network"));
+ HICON hIcon = LoadIconEx(IDI_MAIN,"main",GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON));
+ SendMessage(hwnd, WM_SETICON, ICON_BIG,(LPARAM)hIcon);
+ ShowWindow(hwnd, SW_SHOW);
+ SetActiveWindow(hwnd);
+ }
+ return 0;
+ }
+ if (wParam != ID_STATUS_OFFLINE && (lstrlen(prefs->Nick) <1 || lstrlen(prefs->UserID) < 1 || lstrlen(prefs->Name) < 1))
+ {
+ MIRANDASYSTRAYNOTIFY msn;
+ msn.cbSize = sizeof(MIRANDASYSTRAYNOTIFY);
+ msn.szProto = IRCPROTONAME;
+ msn.szInfoTitle = Translate("IRC error");
+ msn.szInfo = Translate("Connection can not be established! You have not completed all necessary fields (Nickname, User ID and Name)." );
+ msn.dwInfoFlags = NIIF_ERROR;
+ msn.uTimeout = 15000;
+ CallService(MS_CLIST_SYSTRAY_NOTIFY, (WPARAM)NULL,(LPARAM) &msn);
+ return 0;
+ }
+ if (wParam == ID_STATUS_FREECHAT && prefs->Perform && g_ircSession)
+ DoPerform("Event: Free for chat" );
+ if (wParam == ID_STATUS_ONTHEPHONE && prefs->Perform && g_ircSession)
+ DoPerform("Event: On the phone");
+ if (wParam == ID_STATUS_OUTTOLUNCH && prefs->Perform && g_ircSession)
+ DoPerform("Event: Out for lunch");
+ if (wParam == ID_STATUS_ONLINE && prefs->Perform && g_ircSession && (GlobalStatus ==ID_STATUS_ONTHEPHONE ||GlobalStatus ==ID_STATUS_OUTTOLUNCH) && OldStatus !=ID_STATUS_AWAY)
+ DoPerform("Event: Available" );
+ if (lParam != 1)
+ GlobalStatus = wParam;
+
+ // clear custom status on status change
+ if (wParam != OldStatus)
+ if (IRCGetContactSettingByte(NULL, "XStatusReset", DEFAULT_XSTATUS_RESET))
+ IRCSetXStatus(0, 0);
+
+ if ((wParam == ID_STATUS_ONLINE || wParam == ID_STATUS_AWAY || wParam == ID_STATUS_FREECHAT) && !g_ircSession ) //go from offline to online
+ ConnectToServer();
+ else if ((wParam == ID_STATUS_ONLINE || wParam == ID_STATUS_FREECHAT) && g_ircSession && OldStatus == ID_STATUS_AWAY) //go to online while connected
+ {
+ StatusMessage = "";
+ PostIrcMessage( "/AWAY");
+ return 0;
+ }
+ else if (wParam == ID_STATUS_OFFLINE && g_ircSession) //go from online/away to offline
+ DisconnectFromServer();
+ else if (wParam == ID_STATUS_OFFLINE && !g_ircSession) //offline to offline
+ {
+ KillChatTimer( RetryTimer);
+ return 0;
+ }
+ else if (wParam == ID_STATUS_AWAY && g_ircSession) //go to away while connected
+ return 0;
+ else if (wParam == ID_STATUS_ONLINE && g_ircSession) //already online
+ return 0;
+ else
+ Service_SetStatus(ID_STATUS_AWAY, 1);
+ return 0;
+}
+
+static int Service_GetStatus(WPARAM wParam,LPARAM lParam)
+{
+ if (OldStatus == ID_STATUS_CONNECTING)
+ return ID_STATUS_CONNECTING;
+ else if (g_ircSession && OldStatus == ID_STATUS_ONLINE)
+ return ID_STATUS_ONLINE;
+ else if (g_ircSession && OldStatus == ID_STATUS_AWAY)
+ return ID_STATUS_AWAY;
+ else
+ return ID_STATUS_OFFLINE;
+}
+
+static int Service_SetAwayMsg(WPARAM wParam, LPARAM lParam)
+{
+ if (wParam != ID_STATUS_ONLINE && wParam != ID_STATUS_INVISIBLE && wParam != ID_STATUS_FREECHAT && wParam != ID_STATUS_CONNECTING && wParam != ID_STATUS_OFFLINE)
+ {
+ if (StatusMessage == "" || lParam == NULL || StatusMessage != ReplaceString((char *)lParam, "\r\n", " ") )
+ {
+ if(lParam == NULL || *(char*)lParam == '\0')
+ StatusMessage = STR_AWAYMESSAGE;
+ else
+ StatusMessage = ReplaceString((char *)lParam, "\r\n", " ");
+
+ PostIrcMessage( "/AWAY %s", (StatusMessage.substr(0,450)).c_str());
+ }
+ }
+ return 0;
+}
+
+static int Service_AddIncMessToDB(WPARAM wParam, LPARAM lParam)
+{
+ DBEVENTINFO dbei;
+ CCSDATA *ccs = (CCSDATA *) lParam;
+ PROTORECVEVENT *pre = (PROTORECVEVENT *) ccs->lParam;
+
+ DBDeleteContactSetting(ccs->hContact, "CList", "Hidden");
+ ZeroMemory(&dbei, sizeof(dbei));
+ dbei.cbSize = sizeof(dbei);
+ dbei.szModule = IRCPROTONAME;
+ dbei.timestamp = pre->timestamp;
+ dbei.flags = pre->flags & (PREF_CREATEREAD ? DBEF_READ : 0);
+ dbei.eventType = EVENTTYPE_MESSAGE;
+ dbei.cbBlob = strlen(pre->szMessage) + 1;
+ dbei.pBlob = (PBYTE) pre->szMessage;
+ CallService(MS_DB_EVENT_ADD, (WPARAM) ccs->hContact, (LPARAM) & dbei);
+ return 0;
+}
+
+static void __cdecl AckMessageFail(void * lParam)
+{
+ ProtoBroadcastAck(IRCPROTONAME, (void*)lParam, ACKTYPE_MESSAGE, ACKRESULT_FAILED, (HANDLE) 1, (LONG)Translate("The protocol is not online"));
+}
+
+static void __cdecl AckMessageFailDcc(void * lParam)
+{
+ ProtoBroadcastAck(IRCPROTONAME, (void*)lParam, ACKTYPE_MESSAGE, ACKRESULT_FAILED, (HANDLE) 1, (LONG)Translate("The dcc chat connection is not active"));
+}
+
+static void __cdecl AckMessageSuccess(void * lParam)
+{
+ ProtoBroadcastAck(IRCPROTONAME, (void*)lParam, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, (HANDLE) 1, 0);
+}
+
+static int Service_GetMessFromSRMM(WPARAM wParam, LPARAM lParam)
+{
+ CCSDATA *ccs = (CCSDATA *) lParam;
+
+ BYTE bDcc = DBGetContactSettingByte(ccs->hContact, IRCPROTONAME, "DCC", 0) ;
+ WORD wStatus = DBGetContactSettingWord(ccs->hContact, IRCPROTONAME, "Status", ID_STATUS_OFFLINE) ;
+ if (OldStatus !=ID_STATUS_OFFLINE && OldStatus !=ID_STATUS_CONNECTING && !bDcc || bDcc && wStatus == ID_STATUS_ONLINE) {
+ PostIrcMessageWnd(NULL, ccs->hContact, (char *) ccs->lParam);
+ forkthread(AckMessageSuccess, 0, ccs->hContact);
+ }
+ else
+ {
+ if(bDcc)
+ forkthread(AckMessageFailDcc, 0, ccs->hContact);
+ else
+ forkthread(AckMessageFail, 0, ccs->hContact);
+ }
+
+ return 1;
+}
+
+static int Service_GetAwayMessage(WPARAM wParam, LPARAM lParam)
+{
+ CCSDATA *ccs = (CCSDATA *) lParam;
+ WhoisAwayReply = "";
+ DBVARIANT dbv;
+
+ // bypass chat contacts.
+ if(DBGetContactSettingByte(ccs->hContact, IRCPROTONAME, "ChatRoom", 0) == 0)
+
+ if (ccs->hContact && !DBGetContactSetting(ccs->hContact, IRCPROTONAME, "Nick", &dbv) && dbv.type == DBVT_ASCIIZ )
+ {
+ int i = DBGetContactSettingWord(ccs->hContact,IRCPROTONAME, "Status", ID_STATUS_OFFLINE);
+
+// if ( i != ID_STATUS_OFFLINE)
+// {
+// if(DBGetContactSettingByte(NULL,IRCPROTONAME, "XStatusEnabled", 0) && DBGetContactSettingByte(NULL,IRCPROTONAME, "XStatusAuto", 0))
+// if(strcmp(UniGetContactSettingUtf(ccs->hContact,IRCPROTONAME, "MirVer", ""), "Miranda"))
+// {
+// #ifdef _DEBUG
+// DBGprintf("XSTATUS REQUESTED from %s\n", dbv.pszVal);
+// #endif
+// PostIrcMessage( "/PRIVMSG %s \001XSTATUS\001", dbv.pszVal);
+// }
+// }
+
+ if ( i != ID_STATUS_AWAY)
+ {
+ DBFreeVariant( &dbv);
+ return 0;
+ }
+
+ whois_popup = false;
+ String S="WHOIS " + (String)dbv.pszVal ;
+ if (g_ircSession)
+ g_ircSession << CIrcMessage(S.c_str(), false, false);
+ DBFreeVariant( &dbv);
+ }
+
+ return 1;
+}
+
+static int Service_InitUserInfo(WPARAM wParam, LPARAM lParam)
+{
+ char *szProto;
+ szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, lParam, 0);
+ DBVARIANT dbv;
+ HANDLE hContact = (HANDLE) lParam;
+ if (!hContact || !szProto || lstrcmpi(szProto, IRCPROTONAME))
+ {
+ return 0;
+ }
+ if(DBGetContactSettingByte(hContact, IRCPROTONAME, "ChatRoom", 0) != 0)
+ return 0;
+ if(DBGetContactSettingByte(hContact, IRCPROTONAME, "DCC", 0) != 0)
+ return 0;
+
+ if (!DBGetContactSetting(hContact, IRCPROTONAME, "Default", &dbv) && dbv.type == DBVT_ASCIIZ)
+ {
+ if (IsChannel(dbv.pszVal))
+ {
+ DBFreeVariant(&dbv);
+ return 0;
+ }
+ DBFreeVariant(&dbv);
+ }
+
+ OPTIONSDIALOGPAGE odp;
+ odp.cbSize = sizeof(odp);
+ odp.pszTitle = ALTIRCPROTONAME;
+ odp.hIcon = NULL;
+ odp.hInstance = g_hInstance;
+ odp.position = -1900000000;
+ odp.pfnDlgProc = UserDetailsDlgProc;
+ odp.pszTemplate = MAKEINTRESOURCE(IDD_USERINFO);
+ odp.pszTitle = ALTIRCPROTONAME;
+ CallService(MS_USERINFO_ADDPAGE, wParam, (LPARAM) & odp);
+ return 0;
+}
+
+static void CListShowMenuItem(HANDLE hMenuItem, BYTE bShow)
+{
+ CLISTMENUITEM mi = {0};
+
+ mi.cbSize = sizeof(mi);
+// Menu modification
+ if (bShow || !prefs->XStatusAuto)
+ mi.flags = CMIM_FLAGS;
+ else
+ mi.flags = CMIM_FLAGS | CMIF_HIDDEN;
+
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuItem, (LPARAM)&mi);
+}
+
+static void CListSetMenuItemIcon(HANDLE hMenuItem, HICON hIcon)
+{
+ CLISTMENUITEM mi = {0};
+
+ mi.cbSize = sizeof(mi);
+ mi.flags = CMIM_FLAGS | CMIM_ICON;
+
+ mi.hIcon = hIcon;
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuItem, (LPARAM)&mi);
+}
+
+static int PrebuildContactMenu(WPARAM wParam, LPARAM lParam)
+{
+ BYTE bXStatus;
+
+// if(IRCGetContactSettingByte((HANDLE)wParam, "ChatRoom", 0) != 0)
+// {
+// CListShowMenuItem(hUserMenuXStatus, 0);
+// return 0;
+// }
+
+ bXStatus = IRCGetContactSettingByte((HANDLE)wParam, DBSETTING_XSTATUSID, 0);
+ CListShowMenuItem(hUserMenuXStatus, bXStatus);
+ if (bXStatus)
+ {
+ HICON iXStatus = GetXStatusIcon(bXStatus);
+ CListSetMenuItemIcon(hUserMenuXStatus, iXStatus);
+
+ if (iXStatus && !IconLibInstalled())
+ DestroyIcon(iXStatus); // release icon
+ }
+
+ return 0;
+}
+
+static int IconLibIconsChanged(WPARAM wParam, LPARAM lParam)
+{
+ CListSetMenuItemIcon(hMenuQuick, IconLibProcess(LoadIconEx(IDI_QUICK,"quick",GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON)), "quick"));
+ CListSetMenuItemIcon(hMenuJoin, IconLibProcess(LoadIconEx(IDI_JOIN,"join",GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON)), "join"));
+ CListSetMenuItemIcon(hMenuNick, IconLibProcess(LoadIconEx(IDI_WHOIS,"whois",GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON)), "whois"));
+ CListSetMenuItemIcon(hMenuList, IconLibProcess(LoadIconEx(IDI_LIST,"list",GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON)), "list"));
+ CListSetMenuItemIcon(hMenuServer, IconLibProcess(LoadIconEx(IDI_SERVER,"server",GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON)), "server"));
+ CListSetMenuItemIcon(hMenuAvatar, IconLibProcess(LoadIconEx(IDI_AVATAR,"avatar",GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON)), "avatar"));
+
+ ChangedIconsXStatus();
+ return 0;
+}
+
+static int Service_ModulesLoaded(WPARAM wParam,LPARAM lParam)
+{
+ char szTemp[MAX_PATH];
+ char szTemp3[256];
+ NETLIBUSER nlu = {0};
+
+ DBDeleteContactSetting(NULL, IRCPROTONAME, "JTemp");
+
+ InitIconLib();
+ hHookUserMenu = HookEvent(ME_CLIST_PREBUILDCONTACTMENU, PrebuildContactMenu);
+ hHookIconsChanged = IconLibHookIconsChanged(IconLibIconsChanged);
+
+ // Initialize IconLib icons
+ InitIcons();
+
+ InitXStatusIcons();
+ InitXStatusEvents();
+ InitXStatusItems(FALSE);
+
+ // Init extra optional modules
+ InitPopUps();
+
+ nlu.cbSize = sizeof(nlu);
+ nlu.flags = NUF_OUTGOING|NUF_INCOMING|NUF_HTTPCONNS;
+ nlu.szSettingsModule = IRCPROTONAME;
+ wsprintf(szTemp, Translate("%s server connection"), ALTIRCPROTONAME);
+ nlu.szDescriptiveName = szTemp;
+ hNetlib=(HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu);
+
+ char szTemp2[256];
+ nlu.flags = NUF_OUTGOING|NUF_INCOMING|NUF_HTTPCONNS;
+ mir_snprintf(szTemp2, sizeof(szTemp2), "%s DCC", IRCPROTONAME);
+ nlu.szSettingsModule = szTemp2;
+ wsprintf(szTemp, Translate("%s client-to-client connections"), ALTIRCPROTONAME);
+ nlu.szDescriptiveName = szTemp;
+ hNetlibDCC=(HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu);
+
+ //add as a known module in DB Editor ++
+ CallService("DBEditorpp/RegisterSingleModule",(WPARAM)IRCPROTONAME,0);
+ mir_snprintf(szTemp3, sizeof(szTemp3), "%s DCC", IRCPROTONAME);
+ CallService("DBEditorpp/RegisterSingleModule",(WPARAM)szTemp3,0);
+
+ // updater plugin support
+ if(ServiceExists(MS_UPDATE_REGISTER))
+ {
+ Update upd = {0};
+ char szCurrentVersion[30];
+ char *szVersionUrl = "http://dev.mirandaim.ru/iron/IRC/version.txt";
+ char *szUpdateUrl = "http://dev.mirandaim.ru/iron/files/IRC.zip";
+// char *szFLVersionUrl = "http://addons.miranda-im.org/details.php?action=viewfile&id=2951";
+// char *szFLUpdateurl = "http://addons.miranda-im.org/feed.php?dlfile=2951";
+ char *szPrefix = "IRC ";
+
+ upd.cbSize = sizeof(upd);
+ upd.szComponentName = pluginInfo.shortName;
+ upd.pbVersion = (BYTE *)CreateVersionStringPlugin(&pluginInfo, szCurrentVersion);
+ upd.cpbVersion = strlen((char *)upd.pbVersion);
+// upd.szVersionURL = szFLVersionUrl;
+// upd.szUpdateURL = szFLUpdateurl;
+// upd.pbVersionPrefix = (BYTE *)"<span class=\"fileNameHeader\">Updater ";
+
+ upd.szBetaUpdateURL = szUpdateUrl;
+ upd.szBetaVersionURL = szVersionUrl;
+ upd.pbBetaVersionPrefix = (BYTE *)szPrefix;
+ upd.pbVersion = (PBYTE)szCurrentVersion;
+ upd.cpbVersion = lstrlenA(szCurrentVersion);
+
+// upd.cpbVersionPrefix = strlen((char *)upd.pbVersionPrefix);
+ upd.cpbBetaVersionPrefix = strlen((char *)upd.pbBetaVersionPrefix);
+
+ CallService(MS_UPDATE_REGISTER, 0, (LPARAM)&upd);
+ }
+
+ if(ServiceExists("MBot/GetFcnTable"))
+ {
+ CallService(MS_MBOT_REGISTERIRC, 0, (LPARAM)IRCPROTONAME);
+ bMbotInstalled = TRUE;
+ }
+
+ if(ServiceExists(MS_GC_REGISTER))
+ {
+ GCREGISTER gcr = {0};
+
+ GCPTRS gp = {0};
+ CallService(MS_GC_GETEVENTPTR, 0, (LPARAM)&gp);
+ pfnAddEvent = gp.pfnAddEvent;
+
+ gcr.cbSize = sizeof(GCREGISTER);
+ gcr.dwFlags = GC_CHANMGR|GC_BOLD|GC_ITALICS|GC_UNDERLINE|GC_COLOR|GC_BKGCOLOR;
+ gcr.iMaxText = 0;
+ gcr.nColors = 16;
+ gcr.pColors = prefs->colors;
+ gcr.pszModuleDispName = IRCPROTONAME;
+ gcr.pszModule = IRCPROTONAME;
+ CallService(MS_GC_REGISTER, NULL, (LPARAM)&gcr);
+ g_hGCUserEvent = HookEvent(ME_GC_EVENT, Service_GCEventHook);
+ g_hGCMenuBuild = HookEvent(ME_GC_BUILDMENU, Service_GCMenuHook );
+
+ GCSESSION gcw = {0};
+ GCDEST gcd = {0};
+ GCEVENT gce = {0};
+
+ gcw.cbSize = sizeof(GCSESSION);
+ gcw.iType = GCW_SERVER;
+ gcw.pszID = "Network log";
+ gcw.pszModule = IRCPROTONAME;
+ gcw.pszName = Translate("Offline");
+ CallService(MS_GC_NEWSESSION, 0, (LPARAM)&gcw);
+
+ gce.cbSize = sizeof(GCEVENT);
+ gce.pDest = &gcd;
+ gcd.pszID = "Network log";
+ gcd.pszModule = IRCPROTONAME;
+ gcd.iType = GC_EVENT_CONTROL;
+
+ gce.pDest = &gcd;
+ if (prefs->UseServer && !prefs->HideServerWindow)
+ CallChatEvent( WINDOW_VISIBLE, (LPARAM)&gce);
+ else
+ CallChatEvent( WINDOW_HIDDEN, (LPARAM)&gce);
+ bChatInstalled = TRUE;
+
+ }
+ else
+ {
+ if(IDYES == MessageBoxA(0,Translate("The IRC protocol depends on another plugin called \'Chat\'\n\nDo you want to download it from the Miranda IM web site now?"),Translate("Information"),MB_YESNO|MB_ICONINFORMATION))
+ CallService(MS_UTILS_OPENURL, 1, (LPARAM) "http://www.miranda-im.org/download/details.php?action=viewfile&id=1309");
+ }
+
+ mir_snprintf(szTemp, sizeof(szTemp), "%s\\%s_servers.ini", mirandapath, IRCPROTONAME);
+ pszServerFile = IrcLoadFile(szTemp);
+
+ mir_snprintf(szTemp, sizeof(szTemp), "%s\\%s_perform.ini", mirandapath, IRCPROTONAME);
+ pszPerformFile = IrcLoadFile(szTemp);
+
+ mir_snprintf(szTemp, sizeof(szTemp), "%s\\%s_ignore.ini", mirandapath, IRCPROTONAME);
+ pszIgnoreFile = IrcLoadFile(szTemp);
+
+ InitMenus();
+
+ g_hUserInfoInit = HookEvent(ME_USERINFO_INITIALISE, Service_InitUserInfo);
+ g_hMenuCreation = HookEvent(ME_CLIST_PREBUILDCONTACTMENU, Service_MenuPreBuild );
+ g_hOptionsInit = HookEvent(ME_OPT_INITIALISE, InitOptionsPages);
+
+ if (lstrlen(prefs->Nick) == 0)
+ CreateDialog(g_hInstance,MAKEINTRESOURCE(IDD_INIT),NULL, InitWndProc);
+ else
+ {
+ if (lstrlen(prefs->AlternativeNick) == 0)
+ {
+ mir_snprintf(szTemp, 30, "%s%u", prefs->Nick, rand()%9999);
+ DBWriteContactSettingString(NULL, IRCPROTONAME, "AlernativeNick", szTemp);
+ lstrcpyn(prefs->AlternativeNick, szTemp, 30);
+ }
+ if (lstrlen(prefs->Name) == 0)
+ {
+ mir_snprintf(szTemp, 30, "Miranda%u", rand()%9999);
+ DBWriteContactSettingString(NULL, IRCPROTONAME, "Name", szTemp);
+ lstrcpyn(prefs->Name, szTemp, 200);
+ }
+ }
+ return 0;
+}
+
+void HookEvents(void)
+{
+ g_hModulesLoaded = HookEvent(ME_SYSTEM_MODULESLOADED, Service_ModulesLoaded);
+// g_hContactDblClick= HookEvent(ME_CLIST_DOUBLECLICKED, Service_ContactDoubleclicked);
+ g_hSystemPreShutdown = HookEvent(ME_SYSTEM_PRESHUTDOWN, Service_SystemPreShutdown);
+ g_hContactDeleted = HookEvent(ME_DB_CONTACT_DELETED, Service_UserDeletedContact );
+// g_hIconsChanged = HookEvent(ME_SKIN2_ICONSCHANGED, Service_IconsChanged );
+
+ return;
+}
+
+void UnhookEvents(void)
+{
+ UnhookEvent(g_hModulesLoaded);
+ UnhookEvent(g_hSystemPreShutdown);
+// UnhookEvent(g_hContactDblClick);
+ UnhookEvent(g_hContactDeleted);
+ UnhookEvent(g_hUserInfoInit);
+ UnhookEvent(g_hMenuCreation);
+ UnhookEvent(g_hGCUserEvent);
+ UnhookEvent(g_hGCMenuBuild);
+ UnhookEvent(g_hIconsChanged);
+ Netlib_CloseHandle(hNetlib);
+ Netlib_CloseHandle(hNetlibDCC);
+ return;
+}
+
+int Service_GetAvatarInfo(WPARAM wParam, LPARAM lParam)
+{
+// #ifdef _DEBUG
+// DBGprintf( "Event: Service_GetAvatarInfo\n");
+// #endif
+
+ PROTO_AVATAR_INFORMATION* pai = (PROTO_AVATAR_INFORMATION*)lParam;
+// DWORD dwUIN;
+// uid_str szUID;
+ DBVARIANT dbv;
+ int dwPaFormat;
+
+ if (!prefs->AvatarsEnabled) return GAIR_NOAVATAR;
+
+ if (IRCGetContactSetting(pai->hContact, "AvatarHash", &dbv) || dbv.cpbVal != 0x14)
+ return GAIR_NOAVATAR; // we did not found avatar hash or hash invalid - no avatar available
+
+// if (ICQGetContactSettingUID(pai->hContact, &dwUIN, &szUID))
+// {
+// ICQFreeVariant(&dbv);
+// return GAIR_NOAVATAR; // we do not support avatars for invalid contacts
+// }
+
+ dwPaFormat = IRCGetContactSettingByte(pai->hContact, "AvatarType", PA_FORMAT_UNKNOWN);
+ if (dwPaFormat != PA_FORMAT_UNKNOWN)
+ { // we know the format, test file
+// GetFullAvatarFileName(dwUIN, szUID, dwPaFormat, pai->filename, MAX_PATH);
+
+ pai->format = dwPaFormat;
+
+ if (!IsAvatarSaved(pai->hContact, (char *)dbv.pbVal))
+ { // hashes are the same
+ if (access(pai->filename, 0) == 0)
+ {
+ IRCFreeVariant(&dbv);
+ return GAIR_SUCCESS; // we have found the avatar file, whoala
+ }
+ }
+ }
+
+ if (IsAvatarSaved(pai->hContact, (char *)dbv.pbVal))
+ { // we didn't received the avatar before - this ensures we will not request avatar again and again
+ if ((wParam & GAIF_FORCE) != 0 && pai->hContact != 0)
+ { // request avatar data
+// GetAvatarFileName(dwUIN, szUID, pai->filename, MAX_PATH);
+// GetAvatarData(pai->hContact, dwUIN, szUID, dbv.pbVal, dbv.cpbVal, pai->filename);
+ IRCFreeVariant(&dbv);
+ return GAIR_WAITFOR;
+ }
+ }
+ IRCFreeVariant(&dbv);
+
+ return GAIR_NOAVATAR;
+}
+
+int Service_GetMaxAvatarSize(WPARAM wParam, LPARAM lParam)
+{
+// #ifdef _DEBUG
+// DBGprintf( "Event: Service_GetMaxAvatarSize\n");
+// #endif
+
+ if (wParam) *((int*)wParam) = 64;
+ if (lParam) *((int*)lParam) = 64;
+ return 0;
+}
+
+int Service_AvatarFormatSupported(WPARAM wParam, LPARAM lParam)
+{
+// #ifdef _DEBUG
+// DBGprintf( "Event: Service_AvatarFormatSupported\n");
+// #endif
+
+ if (lParam == PA_FORMAT_JPEG || lParam == PA_FORMAT_GIF)
+ return -2;
+ else
+ return 0;
+}
+
+int Service_GetMyAvatar(WPARAM wParam, LPARAM lParam)
+{
+// #ifdef _DEBUG
+// DBGprintf( "Event: Service_GetMyAvatar\n");
+// #endif
+
+ if (!prefs->AvatarsEnabled) return -2;
+
+ if (!wParam) return -3;
+
+ if (!IRCGetContactStaticString(NULL, "AvatarFile", (char*)wParam, (int)lParam))
+ {
+ if (!access((char*)wParam, 0)) return 0;
+ }
+ return -1;
+}
+
+int Service_SetMyAvatar(WPARAM wParam, LPARAM lParam)
+{
+// #ifdef _DEBUG
+// DBGprintf( "Event: Service_SetMyAvatar\n");
+// #endif
+
+ char* szFile = (char*)lParam;
+ int iRet = -1;
+
+ if (!prefs->AvatarsEnabled) return -2;
+
+ if (szFile)
+ { // set file for avatar
+ char szMyFile[MAX_PATH+1];
+ int dwPaFormat = DetectAvatarFormat(szFile);
+ char* hash;
+ HBITMAP avt;
+
+ avt = (HBITMAP)CallService(MS_UTILS_LOADBITMAP, 0, (WPARAM)szFile);
+ if (!avt) return iRet;
+ DeleteObject(avt);
+
+ GetFullAvatarFileName(0, NULL, dwPaFormat, szMyFile, MAX_PATH);
+ if (!CopyFile(szFile, szMyFile, FALSE))
+ return iRet;
+
+ hash = calcMD5Hash(szMyFile);
+ if (hash)
+ {
+ char* ihash = (char*)_alloca(0x14);
+ // upload hash to server
+ ihash[0] = 0; //unknown
+ ihash[1] = 1; //hash type
+ ihash[2] = 1; //hash status
+ ihash[3] = 0x10; //hash len
+ memcpy(ihash+4, hash, 0x10);
+
+ IRCWriteContactSettingBlob(NULL, "AvatarHash", ihash, 0x14);
+ IRCWriteContactSettingString(NULL, "AvatarFile", szMyFile);
+
+ iRet = 0;
+ SAFE_FREE((void **)&hash);
+ }
+ }
+ else
+ { // delete user avatar
+ IRCDeleteContactSetting(NULL, "AvatarFile");
+ IRCDeleteContactSetting(NULL, "AvatarHash");
+ iRet = 0;
+ }
+
+ return iRet;
+}
+
+void CreateServiceFunctions(void)
+{
+ char temp[MAXMODULELABELLENGTH];
+
+ wsprintf(temp, "%s%s", IRCPROTONAME, PS_GETCAPS);
+ CreateServiceFunction(temp, Service_GetCaps);
+
+ wsprintf(temp, "%s%s", IRCPROTONAME, PS_GETNAME);
+ CreateServiceFunction(temp,Service_GetName);
+
+ wsprintf(temp, "%s%s", IRCPROTONAME, PS_LOADICON);
+ CreateServiceFunction(temp,Service_LoadIcon);
+
+ wsprintf(temp, "%s%s", IRCPROTONAME, PS_SETSTATUS);
+ CreateServiceFunction(temp,Service_SetStatus);
+
+ wsprintf(temp, "%s%s", IRCPROTONAME, PS_GETSTATUS);
+ CreateServiceFunction(temp,Service_GetStatus);
+
+ wsprintf(temp, "%s%s", IRCPROTONAME, PS_SETAWAYMSG);
+ CreateServiceFunction(temp, Service_SetAwayMsg);
+
+ wsprintf(temp, "%s%s", IRCPROTONAME, PS_BASICSEARCH);
+ CreateServiceFunction(temp, Service_BasicSearch);
+
+ wsprintf(temp, "%s%s", IRCPROTONAME, PS_ADDTOLIST);
+ CreateServiceFunction(temp, Service_AddToList);
+
+ wsprintf(temp, "%s%s", IRCPROTONAME, PSR_MESSAGE);
+ CreateServiceFunction(temp,Service_AddIncMessToDB);
+
+ wsprintf(temp, "%s%s", IRCPROTONAME, PSS_MESSAGE);
+ CreateServiceFunction(temp, Service_GetMessFromSRMM);
+
+ wsprintf(temp, "%s%s", IRCPROTONAME, PSS_GETAWAYMSG);
+ CreateServiceFunction(temp, Service_GetAwayMessage);
+
+ wsprintf(temp,"%s/JoinChannelMenu", IRCPROTONAME);
+ CreateServiceFunction(temp,Service_JoinMenuCommand);
+
+ wsprintf(temp,"%s/QuickConnectMenu", IRCPROTONAME);
+ CreateServiceFunction(temp,Service_QuickConnectMenuCommand);
+
+ wsprintf(temp,"%s/ChangeNickMenu", IRCPROTONAME);
+ CreateServiceFunction(temp,Service_ChangeNickMenuCommand);
+
+ wsprintf(temp,"%s/ShowListMenu", IRCPROTONAME);
+ CreateServiceFunction(temp,Service_ShowListMenuCommand);
+
+ wsprintf(temp,"%s/ShowServerMenu", IRCPROTONAME);
+ CreateServiceFunction(temp,Service_ShowServerMenuCommand);
+
+ wsprintf(temp,"%s/SetAvatarMenu", IRCPROTONAME);
+ CreateServiceFunction(temp, Service_SetAvatarMenuCommand);
+
+ wsprintf(temp,"%s/Menu1ChannelMenu", IRCPROTONAME);
+ CreateServiceFunction(temp,Service_Menu1Command);
+
+ wsprintf(temp,"%s/Menu2ChannelMenu", IRCPROTONAME);
+ CreateServiceFunction(temp,Service_Menu2Command);
+
+ wsprintf(temp,"%s/Menu3ChannelMenu", IRCPROTONAME);
+ CreateServiceFunction(temp,Service_Menu3Command);
+
+ wsprintf(temp,"%s/DblClickEvent", IRCPROTONAME);
+ CreateServiceFunction(temp, Service_EventDoubleclicked);
+
+ wsprintf(temp,"%s/InsertRawIn", IRCPROTONAME);
+ CreateServiceFunction(temp, Scripting_InsertRawIn);
+
+ wsprintf(temp,"%s/InsertRawOut", IRCPROTONAME);
+ CreateServiceFunction(temp, Scripting_InsertRawOut);
+
+ wsprintf(temp,"%s/InsertGuiIn", IRCPROTONAME);
+ CreateServiceFunction(temp, Scripting_InsertGuiIn);
+
+ wsprintf(temp,"%s/InsertGuiOut", IRCPROTONAME);
+ CreateServiceFunction(temp, Scripting_InsertGuiOut);
+
+ wsprintf(temp,"%s/GetIrcData", IRCPROTONAME);
+ CreateServiceFunction(temp, Scripting_GetIrcData);
+
+ wsprintf(temp,"%s%s", IRCPROTONAME, PSS_FILEALLOW);
+ CreateServiceFunction(temp, Service_FileAllow);
+
+ wsprintf(temp,"%s%s", IRCPROTONAME, PSS_FILEDENY);
+ CreateServiceFunction(temp, Service_FileDeny);
+
+ wsprintf(temp,"%s%s", IRCPROTONAME, PSS_FILECANCEL);
+ CreateServiceFunction(temp, Service_FileCancel);
+
+ wsprintf(temp,"%s%s", IRCPROTONAME, PSS_FILE);
+ CreateServiceFunction(temp, Service_FileSend);
+
+ wsprintf(temp,"%s%s", IRCPROTONAME, PSR_FILE);
+ CreateServiceFunction(temp, Service_FileReceive);
+
+ wsprintf(temp,"%s%s", IRCPROTONAME, PS_FILERESUME);
+ CreateServiceFunction(temp, Service_FileResume);
+
+// Typing Notify
+ wsprintf(temp,"%s%s", IRCPROTONAME, PSS_USERISTYPING);
+ CreateServiceFunction(temp, Service_SendUserIsTyping);
+
+// Nudge
+ wsprintf(temp,"%s%s", IRCPROTONAME, PS_SEND_NUDGE);
+ CreateServiceFunction(temp, Service_SendNudge);
+
+//Begin Custom Status API
+ wsprintf(temp,"%s%s", IRCPROTONAME, PS_SETCUSTOMSTATUS);
+ CreateServiceFunction(temp, IRCSetXStatus);
+
+ wsprintf(temp,"%s%s", IRCPROTONAME, PS_GETCUSTOMSTATUSICON);
+ CreateServiceFunction(temp, IRCGetXStatusIcon);
+
+ wsprintf(temp,"%s%s", IRCPROTONAME, PS_GETCUSTOMSTATUS);
+ CreateServiceFunction(temp, IRCGetXStatus);
+
+ wsprintf(temp,"%s%s", IRCPROTONAME, PS_REQUESTCUSTOMSTATUS);
+ CreateServiceFunction(temp, IRCRequestXStatusDetails);
+
+ wsprintf(temp,"%s%s", IRCPROTONAME, MS_XSTATUS_SHOWDETAILS);
+ CreateServiceFunction(temp, IRCShowXStatusDetails);
+//End Custom Status API
+
+// Begin Avatar API
+ wsprintf(temp,"%s%s", IRCPROTONAME, PS_IRC_GETMYAVATARMAXSIZE);
+ CreateServiceFunction(temp, Service_GetMaxAvatarSize);
+
+ wsprintf(temp,"%s%s", IRCPROTONAME, PS_IRC_ISAVATARFORMATSUPPORTED);
+ CreateServiceFunction(temp, Service_AvatarFormatSupported);
+
+ wsprintf(temp,"%s%s", IRCPROTONAME, PS_IRC_GETMYAVATAR);
+ CreateServiceFunction(temp, Service_GetMyAvatar);
+
+ wsprintf(temp,"%s%s", IRCPROTONAME, PS_IRC_SETMYAVATAR);
+ CreateServiceFunction(temp, Service_SetMyAvatar);
+
+ wsprintf(temp,"%s%s", IRCPROTONAME, PS_GETAVATARINFO);
+ CreateServiceFunction(temp, Service_GetAvatarInfo);
+// End Avatar API
+
+ return;
+}
+
+void handleNudgeNotification(const char* NickName)
+{
+ if(ServiceExists(MS_NUDGE_SEND))
+ {
+ HANDLE hContact = GetContactByName(NickName);
+ if(hContact)
+ {
+ #ifdef _DEBUG
+ DBGprintf( "Event: NudgeNotification (TRUE)\n");
+ #endif
+
+ DBVARIANT dbv1;
+ if(DBGetContactSettingByte(hContact, IRCPROTONAME, "AdvancedMode", 0) == 0)
+ DoUserhostWithReason(1, ((String)"S" + NickName).c_str(), true, NickName);
+ else
+ {
+ if (!DBGetContactSetting(hContact, IRCPROTONAME, "UWildcard", &dbv1) && dbv1.type == DBVT_ASCIIZ)
+ {
+ DoUserhostWithReason(2, ((String)"S" + dbv1.pszVal).c_str(), true, dbv1.pszVal);
+ DBFreeVariant(&dbv1);
+ }
+ else
+ {
+ DoUserhostWithReason(2, ((String)"S" + NickName).c_str(), true, NickName);
+ }
+ }
+
+ NotifyEventHooks(hIRCNudge,WPARAM(hContact),0);
+ }
+ else
+ {
+ #ifdef _DEBUG
+ DBGprintf( "Event: NudgeNotification (FALSE)\n");
+ #endif
+
+ }
+ }
+}
+
+void handleTypingNotification(const char* NickName, WORD wMTNCode)
+{
+ LPARAM lParam;
+
+ if(prefs->TypingEnabled)
+ {
+ switch (wMTNCode)
+ {
+ case MTN_TYPED:
+ lParam = PROTOTYPE_CONTACTTYPING_OFF;
+ break;
+ case MTN_BEGUN:
+ lParam = (LPARAM)60;
+ break;
+ default:
+ break;
+ }
+
+ HANDLE hContact = GetContactByName(NickName);
+ DBWriteContactSettingByte(hContact,"SRMsg", "SupportTyping", 1);
+ if (hContact)
+ {
+ DBVARIANT dbv1;
+
+ if(DBGetContactSettingByte(hContact, IRCPROTONAME, "AdvancedMode", 0) == 0)
+ DoUserhostWithReason(1, ((String)"S" + NickName).c_str(), true, NickName);
+ else
+ {
+ if (!DBGetContactSetting(hContact, IRCPROTONAME, "UWildcard", &dbv1) && dbv1.type == DBVT_ASCIIZ)
+ {
+ DoUserhostWithReason(2, ((String)"S" + dbv1.pszVal).c_str(), true, dbv1.pszVal);
+ DBFreeVariant(&dbv1);
+ }
+ else
+ {
+ DoUserhostWithReason(2, ((String)"S" + NickName).c_str(), true, NickName);
+ }
+ }
+
+ }
+
+ CallService(MS_PROTO_CONTACTISTYPING, (WPARAM)hContact, lParam);
+ }
+}
+
+void handleXStatus(const char* NickName)
+{
+ BYTE bXStatus = NULL;
+ char *szName;
+
+ if(DBGetContactSettingByte(NULL,IRCPROTONAME, "XStatusEnabled", 0))
+ {
+ bXStatus = IRCGetContactSettingByte(NULL, DBSETTING_XSTATUSID, 0);
+ szName = UniGetContactSettingUtf(NULL, ALTIRCPROTONAME, DBSETTING_XSTATUSNAME, "");
+ String szText = UniGetContactSettingUtf(NULL, ALTIRCPROTONAME, DBSETTING_XSTATUSMSG, "");
+ szText = ReplaceString( (char *)szText.c_str(), "\r\n", "\005");
+ PostIrcMessage("/NOTICE %s \001XSTATUS %d %s\004%s\001", NickName, bXStatus, szName, szText.c_str());
+ }
+ else
+ PostIrcMessage("/NOTICE %s \001XSTATUS OFF\001", NickName);
+}
+
+void handleAvatarHash(const char* NickName)
+{
+ DBVARIANT dbvHash;
+
+ if(!IRCGetContactSetting(NULL, "AvatarHash", &dbvHash))
+ {
+ char hash[50]="",h[9],path[255];
+ for(int i=0;i<20;i+=4)
+ {
+ sprintf(h,"%.8X",*((unsigned int*)(dbvHash.pbVal+i)));
+ strcat(hash,h);
+ }
+ IRCFreeVariant(&dbvHash);
+ IRCGetContactSettingString(NULL,"AvatarPath",path);
+// #ifdef _DEBUG
+// DBGprintf("AvatarHash = %s\n", hash);
+// #endif
+ PostIrcMessage("/NOTICE %s \001AVATAR %s %s\001", NickName, hash, path);
+ }
+}
+
+void sendTypingNotification(HANDLE hContact, WORD wMTNCode)
+{
+ DBVARIANT dbv;
+ DBCONTACTGETSETTING dcs;
+
+ dcs.szModule=IRCPROTONAME;
+ dcs.szSetting="Nick";
+ dcs.pValue=&dbv;
+ dbv.type=DBVT_ASCIIZ;
+ CallService(MS_DB_CONTACT_GETSETTING,(WPARAM)hContact,(LPARAM)&dcs);
+
+ switch (wMTNCode)
+ {
+ case MTN_BEGUN:
+ PostIrcMessage( "/PRIVMSG %s \001TYPINGSTART\001", dbv.pszVal);
+ break;
+ case MTN_FINISHED:
+ PostIrcMessage( "/PRIVMSG %s \001TYPINGSTOP\001", dbv.pszVal);
+ break;
+ default:
+ break;
+ }
+
+ DBFreeVariant(&dbv);
+
+ return;
+}
+
+
+VOID CALLBACK RetryTimerProc(HWND hwnd,UINT uMsg,UINT idEvent,DWORD dwTime)
+{
+ if (RetryCount <= StrToInt(prefs->RetryCount) && prefs->Retry)
+ {
+ char szTemp[300];
+ PortCount++;
+ if (PortCount > StrToInt(prefs->PortEnd) || StrToInt(prefs->PortEnd) ==0)
+ PortCount = StrToInt(prefs->PortStart);
+ si.iPort = PortCount;
+
+ mir_snprintf(szTemp, sizeof(szTemp), "\0033%s \002%s\002 (%s: %u, try %u)", Translate("Reconnecting to"), si.sNetwork.c_str(), si.sServer.c_str(), si.iPort, RetryCount);
+
+ DoEvent(GC_EVENT_INFORMATION, "Network log", NULL, szTemp, NULL, NULL, NULL, true, false);
+
+ if (!bConnectThreadRunning)
+ {
+ forkthread(ConnectServerThread, 0, NULL );
+ }
+ else
+ bConnectRequested = true;
+
+ RetryCount++;
+ }
+ else
+ KillChatTimer(RetryTimer);
+}
+