PageRenderTime 71ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/miranda/protocols/JabberG/jabber_misc.cpp

http://miranda.googlecode.com/
C++ | 643 lines | 484 code | 93 blank | 66 comment | 124 complexity | c4830feb10a52d94efd038f39021cf60 MD5 | raw file
Possible License(s): GPL-2.0, MPL-2.0-no-copyleft-exception, LGPL-3.0, LGPL-2.1
  1. /*
  2. Jabber Protocol Plugin for Miranda IM
  3. Copyright ( C ) 2002-04 Santithorn Bunchua
  4. Copyright ( C ) 2005-11 George Hazan
  5. Copyright ( C ) 2007 Maxim Mluhov
  6. This program is free software; you can redistribute it and/or
  7. modify it under the terms of the GNU General Public License
  8. as published by the Free Software Foundation; either version 2
  9. of the License, or ( at your option ) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17. Revision : $Revision: 14331 $
  18. Last change on : $Date: 2006-07-13 16:11:29 +0400
  19. Last change by : $Author: borkra $
  20. */
  21. #include "jabber.h"
  22. #include "jabber_list.h"
  23. #include "jabber_caps.h"
  24. #include <m_popup.h>
  25. #include "sdk/m_folders.h"
  26. ///////////////////////////////////////////////////////////////////////////////
  27. // JabberAddContactToRoster() - adds a contact to the roster
  28. void CJabberProto::AddContactToRoster( const TCHAR* jid, const TCHAR* nick, const TCHAR* grpName )
  29. {
  30. XmlNodeIq iq( _T("set"), SerialNext());
  31. HXML query = iq << XQUERY( _T(JABBER_FEAT_IQ_ROSTER))
  32. << XCHILD( _T("item")) << XATTR( _T("jid"), jid ) << XATTR( _T("name"), nick );
  33. if ( grpName )
  34. query << XCHILD( _T("group"), grpName );
  35. m_ThreadInfo->send( iq );
  36. }
  37. ///////////////////////////////////////////////////////////////////////////////
  38. // JabberChatDllError() - missing CHAT.DLL
  39. void JabberChatDllError()
  40. {
  41. MessageBox( NULL,
  42. TranslateT( "CHAT plugin is required for conferences. Install it before chatting" ),
  43. TranslateT( "Jabber Error" ), MB_OK|MB_SETFOREGROUND );
  44. }
  45. ///////////////////////////////////////////////////////////////////////////////
  46. // JabberCompareJids
  47. int JabberCompareJids( const TCHAR* jid1, const TCHAR* jid2 )
  48. {
  49. if ( !lstrcmpi( jid1, jid2 ))
  50. return 0;
  51. // match only node@domain part
  52. TCHAR szTempJid1[ JABBER_MAX_JID_LEN ], szTempJid2[ JABBER_MAX_JID_LEN ];
  53. return lstrcmpi(
  54. JabberStripJid( jid1, szTempJid1, SIZEOF(szTempJid1) ),
  55. JabberStripJid( jid2, szTempJid2, SIZEOF(szTempJid2)) );
  56. }
  57. ///////////////////////////////////////////////////////////////////////////////
  58. // JabberContactListCreateGroup()
  59. static void JabberContactListCreateClistGroup( TCHAR* groupName )
  60. {
  61. char str[33];
  62. int i;
  63. DBVARIANT dbv;
  64. for ( i=0;;i++ ) {
  65. _itoa( i, str, 10 );
  66. if ( DBGetContactSettingTString( NULL, "CListGroups", str, &dbv ))
  67. break;
  68. TCHAR* name = dbv.ptszVal;
  69. if ( name[0]!='\0' && !_tcscmp( name+1, groupName )) {
  70. // Already exists, no need to create
  71. JFreeVariant( &dbv );
  72. return;
  73. }
  74. JFreeVariant( &dbv );
  75. }
  76. // Create new group with id = i ( str is the text representation of i )
  77. TCHAR newName[128];
  78. newName[0] = 1 | GROUPF_EXPANDED;
  79. _tcsncpy( newName+1, groupName, SIZEOF( newName )-1 );
  80. newName[ SIZEOF( newName )-1] = '\0';
  81. DBWriteContactSettingTString( NULL, "CListGroups", str, newName );
  82. JCallService( MS_CLUI_GROUPADDED, i+1, 0 );
  83. }
  84. void JabberContactListCreateGroup( TCHAR* groupName )
  85. {
  86. TCHAR name[128], *p;
  87. if ( groupName==NULL || groupName[0]=='\0' || groupName[0]=='\\' ) return;
  88. _tcsncpy( name, groupName, SIZEOF( name ));
  89. name[ SIZEOF( name )-1] = '\0';
  90. for ( p=name; *p!='\0'; p++ ) {
  91. if ( *p == '\\' ) {
  92. *p = '\0';
  93. JabberContactListCreateClistGroup( name );
  94. *p = '\\';
  95. }
  96. }
  97. JabberContactListCreateClistGroup( name );
  98. }
  99. ///////////////////////////////////////////////////////////////////////////////
  100. // JabberDBAddAuthRequest()
  101. void CJabberProto::DBAddAuthRequest( const TCHAR* jid, const TCHAR* nick )
  102. {
  103. HANDLE hContact = DBCreateContact( jid, NULL, TRUE, TRUE );
  104. JDeleteSetting( hContact, "Hidden" );
  105. //JSetStringT( hContact, "Nick", nick );
  106. char* szJid = mir_utf8encodeT( jid );
  107. char* szNick = mir_utf8encodeT( nick );
  108. //blob is: uin( DWORD ), hContact( HANDLE ), nick( ASCIIZ ), first( ASCIIZ ), last( ASCIIZ ), email( ASCIIZ ), reason( ASCIIZ )
  109. //blob is: 0( DWORD ), hContact( HANDLE ), nick( ASCIIZ ), ""( ASCIIZ ), ""( ASCIIZ ), email( ASCIIZ ), ""( ASCIIZ )
  110. DBEVENTINFO dbei = {0};
  111. dbei.cbSize = sizeof( DBEVENTINFO );
  112. dbei.szModule = m_szModuleName;
  113. dbei.timestamp = ( DWORD )time( NULL );
  114. dbei.flags = DBEF_UTF;
  115. dbei.eventType = EVENTTYPE_AUTHREQUEST;
  116. dbei.cbBlob = (DWORD)(sizeof( DWORD )+ sizeof( HANDLE ) + strlen( szNick ) + strlen( szJid ) + 5);
  117. PBYTE pCurBlob = dbei.pBlob = ( PBYTE ) mir_alloc( dbei.cbBlob );
  118. *(( PDWORD ) pCurBlob ) = 0; pCurBlob += sizeof( DWORD );
  119. *(( PHANDLE ) pCurBlob ) = hContact; pCurBlob += sizeof( HANDLE );
  120. strcpy(( char* )pCurBlob, szNick ); pCurBlob += strlen( szNick )+1;
  121. *pCurBlob = '\0'; pCurBlob++; //firstName
  122. *pCurBlob = '\0'; pCurBlob++; //lastName
  123. strcpy(( char* )pCurBlob, szJid ); pCurBlob += strlen( szJid )+1;
  124. *pCurBlob = '\0'; //reason
  125. JCallService( MS_DB_EVENT_ADD, ( WPARAM ) ( HANDLE ) NULL, ( LPARAM )&dbei );
  126. Log( "Setup DBAUTHREQUEST with nick='%s' jid='%s'", szNick, szJid );
  127. mir_free( szJid );
  128. mir_free( szNick );
  129. }
  130. ///////////////////////////////////////////////////////////////////////////////
  131. // JabberDBCreateContact()
  132. HANDLE CJabberProto::DBCreateContact( const TCHAR* jid, const TCHAR* nick, BOOL temporary, BOOL stripResource )
  133. {
  134. TCHAR* s, *p, *q;
  135. size_t len;
  136. char* szProto;
  137. if ( jid==NULL || jid[0]=='\0' )
  138. return NULL;
  139. s = mir_tstrdup( jid );
  140. q = NULL;
  141. // strip resource if present
  142. if (( p = _tcschr( s, '@' )) != NULL )
  143. if (( q = _tcschr( p, '/' )) != NULL )
  144. *q = '\0';
  145. if ( !stripResource && q!=NULL ) // so that resource is not stripped
  146. *q = '/';
  147. len = _tcslen( s );
  148. // We can't use JabberHContactFromJID() here because of the stripResource option
  149. HANDLE hContact = ( HANDLE ) JCallService( MS_DB_CONTACT_FINDFIRST, 0, 0 );
  150. while ( hContact != NULL ) {
  151. szProto = ( char* )JCallService( MS_PROTO_GETCONTACTBASEPROTO, ( WPARAM ) hContact, 0 );
  152. if ( szProto!=NULL && !strcmp( m_szModuleName, szProto )) {
  153. DBVARIANT dbv;
  154. if ( !JGetStringT( hContact, "jid", &dbv )) {
  155. p = dbv.ptszVal;
  156. if ( p && _tcslen( p )>=len && ( p[len]=='\0'||p[len]=='/' ) && !_tcsnicmp( p, s, len )) {
  157. JFreeVariant( &dbv );
  158. break;
  159. }
  160. JFreeVariant( &dbv );
  161. } }
  162. hContact = ( HANDLE ) JCallService( MS_DB_CONTACT_FINDNEXT, ( WPARAM ) hContact, 0 );
  163. }
  164. if ( hContact == NULL ) {
  165. hContact = ( HANDLE ) JCallService( MS_DB_CONTACT_ADD, 0, 0 );
  166. JCallService( MS_PROTO_ADDTOCONTACT, ( WPARAM ) hContact, ( LPARAM )m_szModuleName );
  167. JSetStringT( hContact, "jid", s );
  168. if ( nick != NULL && *nick != '\0' )
  169. JSetStringT( hContact, "Nick", nick );
  170. if ( temporary )
  171. DBWriteContactSettingByte( hContact, "CList", "NotOnList", 1 );
  172. else
  173. SendGetVcard( s );
  174. Log( "Create Jabber contact jid=" TCHAR_STR_PARAM ", nick=" TCHAR_STR_PARAM, s, nick );
  175. DBCheckIsTransportedContact(s,hContact);
  176. }
  177. mir_free( s );
  178. return hContact;
  179. }
  180. BOOL CJabberProto::AddDbPresenceEvent(HANDLE hContact, BYTE btEventType)
  181. {
  182. if ( !hContact )
  183. return FALSE;
  184. switch ( btEventType ) {
  185. case JABBER_DB_EVENT_PRESENCE_SUBSCRIBE:
  186. case JABBER_DB_EVENT_PRESENCE_SUBSCRIBED:
  187. case JABBER_DB_EVENT_PRESENCE_UNSUBSCRIBE:
  188. case JABBER_DB_EVENT_PRESENCE_UNSUBSCRIBED:
  189. if ( !m_options.LogPresence )
  190. return FALSE;
  191. break;
  192. case JABBER_DB_EVENT_PRESENCE_ERROR:
  193. if ( !m_options.LogPresenceErrors )
  194. return FALSE;
  195. break;
  196. }
  197. DBEVENTINFO dbei;
  198. dbei.cbSize = sizeof( dbei );
  199. dbei.pBlob = &btEventType;
  200. dbei.cbBlob = sizeof( btEventType );
  201. dbei.eventType = JABBER_DB_EVENT_TYPE_PRESENCE;
  202. dbei.flags = DBEF_READ;
  203. dbei.timestamp = time( NULL );
  204. dbei.szModule = m_szModuleName;
  205. CallService( MS_DB_EVENT_ADD, (WPARAM)hContact, (LPARAM)&dbei );
  206. return TRUE;
  207. }
  208. ///////////////////////////////////////////////////////////////////////////////
  209. // JabberGetAvatarFileName() - gets a file name for the avatar image
  210. static HANDLE hJabberAvatarsFolder = NULL;
  211. static bool bInitDone = false;
  212. void CJabberProto::InitCustomFolders( void )
  213. {
  214. if ( bInitDone )
  215. return;
  216. bInitDone = true;
  217. if ( ServiceExists( MS_FOLDERS_REGISTER_PATH )) {
  218. TCHAR AvatarsFolder[MAX_PATH];
  219. TCHAR* tmpPath = Utils_ReplaceVarsT( _T("%miranda_avatarcache%"));
  220. mir_sntprintf( AvatarsFolder, SIZEOF( AvatarsFolder ), _T("%s\\Jabber"), tmpPath );
  221. mir_free(tmpPath);
  222. hJabberAvatarsFolder = FoldersRegisterCustomPathT( m_szModuleName, "Avatars", AvatarsFolder ); // title!!!!!!!!!!!
  223. } }
  224. void CJabberProto::GetAvatarFileName( HANDLE hContact, TCHAR* pszDest, size_t cbLen )
  225. {
  226. size_t tPathLen;
  227. TCHAR* path = ( TCHAR* )alloca( cbLen * sizeof( TCHAR ));
  228. InitCustomFolders();
  229. if ( hJabberAvatarsFolder == NULL || FoldersGetCustomPathT( hJabberAvatarsFolder, path, (int)cbLen, _T(""))) {
  230. TCHAR *tmpPath = Utils_ReplaceVarsT( _T("%miranda_avatarcache%"));
  231. tPathLen = mir_sntprintf( pszDest, cbLen, _T("%s\\Jabber"), tmpPath );
  232. mir_free(tmpPath);
  233. }
  234. else tPathLen = mir_sntprintf( pszDest, cbLen, _T("%s"), path );
  235. DWORD dwAttributes = GetFileAttributes( pszDest );
  236. if ( dwAttributes == 0xffffffff || ( dwAttributes & FILE_ATTRIBUTE_DIRECTORY ) == 0 )
  237. JCallService( MS_UTILS_CREATEDIRTREET, 0, ( LPARAM )pszDest );
  238. pszDest[ tPathLen++ ] = '\\';
  239. char* szFileType = NULL;
  240. switch( JGetByte( hContact, "AvatarType", PA_FORMAT_PNG )) {
  241. case PA_FORMAT_JPEG: szFileType = "jpg"; break;
  242. case PA_FORMAT_PNG: szFileType = "png"; break;
  243. case PA_FORMAT_GIF: szFileType = "gif"; break;
  244. case PA_FORMAT_BMP: szFileType = "bmp"; break;
  245. }
  246. if ( hContact != NULL ) {
  247. char str[ 256 ];
  248. DBVARIANT dbv;
  249. if ( !JGetStringUtf( hContact, "jid", &dbv )) {
  250. strncpy( str, dbv.pszVal, sizeof str );
  251. str[ sizeof(str)-1 ] = 0;
  252. JFreeVariant( &dbv );
  253. }
  254. else _i64toa(( LONG_PTR )hContact, str, 10 );
  255. char* hash = JabberSha1( str );
  256. mir_sntprintf( pszDest + tPathLen, MAX_PATH - tPathLen, _T(TCHAR_STR_PARAM) _T(".") _T(TCHAR_STR_PARAM), hash, szFileType );
  257. mir_free( hash );
  258. }
  259. else if ( m_ThreadInfo != NULL ) {
  260. mir_sntprintf( pszDest + tPathLen, MAX_PATH - tPathLen, _T("%s@") _T(TCHAR_STR_PARAM) _T(" avatar.") _T(TCHAR_STR_PARAM),
  261. m_ThreadInfo->username, m_ThreadInfo->server, szFileType );
  262. }
  263. else {
  264. DBVARIANT dbv1, dbv2;
  265. BOOL res1 = DBGetContactSettingString( NULL, m_szModuleName, "LoginName", &dbv1 );
  266. BOOL res2 = DBGetContactSettingString( NULL, m_szModuleName, "LoginServer", &dbv2 );
  267. mir_sntprintf( pszDest + tPathLen, MAX_PATH - tPathLen, _T(TCHAR_STR_PARAM) _T("@") _T(TCHAR_STR_PARAM) _T(" avatar.") _T(TCHAR_STR_PARAM),
  268. res1 ? "noname" : dbv1.pszVal,
  269. res2 ? m_szModuleName : dbv2.pszVal,
  270. szFileType );
  271. if (!res1) JFreeVariant( &dbv1 );
  272. if (!res2) JFreeVariant( &dbv2 );
  273. }
  274. }
  275. ///////////////////////////////////////////////////////////////////////////////
  276. // JabberResolveTransportNicks - massive vcard update
  277. void CJabberProto::ResolveTransportNicks( const TCHAR* jid )
  278. {
  279. // Set all contacts to offline
  280. HANDLE hContact = m_ThreadInfo->resolveContact;
  281. if ( hContact == NULL )
  282. hContact = ( HANDLE ) JCallService( MS_DB_CONTACT_FINDFIRST, 0, 0 );
  283. for ( ; hContact != NULL; hContact = ( HANDLE )JCallService( MS_DB_CONTACT_FINDNEXT, ( WPARAM ) hContact, 0 )) {
  284. char* szProto = ( char* )JCallService( MS_PROTO_GETCONTACTBASEPROTO, ( WPARAM ) hContact, 0 );
  285. if ( lstrcmpA( szProto, m_szModuleName ))
  286. continue;
  287. if ( !JGetByte( hContact, "IsTransported", 0 ))
  288. continue;
  289. DBVARIANT dbv, nick;
  290. if ( JGetStringT( hContact, "jid", &dbv ))
  291. continue;
  292. if ( JGetStringT( hContact, "Nick", &nick )) {
  293. JFreeVariant( &dbv );
  294. continue;
  295. }
  296. TCHAR* p = _tcschr( dbv.ptszVal, '@' );
  297. if ( p ) {
  298. *p = 0;
  299. if ( !lstrcmp( jid, p+1 ) && !lstrcmp( dbv.ptszVal, nick.ptszVal )) {
  300. *p = '@';
  301. m_ThreadInfo->resolveID = SendGetVcard( dbv.ptszVal );
  302. m_ThreadInfo->resolveContact = hContact;
  303. JFreeVariant( &dbv );
  304. JFreeVariant( &nick );
  305. return;
  306. } }
  307. JFreeVariant( &dbv );
  308. JFreeVariant( &nick );
  309. }
  310. m_ThreadInfo->resolveID = -1;
  311. m_ThreadInfo->resolveContact = NULL;
  312. }
  313. ///////////////////////////////////////////////////////////////////////////////
  314. // JabberSetServerStatus()
  315. void CJabberProto::SetServerStatus( int iNewStatus )
  316. {
  317. if ( !m_bJabberOnline )
  318. return;
  319. // change status
  320. int oldStatus = m_iStatus;
  321. switch ( iNewStatus ) {
  322. case ID_STATUS_ONLINE:
  323. case ID_STATUS_NA:
  324. case ID_STATUS_FREECHAT:
  325. case ID_STATUS_INVISIBLE:
  326. m_iStatus = iNewStatus;
  327. break;
  328. case ID_STATUS_AWAY:
  329. case ID_STATUS_ONTHEPHONE:
  330. case ID_STATUS_OUTTOLUNCH:
  331. m_iStatus = ID_STATUS_AWAY;
  332. break;
  333. case ID_STATUS_DND:
  334. case ID_STATUS_OCCUPIED:
  335. m_iStatus = ID_STATUS_DND;
  336. break;
  337. default:
  338. return;
  339. }
  340. if ( m_iStatus == oldStatus )
  341. return;
  342. // send presence update
  343. SendPresence( m_iStatus, true );
  344. JSendBroadcast( NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, ( HANDLE ) oldStatus, m_iStatus );
  345. }
  346. // Process a string, and double all % characters, according to chat.dll's restrictions
  347. // Returns a pointer to the new string (old one is not freed)
  348. TCHAR* EscapeChatTags(TCHAR* pszText)
  349. {
  350. int nChars = 0;
  351. for ( TCHAR* p = pszText; ( p = _tcschr( p, '%' )) != NULL; p++ )
  352. nChars++;
  353. if ( nChars == 0 )
  354. return mir_tstrdup( pszText );
  355. TCHAR* pszNewText = (TCHAR*)mir_alloc( sizeof(TCHAR)*(_tcslen( pszText ) + 1 + nChars )), *s, *d;
  356. if ( pszNewText == NULL )
  357. return mir_tstrdup( pszText );
  358. for ( s = pszText, d = pszNewText; *s; s++ ) {
  359. if ( *s == '%' )
  360. *d++ = '%';
  361. *d++ = *s;
  362. }
  363. *d = 0;
  364. return pszNewText;
  365. }
  366. TCHAR* UnEscapeChatTags(TCHAR* str_in)
  367. {
  368. TCHAR* s = str_in, *d = str_in;
  369. while ( *s ) {
  370. if ( *s == '%' && s[1] == '%' )
  371. s++;
  372. *d++ = *s++;
  373. }
  374. *d = 0;
  375. return str_in;
  376. }
  377. //////////////////////////////////////////////////////////////////////////
  378. // update MirVer with data for active resource
  379. struct
  380. {
  381. TCHAR *node;
  382. TCHAR *name;
  383. }
  384. static sttCapsNodeToName_Map[] =
  385. {
  386. { _T("http://miranda-im.org"), _T("Miranda IM Jabber") },
  387. { _T("http://www.google.com"), _T("GTalk") },
  388. { _T("http://mail.google.com"), _T("GMail") },
  389. { _T("http://talk.google.com/xmpp/bot"), _T("GTalk Bot") },
  390. { _T("http://www.android.com"), _T("Android") },
  391. };
  392. void CJabberProto::UpdateMirVer(JABBER_LIST_ITEM *item)
  393. {
  394. HANDLE hContact = HContactFromJID(item->jid);
  395. if (!hContact)
  396. return;
  397. Log("JabberUpdateMirVer: for jid " TCHAR_STR_PARAM, item->jid);
  398. JABBER_RESOURCE_STATUS *resource = item->resourceMode == RSMODE_MANUAL ? item->manualResource : item->lastSeenResource;
  399. if (resource == NULL) resource = &item->resource[0];
  400. UpdateMirVer( hContact, resource );
  401. }
  402. void CJabberProto::FormatMirVer(JABBER_RESOURCE_STATUS *resource, TCHAR *buf, int bufSize)
  403. {
  404. if ( !buf || !bufSize ) return;
  405. buf[ 0 ] = _T('\0');
  406. if ( !resource ) return;
  407. // jabber:iq:version info requested and exists?
  408. if ( resource->dwVersionRequestTime && resource->software ) {
  409. Log("JabberUpdateMirVer: for iq:version rc " TCHAR_STR_PARAM ": " TCHAR_STR_PARAM, resource->resourceName, resource->software);
  410. if ( !resource->version || _tcsstr(resource->software, resource->version))
  411. lstrcpyn(buf, resource->software, bufSize);
  412. else
  413. mir_sntprintf(buf, bufSize, _T("%s %s"), resource->software, resource->version);
  414. }
  415. // no version info and no caps info? set MirVer = resource name
  416. else if ( !resource->szCapsNode || !resource->szCapsVer ) {
  417. Log("JabberUpdateMirVer: for rc " TCHAR_STR_PARAM ": " TCHAR_STR_PARAM, resource->resourceName, resource->resourceName);
  418. if ( resource->resourceName )
  419. lstrcpyn(buf, resource->resourceName, bufSize);
  420. }
  421. // XEP-0115 caps mode
  422. else {
  423. Log("JabberUpdateMirVer: for rc " TCHAR_STR_PARAM ": " TCHAR_STR_PARAM "#" TCHAR_STR_PARAM, resource->resourceName, resource->szCapsNode, resource->szCapsVer);
  424. int i;
  425. // search through known software list
  426. for (i = 0; i < SIZEOF(sttCapsNodeToName_Map); ++i)
  427. if ( _tcsstr( resource->szCapsNode, sttCapsNodeToName_Map[i].node ) )
  428. {
  429. mir_sntprintf( buf, bufSize, _T("%s %s"), sttCapsNodeToName_Map[i].name, resource->szCapsVer );
  430. break;
  431. }
  432. // unknown software
  433. if (i == SIZEOF(sttCapsNodeToName_Map))
  434. mir_sntprintf( buf, bufSize, _T("%s %s"), resource->szCapsNode, resource->szCapsVer );
  435. }
  436. // attach additional info for fingerprint plguin
  437. if (resource->resourceName && !_tcsstr(buf, resource->resourceName))
  438. {
  439. if (_tcsstr(buf, _T("Miranda IM")) || m_options.ShowForeignResourceInMirVer )
  440. {
  441. int offset = lstrlen(buf);
  442. mir_sntprintf(buf + offset, bufSize - offset, _T(" [%s]"), resource->resourceName);
  443. }
  444. }
  445. if (resource->szCapsExt && _tcsstr(resource->szCapsExt, _T(JABBER_EXT_SECUREIM)) && !_tcsstr(buf, _T("(SecureIM)")))
  446. {
  447. int offset = lstrlen(buf);
  448. mir_sntprintf(buf + offset, bufSize - offset, _T(" (SecureIM)"));
  449. }
  450. }
  451. void CJabberProto::UpdateMirVer(HANDLE hContact, JABBER_RESOURCE_STATUS *resource)
  452. {
  453. TCHAR szMirVer[ 512 ];
  454. FormatMirVer(resource, szMirVer, SIZEOF(szMirVer));
  455. if ( szMirVer[0] )
  456. JSetStringT( hContact, "MirVer", szMirVer );
  457. else
  458. JDeleteSetting( hContact, "MirVer" );
  459. DBVARIANT dbv;
  460. if ( !JGetStringT( hContact, "jid", &dbv )) {
  461. TCHAR szFullJid[ JABBER_MAX_JID_LEN ];
  462. if ( resource->resourceName )
  463. mir_sntprintf( szFullJid, SIZEOF( szFullJid ), _T("%s/%s"), dbv.ptszVal, resource->resourceName );
  464. else
  465. lstrcpyn( szFullJid, dbv.ptszVal, SIZEOF(szFullJid) );
  466. JSetStringT( hContact, DBSETTING_DISPLAY_UID, szFullJid );
  467. JFreeVariant( &dbv );
  468. }
  469. }
  470. void CJabberProto::UpdateSubscriptionInfo(HANDLE hContact, JABBER_LIST_ITEM *item)
  471. {
  472. switch (item->subscription)
  473. {
  474. case SUB_TO:
  475. JSetStringT(hContact, "SubscriptionText", TranslateT("To"));
  476. JSetString(hContact, "Subscription", "to");
  477. JSetByte(hContact, "Auth", 0);
  478. JSetByte(hContact, "Grant", 1);
  479. break;
  480. case SUB_FROM:
  481. JSetStringT(hContact, "SubscriptionText", TranslateT("From"));
  482. JSetString(hContact, "Subscription", "from");
  483. JSetByte(hContact, "Auth", 1);
  484. JSetByte(hContact, "Grant", 0);
  485. break;
  486. case SUB_BOTH:
  487. JSetStringT(hContact, "SubscriptionText", TranslateT("Both"));
  488. JSetString(hContact, "Subscription", "both");
  489. JSetByte(hContact, "Auth", 0);
  490. JSetByte(hContact, "Grant", 0);
  491. break;
  492. case SUB_NONE:
  493. JSetStringT(hContact, "SubscriptionText", TranslateT("None"));
  494. JSetString(hContact, "Subscription", "none");
  495. JSetByte(hContact, "Auth", 1);
  496. JSetByte(hContact, "Grant", 1);
  497. break;
  498. }
  499. }
  500. void CJabberProto::SetContactOfflineStatus( HANDLE hContact )
  501. {
  502. if ( JGetWord( hContact, "Status", ID_STATUS_OFFLINE ) != ID_STATUS_OFFLINE )
  503. JSetWord( hContact, "Status", ID_STATUS_OFFLINE );
  504. JDeleteSetting( hContact, DBSETTING_XSTATUSID );
  505. JDeleteSetting( hContact, DBSETTING_XSTATUSNAME );
  506. JDeleteSetting( hContact, DBSETTING_XSTATUSMSG );
  507. JDeleteSetting( hContact, DBSETTING_DISPLAY_UID );
  508. ResetAdvStatus( hContact, ADVSTATUS_MOOD );
  509. ResetAdvStatus( hContact, ADVSTATUS_TUNE );
  510. //JabberUpdateContactExtraIcon(hContact);
  511. }
  512. void CJabberProto::InitPopups(void)
  513. {
  514. TCHAR desc[256];
  515. char name[256];
  516. POPUPCLASS ppc = {0};
  517. ppc.cbSize = sizeof(ppc);
  518. ppc.flags = PCF_TCHAR;
  519. ppc.ptszDescription = desc;
  520. ppc.pszName = name;
  521. ppc.hIcon = LoadIconEx("main");
  522. ppc.colorBack = RGB(191, 0, 0); //Red
  523. ppc.colorText = RGB(255, 245, 225); //Yellow
  524. ppc.iSeconds = 60;
  525. mir_sntprintf(desc, SIZEOF(desc), _T("%s %s"), m_tszUserName, TranslateT("Errors"));
  526. mir_snprintf(name, SIZEOF(name), "%s_%s", m_szModuleName, "Error");
  527. JCallService(MS_POPUP_REGISTERCLASS, 0, (WPARAM)&ppc);
  528. }
  529. void CJabberProto::MsgPopup(HANDLE hContact, const TCHAR *szMsg, const TCHAR *szTitle)
  530. {
  531. if (ServiceExists(MS_POPUP_ADDPOPUPCLASS)) {
  532. char name[256];
  533. POPUPDATACLASS ppd = { sizeof(ppd) };
  534. ppd.ptszTitle = szTitle;
  535. ppd.ptszText = szMsg;
  536. ppd.pszClassName = name;
  537. ppd.hContact = hContact;
  538. mir_snprintf(name, SIZEOF(name), "%s_%s", m_szModuleName, "Error");
  539. JCallService(MS_POPUP_ADDPOPUPCLASS, 0, (LPARAM)&ppd);
  540. } else {
  541. DWORD mtype = MB_OK | MB_SETFOREGROUND | MB_ICONSTOP;
  542. MessageBox(NULL, szMsg, szTitle, mtype);
  543. }
  544. }