From 1680c6d262eb0525c1af95195b5b79839a5e2ce9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20P=C3=B6sel?= Date: Tue, 22 May 2012 23:20:07 +0000 Subject: Added Omegle protocol. git-svn-id: http://svn.miranda-ng.org/main/trunk@136 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/Omegle/chat.cpp | 405 ++++++++++++ protocols/Omegle/client.h | 123 ++++ protocols/Omegle/common.h | 86 +++ protocols/Omegle/communication.cpp | 809 +++++++++++++++++++++++ protocols/Omegle/connection.cpp | 179 +++++ protocols/Omegle/constants.h | 54 ++ protocols/Omegle/db.h | 55 ++ protocols/Omegle/dialogs.cpp | 231 +++++++ protocols/Omegle/dialogs.h | 26 + protocols/Omegle/docs/omegle - langpack.txt | 104 +++ protocols/Omegle/docs/omegle - readme_cz.txt | 80 +++ protocols/Omegle/docs/omegle - readme_en.txt | 80 +++ protocols/Omegle/events.cpp | 39 ++ protocols/Omegle/http.cpp | 23 + protocols/Omegle/http.h | 48 ++ protocols/Omegle/icons/omegle.ico | Bin 0 -> 894 bytes protocols/Omegle/icons/proto_offline.ico | Bin 0 -> 1150 bytes protocols/Omegle/icons/proto_online.ico | Bin 0 -> 1150 bytes protocols/Omegle/main.cpp | 210 ++++++ protocols/Omegle/messages.cpp | 92 +++ protocols/Omegle/omegle.aps | Bin 0 -> 40344 bytes protocols/Omegle/omegle.rc | 214 ++++++ protocols/Omegle/omegle.sln | 36 + protocols/Omegle/omegle_10.vcxproj | 310 +++++++++ protocols/Omegle/omegle_10.vcxproj.filters | 97 +++ protocols/Omegle/omegle_icons.cpp | 0 protocols/Omegle/omegle_icons.rc | 73 ++ protocols/Omegle/omegle_icons_10.vcxproj | 145 ++++ protocols/Omegle/omegle_icons_10.vcxproj.filters | 30 + protocols/Omegle/process.cpp | 77 +++ protocols/Omegle/proto.cpp | 255 +++++++ protocols/Omegle/proto.h | 159 +++++ protocols/Omegle/readme.txt | 2 + protocols/Omegle/resource.h | 31 + protocols/Omegle/resource_icons.h | 17 + protocols/Omegle/stubs.cpp | 173 +++++ protocols/Omegle/theme.cpp | 115 ++++ protocols/Omegle/theme.h | 30 + protocols/Omegle/utils.cpp | 150 +++++ protocols/Omegle/utils.h | 103 +++ 40 files changed, 4661 insertions(+) create mode 100644 protocols/Omegle/chat.cpp create mode 100644 protocols/Omegle/client.h create mode 100644 protocols/Omegle/common.h create mode 100644 protocols/Omegle/communication.cpp create mode 100644 protocols/Omegle/connection.cpp create mode 100644 protocols/Omegle/constants.h create mode 100644 protocols/Omegle/db.h create mode 100644 protocols/Omegle/dialogs.cpp create mode 100644 protocols/Omegle/dialogs.h create mode 100644 protocols/Omegle/docs/omegle - langpack.txt create mode 100644 protocols/Omegle/docs/omegle - readme_cz.txt create mode 100644 protocols/Omegle/docs/omegle - readme_en.txt create mode 100644 protocols/Omegle/events.cpp create mode 100644 protocols/Omegle/http.cpp create mode 100644 protocols/Omegle/http.h create mode 100644 protocols/Omegle/icons/omegle.ico create mode 100644 protocols/Omegle/icons/proto_offline.ico create mode 100644 protocols/Omegle/icons/proto_online.ico create mode 100644 protocols/Omegle/main.cpp create mode 100644 protocols/Omegle/messages.cpp create mode 100644 protocols/Omegle/omegle.aps create mode 100644 protocols/Omegle/omegle.rc create mode 100644 protocols/Omegle/omegle.sln create mode 100644 protocols/Omegle/omegle_10.vcxproj create mode 100644 protocols/Omegle/omegle_10.vcxproj.filters create mode 100644 protocols/Omegle/omegle_icons.cpp create mode 100644 protocols/Omegle/omegle_icons.rc create mode 100644 protocols/Omegle/omegle_icons_10.vcxproj create mode 100644 protocols/Omegle/omegle_icons_10.vcxproj.filters create mode 100644 protocols/Omegle/process.cpp create mode 100644 protocols/Omegle/proto.cpp create mode 100644 protocols/Omegle/proto.h create mode 100644 protocols/Omegle/readme.txt create mode 100644 protocols/Omegle/resource.h create mode 100644 protocols/Omegle/resource_icons.h create mode 100644 protocols/Omegle/stubs.cpp create mode 100644 protocols/Omegle/theme.cpp create mode 100644 protocols/Omegle/theme.h create mode 100644 protocols/Omegle/utils.cpp create mode 100644 protocols/Omegle/utils.h (limited to 'protocols/Omegle') diff --git a/protocols/Omegle/chat.cpp b/protocols/Omegle/chat.cpp new file mode 100644 index 0000000000..169877b9fb --- /dev/null +++ b/protocols/Omegle/chat.cpp @@ -0,0 +1,405 @@ +/* + +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" + +void OmegleProto::UpdateChat(const TCHAR *name, const TCHAR *message, bool addtolog) +{ + GCDEST gcd = { m_szModuleName }; + gcd.ptszID = const_cast(m_tszUserName); + + GCEVENT gce = {sizeof(gce)}; + gce.pDest = &gcd; + gce.ptszText = message; + gce.time = ::time(NULL); + gce.dwFlags = GC_TCHAR; + gcd.iType = GC_EVENT_MESSAGE; + + if (name == NULL) { + gcd.iType = GC_EVENT_INFORMATION; + name = TranslateT("Server"); + gce.bIsMe = false; + } else { + gce.bIsMe = !_tcscmp(name, this->facy.nick_); + } + + if (addtolog) + gce.dwFlags |= GCEF_ADDTOLOG; + + gce.ptszNick = name; + gce.ptszUID = gce.ptszNick; + + CallServiceSync(MS_GC_EVENT,0,reinterpret_cast(&gce)); +} + +int OmegleProto::OnChatEvent(WPARAM wParam,LPARAM lParam) +{ + GCHOOK *hook = reinterpret_cast(lParam); + + if(strcmp(hook->pDest->pszModule,m_szModuleName)) + return 0; + + switch(hook->pDest->iType) + { + case GC_USER_MESSAGE: + { + std::string text = mir_t2a_cp(hook->ptszText,CP_UTF8); + + if (text.empty()) + break; + + if (text.substr(0,1) == "/") + { // Process commands + + std::string command = ""; + std::string params = ""; + + std::string::size_type pos = 0; + if ((pos = text.find(" ")) != std::string::npos) { + command = text.substr(1, pos-1); + params = text.substr(pos+1); + } else { + command = text.substr(1); + } + + if (!stricmp(command.c_str(), "new")) + { + facy.spy_mode_ = false; + facy.question_ = ""; + + ForkThread(&OmegleProto::NewChatWorker, this, NULL); + break; + } + else if (!stricmp(command.c_str(), "quit")) + { + ForkThread(&OmegleProto::StopChatWorker, this, NULL); + break; + } + else if (!stricmp(command.c_str(), "spy")) + { + facy.spy_mode_ = true; + facy.question_ = ""; + + ForkThread(&OmegleProto::NewChatWorker, this, NULL); + break; + } + else if (!stricmp(command.c_str(), "ask")) + { + if (params.empty()) { + // Load last question + DBVARIANT dbv; + if ( !getU8String( OMEGLE_KEY_LAST_QUESTION,&dbv ) ) { + params = dbv.pszVal; + DBFreeVariant(&dbv); + } + + if (params.empty()) { + UpdateChat(NULL, TranslateT("Last question is empty."), false); + break; + } + } else { + // Save actual question as last question + if (strlen(params.c_str()) >= OMEGLE_QUESTION_MIN_LENGTH) + { + setU8String( OMEGLE_KEY_LAST_QUESTION, params.c_str() ); + } + } + + if (strlen(params.c_str()) < OMEGLE_QUESTION_MIN_LENGTH) + { + UpdateChat(NULL, TranslateT("Your question is too short."), false); + break; + } + + facy.spy_mode_ = true; + facy.question_ = params; + ForkThread(&OmegleProto::NewChatWorker, this, NULL); + break; + } + else if (!stricmp(command.c_str(), "asl")) + { + DBVARIANT dbv; + if ( !getU8String( OMEGLE_KEY_ASL,&dbv ) ) { + text = dbv.pszVal; + DBFreeVariant(&dbv); + } else { + UpdateChat(NULL, TranslateT("Your '/asl' setting is empty."), false); + break; + } + } + else if (!stricmp(command.c_str(), "help")) + { + UpdateChat(NULL, TranslateT("There are three different modes of chatting:\ +\n1) Standard mode\t - You chat with random stranger privately\ +\n2) Question mode\t - You ask two strangers a question and see how they discuss it (you can't join their conversation, only watch)\ +\n3) Spy mode\t - You and stranger got a question to discuss from third stranger (he can't join your conversation, only watch)\ +\n\nSend '/commands' for available commands."), false); + } + else if (!stricmp(command.c_str(), "commands")) + { + UpdateChat(NULL, TranslateT("You can use different commands:\ +\n/help\t - show info about chat modes\ +\n/new\t - start standard mode\ +\n/ask - start question mode with your question\ +\n/ask\t - start question mode with your last asked question\ +\n/spy\t - start spy mode\ +\n/quit\t - disconnect from stranger or stop connecting\ +\n/asl\t - send your predefined ASL message\ +\n\nNote: You can reconnect to different stranger without disconnecting from current one."), false); + break; + } + else + { + UpdateChat(NULL, TranslateT("Unknown command. Send '/commands' for list."), false); + break; + } + + } + + // Outgoing message + switch (facy.state_) + { + case STATE_ACTIVE: + LOG("**Chat - Outgoing message: %s", text.c_str()); + ForkThread(&OmegleProto::SendMsgWorker, this, (void*)new std::string(text)); + break; + + case STATE_INACTIVE: + UpdateChat(NULL, TranslateT("You aren't connected to any stranger. Send '/help' or '/commands' for help."), false); + break; + + case STATE_SPY: + UpdateChat(NULL, TranslateT("You can't send messages in question mode."), false); + break; + + //case STATE_WAITING: + //case STATE_DISCONNECTING: + default: + break; + } + + break; + } + + case GC_USER_TYPNOTIFY: + if ( facy.state_ == STATE_ACTIVE ) + ForkThread(&OmegleProto::SendTypingWorker, this, (void*)mir_tstrdup(hook->ptszText)); + break; + + case GC_USER_LEAVE: + case GC_SESSION_TERMINATE: + mir_free( facy.nick_ ); + ForkThread(&OmegleProto::StopChatWorker, this, NULL); + break; + } + + return 0; +} + +/*void OmegleProto::SendChatEvent(int type) +{ + GCDEST gcd = { m_szModuleName }; + gcd.ptszID = const_cast(m_tszUserName); + gcd.iType = GC_EVENT_CONTROL; + + GCEVENT gce = {sizeof(gce)}; + gce.dwFlags = GC_TCHAR; + gce.pDest = &gcd; + + CallServiceSync(MS_GC_EVENT,WINDOW_CLEARLOG,reinterpret_cast(&gce)); +}*/ + +void OmegleProto::AddChatContact(const TCHAR *name) +{ + GCDEST gcd = { m_szModuleName }; + gcd.ptszID = const_cast(m_tszUserName); + gcd.iType = GC_EVENT_JOIN; + + GCEVENT gce = {sizeof(gce)}; + gce.pDest = &gcd; + gce.dwFlags = GC_TCHAR | GCEF_ADDTOLOG; + gce.ptszNick = name; + gce.ptszUID = gce.ptszNick; + gce.time = static_cast(time(0)); + + if (name == NULL) + gce.bIsMe = false; + else + gce.bIsMe = !_tcscmp(name, this->facy.nick_); + + if (gce.bIsMe) + gce.ptszStatus = _T("Admin"); + else + gce.ptszStatus = _T("Normal"); + + CallServiceSync(MS_GC_EVENT,0,reinterpret_cast(&gce)); +} + +void OmegleProto::DeleteChatContact(const TCHAR *name) +{ + GCDEST gcd = { m_szModuleName }; + gcd.ptszID = const_cast(m_tszUserName); + gcd.iType = GC_EVENT_PART; + + GCEVENT gce = {sizeof(gce)}; + gce.pDest = &gcd; + gce.dwFlags = GC_TCHAR | GCEF_ADDTOLOG; + gce.ptszNick = name; + gce.ptszUID = gce.ptszNick; + gce.time = static_cast(time(0)); + if (name == NULL) + gce.bIsMe = false; + else + gce.bIsMe = !_tcscmp(name, this->facy.nick_); + + CallServiceSync(MS_GC_EVENT,0,reinterpret_cast(&gce)); +} + +int OmegleProto::OnJoinChat(WPARAM,LPARAM suppress) +{ + GCSESSION gcw = {sizeof(gcw)}; + + // Create the group chat session + gcw.dwFlags = GC_TCHAR; + gcw.iType = GCW_CHATROOM; + gcw.pszModule = m_szModuleName; + gcw.ptszName = m_tszUserName; + gcw.ptszID = m_tszUserName; + CallServiceSync(MS_GC_NEWSESSION, 0, (LPARAM)&gcw); + + if(m_iStatus == ID_STATUS_OFFLINE) + return 0; + + // Create a group + GCDEST gcd = { m_szModuleName }; + gcd.ptszID = const_cast(m_tszUserName); + + GCEVENT gce = {sizeof(gce)}; + gce.pDest = &gcd; + gce.dwFlags = GC_TCHAR; + + gcd.iType = GC_EVENT_ADDGROUP; + + gce.ptszStatus = _T("Admin"); + CallServiceSync( MS_GC_EVENT, NULL, reinterpret_cast(&gce) ); + + gce.ptszStatus = _T("Normal"); + CallServiceSync( MS_GC_EVENT, NULL, reinterpret_cast(&gce) ); + + SetTopic(); + + // Note: Initialization will finish up in SetChatStatus, called separately + if(!suppress) + SetChatStatus(m_iStatus); + + return 0; +} + +void OmegleProto::SetTopic(const TCHAR *topic) +{ + GCDEST gcd = { m_szModuleName }; + gcd.ptszID = const_cast(m_tszUserName); + gcd.iType = GC_EVENT_TOPIC; + + GCEVENT gce = {sizeof(gce)}; + gce.pDest = &gcd; + gce.dwFlags = GC_TCHAR; + gce.time = ::time(NULL); + + if (topic == NULL) + gce.ptszText = TranslateT("Omegle is a great way of meeting new friends!"); + else + gce.ptszText = topic; + + CallServiceSync(MS_GC_EVENT,0, reinterpret_cast(&gce)); +} + +int OmegleProto::OnLeaveChat(WPARAM,LPARAM) +{ + GCDEST gcd = { m_szModuleName }; + gcd.ptszID = const_cast(m_tszUserName); + gcd.iType = GC_EVENT_CONTROL; + + GCEVENT gce = {sizeof(gce)}; + gce.dwFlags = GC_TCHAR; + gce.time = ::time(NULL); + gce.pDest = &gcd; + + CallServiceSync(MS_GC_EVENT,SESSION_OFFLINE, reinterpret_cast(&gce)); + CallServiceSync(MS_GC_EVENT,SESSION_TERMINATE,reinterpret_cast(&gce)); + + return 0; +} + +void OmegleProto::SetChatStatus(int status) +{ + GCDEST gcd = { m_szModuleName }; + gcd.ptszID = const_cast(m_tszUserName); + gcd.iType = GC_EVENT_CONTROL; + + GCEVENT gce = {sizeof(gce)}; + gce.dwFlags = GC_TCHAR; + gce.time = ::time(NULL); + gce.pDest = &gcd; + + if(status == ID_STATUS_ONLINE) + { + // Free previously loaded name + mir_free(facy.nick_); + + // Load actual name from database + DBVARIANT dbv; + if ( !DBGetContactSettingTString(NULL, m_szModuleName, OMEGLE_KEY_NAME, &dbv) ) + { + facy.nick_ = mir_tstrdup(dbv.ptszVal); + DBFreeVariant(&dbv); + } else { + facy.nick_ = mir_tstrdup(TranslateT("You")); + DBWriteContactSettingTString(NULL, m_szModuleName, OMEGLE_KEY_NAME, facy.nick_); + } + + // Add self contact + AddChatContact(facy.nick_); + + CallServiceSync(MS_GC_EVENT,SESSION_INITDONE,reinterpret_cast(&gce)); + CallServiceSync(MS_GC_EVENT,SESSION_ONLINE, reinterpret_cast(&gce)); + } + else + { + CallServiceSync(MS_GC_EVENT,SESSION_OFFLINE,reinterpret_cast(&gce)); + } +} + +void OmegleProto::ClearChat() +{ + if (getByte(OMEGLE_KEY_NO_CLEAR, 0)) + return; + + GCDEST gcd = { m_szModuleName }; + gcd.ptszID = const_cast(m_tszUserName); + gcd.iType = GC_EVENT_CONTROL; + + GCEVENT gce = {sizeof(gce)}; + gce.dwFlags = GC_TCHAR; + gce.pDest = &gcd; + + CallServiceSync(MS_GC_EVENT,WINDOW_CLEARLOG,reinterpret_cast(&gce)); +} \ No newline at end of file diff --git a/protocols/Omegle/client.h b/protocols/Omegle/client.h new file mode 100644 index 0000000000..be5ec9055c --- /dev/null +++ b/protocols/Omegle/client.h @@ -0,0 +1,123 @@ +/* + +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 . + +*/ + +#pragma once + +#define FORCE_DISCONNECT true + +#define STATE_INACTIVE 0 // not connected to any stranger +#define STATE_WAITING 1 // connecting to stranger +#define STATE_ACTIVE 2 // active discussion +#define STATE_DISCONNECTING 3 // disconnecting from stranger +#define STATE_SPY 4 // spy mode (read-only) + +class Omegle_client +{ +public: + + // Client definition + Omegle_client( ) + { + chat_id_ = server_ = question_ = ""; + nick_ = NULL; + //msgid_ = 0; + send_message_lock_ = NULL; + state_ = STATE_INACTIVE; + + old_typing_ = typing_ = spy_mode_ = false; + + hConnection = NULL; + hEventsConnection = NULL; + connection_lock_ = NULL; + } + + HANDLE hConnection; + HANDLE hEventsConnection; + HANDLE connection_lock_; + + // Parent handle + OmegleProto* parent; + + // Chat data + std::string chat_id_; + std::string server_; + std::string question_; + TCHAR *nick_; + + HANDLE send_message_lock_; + //int msgid_; + + // State of client + int state_; + bool typing_; + bool old_typing_; + bool spy_mode_; + + // Data storage + std::map< std::string, std::string > headers; + void store_headers( http::response* resp, NETLIBHTTPHEADER* headers, int headers_count ); + + std::string get_server( bool not_last = false ); + + // Connection handling + unsigned int error_count_; + + bool handle_entry( std::string method ); + bool handle_success( std::string method ); + bool handle_error( std::string method, bool force_disconnect = false ); + + void __inline increment_error( ) { error_count_++; } + void __inline decrement_error( ) { if ( error_count_ > 0 ) error_count_--; } + void __inline reset_error( ) { error_count_ = 0; } + + bool start( ); + bool stop( ); + bool events( ); + + bool typing_start( ); + bool typing_stop( ); + bool recaptcha( ); + + std::string get_page( int ); + + bool send_message( std::string message_text ); + + // HTTP communication + http::response flap( const int request_type, std::string* request_data = NULL, std::string* get_data = NULL ); + + int choose_method( int ); + std::string choose_proto( int ); + std::string choose_server( int, std::string* data = NULL, std::string* get_data = NULL ); + std::string choose_action( int, std::string* data = NULL, std::string* get_data = NULL ); + std::string choose_request_url( int, std::string* data = NULL, std::string* get_data = NULL ); + + NETLIBHTTPHEADER* get_request_headers( int request_type, int* headers_count ); + + // Netlib handle + + HANDLE handle_; + + void set_handle(HANDLE h) + { + handle_ = h; + } +}; diff --git a/protocols/Omegle/common.h b/protocols/Omegle/common.h new file mode 100644 index 0000000000..155521c59f --- /dev/null +++ b/protocols/Omegle/common.h @@ -0,0 +1,86 @@ +/* + +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 . + +*/ + +#pragma once + +#pragma warning(disable:4996) + +#define MIRANDA_VER 0x1000 +#define _WIN32_WINNT 0x0500 +#define _WIN32_WINDOWS 0x0500 + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include + +class OmegleProto; + +#define LOG Log + +#include "http.h" +#include "utils.h" +#include "client.h" +#include "proto.h" +#include "db.h" +#include "constants.h" +#include "dialogs.h" +#include "theme.h" +#include "resource.h" + +extern HINSTANCE g_hInstance; +extern std::string g_strUserAgent; +extern DWORD g_mirandaVersion; \ No newline at end of file diff --git a/protocols/Omegle/communication.cpp b/protocols/Omegle/communication.cpp new file mode 100644 index 0000000000..bdc5490bb1 --- /dev/null +++ b/protocols/Omegle/communication.cpp @@ -0,0 +1,809 @@ +/* + +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" + +http::response Omegle_client::flap( const int request_type, std::string* request_data, std::string* get_data ) +{ + NETLIBHTTPREQUEST nlhr = {sizeof( NETLIBHTTPREQUEST )}; + nlhr.requestType = choose_method( request_type ); + std::string url = choose_request_url( request_type, request_data, get_data ); + nlhr.szUrl = (char*)url.c_str( ); + nlhr.flags = NLHRF_HTTP11 | NLHRF_NODUMP; + nlhr.headers = get_request_headers( request_type, &nlhr.headersCount ); + nlhr.timeout = 1000 * (( request_type == OMEGLE_REQUEST_EVENTS ) ? 60 : 15); + + if ( request_data != NULL ) + { + nlhr.pData = (char*)(*request_data).c_str(); + nlhr.dataLength = (int)request_data->length( ); + } + + parent->Log("@@@@@ Sending request to '%s'", nlhr.szUrl); + + switch ( request_type ) + { + case OMEGLE_REQUEST_HOME: + nlhr.nlc = NULL; + break; + + case OMEGLE_REQUEST_EVENTS: + nlhr.nlc = hEventsConnection; + nlhr.flags |= NLHRF_PERSISTENT; + break; + + default: + WaitForSingleObject(connection_lock_, INFINITE); + nlhr.nlc = hConnection; + nlhr.flags |= NLHRF_PERSISTENT; + break; + } + + NETLIBHTTPREQUEST* pnlhr = ( NETLIBHTTPREQUEST* )CallService( MS_NETLIB_HTTPTRANSACTION, (WPARAM)handle_, (LPARAM)&nlhr ); + + http::response resp; + + switch ( request_type ) + { + case OMEGLE_REQUEST_HOME: + break; + + case OMEGLE_REQUEST_EVENTS: + hEventsConnection = pnlhr ? pnlhr->nlc : NULL; + break; + + default: + ReleaseMutex(connection_lock_); + hConnection = pnlhr ? pnlhr->nlc : NULL; + break; + } + + if ( pnlhr != NULL ) + { + parent->Log("@@@@@ Got response with code %d", pnlhr->resultCode); + store_headers( &resp, pnlhr->headers, pnlhr->headersCount ); + resp.code = pnlhr->resultCode; + resp.data = pnlhr->pData ? pnlhr->pData : ""; + + parent->Log("&&&&& Got response: %s", resp.data.c_str()); + + CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)pnlhr); + } else { + parent->Log("!!!!! No response from server (time-out)"); + resp.code = HTTP_CODE_FAKE_DISCONNECTED; + // Better to have something set explicitely as this value + // is compaired in all communication requests + } + + return resp; +} + +bool Omegle_client::handle_entry( std::string method ) +{ + parent->Log(" >> Entering %s()", method.c_str()); + return true; +} + +bool Omegle_client::handle_success( std::string method ) +{ + parent->Log(" << Quitting %s()", method.c_str()); + reset_error(); + return true; +} + +bool Omegle_client::handle_error( std::string method, bool force_disconnect ) +{ + bool result; + increment_error(); + parent->Log("!!!!! %s(): Something with Omegle went wrong", method.c_str()); + + if ( force_disconnect ) + result = false; + else if ( error_count_ <= (UINT)DBGetContactSettingByte(NULL,parent->m_szModuleName,OMEGLE_KEY_TIMEOUTS_LIMIT,OMEGLE_TIMEOUTS_LIMIT)) + result = true; + else + result = false; + + if ( result == false ) + { + reset_error(); + parent->UpdateChat(NULL, TranslateT("Connection error.")); + parent->StopChat(false); + } + + return result; +} + +////////////////////////////////////////////////////////////////////////////// + +std::string Omegle_client::get_server( bool not_last ) +{ + BYTE q = not_last ? 1 : 0; + + BYTE server = DBGetContactSettingByte(NULL, parent->m_szModuleName, OMEGLE_KEY_SERVER, 0); + if (server < 0 || server >= (SIZEOF(servers)-q)) + server = 0; + + if (server == 0) { + srand(::time(NULL)); + server = (rand() % (SIZEOF(servers)-1-q))+1; + } + + return servers[server]; +} + +int Omegle_client::choose_method( int request_type ) +{ + switch ( request_type ) + { + case OMEGLE_REQUEST_HOME: + case OMEGLE_REQUEST_COUNT: + return REQUEST_GET; + +/* case OMEGLE_REQUEST_START: + case OMEGLE_REQUEST_STOP: + case OMEGLE_REQUEST_SEND: + case OMEGLE_REQUEST_EVENTS: + case OMEGLE_REQUEST_TYPING_START: + case OMEGLE_REQUEST_TYPING_STOP: + case OMEGLE_REQUEST_RECAPTCHA: +*/ default: + return REQUEST_POST; + } +} + +std::string Omegle_client::choose_server( int request_type, std::string* data, std::string* get_data ) +{ + switch ( request_type ) + { + case OMEGLE_REQUEST_HOME: + return OMEGLE_SERVER_REGULAR; + +/* case OMEGLE_REQUEST_START: + case OMEGLE_REQUEST_STOP: + case OMEGLE_REQUEST_SEND: + case OMEGLE_REQUEST_EVENTS: + case OMEGLE_REQUEST_TYPING_START: + case OMEGLE_REQUEST_TYPING_STOP: + case OMEGLE_REQUEST_RECAPTCHA: + case OMEGLE_REQUEST_COUNT: +*/ default: + std::string server = OMEGLE_SERVER_CHAT; + utils::text::replace_first( &server, "%s", this->server_ ); + return server; + } +} + +std::string Omegle_client::choose_action( int request_type, std::string* data, std::string* get_data ) +{ + switch ( request_type ) + { + case OMEGLE_REQUEST_START: + { + std::string action = "/start?rcs=1&spid="; + if (get_data != NULL) + action += (*get_data); + + return action; + } + + case OMEGLE_REQUEST_STOP: + return "/disconnect"; + + case OMEGLE_REQUEST_SEND: + return "/send"; + + case OMEGLE_REQUEST_EVENTS: + return "/events"; + + case OMEGLE_REQUEST_TYPING_START: + return "/typing"; + + case OMEGLE_REQUEST_TYPING_STOP: + return "/stoppedtyping"; + + case OMEGLE_REQUEST_RECAPTCHA: + return "/recaptcha"; + + case OMEGLE_REQUEST_COUNT: + return "/count"; + + // "/stoplookingforcommonlikes" + +/* case OMEGLE_REQUEST_HOME: +*/ default: + return "/"; + } +} + +std::string Omegle_client::choose_request_url( int request_type, std::string* data, std::string* get_data ) +{ + std::string url = ""; + url.append( choose_server( request_type, data, get_data ) ); + url.append( choose_action( request_type, data, get_data ) ); + return url; +} + +NETLIBHTTPHEADER* Omegle_client::get_request_headers( int request_type, int* headers_count ) +{ + switch ( request_type ) + { + case OMEGLE_REQUEST_START: + case OMEGLE_REQUEST_STOP: + case OMEGLE_REQUEST_SEND: + case OMEGLE_REQUEST_EVENTS: + case OMEGLE_REQUEST_TYPING_START: + case OMEGLE_REQUEST_TYPING_STOP: + case OMEGLE_REQUEST_RECAPTCHA: + *headers_count = 4; + break; + + case OMEGLE_REQUEST_HOME: + case OMEGLE_REQUEST_COUNT: + default: + *headers_count = 3; + break; + } + + NETLIBHTTPHEADER* headers = ( NETLIBHTTPHEADER* )utils::mem::allocate( sizeof( NETLIBHTTPHEADER )*( *headers_count ) ); + + switch ( request_type ) + { + case OMEGLE_REQUEST_START: + case OMEGLE_REQUEST_STOP: + case OMEGLE_REQUEST_SEND: + case OMEGLE_REQUEST_EVENTS: + case OMEGLE_REQUEST_TYPING_START: + case OMEGLE_REQUEST_TYPING_STOP: + case OMEGLE_REQUEST_RECAPTCHA: + headers[3].szName = "Content-Type"; + headers[3].szValue = "application/x-www-form-urlencoded; charset=utf-8"; + + case OMEGLE_REQUEST_HOME: + case OMEGLE_REQUEST_COUNT: + default: + headers[2].szName = "User-Agent"; + headers[2].szValue = (char *)g_strUserAgent.c_str( ); + headers[1].szName = "Accept"; + headers[1].szValue = "*/*"; + headers[0].szName = "Accept-Language"; + headers[0].szValue = "en,en-US;q=0.9"; + break; + } + + return headers; +} + +void Omegle_client::store_headers( http::response* resp, NETLIBHTTPHEADER* headers, int headersCount ) +{ + for ( int i = 0; i < headersCount; i++ ) + { + std::string header_name = headers[i].szName; + std::string header_value = headers[i].szValue; + + // TODO RM: (un)comment + //parent->Log("----- Got header '%s': %s", header_name.c_str(), header_value.c_str() ); + resp->headers[header_name] = header_value; + } +} + +////////////////////////////////////////////////////////////////////////////// + +bool Omegle_client::start() +{ + handle_entry( "start" ); + + this->server_ = get_server(); + //parent->Log("Chosing server %s", this->server_.c_str()); + //std::string log = Translate("Chosing server: ") + this->server_; + //parent->UpdateChat(NULL, log.c_str()); + + std::string data; + + if (this->spy_mode_) { + // Select any server but quarks, which doesn't support this (it seems) + this->server_ = get_server(true); + + if (this->question_.empty()) { + data = "&wantsspy=1"; + } else { + data = "&ask=" + utils::url::encode(this->question_); + data += "&cansavequestion="; + data += DBGetContactSettingByte(NULL, parent->m_szModuleName, OMEGLE_KEY_REUSE_QUESTION, 0) ? "1" : "0"; + } + } + else if ( DBGetContactSettingByte(NULL, parent->m_szModuleName, OMEGLE_KEY_MEET_COMMON, 0) ) + { + DBVARIANT dbv; + if (!DBGetContactSettingUTF8String(NULL, parent->m_szModuleName, OMEGLE_KEY_INTERESTS, &dbv)) + { + std::string topics = dbv.pszVal; + std::string topic; + + DBFreeVariant(&dbv); + + std::string::size_type pos = 0; + std::string::size_type pos2 = 0; + while ((pos2 = topics.find(",", pos)) != std::string::npos) { + topic = topics.substr(pos, pos2 - pos); + topic = utils::text::trim(topic); + + if (!topic.empty()) { + if (pos > 0) + data += ","; + + data += "\"" + topic + "\""; + } + + pos = pos2 + 1; + } + + topic = topics.substr(pos); + topic = utils::text::trim(topic); + if (!topic.empty()) { + if (pos > 0) + data += ","; + data += "\"" + topic + "\""; + } + + parent->Log("TOPICS: %s", data.c_str()); + + if (!data.empty()) { + data = "[" + data + "]"; + data = "&topics=" + utils::url::encode(data); + } + + // Interests feature supports only Quarks server + this->server_ = "quarks"; + } + } + + if (DBGetContactSettingByte(NULL, parent->m_szModuleName, OMEGLE_KEY_SERVER_INFO, 0)) + { + std::string count = get_page( OMEGLE_REQUEST_COUNT ); + if (!count.empty()) { + char str[255]; + mir_snprintf(str, sizeof(str), Translate("Connected to server %s. There are %s users online now."), server_.c_str(), count.c_str()); + + TCHAR *msg = mir_a2t_cp(str,CP_UTF8); + parent->UpdateChat(NULL, msg); + mir_free(msg); + } + } + + // Send validation + http::response resp = flap( OMEGLE_REQUEST_START, NULL, &data ); + + switch ( resp.code ) + { + case HTTP_CODE_FAKE_DISCONNECTED: + { + // If is is only timeout error, try login once more + if ( handle_error( "start" ) ) + return start(); + else + return false; + } + + case HTTP_CODE_OK: + { + if (!resp.data.empty()) { + this->chat_id_ = resp.data.substr(1,resp.data.length()-2); + this->state_ = STATE_WAITING; + + return handle_success( "start" ); + } else { + return handle_error( "start", FORCE_DISCONNECT ); + } + } + + default: + return handle_error( "start", FORCE_DISCONNECT ); + } +} + +bool Omegle_client::stop( ) +{ + if ( parent->isOffline() ) + return true; + + handle_entry( "stop" ); + + std::string data = "id=" + this->chat_id_; + + http::response resp = flap( OMEGLE_REQUEST_STOP, &data ); + + if (hConnection) + Netlib_CloseHandle(hConnection); + hConnection = NULL; + + if (hEventsConnection) + Netlib_CloseHandle(hEventsConnection); + hEventsConnection = NULL; + + if (resp.data == "win") { + return handle_success( "stop" ); + } else { + return handle_error( "stop" ); + } + +/* switch ( resp.code ) + { + case HTTP_CODE_OK: + case HTTP_CODE_FOUND: + + default: + + }*/ +} + +bool Omegle_client::events( ) +{ + handle_entry( "events" ); + + std::string data = "id=" + this->chat_id_; + + // Get update + http::response resp = flap( OMEGLE_REQUEST_EVENTS, &data ); + + // Return + switch ( resp.code ) + { + case HTTP_CODE_OK: + { + if ( resp.data == "null" ) { + // Everything is OK, no new message received -- OR it is a problem + // TODO: if we are waiting for Stranger with common likes, then we should try standard Stranger if this takes too long + return handle_error( "events" ); + } else if ( resp.data == "fail" ) { + // Something went wrong + return handle_error( "events" ); + } + + std::string::size_type pos = 0; + bool newStranger = false; + bool waiting = false; + + if ( resp.data.find( "[\"waiting\"]" ) != std::string::npos ) { + // We are just waiting for new Stranger + waiting = true; + } + + /*if ( (pos = resp.data.find( "[\"count\"," )) != std::string::npos ) { + // We got info about count of connected people there + pos += 9; + + std::string count = utils::text::trim( resp.data.substr(pos, resp.data.find("]", pos) - pos) ); + + char str[255]; + mir_snprintf(str, sizeof(str), Translate("On whole Omegle are %s strangers online now."), count.c_str()); + + TCHAR *msg = mir_a2t_cp(str,CP_UTF8); + parent->UpdateChat(NULL, msg); + mir_free(msg); + }*/ + + if ( resp.data.find( "[\"connected\"]" ) != std::string::npos ) { + // Stranger connected + if (this->spy_mode_ && !this->question_.empty()) { + parent->AddChatContact(TranslateT("Stranger 1")); + parent->AddChatContact(TranslateT("Stranger 2")); + this->state_ = STATE_SPY; + } else { + parent->AddChatContact(TranslateT("Stranger")); + this->state_ = STATE_ACTIVE; + } + + newStranger = true; + waiting = false; + } + + if ( (pos = resp.data.find( "[\"commonLikes\"," )) != std::string::npos ) { + pos += 18; + std::string like = resp.data.substr(pos, resp.data.find("\"]", pos) - pos); + utils::text::replace_all(&like, "\", \"", ", "); + + parent->Log("Got common likes: '%s'", like.c_str()); + + like = Translate("You and the Stranger both like: ") + like; + + TCHAR *msg = mir_a2t_cp(like.c_str(),CP_UTF8); + parent->SetTopic(msg); + mir_free(msg); + } + + if ( (pos = resp.data.find( "[\"question\"," )) != std::string::npos ) { + pos += 14; + + std::string question = utils::text::trim( + utils::text::special_expressions_decode( + utils::text::slashu_to_utf8( + resp.data.substr(pos, resp.data.find("\"]", pos) - pos) ) ) ); + + TCHAR *msg = mir_a2t_cp(question.c_str(),CP_UTF8); + parent->SetTopic(msg); + mir_free(msg); + } + + if ( resp.data.find( "[\"typing\"]" ) != std::string::npos + || resp.data.find( "[\"spyTyping\"," ) != std::string::npos ) + { + // Stranger is typing, not supported by chat module yet + SkinPlaySound( "StrangerTyp" ); + } + + if ( resp.data.find( "[\"stoppedTyping\"]" ) != std::string::npos + || resp.data.find( "[\"spyStoppedTyping\"," ) != std::string::npos ) + { + // Stranger stopped typing, not supported by chat module yet + SkinPlaySound( "StrangerTypStop" ); + } + + pos = 0; + while ( (pos = resp.data.find( "[\"gotMessage\",", pos )) != std::string::npos ) { + pos += 16; + + std::string message = utils::text::trim( + utils::text::special_expressions_decode( + utils::text::slashu_to_utf8( + resp.data.substr(pos, resp.data.find("\"]", pos) - pos) ) ) ); + + if (state_ == STATE_ACTIVE) { + TCHAR *msg = mir_a2t_cp(message.c_str(),CP_UTF8); + parent->UpdateChat(TranslateT("Stranger"), msg); + mir_free(msg); + } + } + + pos = 0; + while ( (pos = resp.data.find( "[\"spyMessage\",", pos )) != std::string::npos ) { + pos += 16; + + std::string message = resp.data.substr(pos, resp.data.find("\"]", pos) - pos); + + if (state_ == STATE_SPY) { + std::string stranger = message.substr(0, message.find("\"")); + message = message.substr(stranger.length() + 4); + + message = utils::text::trim( + utils::text::special_expressions_decode( + utils::text::slashu_to_utf8( message ) ) ); + + stranger = Translate(stranger.c_str()); + + TCHAR *str = mir_a2t_cp(stranger.c_str(), CP_UTF8); + TCHAR *msg = mir_a2t_cp(message.c_str(), CP_UTF8); + + parent->UpdateChat(str, msg); + + mir_free(msg); + mir_free(str); + } + } + + if ( resp.data.find( "[\"strangerDisconnected\"]" ) != std::string::npos ) { + // Stranger disconnected + if (DBGetContactSettingByte(NULL, parent->m_szModuleName, OMEGLE_KEY_DONT_STOP, 0)) + { + SkinPlaySound( "StrangerChange" ); + parent->NewChat(); + } + else + parent->StopChat(false); + } + + if ( (pos = resp.data.find( "[\"spyDisconnected\"," )) != std::string::npos ) { + pos += 21; + + std::string stranger = utils::text::trim( + utils::text::special_expressions_decode( + utils::text::slashu_to_utf8( + resp.data.substr(pos, resp.data.find("\"]", pos) - pos) ) ) ); + + char str[255]; + mir_snprintf(str, sizeof(str), Translate("%s disconnected."), Translate(stranger.c_str())); + + TCHAR *msg = mir_a2t_cp(str, CP_UTF8); + parent->UpdateChat(NULL, msg); + mir_free(msg); + + // Stranger disconnected + if (DBGetContactSettingByte(NULL, parent->m_szModuleName, OMEGLE_KEY_DONT_STOP, 0)) + { + SkinPlaySound( "StrangerChange" ); + parent->NewChat(); + } + else + parent->StopChat(false); + } + + if ( resp.data.find( "[\"recaptchaRequired\"" ) != std::string::npos ) { + // Nothing to do with recaptcha + parent->UpdateChat(NULL, TranslateT("Recaptcha is required.\nOpen Omegle chat in webbrowser, solve Recaptcha and try again.")); + parent->StopChat(false); + } + + if ( resp.data.find( "[\"recaptchaRejected\"]" ) != std::string::npos ) { + // Nothing to do with recaptcha + parent->StopChat(false); + } + + if ( (pos = resp.data.find( "[\"error\"," )) != std::string::npos ) { + pos += 11; + + std::string error = utils::text::trim( + utils::text::special_expressions_decode( + utils::text::slashu_to_utf8( + resp.data.substr(pos, resp.data.find("\"]", pos) - pos) ) ) ); + + error = Translate("Error: ") + error; + + TCHAR *msg = mir_a2t_cp(error.c_str(),CP_UTF8); + parent->UpdateChat(NULL, msg); + mir_free(msg); + } + + if (newStranger && state_ != STATE_SPY) { + // We got new stranger in this event, lets say him "Hi message" if enabled + if ( DBGetContactSettingByte( NULL, parent->m_szModuleName, OMEGLE_KEY_HI_ENABLED, 0 ) ) { + DBVARIANT dbv; + if ( !DBGetContactSettingUTF8String( NULL, parent->m_szModuleName, OMEGLE_KEY_HI, &dbv ) ) { + std::string *message = new std::string(dbv.pszVal); + DBFreeVariant(&dbv); + + parent->Log("**Chat - saying Hi! message"); + ForkThread(&OmegleProto::SendMsgWorker, parent, (void*)message); + } else { + parent->Log("**Chat - Hi message is enabled but not used"); + } + } + } + + if (waiting) { + // If we are only waiting in this event... + parent->UpdateChat(NULL, TranslateT("We are still waiting...")); + } + + return handle_success( "events" ); + } + + case HTTP_CODE_FAKE_DISCONNECTED: + // timeout + return handle_success( "events" ); + + case HTTP_CODE_FAKE_ERROR: + default: + return handle_error( "events" ); + } +} + +bool Omegle_client::send_message( std::string message_text ) +{ + handle_entry( "send_message" ); + + std::string data = "msg=" + utils::url::encode( message_text ); + data += "&id=" + this->chat_id_; + + http::response resp = flap( OMEGLE_REQUEST_SEND, &data ); + + switch ( resp.code ) + { + case HTTP_CODE_OK: + if (resp.data == "win") { + return handle_success( "send_message" ); + } + + case HTTP_CODE_FAKE_ERROR: + case HTTP_CODE_FAKE_DISCONNECTED: + default: + return handle_error( "send_message" ); + } +} + +bool Omegle_client::typing_start() +{ + handle_entry( "typing_start" ); + + std::string data = "id=" + this->chat_id_; + + http::response resp = flap( OMEGLE_REQUEST_TYPING_START, &data ); + + switch ( resp.code ) + { + case HTTP_CODE_OK: + if (resp.data == "win") { + return handle_success( "typing_start" ); + } + + case HTTP_CODE_FAKE_ERROR: + case HTTP_CODE_FAKE_DISCONNECTED: + default: + return handle_error( "typing_start" ); + } +} + +bool Omegle_client::typing_stop() +{ + handle_entry( "typing_stop" ); + + std::string data = "id=" + this->chat_id_; + + http::response resp = flap( OMEGLE_REQUEST_TYPING_STOP, &data ); + + switch ( resp.code ) + { + case HTTP_CODE_OK: + if (resp.data == "win") { + return handle_success( "typing_stop" ); + } + + case HTTP_CODE_FAKE_ERROR: + case HTTP_CODE_FAKE_DISCONNECTED: + default: + return handle_error( "typing_stop" ); + } +} + +bool Omegle_client::recaptcha() +{ + // TODO: Implement! + + handle_entry( "recaptcha" ); + + // data:{id:this.clientID,challenge:b,response:a}} + //std::string data = "?id=...&challenge= ..., &response= ..."; + + http::response resp = flap( OMEGLE_REQUEST_RECAPTCHA ); + + switch ( resp.code ) + { + case HTTP_CODE_OK: +/* if (resp.data == "win") { + return handle_success( "typing_start" ); + }*/ + + case HTTP_CODE_FAKE_ERROR: + case HTTP_CODE_FAKE_DISCONNECTED: + default: + return handle_error( "typing_start" ); + } +} + +std::string Omegle_client::get_page( const int request_type ) +{ + handle_entry( "get_page" ); + + http::response resp = flap( OMEGLE_REQUEST_COUNT ); + + switch ( resp.code ) + { + case HTTP_CODE_OK: + handle_success( "get_page" ); + break; + + case HTTP_CODE_FAKE_ERROR: + case HTTP_CODE_FAKE_DISCONNECTED: + default: + handle_error( "get_page" ); + } + + return resp.data; +} diff --git a/protocols/Omegle/connection.cpp b/protocols/Omegle/connection.cpp new file mode 100644 index 0000000000..f5c3b9d6b6 --- /dev/null +++ b/protocols/Omegle/connection.cpp @@ -0,0 +1,179 @@ +/* + +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" + +void OmegleProto::SignOn(void*) +{ + SYSTEMTIME t; + GetLocalTime( &t ); + Log("[%d.%d.%d] Using Omegle Protocol %s", t.wDay, t.wMonth, t.wYear, __VERSION_STRING); + + ScopedLock s(signon_lock_); + + int old_status = m_iStatus; + m_iStatus = m_iDesiredStatus; + ProtoBroadcastAck(m_szModuleName,0,ACKTYPE_STATUS,ACKRESULT_SUCCESS,(HANDLE)old_status,m_iStatus); + + setDword( "LogonTS", (DWORD)time(NULL) ); + ClearChat(); + OnJoinChat(0,false); + + //ToggleStatusMenuItems(true); +} + +void OmegleProto::SignOff(void*) +{ + ScopedLock s(signon_lock_); + + int old_status = m_iStatus; + m_iStatus = ID_STATUS_OFFLINE; + + Netlib_Shutdown(facy.hEventsConnection); + + OnLeaveChat(NULL, NULL); + + deleteSetting( "LogonTS" ); + + ProtoBroadcastAck(m_szModuleName,0,ACKTYPE_STATUS,ACKRESULT_SUCCESS,(HANDLE)old_status,m_iStatus); + + //SetAllContactStatuses( ID_STATUS_OFFLINE ); + //ToggleStatusMenuItems(false); + + if (facy.hEventsConnection) + Netlib_CloseHandle(facy.hEventsConnection); + facy.hEventsConnection = NULL; +} + +void OmegleProto::StopChat(bool disconnect) +{ + if (facy.state_ == STATE_WAITING) { + UpdateChat(NULL, TranslateT("Connecting canceled."), false); + } else if (facy.state_ == STATE_ACTIVE || facy.state_ == STATE_SPY) { + bool spy = facy.state_ == STATE_SPY; + + if (disconnect) + { + facy.state_ = STATE_DISCONNECTING; + UpdateChat(NULL, TranslateT("Disconnecting..."), true); + + if (facy.stop()) + LOG("***** Disconnected from stranger %s", facy.chat_id_.c_str()); + else + LOG("***** Error in disconnecting from stranger %s", facy.chat_id_.c_str()); + } + + if (spy) { + DeleteChatContact(TranslateT("Stranger 1")); + DeleteChatContact(TranslateT("Stranger 2")); + } else { + DeleteChatContact(TranslateT("Stranger")); + } + + SetTopic(); // reset topic content + } + else + { // disconnecting or inactive + return; + } + + facy.state_ = STATE_INACTIVE; + facy.chat_id_ = ""; +} + +void OmegleProto::NewChat() +{ + if (facy.state_ == STATE_WAITING) + { + UpdateChat(NULL, TranslateT("We are already waiting for new stranger..."), false); + return; + } + else if (facy.state_ == STATE_ACTIVE || facy.state_ == STATE_SPY) + { + UpdateChat(NULL, TranslateT("Disconnecting..."), true); + + if (facy.stop()) + LOG("***** Disconnected from stranger %s", facy.chat_id_.c_str()); + else + LOG("***** Error in disconnecting from stranger %s", facy.chat_id_.c_str()); + + if (facy.state_ == STATE_SPY) { + DeleteChatContact(TranslateT("Stranger 1")); + DeleteChatContact(TranslateT("Stranger 2")); + } else { + DeleteChatContact(TranslateT("Stranger")); + } + + SetTopic(); // reset topic content + + ClearChat(); + + UpdateChat(NULL, TranslateT("Connecting..."), true); + + facy.state_ = STATE_WAITING; + + if (facy.start()) + { + UpdateChat(NULL, TranslateT("Waiting for Stranger..."), true); + LOG("***** Waiting for stranger %s", facy.chat_id_.c_str()); + } + } + else if (facy.state_ == STATE_DISCONNECTING) + { + //UpdateChat(NULL, TranslateT("We are disconnecting now, wait..."), false); + return; + } + else + { + ClearChat(); + UpdateChat(NULL, TranslateT("Connecting..."), true); + + facy.state_ = STATE_WAITING; + + if (facy.start()) + { + UpdateChat(NULL, TranslateT("Waiting for Stranger..."), true); + LOG("***** Waiting for stranger %s", facy.chat_id_.c_str()); + + ForkThread( &OmegleProto::EventsLoop, this ); + } + } + +} + +void OmegleProto::EventsLoop(void *) +{ + ScopedLock s(events_loop_lock_); + + time_t tim = ::time(NULL); + LOG( ">>>>> Entering Omegle::EventsLoop[%d]", tim ); + + while ( facy.events() ) + { + if ( facy.state_ == STATE_INACTIVE || facy.state_ == STATE_DISCONNECTING || !isOnline() ) + break; + LOG( "***** OmegleProto::EventsLoop[%d] refreshing...", tim ); + } + + ResetEvent(events_loop_lock_); + LOG( "<<<<< Exiting OmegleProto::EventsLoop[%d]", tim ); +} diff --git a/protocols/Omegle/constants.h b/protocols/Omegle/constants.h new file mode 100644 index 0000000000..7fff9789e8 --- /dev/null +++ b/protocols/Omegle/constants.h @@ -0,0 +1,54 @@ +/* + +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 . + +*/ + +#pragma once + +// Version management +#define __VERSION_DWORD PLUGIN_MAKE_VERSION(0,1,0,0) +#define __VERSION_STRING "0.1.0.0" + +// Product management +#define OMEGLE_NAME "Omegle" +#define OMEGLE_SERVER_REGULAR "http://www.omegle.com" +#define OMEGLE_SERVER_CHAT "http://%s.omegle.com" + +// Limits +#define OMEGLE_TIMEOUTS_LIMIT 6 +// There is "no limit" on Omegle, but we should set some wise limit +#define OMEGLE_MESSAGE_LIMIT 4096 +#define OMEGLE_MESSAGE_LIMIT_TEXT "4096" + +#define OMEGLE_QUESTION_MIN_LENGTH 10 + +// Omegle request types +#define OMEGLE_REQUEST_HOME 100 // getting server name +#define OMEGLE_REQUEST_COUNT 105 // get count of connected users +#define OMEGLE_REQUEST_START 110 // starting conversation +#define OMEGLE_REQUEST_STOP 120 // ending conversation +#define OMEGLE_REQUEST_SEND 300 // sending message +#define OMEGLE_REQUEST_EVENTS 301 // receiving events +#define OMEGLE_REQUEST_TYPING_START 310 // started typing +#define OMEGLE_REQUEST_TYPING_STOP 311 // stoped typing +#define OMEGLE_REQUEST_RECAPTCHA 400 // recaptcha handling + +// Servers list +static const char *servers[] = {"Random", "bajor", "cardassia", "promenade", "odo-bucket", "ferengi", "quarks"}; \ No newline at end of file diff --git a/protocols/Omegle/db.h b/protocols/Omegle/db.h new file mode 100644 index 0000000000..fd0d290b3c --- /dev/null +++ b/protocols/Omegle/db.h @@ -0,0 +1,55 @@ +/* + +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 . + +*/ + +#pragma once + +// DB macros +#define getByte( setting, error ) DBGetContactSettingByte( NULL, m_szModuleName, setting, error ) +#define setByte( setting, value ) DBWriteContactSettingByte( NULL, m_szModuleName, setting, value ) +#define getWord( setting, error ) DBGetContactSettingWord( NULL, m_szModuleName, setting, error ) +#define setWord( setting, value ) DBWriteContactSettingWord( NULL, m_szModuleName, setting, value ) +#define getDword( setting, error ) DBGetContactSettingDword( NULL, m_szModuleName, setting, error ) +#define setDword( setting, value ) DBWriteContactSettingDword( NULL, m_szModuleName, setting, value ) +#define getString( setting, dest ) DBGetContactSettingString( NULL, m_szModuleName, setting, dest ) +#define setString( setting, value ) DBWriteContactSettingString( NULL, m_szModuleName, setting, value ) +#define getTString( setting, dest ) DBGetContactSettingTString( NULL, m_szModuleName, setting, dest ) +#define setTString( setting, value ) DBWriteContactSettingTString( NULL, m_szModuleName, setting, value ) +#define getU8String( setting, dest ) DBGetContactSettingUTF8String( NULL, m_szModuleName, setting, dest ) +#define setU8String( setting, value ) DBWriteContactSettingUTF8String( NULL, m_szModuleName, setting, value ) +#define deleteSetting( setting ) DBDeleteContactSetting( NULL, m_szModuleName, setting ) + +// DB settings +#define OMEGLE_KEY_TIMEOUTS_LIMIT "TimeoutsLimit" // [HIDDEN] + +#define OMEGLE_KEY_ASL "MessageAsl" +#define OMEGLE_KEY_HI "MessageHi" +#define OMEGLE_KEY_HI_ENABLED "MessageHiEnabled" +#define OMEGLE_KEY_NAME "Nick" +#define OMEGLE_KEY_DONT_STOP "DontStop" +#define OMEGLE_KEY_NO_CLEAR "NoClear" +#define OMEGLE_KEY_MEET_COMMON "MeetCommon" +#define OMEGLE_KEY_INTERESTS "Interests" +#define OMEGLE_KEY_REUSE_QUESTION "ReuseQuestion" +#define OMEGLE_KEY_SERVER "Server" +#define OMEGLE_KEY_LOGGING "EnableLogging" +#define OMEGLE_KEY_SERVER_INFO "GetServerInfo" +#define OMEGLE_KEY_LAST_QUESTION "LastQuestion" diff --git a/protocols/Omegle/dialogs.cpp b/protocols/Omegle/dialogs.cpp new file mode 100644 index 0000000000..c2c5db9dc1 --- /dev/null +++ b/protocols/Omegle/dialogs.cpp @@ -0,0 +1,231 @@ +/* + +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" + +static BOOL LoadDBCheckState(OmegleProto* ppro, HWND hwnd, int idCtrl, const char* szSetting, BYTE bDef = 0) +{ + BOOL state = DBGetContactSettingByte(NULL, ppro->m_szModuleName, szSetting, bDef); + CheckDlgButton(hwnd, idCtrl, state); + return state; +} + +static BOOL StoreDBCheckState(OmegleProto* ppro, HWND hwnd, int idCtrl, const char* szSetting) +{ + BOOL state = IsDlgButtonChecked(hwnd, idCtrl); + DBWriteContactSettingByte(NULL, ppro->m_szModuleName, szSetting, (BYTE)state); + return state; +} + +static void LoadDBText(OmegleProto* ppro, HWND hwnd, int idCtrl, const char* szSetting) +{ + DBVARIANT dbv; + if( !DBGetContactSettingTString(NULL, ppro->m_szModuleName, szSetting, &dbv) ) + { + SetDlgItemText(hwnd, idCtrl, dbv.ptszVal); + DBFreeVariant(&dbv); + } +} + +static void StoreDBText(OmegleProto* ppro, HWND hwnd, int idCtrl, const char* szSetting) +{ + TCHAR tstr[OMEGLE_MESSAGE_LIMIT+1]; + + GetDlgItemText(hwnd, idCtrl, tstr, sizeof(tstr)); + if ( _tcsclen( tstr ) > 0 ) { + DBWriteContactSettingTString(NULL, ppro->m_szModuleName, szSetting, tstr); + } else { + DBDeleteContactSetting(NULL, ppro->m_szModuleName, szSetting); + } +} + + +INT_PTR CALLBACK OmegleAccountProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam ) +{ + OmegleProto *proto; + + switch ( message ) + { + + case WM_INITDIALOG: + TranslateDialogDefault(hwnd); + + proto = reinterpret_cast(lparam); + SetWindowLong(hwnd,GWLP_USERDATA,lparam); + + SendDlgItemMessage(hwnd,IDC_INTERESTS, EM_LIMITTEXT, 512, 0); + + // Server + SendDlgItemMessageA(hwnd, IDC_SERVER, CB_INSERTSTRING, 0, reinterpret_cast(Translate(servers[0]))); + for(size_t i=1; i(servers[i])); + } + SendDlgItemMessage(hwnd, IDC_SERVER, CB_SETCURSEL, DBGetContactSettingByte(NULL, proto->m_szModuleName, OMEGLE_KEY_SERVER, 0), 0); + + LoadDBText(proto, hwnd, IDC_NAME, OMEGLE_KEY_NAME); + LoadDBText(proto, hwnd, IDC_INTERESTS, OMEGLE_KEY_INTERESTS); + LoadDBCheckState(proto, hwnd, IDC_MEET_COMMON, OMEGLE_KEY_MEET_COMMON); + + return TRUE; + + case WM_COMMAND: + switch(LOWORD(wparam)) + { + case IDC_SERVER: + if (HIWORD(wparam) == CBN_SELCHANGE) { + SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0); + } break; + case IDC_NAME: + case IDC_INTERESTS: + if (HIWORD(wparam) != EN_CHANGE || (HWND) lparam != GetFocus()) { + return TRUE; + } else { + SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0); + } break; + case IDC_MEET_COMMON: + if (HIWORD(wparam) == BN_CLICKED) { + SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0); + } break; + } + break; + + case WM_NOTIFY: + if ( reinterpret_cast(lparam)->code == PSN_APPLY ) + { + proto = reinterpret_cast(GetWindowLong(hwnd,GWLP_USERDATA)); + + DBWriteContactSettingByte(NULL, proto->m_szModuleName, OMEGLE_KEY_SERVER, SendDlgItemMessage(hwnd, IDC_SERVER, CB_GETCURSEL, 0, 0)); + + StoreDBText(proto, hwnd, IDC_NAME, OMEGLE_KEY_NAME); + StoreDBText(proto, hwnd, IDC_INTERESTS, OMEGLE_KEY_INTERESTS); + StoreDBCheckState(proto, hwnd, IDC_MEET_COMMON, OMEGLE_KEY_MEET_COMMON); + + return TRUE; + } + break; + + } + return FALSE; +} + +INT_PTR CALLBACK OmegleOptionsProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam ) +{ + OmegleProto *proto = reinterpret_cast(GetWindowLong(hwnd,GWLP_USERDATA)); + + switch ( message ) + { + + case WM_INITDIALOG: + { + TranslateDialogDefault(hwnd); + + proto = reinterpret_cast(lparam); + SetWindowLong(hwnd,GWLP_USERDATA,lparam); + + SendDlgItemMessage(hwnd,IDC_INTERESTS, EM_LIMITTEXT, 512, 0); + SendDlgItemMessage(hwnd,IDC_HI_MESSAGE, EM_LIMITTEXT, OMEGLE_MESSAGE_LIMIT, 0); + SendDlgItemMessage(hwnd,IDC_ASL_MESSAGE, EM_LIMITTEXT, OMEGLE_MESSAGE_LIMIT, 0); + + // Server + SendDlgItemMessageA(hwnd, IDC_SERVER, CB_INSERTSTRING, 0, reinterpret_cast(Translate(servers[0]))); + for(size_t i=1; i(servers[i])); + } + SendDlgItemMessage(hwnd, IDC_SERVER, CB_SETCURSEL, DBGetContactSettingByte(NULL, proto->m_szModuleName, OMEGLE_KEY_SERVER, 0), 0); + + LoadDBText(proto, hwnd, IDC_NAME, OMEGLE_KEY_NAME); + LoadDBText(proto, hwnd, IDC_INTERESTS, OMEGLE_KEY_INTERESTS); + LoadDBText(proto, hwnd, IDC_HI_MESSAGE, OMEGLE_KEY_HI); + LoadDBText(proto, hwnd, IDC_ASL_MESSAGE, OMEGLE_KEY_ASL); + LoadDBText(proto, hwnd, IDC_LAST_QUESTION, OMEGLE_KEY_LAST_QUESTION); + + LoadDBCheckState(proto, hwnd, IDC_MEET_COMMON, OMEGLE_KEY_MEET_COMMON); + LoadDBCheckState(proto, hwnd, IDC_HI_ENABLED, OMEGLE_KEY_HI_ENABLED); + LoadDBCheckState(proto, hwnd, IDC_NOCLEAR, OMEGLE_KEY_NO_CLEAR); + LoadDBCheckState(proto, hwnd, IDC_DONTSTOP, OMEGLE_KEY_DONT_STOP); + LoadDBCheckState(proto, hwnd, IDC_REUSE_QUESTIONS, OMEGLE_KEY_REUSE_QUESTION); + LoadDBCheckState(proto, hwnd, IDC_SERVER_INFO, OMEGLE_KEY_SERVER_INFO); + LoadDBCheckState(proto, hwnd, IDC_LOGGING, OMEGLE_KEY_LOGGING); + + } return TRUE; + + case WM_COMMAND: { + + switch(LOWORD(wparam)) + { + case IDC_SERVER: + if (HIWORD(wparam) == CBN_SELCHANGE) { + SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0); + } break; + case IDC_NAME: + case IDC_INTERESTS: + case IDC_HI_MESSAGE: + case IDC_ASL_MESSAGE: + if (HIWORD(wparam) != EN_CHANGE || (HWND) lparam != GetFocus()) { + return TRUE; + } else { + SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0); + } break; + case IDC_MEET_COMMON: + case IDC_HI_ENABLED: + case IDC_NOCLEAR: + case IDC_DONTSTOP: + case IDC_REUSE_QUESTIONS: + case IDC_SERVER_INFO: + case IDC_LOGGING: + if (HIWORD(wparam) == BN_CLICKED) { + SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0); + } break; + } + + } break; + + case WM_NOTIFY: + if ( reinterpret_cast(lparam)->code == PSN_APPLY ) + { + proto = reinterpret_cast(GetWindowLong(hwnd,GWLP_USERDATA)); + + DBWriteContactSettingByte(NULL, proto->m_szModuleName, OMEGLE_KEY_SERVER, SendDlgItemMessage(hwnd, IDC_SERVER, CB_GETCURSEL, 0, 0)); + + StoreDBText(proto, hwnd, IDC_NAME, OMEGLE_KEY_NAME); + StoreDBText(proto, hwnd, IDC_INTERESTS, OMEGLE_KEY_INTERESTS); + StoreDBText(proto, hwnd, IDC_HI_MESSAGE, OMEGLE_KEY_HI); + StoreDBText(proto, hwnd, IDC_ASL_MESSAGE, OMEGLE_KEY_ASL); + + StoreDBCheckState(proto, hwnd, IDC_MEET_COMMON, OMEGLE_KEY_MEET_COMMON); + StoreDBCheckState(proto, hwnd, IDC_HI_ENABLED, OMEGLE_KEY_HI_ENABLED); + StoreDBCheckState(proto, hwnd, IDC_NOCLEAR, OMEGLE_KEY_NO_CLEAR); + StoreDBCheckState(proto, hwnd, IDC_DONTSTOP, OMEGLE_KEY_DONT_STOP); + StoreDBCheckState(proto, hwnd, IDC_REUSE_QUESTIONS, OMEGLE_KEY_REUSE_QUESTION); + StoreDBCheckState(proto, hwnd, IDC_SERVER_INFO, OMEGLE_KEY_SERVER_INFO); + StoreDBCheckState(proto, hwnd, IDC_LOGGING, OMEGLE_KEY_LOGGING); + + return TRUE; + } + break; + + } + + return FALSE; +} diff --git a/protocols/Omegle/dialogs.h b/protocols/Omegle/dialogs.h new file mode 100644 index 0000000000..880f04636b --- /dev/null +++ b/protocols/Omegle/dialogs.h @@ -0,0 +1,26 @@ +/* + +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 . + +*/ + +#pragma once + +INT_PTR CALLBACK OmegleAccountProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam ); +INT_PTR CALLBACK OmegleOptionsProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam ); diff --git a/protocols/Omegle/docs/omegle - langpack.txt b/protocols/Omegle/docs/omegle - langpack.txt new file mode 100644 index 0000000000..dde7241ba9 --- /dev/null +++ b/protocols/Omegle/docs/omegle - langpack.txt @@ -0,0 +1,104 @@ +; Omegle Protocol 0.1.0.0 + +[Server] + +[Last question is empty.] + +[Your question is too short.] + +[Your '/asl' setting is empty.] + +[Unknown command. Send '/commands' for list.] + +[You aren't connected to any stranger. Send '/help' or '/commands' for help.] + +[You can't send messages in question mode.] + +[Omegle is a great way of meeting new friends!] + +[You] + +[Connection error.] + +[Chosing server: ] + +[Connected to server %s. There are %s users online now.] + +[On whole Omegle are %s strangers online now.] + +[Stranger 1] + +[Stranger 2] + +[Stranger] + +[You and the Stranger both like: ] + +[%s disconnected.] + +[Recaptcha is required.\nOpen Omegle chat in webbrowser, solve Recaptcha and try again.] + +[Error: ] + +[We are still waiting...] + +[Connecting canceled.] + +[Disconnecting...] + +[We are already waiting for new stranger...] + +[Connecting...] + +[Waiting for Stranger...] + +[We are disconnecting now, wait...] + +[Server:] + +[Visible name:] + +[Meet strangers with common interests (separated by commas):] + +[Automatically send this message to stranger after connection:] + +[This text will be sent when you use "/asl" message:] + +[Don't clear chat before connecting to new stranger] + +[Automatically connect to another stranger when current disconnects] + +[I want Omegle to reuse my questions if they are good enough (Question mode)] + +[Enable logging for debugging purposes] + +[Load count of users on actual server after connection] + +[Last used question (Question mode):] + +[Meet strangers with common interests] + +[Your interests (separated by commas):] + +[%s server connection] + +[Unable to get Netlib connection for Omegle] + +[Stranger typing] + +[Stranger stopped typing] + +[Changing stranger] + +[Network] + +[Account] + +[Omegle Icon] + +[Visit Profile] + +[Protocols] + +[Omegle] + diff --git a/protocols/Omegle/docs/omegle - readme_cz.txt b/protocols/Omegle/docs/omegle - readme_cz.txt new file mode 100644 index 0000000000..bdad6cd73d --- /dev/null +++ b/protocols/Omegle/docs/omegle - readme_cz.txt @@ -0,0 +1,80 @@ +--------------------------- +| Omegle Protocol 0.1.0.0 | +| (26.4.2012) | +--------------------------- + +Autor: Robyer + E-mail: robyer@seznam.cz + Jabber: robyer@jabbim.cz + ICQ: 372317536 + Web: http://robyer.info + +SVN: http://code.google.com/p/robyer/ + +!!!! Vyžadována Miranda 0.9.43 a novìjší nebo 0.10.2 a novìjší !!!!! + +-------------------------------- + SKRYTÉ NASTAVENÍ +-------------------------------- +TimeoutsLimit (byte) - poèet povolených timeoutù pøed odpojením protokolu + +-------------------------------- + Historie verzí +-------------------------------- +0.1.0.0 - 26.4.2012 + První vydání na addons + +0.0.2.0 - 23.4.2012 + ! Commited some fixes from Facebook protocol (patch by borkra) + * Reworked commands + + Remember last question in Question mode + +0.0.1.1 - 13.4.2012 + ! Fixed saving text values in options + +0.0.1.0 - 13.4.2012 + + Added settings and account dialogs + + Getting number of users connected to server + + Support for Question mode and Spy mode + + Support for searching strangers with same interests + + Added sounds for stranger typing notify + ! Code cleanup + ! Many fixes and improvements + +0.0.0.6 - 26.3.2012 + ! Opraveno pøipojení + * Pøi pøipojování k cizinci se volí náhodný Omegle server + +0.0.0.5 - 27.9.2011 + * Interní zmìny ohlednì stavù komunikace + + Added support for send message after stranger connects (see hidden settings) + + Added support for automatic reconnect to another stranger (see hidden settings) + + Added support for not erasing content of chat window (see hidden settings) + +0.0.0.4 - 18.4.2011 + * Pøipojování/odpojování cizincù v jiném vláknì + * Úprava rolí kontaktù v chatu + ! Opraveno v Tabsrmm + ! Opraveno neinformování o odpojení cizince + ! Opravy k zobrazení vlastní pøezdívky místo "You" + ! Oprava pro použití smajlíkù + ! Spousta rùzných oprav + * Zmìna názvu skrytého klíèe "ChatName" na "Nick" + * Možnost zapnutí logování skrz skrytý klíè "EnableLogging" (byte) = 1 + +0.0.0.3 - 16.4.2011 + + Pøidány ikony protokolu (dokud nìkdo nevytvoøí lepší) + + Možnost pøejmenování vlastního jména v chatu skrz Unicode klíè "ChatName". + * Zmìna "ovládání": Pøíkaz "/new" pro pøipojení k nové konverzaci a "/quit" pro ukonèení stávající + ! Opraveno duplikování odchozích událostí po pøepøipojení + ! Oprava nezobrazení zpráv, které byly pøijaty s jinou událostí + +0.0.0.2 - 13.4.2011 + ! Nahrazování speciálních znakù v pøíchozích zprávách (\r,\n,\,") + + Skrytý klíè "MessageAsl" (Unicode string), kde lze zapsat text zprávy, která se odešle pøi odeslání "/asl" + * Použití persistent http pøipojení + * Drobné zmìny èi opravy + +0.0.0.1 - 10.4.2011 + + První veøejná verze + \ No newline at end of file diff --git a/protocols/Omegle/docs/omegle - readme_en.txt b/protocols/Omegle/docs/omegle - readme_en.txt new file mode 100644 index 0000000000..33973f00e8 --- /dev/null +++ b/protocols/Omegle/docs/omegle - readme_en.txt @@ -0,0 +1,80 @@ +--------------------------- +| Omegle Protocol 0.1.0.0 | +| (26.4.2012) | +--------------------------- + +Autor: Robyer + E-mail: robyer@seznam.cz + Jabber: robyer@jabbim.cz + ICQ: 372317536 + Web: http://robyer.info + +SVN: http://code.google.com/p/robyer/ + +!!!! Required Miranda 0.9.43 or newer or Miranda 0.10.2 and newer !!!! + +-------------------------------- + HIDDEN SETTINGS +-------------------------------- +TimeoutsLimit (byte) - number of allowed timeouts before disconnection protocol + +-------------------------------- + Version history +-------------------------------- +0.1.0.0 - 26.4.2012 + First addons release + +0.0.2.0 - 23.4.2012 + ! Commited some fixes from Facebook protocol (patch by borkra) + * Reworked commands + + Remember last question in Question mode + +0.0.1.1 - 13.4.2012 + ! Fixed saving text values in options + +0.0.1.0 - 13.4.2012 + + Added settings and account dialogs + + Getting number of users connected to server + + Support for Question mode and Spy mode + + Support for searching strangers with same interests + + Added sounds for stranger typing notify + ! Code cleanup + ! Many fixes and improvements + +0.0.0.6 - 26.3.2012 + ! Fixed connection + * When connecting to stranger, chose random Omegle server + +0.0.0.5 - 27.9.2011 + * Some internal changes (this brings some bugs - you will see :)) + + Added support for send message after stranger connects (see hidden settings) + + Added support for automatic reconnect to another stranger (see hidden settings) + + Added support for not erasing content of chat window (see hidden settings) + +0.0.0.4 - 18.4.2011 + * (Dis)connecting strangers in other thread + * Added admin role to own contact + ! Fixed in Tabsrmm + ! Fixed not informing about disconnecting stranger + ! Fixes to own nickname (instead of "You") + ! Fixed not supporting smileys + ! Another small fixes + * Changed name of hidden key "ChatName" to "Nick" + * You can enable logging through hidden key "EnableLogging" (byte) = 1 + +0.0.0.3 - 16.4.2011 + + Added protocol icons (until someone creates better) + + You can change your name in chat through hidden key "ChatName" (unicode string) + * Changed commands: Command "/new" for connect to new stranger, "/quit" for end actual conversation + ! Fixed duplicying outgoing events after reconnect + ! Fix for not showing messages, which were received with another event + +0.0.0.2 - 13.4.2011 + ! Replacing special chars in incomming messages (\r,\n,\,") + + Hidden key "MessageAsl" (Unicode string) with text, which is send when you write "/asl" + * Used persistent http connection + * Small changes/fixes + +0.0.0.1 - 10.4.2011 + * First public version + \ No newline at end of file diff --git a/protocols/Omegle/events.cpp b/protocols/Omegle/events.cpp new file mode 100644 index 0000000000..5e2749e70c --- /dev/null +++ b/protocols/Omegle/events.cpp @@ -0,0 +1,39 @@ +/* + +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" + +int OmegleProto::Log(const char *fmt,...) +{ + if (!getByte(OMEGLE_KEY_LOGGING, 0)) + return EXIT_SUCCESS; + + va_list va; + char text[65535]; + ScopedLock s(log_lock_); + + va_start(va,fmt); + mir_vsnprintf(text,sizeof(text),fmt,va); + va_end(va); + + return utils::debug::log( m_szModuleName, text ); +} diff --git a/protocols/Omegle/http.cpp b/protocols/Omegle/http.cpp new file mode 100644 index 0000000000..e360253e1a --- /dev/null +++ b/protocols/Omegle/http.cpp @@ -0,0 +1,23 @@ +/* + +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" diff --git a/protocols/Omegle/http.h b/protocols/Omegle/http.h new file mode 100644 index 0000000000..a09e4f903d --- /dev/null +++ b/protocols/Omegle/http.h @@ -0,0 +1,48 @@ +/* + +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 . + +*/ + +#pragma once + +#define HTTP_CODE_OK 200 +#define HTTP_CODE_MOVED_PERMANENTLY 301 +#define HTTP_CODE_FOUND 302 +#define HTTP_CODE_FORBIDDEN 403 +#define HTTP_CODE_NOT_FOUND 404 +#define HTTP_CODE_REQUEST_TIMEOUT 408 +#define HTTP_CODE_INTERNAL_SERVER_ERROR 500 +#define HTTP_CODE_NOT_IMPLEMENTED 501 +#define HTTP_CODE_BAD_GATEWAY 502 +#define HTTP_CODE_SERVICE_UNAVAILABLE 503 + +#define HTTP_CODE_FAKE_DISCONNECTED 0 +#define HTTP_CODE_FAKE_ERROR 1 + +namespace http +{ + struct response + { + response() : code(0) {} + int code; + std::map< std::string, std::string > headers; + std::string data; + }; +} diff --git a/protocols/Omegle/icons/omegle.ico b/protocols/Omegle/icons/omegle.ico new file mode 100644 index 0000000000..04570a4327 Binary files /dev/null and b/protocols/Omegle/icons/omegle.ico differ diff --git a/protocols/Omegle/icons/proto_offline.ico b/protocols/Omegle/icons/proto_offline.ico new file mode 100644 index 0000000000..bc608d61c8 Binary files /dev/null and b/protocols/Omegle/icons/proto_offline.ico differ diff --git a/protocols/Omegle/icons/proto_online.ico b/protocols/Omegle/icons/proto_online.ico new file mode 100644 index 0000000000..206e829e6b Binary files /dev/null and b/protocols/Omegle/icons/proto_online.ico differ diff --git a/protocols/Omegle/main.cpp b/protocols/Omegle/main.cpp new file mode 100644 index 0000000000..aa69bf7bcb --- /dev/null +++ b/protocols/Omegle/main.cpp @@ -0,0 +1,210 @@ +/* + +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" + +// TODO: Make following as "globals" structure? +PLUGINLINK *pluginLink; +MM_INTERFACE mmi; +LIST_INTERFACE li; +CLIST_INTERFACE* pcli; +UTF8_INTERFACE utfi; +int hLangpack; + +HINSTANCE g_hInstance; +std::string g_strUserAgent; +DWORD g_mirandaVersion; + +PLUGININFOEX pluginInfo = { + sizeof(PLUGININFOEX), + #ifdef _WIN64 + "Omegle Protocol x64", + #else + "Omegle Protocol", + #endif + __VERSION_DWORD, + "Provides basic support for Omegle Chat protocol. [Built: "__DATE__" "__TIME__"]", + "Robert Posel", + "robyer@seznam.cz", + "(c) 2011-12 Robert Posel", + "http://code.google.com/p/robyer/", + UNICODE_AWARE, //not transient + 0, //doesn't replace anything built-in + #ifdef _WIN64 + // {95A3FF9B-0124-4A34-A123-E3262858010F} + { 0x95a3ff9b, 0x124, 0x4a34, { 0xa1, 0x23, 0xe3, 0x26, 0x28, 0x58, 0x1, 0xf } } + #else + // {9E1D9244-606C-4ef4-99A0-1D7D23CB7601} + { 0x9e1d9244, 0x606c, 0x4ef4, { 0x99, 0xa0, 0x1d, 0x7d, 0x23, 0xcb, 0x76, 0x1 } } + #endif +}; + +///////////////////////////////////////////////////////////////////////////// +// Protocol instances +static int compare_protos(const OmegleProto *p1, const OmegleProto *p2) +{ + return _tcscmp(p1->m_tszUserName, p2->m_tszUserName); +} + +OBJLIST g_Instances(1, compare_protos); + +DWORD WINAPI DllMain(HINSTANCE hInstance,DWORD,LPVOID) +{ + g_hInstance = hInstance; + return TRUE; +} + +extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) +{ + if(mirandaVersion > PLUGIN_MAKE_VERSION(0,10,0,0) && + mirandaVersion < PLUGIN_MAKE_VERSION(0,10,0,2)) + { + MessageBox(0,_T("The Omegle protocol plugin cannot be loaded. ") + _T("It requires Miranda IM 0.10 alpha build #2 or later."),_T("Miranda"), + MB_OK|MB_ICONWARNING|MB_SETFOREGROUND|MB_TOPMOST); + return NULL; + } + else if(mirandaVersion < PLUGIN_MAKE_VERSION(0,9,43,0)) + { + MessageBox(0,_T("The Omegle protocol plugin cannot be loaded. ") + _T("It requires Miranda IM 0.9.43 or later."),_T("Miranda"), + MB_OK|MB_ICONWARNING|MB_SETFOREGROUND|MB_TOPMOST); + return NULL; + } + + g_mirandaVersion = mirandaVersion; + return &pluginInfo; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Interface information + +static const MUUID interfaces[] = {MIID_PROTOCOL, MIID_LAST}; +extern "C" __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void) +{ + return interfaces; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Load + +static PROTO_INTERFACE* protoInit(const char *proto_name,const TCHAR *username ) +{ + OmegleProto *proto = new OmegleProto(proto_name, username); + g_Instances.insert(proto); + return proto; +} + +static int protoUninit(PROTO_INTERFACE* proto) +{ + g_Instances.remove(( OmegleProto* )proto); + return EXIT_SUCCESS; +} + +int OnModulesLoaded(WPARAM,LPARAM) +{ + if ( ServiceExists( MS_UPDATE_REGISTER ) ) + { + Update upd = {sizeof(upd)}; + char curr_version[30]; + + upd.szComponentName = pluginInfo.shortName; + upd.szUpdateURL = UPDATER_AUTOREGISTER; + upd.szBetaVersionURL = "http://robyer.info/miranda/omegle/version.html"; + upd.szBetaChangelogURL = "http://robyer.info/miranda/omegle/changelog.html"; + upd.pbBetaVersionPrefix = reinterpret_cast("Omegle "); + upd.cpbBetaVersionPrefix = (int)strlen(reinterpret_cast(upd.pbBetaVersionPrefix)); + #ifdef _WIN64 + upd.szBetaUpdateURL = "http://robyer.info/stahni/omegle_x64.zip"; + #else + upd.szBetaUpdateURL = "http://robyer.info/stahni/omegle.zip"; + #endif + upd.pbVersion = reinterpret_cast(CreateVersionStringPluginEx(&pluginInfo,curr_version) ); + upd.cpbVersion = (int)strlen(reinterpret_cast(upd.pbVersion)); + CallService(MS_UPDATE_REGISTER,0,(LPARAM)&upd); + } + + return 0; +} + +static HANDLE g_hEvents[1]; + +extern "C" int __declspec(dllexport) Load(PLUGINLINK *link) +{ + pluginLink = link; + mir_getMMI(&mmi); + mir_getLI(&li); + mir_getUTFI(&utfi); + mir_getLP(&pluginInfo); + + pcli = reinterpret_cast( CallService( + MS_CLIST_RETRIEVE_INTERFACE,0,reinterpret_cast(g_hInstance)) ); + + PROTOCOLDESCRIPTOR pd = { 0 }; + pd.cbSize = sizeof(pd); + pd.szName = "Omegle"; + pd.type = PROTOTYPE_PROTOCOL; + pd.fnInit = protoInit; + pd.fnUninit = protoUninit; + CallService(MS_PROTO_REGISTERMODULE,0,reinterpret_cast(&pd)); + + g_hEvents[0] = HookEvent(ME_SYSTEM_MODULESLOADED,OnModulesLoaded); + + InitIcons(); + //InitContactMenus(); + + // Init native User-Agent + { + std::stringstream agent; + agent << "Miranda IM/"; + agent << (( g_mirandaVersion >> 24) & 0xFF); + agent << "."; + agent << (( g_mirandaVersion >> 16) & 0xFF); + agent << "."; + agent << (( g_mirandaVersion >> 8) & 0xFF); + agent << "."; + agent << (( g_mirandaVersion ) & 0xFF); + #ifdef _WIN64 + agent << " Omegle Protocol x64/"; + #else + agent << " Omegle Protocol/"; + #endif + agent << __VERSION_STRING; + g_strUserAgent = agent.str( ); + } + + return 0; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Unload + +extern "C" int __declspec(dllexport) Unload(void) +{ + //UninitContactMenus(); + for(size_t i=1; i. + +*/ + +#include "common.h" + +void OmegleProto::SendMsgWorker(void *p) +{ + if(p == NULL) + return; + + ScopedLock s( facy.send_message_lock_ ); + + std::string *data = static_cast(p); + + *data = utils::text::trim(*data); + + if (facy.state_ == STATE_ACTIVE && data->length() && facy.send_message( *data )) + { + TCHAR *msg = mir_a2t_cp(data->c_str(), CP_UTF8); + UpdateChat(facy.nick_, msg); + mir_free(msg); + } + + delete data; +} + +void OmegleProto::SendTypingWorker(void *p) +{ + if (p == NULL) + return; + + // Save typing info + bool typ = !_tcscmp(static_cast(p), _T("1")); + mir_free(p); + + // Ignore same typing info + if ( facy.typing_ == typ ) + return; + + facy.typing_ = typ; + // Wait for eventually changes to typing info by other thread and ignore if changed + SleepEx( 2000, true ); + if ( facy.typing_ != typ || facy.old_typing_ == typ || facy.state_ != STATE_ACTIVE ) + return; + + facy.old_typing_ = typ; + if (typ) + facy.typing_start(); + else + facy.typing_stop(); +} + +void OmegleProto::NewChatWorker(void*p) +{ + NewChat(); +} + +void OmegleProto::StopChatWorker(void*p) +{ + StopChat(); +} + +int OmegleProto::SendMsg(HANDLE hContact, int flags, const char *msg) +{ + // TODO: msg comes as Unicode (retyped wchar_t*), why should we convert it as ANSI to UTF-8? o_O +/* if ( flags & PREF_UNICODE ) + msg = mir_utf8encode(msg); + + facy.msgid_ = (facy.msgid_ % 1024)+1; + ForkThread( &OmegleProto::SendMsgWorker, this,new send_direct(hContact,msg,(HANDLE)facy.msgid_) ); + return facy.msgid_;*/ + return 0; +} diff --git a/protocols/Omegle/omegle.aps b/protocols/Omegle/omegle.aps new file mode 100644 index 0000000000..34b52dc581 Binary files /dev/null and b/protocols/Omegle/omegle.aps differ diff --git a/protocols/Omegle/omegle.rc b/protocols/Omegle/omegle.rc new file mode 100644 index 0000000000..0de9b5dd06 --- /dev/null +++ b/protocols/Omegle/omegle.rc @@ -0,0 +1,214 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" +#include "constants.h" +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Czech (Czech Republic) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CSY) +LANGUAGE LANG_CZECH, SUBLANG_DEFAULT +#pragma code_page(1250) + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_OPTIONS DIALOGEX 0, 0, 316, 248 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + COMBOBOX IDC_SERVER,84,7,130,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Server:",IDC_STATIC,24,9,60,8 + LTEXT "Visible name:",IDC_STATIC,24,26,60,8 + EDITTEXT IDC_NAME,84,23,130,14,ES_AUTOHSCROLL + CONTROL "Meet strangers with common interests (separated by commas):",IDC_MEET_COMMON, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,24,41,272,10 + EDITTEXT IDC_INTERESTS,24,52,272,20,ES_MULTILINE | ES_AUTOVSCROLL | WS_VSCROLL + CONTROL "Automatically send this message to stranger after connection:",IDC_HI_ENABLED, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,24,76,272,10 + EDITTEXT IDC_HI_MESSAGE,24,87,272,20,ES_MULTILINE | ES_AUTOVSCROLL | WS_VSCROLL + EDITTEXT IDC_ASL_MESSAGE,24,121,272,20,ES_MULTILINE | ES_AUTOVSCROLL | WS_VSCROLL + LTEXT "This text will be sent when you use ""/asl"" message:",IDC_STATIC,24,111,272,8 + CONTROL "Don't clear chat before connecting to new stranger",IDC_NOCLEAR, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,24,192,272,10 + CONTROL "Automatically connect to another stranger when current disconnects",IDC_DONTSTOP, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,24,204,272,10 + CONTROL "I want Omegle to reuse my questions if they are good enough (Question mode)",IDC_REUSE_QUESTIONS, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,24,176,272,10 + CONTROL "Enable logging for debugging purposes",IDC_LOGGING, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,24,228,272,10 + CONTROL "Load count of users on actual server after connection",IDC_SERVER_INFO, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,24,216,272,10 + EDITTEXT IDC_LAST_QUESTION,24,154,272,20,ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL + LTEXT "Last used question (Question mode):",IDC_STATIC,24,144,272,8 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_OPTIONS, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 309 + VERTGUIDE, 24 + VERTGUIDE, 84 + VERTGUIDE, 214 + VERTGUIDE, 296 + TOPMARGIN, 7 + BOTTOMMARGIN, 241 + END +END +#endif // APSTUDIO_INVOKED + +#endif // Czech (Czech Republic) resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// English (United States) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_OmegleACCOUNT DIALOGEX 0, 0, 186, 134 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + COMBOBOX IDC_SERVER,60,0,125,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Server:",IDC_STATIC,0,2,60,8 + LTEXT "Visible name:",IDC_STATIC,0,17,60,8 + EDITTEXT IDC_NAME,60,15,125,14,ES_AUTOHSCROLL + CONTROL "Meet strangers with common interests",IDC_MEET_COMMON, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,0,36,185,10 + EDITTEXT IDC_INTERESTS,0,60,185,32,ES_MULTILINE | ES_AUTOVSCROLL | WS_VSCROLL + LTEXT "Your interests (separated by commas):",IDC_STATIC,0,50,185,8 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_OmegleACCOUNT, DIALOG + BEGIN + VERTGUIDE, 60 + VERTGUIDE, 185 + END +END +#endif // APSTUDIO_INVOKED + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "#include ""constants.h""\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_OMEGLE ICON "icons/omegle.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 0,1,0,0 + PRODUCTVERSION 0,9,43,0 + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "FileDescription", "Omegle protocol plugin for Miranda IM" + VALUE "FileVersion", "0.1.0.0" + VALUE "InternalName", "Omegle" + VALUE "LegalCopyright", "Copyright © 2011-12 Robert Pösel" + VALUE "OriginalFilename", "omegle.dll" + VALUE "ProductName", "Omegle Protocol" + VALUE "ProductVersion", "0.9.43.0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +#endif // English (United States) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/protocols/Omegle/omegle.sln b/protocols/Omegle/omegle.sln new file mode 100644 index 0000000000..dcbe0188e2 --- /dev/null +++ b/protocols/Omegle/omegle.sln @@ -0,0 +1,36 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Omegle", "omegle_10.vcxproj", "{DADE9455-DC28-465A-9604-2CA28052B9FB}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "omegle_icons_10", "omegle_icons_10.vcxproj", "{C5AB34D2-15F5-4CBA-8F42-DB48A4E52910}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {DADE9455-DC28-465A-9604-2CA28052B9FB}.Debug|Win32.ActiveCfg = Debug|Win32 + {DADE9455-DC28-465A-9604-2CA28052B9FB}.Debug|Win32.Build.0 = Debug|Win32 + {DADE9455-DC28-465A-9604-2CA28052B9FB}.Debug|x64.ActiveCfg = Debug|x64 + {DADE9455-DC28-465A-9604-2CA28052B9FB}.Debug|x64.Build.0 = Debug|x64 + {DADE9455-DC28-465A-9604-2CA28052B9FB}.Release|Win32.ActiveCfg = Release|Win32 + {DADE9455-DC28-465A-9604-2CA28052B9FB}.Release|Win32.Build.0 = Release|Win32 + {DADE9455-DC28-465A-9604-2CA28052B9FB}.Release|x64.ActiveCfg = Release|x64 + {DADE9455-DC28-465A-9604-2CA28052B9FB}.Release|x64.Build.0 = Release|x64 + {C5AB34D2-15F5-4CBA-8F42-DB48A4E52910}.Debug|Win32.ActiveCfg = Debug|Win32 + {C5AB34D2-15F5-4CBA-8F42-DB48A4E52910}.Debug|Win32.Build.0 = Debug|Win32 + {C5AB34D2-15F5-4CBA-8F42-DB48A4E52910}.Debug|x64.ActiveCfg = Debug|x64 + {C5AB34D2-15F5-4CBA-8F42-DB48A4E52910}.Debug|x64.Build.0 = Debug|x64 + {C5AB34D2-15F5-4CBA-8F42-DB48A4E52910}.Release|Win32.ActiveCfg = Release|Win32 + {C5AB34D2-15F5-4CBA-8F42-DB48A4E52910}.Release|Win32.Build.0 = Release|Win32 + {C5AB34D2-15F5-4CBA-8F42-DB48A4E52910}.Release|x64.ActiveCfg = Release|x64 + {C5AB34D2-15F5-4CBA-8F42-DB48A4E52910}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/protocols/Omegle/omegle_10.vcxproj b/protocols/Omegle/omegle_10.vcxproj new file mode 100644 index 0000000000..a31b25bd38 --- /dev/null +++ b/protocols/Omegle/omegle_10.vcxproj @@ -0,0 +1,310 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {DADE9455-DC28-465A-9604-2CA28052B9FB} + omegle + Win32Proj + Omegle + + + + DynamicLibrary + Unicode + true + Static + v100 + + + DynamicLibrary + Unicode + false + v100 + + + DynamicLibrary + Unicode + true + Static + v100 + + + DynamicLibrary + Unicode + false + v100 + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)\$(Configuration)\Plugins\ + $(SolutionDir)\$(Configuration)\Obj\$(ProjectName)\ + true + $(SolutionDir)\$(Configuration)64\Plugins\ + $(SolutionDir)\$(Configuration)64\Obj\$(ProjectName)\ + true + $(SolutionDir)\$(Configuration)\Plugins\ + $(SolutionDir)\$(Configuration)\Obj\$(ProjectName)\ + $(SolutionDir)\$(Configuration)64\Plugins\ + $(SolutionDir)\$(Configuration)64\Obj\$(ProjectName)\ + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + $(IncludePath) + $(IncludePath) + $(IncludePath) + $(IncludePath) + true + true + + + + + + + + Disabled + false + ../../include;../../plugins/ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;OMEGLE_EXPORTS;_CRT_SECURE_NO_WARNINGS;NOMINMAX;%(PreprocessorDefinitions) + false + MultiThreadedDebug + true + Use + common.h + Level3 + EditAndContinue + + + _UNICODE;UNICODE;_DEBUG;%(PreprocessorDefinitions) + + + true + true + $(TargetDir)$(TargetName).map + Windows + + + + + + + false + MachineX86 + $(IntDir)$(TargetName).lib + + + + + + + + + X64 + + + Disabled + false + ../../include;../../plugins/ExternalAPI;%(AdditionalIncludeDirectories) + _DEBUG;_WINDOWS;_USRDLL;OMEGLE_EXPORTS;_CRT_SECURE_NO_WARNINGS;NOMINMAX;_WIN64;%(PreprocessorDefinitions) + MultiThreadedDebug + false + Use + common.h + Level3 + ProgramDatabase + + + _UNICODE;UNICODE;_DEBUG;%(PreprocessorDefinitions) + + + true + true + $(TargetDir)$(TargetName).map + Windows + + + + + + + false + MachineX64 + $(IntDir)$(TargetName).lib + + + + + + + + + Full + true + Size + ../../include;../../plugins/ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;OMEGLE_EXPORTS;_CRT_SECURE_NO_WARNINGS;NOMINMAX;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + false + Use + common.h + Level3 + ProgramDatabase + NotSet + Fast + false + false + + + _UNICODE;UNICODE;%(PreprocessorDefinitions) + + + + + $(OutDir)$(TargetName)$(TargetExt) + true + false + $(TargetDir)$(TargetName).map + Windows + true + true + false + MachineX86 + $(IntDir)$(TargetName).lib + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + true + + + $(IntDir)$(TargetName)$(TargetExt).embed.manifest + + + + + + + + + X64 + + + Full + true + Size + ../../include;../../plugins/ExternalAPI;%(AdditionalIncludeDirectories) + NDEBUG;_WINDOWS;_USRDLL;OMEGLE_EXPORTS;_CRT_SECURE_NO_WARNINGS;NOMINMAX;_WIN64;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + false + Use + common.h + Level3 + ProgramDatabase + Strict + false + false + + + _UNICODE;UNICODE;%(PreprocessorDefinitions) + + + + + $(OutDir)$(TargetName)$(TargetExt) + true + $(TargetDir)$(TargetName).map + Windows + true + true + false + MachineX64 + $(IntDir)$(TargetName).lib + uuid.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + + + + + Create + Create + Create + Create + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/protocols/Omegle/omegle_10.vcxproj.filters b/protocols/Omegle/omegle_10.vcxproj.filters new file mode 100644 index 0000000000..c222cc6004 --- /dev/null +++ b/protocols/Omegle/omegle_10.vcxproj.filters @@ -0,0 +1,97 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Resource Files + + + Header Files + + + + + Resource Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/protocols/Omegle/omegle_icons.cpp b/protocols/Omegle/omegle_icons.cpp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/protocols/Omegle/omegle_icons.rc b/protocols/Omegle/omegle_icons.rc new file mode 100644 index 0000000000..b04059f025 --- /dev/null +++ b/protocols/Omegle/omegle_icons.rc @@ -0,0 +1,73 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource_icons.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Czech resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CSY) +#ifdef _WIN32 +LANGUAGE LANG_CZECH, SUBLANG_DEFAULT +#pragma code_page(1250) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource_icons.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_OFFLINE ICON "icons\\proto_offline.ico" +IDI_ONLINE ICON "icons\\proto_online.ico" +#endif // Czech resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/protocols/Omegle/omegle_icons_10.vcxproj b/protocols/Omegle/omegle_icons_10.vcxproj new file mode 100644 index 0000000000..f44d5ac8c7 --- /dev/null +++ b/protocols/Omegle/omegle_icons_10.vcxproj @@ -0,0 +1,145 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {C5AB34D2-15F5-4CBA-8F42-DB48A4E52910} + proto_omegle + Proto_Omegle + + + + DynamicLibrary + MultiByte + true + + + DynamicLibrary + MultiByte + true + + + Application + MultiByte + + + Application + MultiByte + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)$(Configuration)\Icons\ + $(SolutionDir)$(Configuration)\Icons\ + $(Configuration)\ + $(Configuration)\ + $(SolutionDir)$(Configuration)\Icons\ + $(SolutionDir)$(Configuration)\Icons\ + $(Platform) $(Configuration)\ + $(Platform) $(Configuration)\ + + + + Disabled + true + EnableFastChecks + MultiThreadedDebug + Level3 + EditAndContinue + + + true + MachineX86 + + + + + Disabled + EnableFastChecks + MultiThreadedDebug + Level3 + ProgramDatabase + + + true + + + + + MaxSpeed + true + MultiThreadedDLL + true + Level3 + ProgramDatabase + + + false + true + true + MachineX86 + + + + + MaxSpeed + true + MultiThreadedDLL + true + Level3 + ProgramDatabase + + + false + true + true + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/protocols/Omegle/omegle_icons_10.vcxproj.filters b/protocols/Omegle/omegle_icons_10.vcxproj.filters new file mode 100644 index 0000000000..ea8b2aa55e --- /dev/null +++ b/protocols/Omegle/omegle_icons_10.vcxproj.filters @@ -0,0 +1,30 @@ + + + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + + + Resource Files + + + + + Resource Files + + + Resource Files + + + + + Resource Files + + + + + + \ No newline at end of file diff --git a/protocols/Omegle/process.cpp b/protocols/Omegle/process.cpp new file mode 100644 index 0000000000..eb707373ec --- /dev/null +++ b/protocols/Omegle/process.cpp @@ -0,0 +1,77 @@ +/* + +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" + +void OmegleProto::ProcessEvents( void* data ) +{ + if ( data == NULL ) + return; + + std::string* resp = (std::string*)data; + + if ( isOffline() ) + goto exit; + + LOG("***** Starting processing messages"); + + CODE_BLOCK_TRY + + std::vector< Omegle_message* > messages; + + Omegle_json_parser* p = new Omegle_json_parser( this ); + p->parse_messages( data, &messages ); + delete p; + + for(std::vector::size_type i=0; imessage_text.c_str()); + +/* + PROTORECVEVENT recv = {}; + CCSDATA ccs = {}; + + recv.flags = PREF_UTF; + recv.szMessage = const_cast(messages[i]->message_text.c_str()); + recv.timestamp = static_cast(messages[i]->time); + + ccs.hContact = hContact; + ccs.szProtoService = PSR_MESSAGE; + ccs.wParam = ID_STATUS_ONLINE; + ccs.lParam = reinterpret_cast(&recv); + CallService(MS_PROTO_CHAINRECV,0,reinterpret_cast(&ccs));*/ + + delete messages[i]; + } + messages.clear(); + + LOG("***** Messages processed"); + + CODE_BLOCK_CATCH + + LOG("***** Error processing messages: %s", e.what()); + + CODE_BLOCK_END + +exit: + delete resp; +} diff --git a/protocols/Omegle/proto.cpp b/protocols/Omegle/proto.cpp new file mode 100644 index 0000000000..7fd27e65c6 --- /dev/null +++ b/protocols/Omegle/proto.cpp @@ -0,0 +1,255 @@ +/* + +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; + } +}*/ diff --git a/protocols/Omegle/proto.h b/protocols/Omegle/proto.h new file mode 100644 index 0000000000..457ea775cd --- /dev/null +++ b/protocols/Omegle/proto.h @@ -0,0 +1,159 @@ +/* + +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 . + +*/ + +#pragma once + +class OmegleProto : public PROTO_INTERFACE +{ +public: + OmegleProto( const char *proto_name, const TCHAR *username ); + ~OmegleProto( ); + + __inline void* operator new( size_t size ) + { + return calloc( 1, size ); + } + __inline void operator delete( void* p ) + { + free( p ); + } + + inline const char* ModuleName( ) const + { + return m_szModuleName; + } + + inline bool isOnline( ) + { + return ( m_iStatus != ID_STATUS_OFFLINE && m_iStatus != ID_STATUS_CONNECTING ); + } + + inline bool isOffline( ) + { + return ( m_iStatus == ID_STATUS_OFFLINE ); + } + + // PROTO_INTERFACE + virtual HANDLE __cdecl AddToList( int flags, PROTOSEARCHRESULT* psr ); + virtual HANDLE __cdecl AddToListByEvent( int flags, int iContact, HANDLE hDbEvent ); + + virtual int __cdecl Authorize( HANDLE hDbEvent ); + virtual int __cdecl AuthDeny( HANDLE hDbEvent, const PROTOCHAR* szReason ); + virtual int __cdecl AuthRecv( HANDLE hContact, PROTORECVEVENT* ); + virtual int __cdecl AuthRequest( HANDLE hContact, const PROTOCHAR* szMessage ); + + virtual HANDLE __cdecl ChangeInfo( int iInfoType, void* pInfoData ); + + virtual HANDLE __cdecl FileAllow( HANDLE hContact, HANDLE hTransfer, const PROTOCHAR* szPath ); + virtual int __cdecl FileCancel( HANDLE hContact, HANDLE hTransfer ); + virtual int __cdecl FileDeny( HANDLE hContact, HANDLE hTransfer, const PROTOCHAR* szReason ); + virtual int __cdecl FileResume( HANDLE hTransfer, int* action, const PROTOCHAR** szFilename ); + + virtual DWORD_PTR __cdecl GetCaps( int type, HANDLE hContact = NULL ); + virtual HICON __cdecl GetIcon( int iconIndex ); + virtual int __cdecl GetInfo( HANDLE hContact, int infoType ); + + virtual HANDLE __cdecl SearchBasic( const PROTOCHAR* id ); + virtual HANDLE __cdecl SearchByEmail( const PROTOCHAR* email ); + virtual HANDLE __cdecl SearchByName( const PROTOCHAR* nick, const PROTOCHAR* firstName, const PROTOCHAR* lastName ); + virtual HWND __cdecl SearchAdvanced( HWND owner ); + virtual HWND __cdecl CreateExtendedSearchUI( HWND owner ); + + virtual int __cdecl RecvContacts( HANDLE hContact, PROTORECVEVENT* ); + virtual int __cdecl RecvFile( HANDLE hContact, PROTOFILEEVENT* ); + virtual int __cdecl RecvMsg( HANDLE hContact, PROTORECVEVENT* ); + virtual int __cdecl RecvUrl( HANDLE hContact, PROTORECVEVENT* ); + + virtual int __cdecl SendContacts( HANDLE hContact, int flags, int nContacts, HANDLE* hContactsList ); + virtual HANDLE __cdecl SendFile( HANDLE hContact, const PROTOCHAR* szDescription, PROTOCHAR** ppszFiles ); + virtual int __cdecl SendMsg( HANDLE hContact, int flags, const char* msg ); + virtual int __cdecl SendUrl( HANDLE hContact, int flags, const char* url ); + + virtual int __cdecl SetApparentMode( HANDLE hContact, int mode ); + virtual int __cdecl SetStatus( int iNewStatus ); + + virtual HANDLE __cdecl GetAwayMsg( HANDLE hContact ); + virtual int __cdecl RecvAwayMsg( HANDLE hContact, int mode, PROTORECVEVENT* evt ); + virtual int __cdecl SendAwayMsg( HANDLE hContact, HANDLE hProcess, const char* msg ); + virtual int __cdecl SetAwayMsg( int iStatus, const PROTOCHAR* msg ); + + virtual int __cdecl UserIsTyping( HANDLE hContact, int type ); + + virtual int __cdecl OnEvent( PROTOEVENTTYPE iEventType, WPARAM wParam, LPARAM lParam ); + + // Services + int __cdecl SvcCreateAccMgrUI( WPARAM, LPARAM ); + + // Events + int __cdecl OnModulesLoaded(WPARAM, LPARAM); + int __cdecl OnOptionsInit(WPARAM, LPARAM); + int __cdecl OnContactDeleted(WPARAM,LPARAM); + int __cdecl OnPreShutdown(WPARAM,LPARAM); + int __cdecl OnPrebuildContactMenu(WPARAM,LPARAM); + + // Chat handling + int __cdecl OnChatEvent(WPARAM,LPARAM); + int __cdecl OnJoinChat(WPARAM,LPARAM); + int __cdecl OnLeaveChat(WPARAM,LPARAM); + + // Loops + void __cdecl EventsLoop(void*); + + // Worker threads + void __cdecl SignOn(void*); + void __cdecl SignOff(void*); + + void __cdecl SendMsgWorker(void*); + void __cdecl SendTypingWorker(void*); + + void __cdecl NewChatWorker(void*); + void __cdecl StopChatWorker(void*); + + void StopChat(bool disconnect = true); + void NewChat(); + + // Contacts handling + //bool IsMyContact(HANDLE, bool include_chat = false); + + // Chat handling + void AddChat(const TCHAR *id,const TCHAR *name); + void UpdateChat(const TCHAR *name, const TCHAR *message, bool addtochat = true); + void AddChatContact(const TCHAR *nick); + void DeleteChatContact(const TCHAR *name); + void SetChatStatus(int); + void ClearChat(); + void SetTopic(const TCHAR *topic = NULL); + + // Connection client + Omegle_client facy; + + HANDLE signon_lock_; + HANDLE log_lock_; + HANDLE events_loop_lock_; + + HANDLE m_hNetlibUser; + + static void CALLBACK APC_callback(ULONG_PTR p); + + // Logging + int Log(const char *fmt,...); +}; diff --git a/protocols/Omegle/readme.txt b/protocols/Omegle/readme.txt new file mode 100644 index 0000000000..cbc85e0bb8 --- /dev/null +++ b/protocols/Omegle/readme.txt @@ -0,0 +1,2 @@ +This plugin is based on sources of Facebook Protocol (OpenSource version 0.1.3.3) by Jarvis, +which can be found there: http://code.google.com/p/eternityplugins \ No newline at end of file diff --git a/protocols/Omegle/resource.h b/protocols/Omegle/resource.h new file mode 100644 index 0000000000..0cfab1d840 --- /dev/null +++ b/protocols/Omegle/resource.h @@ -0,0 +1,31 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by omegle.rc +// +#define IDI_OMEGLE 101 +#define IDD_OmegleACCOUNT 111 +#define IDD_OPTIONS 122 +#define IDC_SERVER 1204 +#define IDC_NAME 1205 +#define IDC_MEET_COMMON 1206 +#define IDC_INTERESTS 1207 +#define IDC_HI_ENABLED 1208 +#define IDC_HI_MESSAGE 1209 +#define IDC_ASL_MESSAGE 1210 +#define IDC_LAST_QUESTION 1211 +#define IDC_NOCLEAR 1213 +#define IDC_DONTSTOP 1214 +#define IDC_REUSE_QUESTIONS 1215 +#define IDC_LOGGING 1216 +#define IDC_SERVER_INFO 1217 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 124 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1208 +#define _APS_NEXT_SYMED_VALUE 131 +#endif +#endif diff --git a/protocols/Omegle/resource_icons.h b/protocols/Omegle/resource_icons.h new file mode 100644 index 0000000000..b150f4933c --- /dev/null +++ b/protocols/Omegle/resource_icons.h @@ -0,0 +1,17 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by omegle_icons.rc +// +#define IDI_OFFLINE 105 +#define IDI_ONLINE 104 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 103 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/protocols/Omegle/stubs.cpp b/protocols/Omegle/stubs.cpp new file mode 100644 index 0000000000..24354c49bc --- /dev/null +++ b/protocols/Omegle/stubs.cpp @@ -0,0 +1,173 @@ +/* + +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" + +HANDLE OmegleProto::AddToList(int flags, PROTOSEARCHRESULT* psr) +{ + return 0; +}; + +HANDLE OmegleProto::AddToListByEvent(int flags,int iContact,HANDLE hDbEvent) +{ + return 0; +}; + +int OmegleProto::Authorize(HANDLE hContact) +{ + return 0; +} + +int OmegleProto::AuthDeny(HANDLE hContact,const PROTOCHAR *reason) +{ + return 0; +} + +int OmegleProto::AuthRecv(HANDLE hContact,PROTORECVEVENT *) +{ + return 0; +} + +int OmegleProto::AuthRequest(HANDLE hContact,const PROTOCHAR *message) +{ + return 0; +} + +HANDLE OmegleProto::ChangeInfo(int type,void *info_data) +{ + return 0; +} + +HANDLE OmegleProto::FileAllow(HANDLE hContact,HANDLE hTransfer,const PROTOCHAR *path) +{ + return 0; +} + +int OmegleProto::FileCancel(HANDLE hContact,HANDLE hTransfer) +{ + return 0; +} + +int OmegleProto::FileDeny(HANDLE hContact,HANDLE hTransfer,const PROTOCHAR *reason) +{ + return 0; +} + +int OmegleProto::FileResume(HANDLE hTransfer,int *action,const PROTOCHAR **filename) +{ + return 0; +} + +int OmegleProto::GetInfo( HANDLE hContact, int infoType ) +{ + return 1; +} + +HANDLE OmegleProto::SearchBasic( const PROTOCHAR* id ) +{ + return 0; +} + +HANDLE OmegleProto::SearchByEmail( const PROTOCHAR* email ) +{ + return 0; +} + +HANDLE OmegleProto::SearchByName( const PROTOCHAR* nick, const PROTOCHAR* firstName, const PROTOCHAR* lastName ) +{ + return 0; +} + +HWND OmegleProto::SearchAdvanced(HWND owner) +{ + return 0; +} + +HWND OmegleProto::CreateExtendedSearchUI(HWND owner) +{ + return 0; +} + +int OmegleProto::RecvContacts(HANDLE hContact,PROTORECVEVENT *) +{ + return 0; +} + +int OmegleProto::RecvFile(HANDLE hContact,PROTORECVFILET *) +{ + return 0; +} + +int OmegleProto::RecvUrl(HANDLE hContact,PROTORECVEVENT *) +{ + return 0; +} + +int OmegleProto::SendContacts(HANDLE hContact,int flags,int nContacts,HANDLE *hContactsList) +{ + return 0; +} + +HANDLE OmegleProto::SendFile(HANDLE hContact,const PROTOCHAR *desc, PROTOCHAR **files) +{ + return 0; +} + +int OmegleProto::SendUrl(HANDLE hContact,int flags,const char *url) +{ + return 0; +} + +int OmegleProto::SetApparentMode(HANDLE hContact,int mode) +{ + return 0; +} + +int OmegleProto::RecvAwayMsg(HANDLE hContact,int mode,PROTORECVEVENT *evt) +{ + return 0; +} + +int OmegleProto::SendAwayMsg(HANDLE hContact,HANDLE hProcess,const char *msg) +{ + return 0; +} + +int OmegleProto::UserIsTyping(HANDLE hContact, int type) +{ + return 0; +} + +int OmegleProto::SetAwayMsg(int iStatus, const PROTOCHAR* msg) +{ + return 0; +} + +HANDLE OmegleProto::GetAwayMsg( HANDLE hContact ) +{ + return 0; +} + +int OmegleProto::RecvMsg(HANDLE hContact, PROTORECVEVENT *pre) +{ + return 0; +} diff --git a/protocols/Omegle/theme.cpp b/protocols/Omegle/theme.cpp new file mode 100644 index 0000000000..ea1cf9cf16 --- /dev/null +++ b/protocols/Omegle/theme.cpp @@ -0,0 +1,115 @@ +/* + +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" + +extern OBJLIST g_Instances; + +struct +{ + const char* name; + const char* descr; + int defIconID; + const char* section; +} +static const icons[] = +{ + { "omegle", LPGEN("Omegle Icon"), IDI_OMEGLE }, +// { "homepage", LPGEN("Visit Profile"), 0, "core_main_2" }, +}; + +static HANDLE hIconLibItem[SIZEOF(icons)]; + +// TODO: uninit +void InitIcons(void) +{ + TCHAR szFile[MAX_PATH]; + GetModuleFileName(g_hInstance, szFile, SIZEOF(szFile)); + + char setting_name[100]; + char section_name[100]; + + SKINICONDESC sid = {0}; + sid.cbSize = sizeof(SKINICONDESC); + sid.ptszDefaultFile = szFile; + sid.cx = sid.cy = 16; + sid.pszName = setting_name; + sid.pszSection = section_name; + sid.flags = SIDF_PATH_TCHAR; + + for (int i=0; i( CallService(MS_PROTO_GETCONTACTBASEPROTO, + reinterpret_cast(hContact),0) ); + if(!proto) + return 0; + + for(int i=0; i +INT_PTR GlobalService(WPARAM wParam,LPARAM lParam) +{ + OmegleProto *proto = GetInstanceByHContact(reinterpret_cast(wParam)); + return proto ? (proto->*Fcn)(wParam,lParam) : 0; +} + diff --git a/protocols/Omegle/theme.h b/protocols/Omegle/theme.h new file mode 100644 index 0000000000..7456803b6c --- /dev/null +++ b/protocols/Omegle/theme.h @@ -0,0 +1,30 @@ +/* + +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 . + +*/ + +#pragma once + +void InitIcons(void); +HANDLE GetIconHandle(const char *name); + +//void InitContactMenus(void); +//void UninitContactMenus(void); +//void ShowContactMenus(bool show, bool deleted = false); \ No newline at end of file diff --git a/protocols/Omegle/utils.cpp b/protocols/Omegle/utils.cpp new file mode 100644 index 0000000000..975ab7df4c --- /dev/null +++ b/protocols/Omegle/utils.cpp @@ -0,0 +1,150 @@ +/* + +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" + +std::string utils::url::encode(const std::string &s) +{ + char *encoded = reinterpret_cast(CallService( MS_NETLIB_URLENCODE, + 0,reinterpret_cast(s.c_str()) )); + std::string ret = encoded; + HeapFree(GetProcessHeap(),0,encoded); + + return ret; +} + +void utils::text::replace_first( std::string* data, std::string from, std::string to ) +{ + std::string::size_type position = 0; + + if ( ( position = data->find(from, position) ) != std::string::npos ) + { + data->replace( position, from.size(), to ); + position++; + } +} + +void utils::text::replace_all( std::string* data, std::string from, std::string to ) +{ + std::string::size_type position = 0; + + while ( ( position = data->find( from, position ) ) != std::string::npos ) + { + data->replace( position, from.size(), to ); + position++; + } +} + +std::string utils::text::special_expressions_decode( std::string data ) +{ + utils::text::replace_all( &data, "\\r", "\r" ); + utils::text::replace_all( &data, "\\n", "\n" ); + utils::text::replace_all( &data, "\\\"", "\"" ); + utils::text::replace_all( &data, "\\\\", "\\" ); + + return data; +} + + +std::string utils::text::slashu_to_utf8( std::string data ) +{ + std::string new_string = ""; + + for ( std::string::size_type i = 0; i < data.length( ); i++ ) + { + if ( data.at(i) == '\\' && (i+1) < data.length( ) && data.at(i+1) == 'u' ) + { + unsigned int udn = strtol( data.substr( i + 2, 4 ).c_str(), NULL, 16 ); + + if ( udn >= 128 && udn <= 2047 ) + { // U+0080 .. U+07FF + new_string += ( char )( 192 + ( udn / 64 ) ); + new_string += ( char )( 128 + ( udn % 64 ) ); + } + else if ( udn >= 2048 && udn <= 65535 ) + { // U+0800 .. U+FFFF + new_string += ( char )( 224 + ( udn / 4096 ) ); + new_string += ( char )( 128 + ( ( udn / 64 ) % 64 ) ); + new_string += ( char )( 128 + ( udn % 64 ) ); + } + else if ( udn <= 127 ) + { // U+0000 .. U+007F (should not appear) + new_string += ( char )udn; + } + + i += 5; + continue; + } + + new_string += data.at(i); + } + + return new_string; +} + +std::string utils::text::trim( std::string data ) +{ + std::string spaces = " \t\r\n"; + std::string::size_type begin = data.find_first_not_of( spaces ); + std::string::size_type end = data.find_last_not_of( spaces ) + 1; + + return (begin != std::string::npos) ? data.substr( begin, end - begin ) : ""; +} + +int utils::debug::log(std::string file_name, std::string text) +{ + char szFile[MAX_PATH]; + GetModuleFileNameA(g_hInstance, szFile, SIZEOF(szFile)); + std::string path = szFile; + path = path.substr( 0, path.rfind( "\\" ) ); + path = path.substr( 0, path.rfind( "\\" ) + 1 ); + path = path + file_name.c_str() + ".txt"; + + SYSTEMTIME time; + GetLocalTime( &time ); + + std::ofstream out( path.c_str(), std::ios_base::out | std::ios_base::app | std::ios_base::ate ); + out << "[" << (time.wHour < 10 ? "0" : "") << time.wHour << ":" << (time.wMinute < 10 ? "0" : "") << time.wMinute << ":" << (time.wSecond < 10 ? "0" : "") << time.wSecond << "] " << text << std::endl; + out.close( ); + + return EXIT_SUCCESS; +} + +void __fastcall utils::mem::detract(char** str ) +{ + utils::mem::detract( ( void** )str ); +} + +void __fastcall utils::mem::detract(void** p) +{ + utils::mem::detract((void*)(*p)); +} + +void __fastcall utils::mem::detract(void* p) +{ + mir_free(p); +} + +void* __fastcall utils::mem::allocate(size_t size) +{ + return mir_calloc(size); +} diff --git a/protocols/Omegle/utils.h b/protocols/Omegle/utils.h new file mode 100644 index 0000000000..908b721e72 --- /dev/null +++ b/protocols/Omegle/utils.h @@ -0,0 +1,103 @@ +/* + +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 . + +*/ + +#pragma once + +template +void CreateProtoService(const char *module,const char *service, + int (__cdecl T::*serviceProc)(WPARAM,LPARAM),T *self) +{ + char temp[MAX_PATH*2]; + + mir_snprintf(temp,sizeof(temp),"%s%s",module,service); + CreateServiceFunctionObj(temp,( MIRANDASERVICEOBJ )*(void**)&serviceProc, self ); +} + +template +void HookProtoEvent(const char* evt, int (__cdecl T::*eventProc)(WPARAM,LPARAM), T *self) +{ + ::HookEventObj(evt,(MIRANDAHOOKOBJ)*(void**)&eventProc,self); +} + +template +HANDLE ForkThreadEx(void (__cdecl T::*thread)(void*),T *self,void *data = 0) +{ + return reinterpret_cast( mir_forkthreadowner( + (pThreadFuncOwner)*(void**)&thread,self,data,0)); +} + +template +void ForkThread(void (__cdecl T::*thread)(void*),T *self,void *data = 0) +{ + CloseHandle(ForkThreadEx(thread,self,data)); +} + +namespace utils +{ + namespace url + { + std::string encode(const std::string &s); + }; + + namespace text + { + void replace_first( std::string* data, std::string from, std::string to ); + void replace_all( std::string* data, std::string from, std::string to ); + std::string special_expressions_decode( std::string data ); + std::string slashu_to_utf8( std::string data ); + std::string trim( std::string data ); + }; + + namespace debug + { + int log(std::string file_name, std::string text); + }; + + namespace mem + { + void __fastcall detract(char** str ); + void __fastcall detract(void** p); + void __fastcall detract(void* p); + void* __fastcall allocate(size_t size); + }; +}; + +class ScopedLock +{ +public: + ScopedLock(HANDLE h) : handle_(h) + { + WaitForSingleObject(handle_,INFINITE); + } + ~ScopedLock() + { + if(handle_) + ReleaseMutex(handle_); + } + void Unlock() + { + ReleaseMutex(handle_); + handle_ = 0; + } +private: + HANDLE handle_; +}; -- cgit v1.2.3