summaryrefslogtreecommitdiff
path: root/protocols/Omegle/communication.cpp
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/Omegle/communication.cpp
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/Omegle/communication.cpp')
-rw-r--r--protocols/Omegle/communication.cpp809
1 files changed, 809 insertions, 0 deletions
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;
+}