summaryrefslogtreecommitdiff
path: root/protocols
diff options
context:
space:
mode:
authorRobert Pösel <robyer@seznam.cz>2012-05-22 23:20:07 +0000
committerRobert Pösel <robyer@seznam.cz>2012-05-22 23:20:07 +0000
commit1680c6d262eb0525c1af95195b5b79839a5e2ce9 (patch)
tree41ea277d8d4ee4af48aff151daabdac485f49938 /protocols
parent3615f38b14197411ed8ae434b38d2ec00bf62768 (diff)
Added Omegle protocol.
git-svn-id: http://svn.miranda-ng.org/main/trunk@136 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'protocols')
-rw-r--r--protocols/Omegle/chat.cpp405
-rw-r--r--protocols/Omegle/client.h123
-rw-r--r--protocols/Omegle/common.h86
-rw-r--r--protocols/Omegle/communication.cpp809
-rw-r--r--protocols/Omegle/connection.cpp179
-rw-r--r--protocols/Omegle/constants.h54
-rw-r--r--protocols/Omegle/db.h55
-rw-r--r--protocols/Omegle/dialogs.cpp231
-rw-r--r--protocols/Omegle/dialogs.h26
-rw-r--r--protocols/Omegle/docs/omegle - langpack.txt104
-rw-r--r--protocols/Omegle/docs/omegle - readme_cz.txt80
-rw-r--r--protocols/Omegle/docs/omegle - readme_en.txt80
-rw-r--r--protocols/Omegle/events.cpp39
-rw-r--r--protocols/Omegle/http.cpp23
-rw-r--r--protocols/Omegle/http.h48
-rw-r--r--protocols/Omegle/icons/omegle.icobin0 -> 894 bytes
-rw-r--r--protocols/Omegle/icons/proto_offline.icobin0 -> 1150 bytes
-rw-r--r--protocols/Omegle/icons/proto_online.icobin0 -> 1150 bytes
-rw-r--r--protocols/Omegle/main.cpp210
-rw-r--r--protocols/Omegle/messages.cpp92
-rw-r--r--protocols/Omegle/omegle.apsbin0 -> 40344 bytes
-rw-r--r--protocols/Omegle/omegle.rc214
-rw-r--r--protocols/Omegle/omegle.sln36
-rw-r--r--protocols/Omegle/omegle_10.vcxproj310
-rw-r--r--protocols/Omegle/omegle_10.vcxproj.filters97
-rw-r--r--protocols/Omegle/omegle_icons.cpp0
-rw-r--r--protocols/Omegle/omegle_icons.rc73
-rw-r--r--protocols/Omegle/omegle_icons_10.vcxproj145
-rw-r--r--protocols/Omegle/omegle_icons_10.vcxproj.filters30
-rw-r--r--protocols/Omegle/process.cpp77
-rw-r--r--protocols/Omegle/proto.cpp255
-rw-r--r--protocols/Omegle/proto.h159
-rw-r--r--protocols/Omegle/readme.txt2
-rw-r--r--protocols/Omegle/resource.h31
-rw-r--r--protocols/Omegle/resource_icons.h17
-rw-r--r--protocols/Omegle/stubs.cpp173
-rw-r--r--protocols/Omegle/theme.cpp115
-rw-r--r--protocols/Omegle/theme.h30
-rw-r--r--protocols/Omegle/utils.cpp150
-rw-r--r--protocols/Omegle/utils.h103
40 files changed, 4661 insertions, 0 deletions
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 <http://www.gnu.org/licenses/>.
+*/
+
+#include "common.h"
+
+void OmegleProto::UpdateChat(const TCHAR *name, const TCHAR *message, bool addtolog)
+{
+ GCDEST gcd = { m_szModuleName };
+ gcd.ptszID = const_cast<TCHAR*>(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<LPARAM>(&gce));
+}
+
+int OmegleProto::OnChatEvent(WPARAM wParam,LPARAM lParam)
+{
+ GCHOOK *hook = reinterpret_cast<GCHOOK*>(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 <question> - 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<TCHAR*>(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<LPARAM>(&gce));
+}*/
+
+void OmegleProto::AddChatContact(const TCHAR *name)
+{
+ GCDEST gcd = { m_szModuleName };
+ gcd.ptszID = const_cast<TCHAR*>(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<DWORD>(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<LPARAM>(&gce));
+}
+
+void OmegleProto::DeleteChatContact(const TCHAR *name)
+{
+ GCDEST gcd = { m_szModuleName };
+ gcd.ptszID = const_cast<TCHAR*>(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<DWORD>(time(0));
+ if (name == NULL)
+ gce.bIsMe = false;
+ else
+ gce.bIsMe = !_tcscmp(name, this->facy.nick_);
+
+ CallServiceSync(MS_GC_EVENT,0,reinterpret_cast<LPARAM>(&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<TCHAR*>(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<LPARAM>(&gce) );
+
+ gce.ptszStatus = _T("Normal");
+ CallServiceSync( MS_GC_EVENT, NULL, reinterpret_cast<LPARAM>(&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<TCHAR*>(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<LPARAM>(&gce));
+}
+
+int OmegleProto::OnLeaveChat(WPARAM,LPARAM)
+{
+ GCDEST gcd = { m_szModuleName };
+ gcd.ptszID = const_cast<TCHAR*>(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<LPARAM>(&gce));
+ CallServiceSync(MS_GC_EVENT,SESSION_TERMINATE,reinterpret_cast<LPARAM>(&gce));
+
+ return 0;
+}
+
+void OmegleProto::SetChatStatus(int status)
+{
+ GCDEST gcd = { m_szModuleName };
+ gcd.ptszID = const_cast<TCHAR*>(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<LPARAM>(&gce));
+ CallServiceSync(MS_GC_EVENT,SESSION_ONLINE, reinterpret_cast<LPARAM>(&gce));
+ }
+ else
+ {
+ CallServiceSync(MS_GC_EVENT,SESSION_OFFLINE,reinterpret_cast<LPARAM>(&gce));
+ }
+}
+
+void OmegleProto::ClearChat()
+{
+ if (getByte(OMEGLE_KEY_NO_CLEAR, 0))
+ return;
+
+ GCDEST gcd = { m_szModuleName };
+ gcd.ptszID = const_cast<TCHAR*>(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<LPARAM>(&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 <http://www.gnu.org/licenses/>.
+
+*/
+
+#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 <http://www.gnu.org/licenses/>.
+
+*/
+
+#pragma once
+
+#pragma warning(disable:4996)
+
+#define MIRANDA_VER 0x1000
+#define _WIN32_WINNT 0x0500
+#define _WIN32_WINDOWS 0x0500
+
+#include <m_stdhdr.h>
+
+#include <string>
+#include <cstring>
+#include <sstream>
+#include <fstream>
+#include <map>
+#include <stdarg.h>
+#include <time.h>
+#include <assert.h>
+#include <io.h>
+
+#include <windows.h>
+#include <win2k.h>
+#include <commctrl.h>
+
+#include <newpluginapi.h>
+#include <m_version.h>
+#include <m_system.h>
+#include <m_system_cpp.h>
+#include <m_chat.h>
+#include <m_clistint.h>
+#include <m_database.h>
+#include <m_langpack.h>
+#include <m_netlib.h>
+#include <m_options.h>
+#include <m_popup.h>
+#include <m_protocols.h>
+#include <m_protosvc.h>
+#include <m_protoint.h>
+#include <m_protomod.h>
+#include <m_skin.h>
+#include <statusmodes.h>
+#include <m_icolib.h>
+#include <m_utils.h>
+#include <m_hotkeys.h>
+#include <m_updater.h>
+//#include <m_msg_buttonsbar.h>
+
+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 <http://www.gnu.org/licenses/>.
+*/
+
+#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 <http://www.gnu.org/licenses/>.
+
+*/
+
+#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 <http://www.gnu.org/licenses/>.
+
+*/
+
+#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 <http://www.gnu.org/licenses/>.
+
+*/
+
+#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 <http://www.gnu.org/licenses/>.
+
+*/
+
+#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<OmegleProto*>(lparam);
+ SetWindowLong(hwnd,GWLP_USERDATA,lparam);
+
+ SendDlgItemMessage(hwnd,IDC_INTERESTS, EM_LIMITTEXT, 512, 0);
+
+ // Server
+ SendDlgItemMessageA(hwnd, IDC_SERVER, CB_INSERTSTRING, 0, reinterpret_cast<LPARAM>(Translate(servers[0])));
+ for(size_t i=1; i<SIZEOF(servers); i++)
+ {
+ SendDlgItemMessageA(hwnd, IDC_SERVER, CB_INSERTSTRING, i, reinterpret_cast<LPARAM>(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<NMHDR*>(lparam)->code == PSN_APPLY )
+ {
+ proto = reinterpret_cast<OmegleProto*>(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<OmegleProto*>(GetWindowLong(hwnd,GWLP_USERDATA));
+
+ switch ( message )
+ {
+
+ case WM_INITDIALOG:
+ {
+ TranslateDialogDefault(hwnd);
+
+ proto = reinterpret_cast<OmegleProto*>(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<LPARAM>(Translate(servers[0])));
+ for(size_t i=1; i<SIZEOF(servers); i++)
+ {
+ SendDlgItemMessageA(hwnd, IDC_SERVER, CB_INSERTSTRING, i, reinterpret_cast<LPARAM>(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<NMHDR*>(lparam)->code == PSN_APPLY )
+ {
+ proto = reinterpret_cast<OmegleProto*>(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 <http://www.gnu.org/licenses/>.
+
+*/
+
+#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 <undef> 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 <undef> 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 <http://www.gnu.org/licenses/>.
+
+*/
+
+#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 <http://www.gnu.org/licenses/>.
+
+*/
+
+#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 <http://www.gnu.org/licenses/>.
+
+*/
+
+#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
--- /dev/null
+++ b/protocols/Omegle/icons/omegle.ico
Binary files differ
diff --git a/protocols/Omegle/icons/proto_offline.ico b/protocols/Omegle/icons/proto_offline.ico
new file mode 100644
index 0000000000..bc608d61c8
--- /dev/null
+++ b/protocols/Omegle/icons/proto_offline.ico
Binary files differ
diff --git a/protocols/Omegle/icons/proto_online.ico b/protocols/Omegle/icons/proto_online.ico
new file mode 100644
index 0000000000..206e829e6b
--- /dev/null
+++ b/protocols/Omegle/icons/proto_online.ico
Binary files 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 <http://www.gnu.org/licenses/>.
+
+*/
+
+#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<OmegleProto> 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<BYTE*>("Omegle ");
+ upd.cpbBetaVersionPrefix = (int)strlen(reinterpret_cast<char*>(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<BYTE*>(CreateVersionStringPluginEx(&pluginInfo,curr_version) );
+ upd.cpbVersion = (int)strlen(reinterpret_cast<char*>(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<CLIST_INTERFACE*>( CallService(
+ MS_CLIST_RETRIEVE_INTERFACE,0,reinterpret_cast<LPARAM>(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<LPARAM>(&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<SIZEOF(g_hEvents); i++)
+ UnhookEvent(g_hEvents[i]);
+
+ g_Instances.destroy();
+
+ return 0;
+}
diff --git a/protocols/Omegle/messages.cpp b/protocols/Omegle/messages.cpp
new file mode 100644
index 0000000000..7d2418f3e6
--- /dev/null
+++ b/protocols/Omegle/messages.cpp
@@ -0,0 +1,92 @@
+/*
+
+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 <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "common.h"
+
+void OmegleProto::SendMsgWorker(void *p)
+{
+ if(p == NULL)
+ return;
+
+ ScopedLock s( facy.send_message_lock_ );
+
+ std::string *data = static_cast<std::string*>(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<TCHAR*>(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
--- /dev/null
+++ b/protocols/Omegle/omegle.aps
Binary files 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 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{DADE9455-DC28-465A-9604-2CA28052B9FB}</ProjectGuid>
+ <RootNamespace>omegle</RootNamespace>
+ <Keyword>Win32Proj</Keyword>
+ <ProjectName>Omegle</ProjectName>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <UseOfMfc>Static</UseOfMfc>
+ <PlatformToolset>v100</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ <PlatformToolset>v100</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <UseOfMfc>Static</UseOfMfc>
+ <PlatformToolset>v100</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ <PlatformToolset>v100</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)\$(Configuration)\Plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)\$(Configuration)\Obj\$(ProjectName)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)\$(Configuration)64\Plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)\$(Configuration)64\Obj\$(ProjectName)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)\$(Configuration)\Plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)\$(Configuration)\Obj\$(ProjectName)\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)\$(Configuration)64\Plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)\$(Configuration)64\Obj\$(ProjectName)\</IntDir>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IncludePath)</IncludePath>
+ <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IncludePath)</IncludePath>
+ <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IncludePath)</IncludePath>
+ <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IncludePath)</IncludePath>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</LinkIncremental>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <PreBuildEvent>
+ <Command>
+ </Command>
+ </PreBuildEvent>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ <AdditionalIncludeDirectories>../../include;../../plugins/ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;OMEGLE_EXPORTS;_CRT_SECURE_NO_WARNINGS;NOMINMAX;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>common.h</PrecompiledHeaderFile>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_UNICODE;UNICODE;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(TargetDir)$(TargetName).map</MapFileName>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>
+ </OptimizeReferences>
+ <EnableCOMDATFolding>
+ </EnableCOMDATFolding>
+ <LinkTimeCodeGeneration>
+ </LinkTimeCodeGeneration>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <TargetMachine>MachineX86</TargetMachine>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <PreBuildEvent>
+ <Command>
+ </Command>
+ </PreBuildEvent>
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ <AdditionalIncludeDirectories>../../include;../../plugins/ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;OMEGLE_EXPORTS;_CRT_SECURE_NO_WARNINGS;NOMINMAX;_WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <FunctionLevelLinking>false</FunctionLevelLinking>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>common.h</PrecompiledHeaderFile>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_UNICODE;UNICODE;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(TargetDir)$(TargetName).map</MapFileName>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>
+ </OptimizeReferences>
+ <EnableCOMDATFolding>
+ </EnableCOMDATFolding>
+ <LinkTimeCodeGeneration>
+ </LinkTimeCodeGeneration>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <TargetMachine>MachineX64</TargetMachine>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <PreBuildEvent>
+ <Command>
+ </Command>
+ </PreBuildEvent>
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <AdditionalIncludeDirectories>../../include;../../plugins/ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;OMEGLE_EXPORTS;_CRT_SECURE_NO_WARNINGS;NOMINMAX;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>common.h</PrecompiledHeaderFile>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <FloatingPointExceptions>false</FloatingPointExceptions>
+ <CreateHotpatchableImage>false</CreateHotpatchableImage>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>
+ </AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <Link>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <GenerateMapFile>false</GenerateMapFile>
+ <MapFileName>$(TargetDir)$(TargetName).map</MapFileName>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <TargetMachine>MachineX86</TargetMachine>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <AdditionalDependencies>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)</AdditionalDependencies>
+ </Link>
+ <ProjectReference>
+ <LinkLibraryDependencies>true</LinkLibraryDependencies>
+ </ProjectReference>
+ <Manifest>
+ <OutputManifestFile>$(IntDir)$(TargetName)$(TargetExt).embed.manifest</OutputManifestFile>
+ </Manifest>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <PreBuildEvent>
+ <Command>
+ </Command>
+ </PreBuildEvent>
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <AdditionalIncludeDirectories>../../include;../../plugins/ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;OMEGLE_EXPORTS;_CRT_SECURE_NO_WARNINGS;NOMINMAX;_WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <PrecompiledHeaderFile>common.h</PrecompiledHeaderFile>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <FloatingPointModel>Strict</FloatingPointModel>
+ <FloatingPointExceptions>false</FloatingPointExceptions>
+ <CreateHotpatchableImage>false</CreateHotpatchableImage>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>
+ </AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <Link>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <MapFileName>$(TargetDir)$(TargetName).map</MapFileName>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <TargetMachine>MachineX64</TargetMachine>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <AdditionalDependencies>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)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="chat.cpp" />
+ <ClCompile Include="communication.cpp" />
+ <ClCompile Include="connection.cpp" />
+ <ClCompile Include="dialogs.cpp" />
+ <ClCompile Include="events.cpp" />
+ <ClCompile Include="http.cpp" />
+ <ClCompile Include="main.cpp">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="messages.cpp" />
+ <ClCompile Include="proto.cpp" />
+ <ClCompile Include="stubs.cpp" />
+ <ClCompile Include="theme.cpp" />
+ <ClCompile Include="utils.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="client.h" />
+ <ClInclude Include="common.h" />
+ <ClInclude Include="constants.h" />
+ <ClInclude Include="db.h" />
+ <ClInclude Include="dialogs.h" />
+ <ClInclude Include="http.h" />
+ <ClInclude Include="proto.h" />
+ <ClInclude Include="theme.h" />
+ <ClInclude Include="utils.h" />
+ <ClInclude Include="resource.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="icons\omegle.ico" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="omegle.rc" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ 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 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="chat.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="communication.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="connection.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="events.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="http.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="main.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="messages.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="proto.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="stubs.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="theme.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="utils.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="dialogs.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="client.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="common.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="constants.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="db.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="http.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="proto.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="theme.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="utils.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="resource.h">
+ <Filter>Resource Files</Filter>
+ </ClInclude>
+ <ClInclude Include="dialogs.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="icons\omegle.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="omegle.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+</Project> \ 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
--- /dev/null
+++ b/protocols/Omegle/omegle_icons.cpp
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 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{C5AB34D2-15F5-4CBA-8F42-DB48A4E52910}</ProjectGuid>
+ <RootNamespace>proto_omegle</RootNamespace>
+ <ProjectName>Proto_Omegle</ProjectName>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\Icons\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Configuration)\Icons\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\Icons\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Configuration)\Icons\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform) $(Configuration)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform) $(Configuration)\</IntDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ResourceCompile Include="omegle_icons.rc" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="icons\proto_offline.ico" />
+ <None Include="icons\proto_online.ico" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="resource_icons.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="omegle_icons.cpp" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ 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 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="omegle_icons.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="icons\proto_offline.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="icons\proto_online.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="resource_icons.h">
+ <Filter>Resource Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="omegle_icons.cpp" />
+ </ItemGroup>
+</Project> \ 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 <http://www.gnu.org/licenses/>.
+
+*/
+
+#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<Omegle_message*>::size_type i=0; i<messages.size( ); i++)
+ {
+ LOG(" Got message: %s", messages[i]->message_text.c_str());
+
+/*
+ PROTORECVEVENT recv = {};
+ CCSDATA ccs = {};
+
+ recv.flags = PREF_UTF;
+ recv.szMessage = const_cast<char*>(messages[i]->message_text.c_str());
+ recv.timestamp = static_cast<DWORD>(messages[i]->time);
+
+ ccs.hContact = hContact;
+ ccs.szProtoService = PSR_MESSAGE;
+ ccs.wParam = ID_STATUS_ONLINE;
+ ccs.lParam = reinterpret_cast<LPARAM>(&recv);
+ CallService(MS_PROTO_CHAINRECV,0,reinterpret_cast<LPARAM>(&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 <http://www.gnu.org/licenses/>.
+
+*/
+
+#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<LPARAM>(&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<char*>( CallService(MS_PROTO_GETCONTACTBASEPROTO,
+ reinterpret_cast<WPARAM>(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 <http://www.gnu.org/licenses/>.
+
+*/
+
+#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 <http://www.gnu.org/licenses/>.
+
+*/
+
+#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 <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "common.h"
+
+extern OBJLIST<OmegleProto> 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<SIZEOF(icons); i++)
+ {
+ if(icons[i].defIconID)
+ {
+ mir_snprintf(setting_name,sizeof(setting_name),"%s_%s","Omegle",icons[i].name);
+
+ if (icons[i].section)
+ {
+ mir_snprintf(section_name,sizeof(section_name),"%s/%s/%s",LPGEN("Protocols"),
+ LPGEN("Omegle"), icons[i].section);
+ } else {
+ mir_snprintf(section_name,sizeof(section_name),"%s/%s",LPGEN("Protocols"),
+ LPGEN("Omegle"));
+ }
+
+ sid.pszDescription = (char*)icons[i].descr;
+ sid.iDefaultIndex = -icons[i].defIconID;
+ hIconLibItem[i] = (HANDLE)CallService(MS_SKIN2_ADDICON,0,(LPARAM)&sid);
+ } else { // External icons
+ hIconLibItem[i] = (HANDLE)CallService(MS_SKIN2_GETICONHANDLE,0,
+ (LPARAM)icons[i].section);
+ }
+ }
+}
+
+HANDLE GetIconHandle(const char* name)
+{
+ for(size_t i=0; i<SIZEOF(icons); i++)
+ {
+ if(strcmp(icons[i].name,name) == 0)
+ return hIconLibItem[i];
+ }
+ return 0;
+}
+
+// Helper functions
+static OmegleProto * GetInstanceByHContact(HANDLE hContact)
+{
+ char *proto = reinterpret_cast<char*>( CallService(MS_PROTO_GETCONTACTBASEPROTO,
+ reinterpret_cast<WPARAM>(hContact),0) );
+ if(!proto)
+ return 0;
+
+ for(int i=0; i<g_Instances.getCount(); i++)
+ if(!strcmp(proto,g_Instances[i].m_szModuleName))
+ return &g_Instances[i];
+
+ return 0;
+}
+
+template<int (__cdecl OmegleProto::*Fcn)(WPARAM,LPARAM)>
+INT_PTR GlobalService(WPARAM wParam,LPARAM lParam)
+{
+ OmegleProto *proto = GetInstanceByHContact(reinterpret_cast<HANDLE>(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 <http://www.gnu.org/licenses/>.
+
+*/
+
+#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 <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "common.h"
+
+std::string utils::url::encode(const std::string &s)
+{
+ char *encoded = reinterpret_cast<char*>(CallService( MS_NETLIB_URLENCODE,
+ 0,reinterpret_cast<LPARAM>(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 <http://www.gnu.org/licenses/>.
+
+*/
+
+#pragma once
+
+template<typename T>
+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<typename T>
+void HookProtoEvent(const char* evt, int (__cdecl T::*eventProc)(WPARAM,LPARAM), T *self)
+{
+ ::HookEventObj(evt,(MIRANDAHOOKOBJ)*(void**)&eventProc,self);
+}
+
+template<typename T>
+HANDLE ForkThreadEx(void (__cdecl T::*thread)(void*),T *self,void *data = 0)
+{
+ return reinterpret_cast<HANDLE>( mir_forkthreadowner(
+ (pThreadFuncOwner)*(void**)&thread,self,data,0));
+}
+
+template<typename T>
+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_;
+};