/* Omegle plugin for Miranda Instant Messenger _____________________________________________ Copyright © 2011-12 Robert Pösel This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "common.h" OmegleProto::OmegleProto(const char* proto_name, const TCHAR* username) { m_iVersion = 2; m_szProtoName = mir_strdup( proto_name ); m_szModuleName = mir_strdup( proto_name ); m_tszUserName = mir_tstrdup( username ); this->facy.parent = this; this->signon_lock_ = CreateMutex( NULL, FALSE, NULL ); this->log_lock_ = CreateMutex( NULL, FALSE, NULL ); this->facy.send_message_lock_ = CreateMutex( NULL, FALSE, NULL ); this->facy.connection_lock_ = CreateMutex( NULL, FALSE, NULL ); // Group chats CreateProtoService(m_szModuleName, PS_JOINCHAT, &OmegleProto::OnJoinChat, this); CreateProtoService(m_szModuleName, PS_LEAVECHAT, &OmegleProto::OnLeaveChat, this); CreateProtoService(m_szModuleName, PS_CREATEACCMGRUI, &OmegleProto::SvcCreateAccMgrUI, this); HookProtoEvent(ME_OPT_INITIALISE, &OmegleProto::OnOptionsInit, this); HookProtoEvent(ME_GC_EVENT, &OmegleProto::OnChatEvent, this); // Create standard network connection TCHAR descr[512]; NETLIBUSER nlu = {sizeof(nlu)}; nlu.flags = NUF_INCOMING | NUF_OUTGOING | NUF_HTTPCONNS | NUF_TCHAR; nlu.szSettingsModule = m_szModuleName; char module[512]; mir_snprintf(module,SIZEOF(module),"%sAv",m_szModuleName); nlu.szSettingsModule = module; mir_sntprintf(descr,SIZEOF(descr),TranslateT("%s server connection"),m_tszUserName); nlu.ptszDescriptiveName = descr; m_hNetlibUser = (HANDLE)CallService(MS_NETLIB_REGISTERUSER,0,(LPARAM)&nlu); if(m_hNetlibUser == NULL) MessageBox(NULL,TranslateT("Unable to get Netlib connection for Omegle"),m_tszUserName,MB_OK); facy.set_handle(m_hNetlibUser); SkinAddNewSoundExT( "StrangerTyp", m_tszUserName, LPGENT( "Stranger typing" ) ); SkinAddNewSoundExT( "StrangerTypStop", m_tszUserName, LPGENT( "Stranger stopped typing" ) ); SkinAddNewSoundExT( "StrangerChange", m_tszUserName, LPGENT( "Changing stranger" ) ); } OmegleProto::~OmegleProto( ) { Netlib_CloseHandle( m_hNetlibUser ); WaitForSingleObject( this->signon_lock_, IGNORE ); WaitForSingleObject( this->log_lock_, IGNORE ); WaitForSingleObject( this->facy.send_message_lock_, IGNORE ); WaitForSingleObject( this->events_loop_lock_, IGNORE ); CloseHandle( this->signon_lock_ ); CloseHandle( this->log_lock_ ); CloseHandle( this->facy.send_message_lock_ ); CloseHandle( this->events_loop_lock_ ); CloseHandle( this->facy.connection_lock_ ); mir_free( this->facy.nick_ ); mir_free( m_tszUserName ); mir_free( m_szModuleName ); mir_free( m_szProtoName ); } ////////////////////////////////////////////////////////////////////////////// DWORD_PTR OmegleProto::GetCaps( int type, HANDLE hContact ) { switch(type) { case PFLAGNUM_1: return PF1_IM | PF1_CHAT; // TODO: Why we need PF1_IM to activate smileys? Shouldnt be PF1_CHAT enough? case PFLAGNUM_2: return PF2_ONLINE; case PFLAGNUM_4: return PF4_IMSENDUTF; // | PF4_SUPPORTTYPING; case PFLAG_MAXLENOFMESSAGE: return OMEGLE_MESSAGE_LIMIT; } return 0; } HICON OmegleProto::GetIcon(int index) { if(LOWORD(index) == PLI_PROTOCOL) { HICON ico = (HICON)CallService(MS_SKIN2_GETICON,0,(LPARAM)"Omegle_omegle"); return CopyIcon(ico); } else { return 0; } } ////////////////////////////////////////////////////////////////////////////// int OmegleProto::SetStatus( int new_status ) { // Routing statuses not supported by Omegle switch ( new_status ) { case ID_STATUS_OFFLINE: case ID_STATUS_CONNECTING: new_status = ID_STATUS_OFFLINE; break; default: new_status = ID_STATUS_ONLINE; break; } m_iDesiredStatus = new_status; if ( new_status == m_iStatus) { return 0; } if ( m_iStatus == ID_STATUS_CONNECTING && new_status != ID_STATUS_OFFLINE ) { return 0; } if ( new_status == ID_STATUS_OFFLINE ) { ForkThread( &OmegleProto::SignOff, this ); } else { ForkThread( &OmegleProto::SignOn, this ); } return 0; } ////////////////////////////////////////////////////////////////////////////// int OmegleProto::OnEvent(PROTOEVENTTYPE event,WPARAM wParam,LPARAM lParam) { switch(event) { case EV_PROTO_ONLOAD: return OnModulesLoaded(wParam,lParam); case EV_PROTO_ONEXIT: return OnPreShutdown (wParam,lParam); case EV_PROTO_ONOPTIONS: return OnOptionsInit (wParam,lParam); case EV_PROTO_ONCONTACTDELETED: return OnContactDeleted(wParam,lParam); } return 1; } ////////////////////////////////////////////////////////////////////////////// // EVENTS int OmegleProto::SvcCreateAccMgrUI(WPARAM wParam,LPARAM lParam) { return (int)CreateDialogParam(g_hInstance,MAKEINTRESOURCE(IDD_OmegleACCOUNT), (HWND)lParam, OmegleAccountProc, (LPARAM)this ); } int OmegleProto::OnModulesLoaded(WPARAM wParam,LPARAM lParam) { // Register group chat GCREGISTER gcr = {sizeof(gcr)}; gcr.dwFlags = GC_TYPNOTIF; //GC_ACKMSG; gcr.pszModule = m_szModuleName; gcr.pszModuleDispName = m_szModuleName; gcr.iMaxText = OMEGLE_MESSAGE_LIMIT; gcr.nColors = 0; gcr.pColors = NULL; CallService(MS_GC_REGISTER,0,reinterpret_cast(&gcr)); return 0; } int OmegleProto::OnOptionsInit(WPARAM wParam,LPARAM lParam) { OPTIONSDIALOGPAGE odp = {sizeof(odp)}; odp.hInstance = g_hInstance; odp.ptszTitle = m_tszUserName; odp.dwInitParam = LPARAM(this); odp.flags = ODPF_BOLDGROUPS | ODPF_TCHAR | ODPF_DONTTRANSLATE; odp.position = 271828; odp.ptszGroup = LPGENT("Network"); odp.ptszTab = LPGENT("Account"); odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS); odp.pfnDlgProc = OmegleOptionsProc; CallService(MS_OPT_ADDPAGE,wParam,(LPARAM)&odp); return 0; } int OmegleProto::OnPreShutdown(WPARAM wParam,LPARAM lParam) { SetStatus( ID_STATUS_OFFLINE ); return 0; } int OmegleProto::OnContactDeleted(WPARAM wparam,LPARAM) { //HANDLE hContact = (HANDLE)wparam; OnLeaveChat(NULL, NULL); return 0; } ////////////////////////////////////////////////////////////////////////////// // OTHER /*bool OmegleProto::IsMyContact(HANDLE hContact, bool include_chat) { const char *proto = reinterpret_cast( CallService(MS_PROTO_GETCONTACTBASEPROTO, reinterpret_cast(hContact),0) ); if ( proto && strcmp(m_szModuleName,proto) == 0 ) { if ( include_chat ) return true; else return DBGetContactSettingByte(hContact,m_szModuleName,"ChatRoom",0) == 0; } else { return false; } }*/