/* Omegle plugin for Miranda Instant Messenger _____________________________________________ Copyright © 2011-17 Robert Pösel, 2017-23 Miranda NG team 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 "stdafx.h" OmegleProto::OmegleProto(const char* proto_name, const wchar_t* username) : PROTO(proto_name, username) { this->facy.parent = this; this->signon_lock_ = CreateMutex(nullptr, FALSE, nullptr); this->log_lock_ = CreateMutex(nullptr, FALSE, nullptr); this->facy.connection_lock_ = CreateMutex(nullptr, FALSE, nullptr); this->events_loop_lock_ = CreateMutex(nullptr, FALSE, nullptr); // Group chats CreateProtoService(PS_JOINCHAT, &OmegleProto::OnJoinChat); CreateProtoService(PS_LEAVECHAT, &OmegleProto::OnLeaveChat); HookProtoEvent(ME_OPT_INITIALISE, &OmegleProto::OnOptionsInit); HookProtoEvent(ME_GC_EVENT, &OmegleProto::OnChatEvent); // Create standard network connection NETLIBUSER nlu = {}; nlu.flags = NUF_INCOMING | NUF_OUTGOING | NUF_HTTPCONNS | NUF_UNICODE; nlu.szSettingsModule = m_szModuleName; nlu.szDescriptiveName.w = m_tszUserName; m_hNetlibUser = Netlib_RegisterUser(&nlu); if (m_hNetlibUser == nullptr) { wchar_t error[200]; mir_snwprintf(error, TranslateT("Unable to initialize Netlib for %s."), m_tszUserName); MessageBox(nullptr, error, L"Miranda NG", MB_OK | MB_ICONERROR); } facy.set_handle(m_hNetlibUser); g_plugin.addSound("StrangerTyp", m_tszUserName, LPGENW("Stranger is typing")); g_plugin.addSound("StrangerTypStop", m_tszUserName, LPGENW("Stranger stopped typing")); g_plugin.addSound("StrangerChange", m_tszUserName, LPGENW("Changing stranger")); g_plugin.addSound("StrangerMessage", m_tszUserName, LPGENW("Receive message")); // Register group chat GCREGISTER gcr = {}; gcr.dwFlags = 0; //GC_TYPNOTIF; //GC_ACKMSG; gcr.pszModule = m_szModuleName; gcr.ptszDispName = m_tszUserName; gcr.iMaxText = OMEGLE_MESSAGE_LIMIT; Chat_Register(&gcr); } OmegleProto::~OmegleProto() { Netlib_CloseHandle(m_hNetlibUser); WaitForSingleObject(this->signon_lock_, IGNORE); WaitForSingleObject(this->log_lock_, IGNORE); WaitForSingleObject(this->events_loop_lock_, IGNORE); CloseHandle(this->signon_lock_); CloseHandle(this->log_lock_); CloseHandle(this->events_loop_lock_); CloseHandle(this->facy.connection_lock_); } ////////////////////////////////////////////////////////////////////////////// INT_PTR OmegleProto::GetCaps(int type, MCONTACT) { switch (type) { case PFLAGNUM_1: return PF1_CHAT; case PFLAGNUM_2: return PF2_ONLINE; case PFLAGNUM_4: return PF4_SUPPORTTYPING; case PFLAG_MAXLENOFMESSAGE: return OMEGLE_MESSAGE_LIMIT; case PFLAG_UNIQUEIDTEXT: return (INT_PTR)TranslateT("Visible name"); } 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; } ////////////////////////////////////////////////////////////////////////////// // EVENTS MWindow OmegleProto::OnCreateAccMgrUI(MWindow hwndParent) { return CreateDialogParam(g_plugin.getInst(), MAKEINTRESOURCE(IDD_OmegleACCOUNT), hwndParent, OmegleAccountProc, (LPARAM)this); } void OmegleProto::OnShutdown() { SetStatus(ID_STATUS_OFFLINE); } int OmegleProto::OnOptionsInit(WPARAM wParam, LPARAM) { OPTIONSDIALOGPAGE odp = {}; odp.szTitle.w = m_tszUserName; odp.dwInitParam = LPARAM(this); odp.flags = ODPF_BOLDGROUPS | ODPF_UNICODE | ODPF_DONTTRANSLATE; odp.position = 271828; odp.szGroup.w = LPGENW("Network"); odp.szTab.w = LPGENW("Account"); odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS); odp.pfnDlgProc = OmegleOptionsProc; g_plugin.addOptions(wParam, &odp); return 0; } void OmegleProto::OnContactDeleted(MCONTACT) { OnLeaveChat(NULL, NULL); } int OmegleProto::UserIsTyping(MCONTACT hContact, int type) { if (hContact && facy.state_ == STATE_ACTIVE) ForkThread(&OmegleProto::SendTypingWorker, new int(type)); return 0; }