From 1680c6d262eb0525c1af95195b5b79839a5e2ce9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20P=C3=B6sel?= Date: Tue, 22 May 2012 23:20:07 +0000 Subject: Added Omegle protocol. git-svn-id: http://svn.miranda-ng.org/main/trunk@136 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/Omegle/chat.cpp | 405 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 405 insertions(+) create mode 100644 protocols/Omegle/chat.cpp (limited to 'protocols/Omegle/chat.cpp') diff --git a/protocols/Omegle/chat.cpp b/protocols/Omegle/chat.cpp new file mode 100644 index 0000000000..169877b9fb --- /dev/null +++ b/protocols/Omegle/chat.cpp @@ -0,0 +1,405 @@ +/* + +Omegle plugin for Miranda Instant Messenger +_____________________________________________ + +Copyright © 2011-12 Robert Pösel + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include "common.h" + +void OmegleProto::UpdateChat(const TCHAR *name, const TCHAR *message, bool addtolog) +{ + GCDEST gcd = { m_szModuleName }; + gcd.ptszID = const_cast(m_tszUserName); + + GCEVENT gce = {sizeof(gce)}; + gce.pDest = &gcd; + gce.ptszText = message; + gce.time = ::time(NULL); + gce.dwFlags = GC_TCHAR; + gcd.iType = GC_EVENT_MESSAGE; + + if (name == NULL) { + gcd.iType = GC_EVENT_INFORMATION; + name = TranslateT("Server"); + gce.bIsMe = false; + } else { + gce.bIsMe = !_tcscmp(name, this->facy.nick_); + } + + if (addtolog) + gce.dwFlags |= GCEF_ADDTOLOG; + + gce.ptszNick = name; + gce.ptszUID = gce.ptszNick; + + CallServiceSync(MS_GC_EVENT,0,reinterpret_cast(&gce)); +} + +int OmegleProto::OnChatEvent(WPARAM wParam,LPARAM lParam) +{ + GCHOOK *hook = reinterpret_cast(lParam); + + if(strcmp(hook->pDest->pszModule,m_szModuleName)) + return 0; + + switch(hook->pDest->iType) + { + case GC_USER_MESSAGE: + { + std::string text = mir_t2a_cp(hook->ptszText,CP_UTF8); + + if (text.empty()) + break; + + if (text.substr(0,1) == "/") + { // Process commands + + std::string command = ""; + std::string params = ""; + + std::string::size_type pos = 0; + if ((pos = text.find(" ")) != std::string::npos) { + command = text.substr(1, pos-1); + params = text.substr(pos+1); + } else { + command = text.substr(1); + } + + if (!stricmp(command.c_str(), "new")) + { + facy.spy_mode_ = false; + facy.question_ = ""; + + ForkThread(&OmegleProto::NewChatWorker, this, NULL); + break; + } + else if (!stricmp(command.c_str(), "quit")) + { + ForkThread(&OmegleProto::StopChatWorker, this, NULL); + break; + } + else if (!stricmp(command.c_str(), "spy")) + { + facy.spy_mode_ = true; + facy.question_ = ""; + + ForkThread(&OmegleProto::NewChatWorker, this, NULL); + break; + } + else if (!stricmp(command.c_str(), "ask")) + { + if (params.empty()) { + // Load last question + DBVARIANT dbv; + if ( !getU8String( OMEGLE_KEY_LAST_QUESTION,&dbv ) ) { + params = dbv.pszVal; + DBFreeVariant(&dbv); + } + + if (params.empty()) { + UpdateChat(NULL, TranslateT("Last question is empty."), false); + break; + } + } else { + // Save actual question as last question + if (strlen(params.c_str()) >= OMEGLE_QUESTION_MIN_LENGTH) + { + setU8String( OMEGLE_KEY_LAST_QUESTION, params.c_str() ); + } + } + + if (strlen(params.c_str()) < OMEGLE_QUESTION_MIN_LENGTH) + { + UpdateChat(NULL, TranslateT("Your question is too short."), false); + break; + } + + facy.spy_mode_ = true; + facy.question_ = params; + ForkThread(&OmegleProto::NewChatWorker, this, NULL); + break; + } + else if (!stricmp(command.c_str(), "asl")) + { + DBVARIANT dbv; + if ( !getU8String( OMEGLE_KEY_ASL,&dbv ) ) { + text = dbv.pszVal; + DBFreeVariant(&dbv); + } else { + UpdateChat(NULL, TranslateT("Your '/asl' setting is empty."), false); + break; + } + } + else if (!stricmp(command.c_str(), "help")) + { + UpdateChat(NULL, TranslateT("There are three different modes of chatting:\ +\n1) Standard mode\t - You chat with random stranger privately\ +\n2) Question mode\t - You ask two strangers a question and see how they discuss it (you can't join their conversation, only watch)\ +\n3) Spy mode\t - You and stranger got a question to discuss from third stranger (he can't join your conversation, only watch)\ +\n\nSend '/commands' for available commands."), false); + } + else if (!stricmp(command.c_str(), "commands")) + { + UpdateChat(NULL, TranslateT("You can use different commands:\ +\n/help\t - show info about chat modes\ +\n/new\t - start standard mode\ +\n/ask - start question mode with your question\ +\n/ask\t - start question mode with your last asked question\ +\n/spy\t - start spy mode\ +\n/quit\t - disconnect from stranger or stop connecting\ +\n/asl\t - send your predefined ASL message\ +\n\nNote: You can reconnect to different stranger without disconnecting from current one."), false); + break; + } + else + { + UpdateChat(NULL, TranslateT("Unknown command. Send '/commands' for list."), false); + break; + } + + } + + // Outgoing message + switch (facy.state_) + { + case STATE_ACTIVE: + LOG("**Chat - Outgoing message: %s", text.c_str()); + ForkThread(&OmegleProto::SendMsgWorker, this, (void*)new std::string(text)); + break; + + case STATE_INACTIVE: + UpdateChat(NULL, TranslateT("You aren't connected to any stranger. Send '/help' or '/commands' for help."), false); + break; + + case STATE_SPY: + UpdateChat(NULL, TranslateT("You can't send messages in question mode."), false); + break; + + //case STATE_WAITING: + //case STATE_DISCONNECTING: + default: + break; + } + + break; + } + + case GC_USER_TYPNOTIFY: + if ( facy.state_ == STATE_ACTIVE ) + ForkThread(&OmegleProto::SendTypingWorker, this, (void*)mir_tstrdup(hook->ptszText)); + break; + + case GC_USER_LEAVE: + case GC_SESSION_TERMINATE: + mir_free( facy.nick_ ); + ForkThread(&OmegleProto::StopChatWorker, this, NULL); + break; + } + + return 0; +} + +/*void OmegleProto::SendChatEvent(int type) +{ + GCDEST gcd = { m_szModuleName }; + gcd.ptszID = const_cast(m_tszUserName); + gcd.iType = GC_EVENT_CONTROL; + + GCEVENT gce = {sizeof(gce)}; + gce.dwFlags = GC_TCHAR; + gce.pDest = &gcd; + + CallServiceSync(MS_GC_EVENT,WINDOW_CLEARLOG,reinterpret_cast(&gce)); +}*/ + +void OmegleProto::AddChatContact(const TCHAR *name) +{ + GCDEST gcd = { m_szModuleName }; + gcd.ptszID = const_cast(m_tszUserName); + gcd.iType = GC_EVENT_JOIN; + + GCEVENT gce = {sizeof(gce)}; + gce.pDest = &gcd; + gce.dwFlags = GC_TCHAR | GCEF_ADDTOLOG; + gce.ptszNick = name; + gce.ptszUID = gce.ptszNick; + gce.time = static_cast(time(0)); + + if (name == NULL) + gce.bIsMe = false; + else + gce.bIsMe = !_tcscmp(name, this->facy.nick_); + + if (gce.bIsMe) + gce.ptszStatus = _T("Admin"); + else + gce.ptszStatus = _T("Normal"); + + CallServiceSync(MS_GC_EVENT,0,reinterpret_cast(&gce)); +} + +void OmegleProto::DeleteChatContact(const TCHAR *name) +{ + GCDEST gcd = { m_szModuleName }; + gcd.ptszID = const_cast(m_tszUserName); + gcd.iType = GC_EVENT_PART; + + GCEVENT gce = {sizeof(gce)}; + gce.pDest = &gcd; + gce.dwFlags = GC_TCHAR | GCEF_ADDTOLOG; + gce.ptszNick = name; + gce.ptszUID = gce.ptszNick; + gce.time = static_cast(time(0)); + if (name == NULL) + gce.bIsMe = false; + else + gce.bIsMe = !_tcscmp(name, this->facy.nick_); + + CallServiceSync(MS_GC_EVENT,0,reinterpret_cast(&gce)); +} + +int OmegleProto::OnJoinChat(WPARAM,LPARAM suppress) +{ + GCSESSION gcw = {sizeof(gcw)}; + + // Create the group chat session + gcw.dwFlags = GC_TCHAR; + gcw.iType = GCW_CHATROOM; + gcw.pszModule = m_szModuleName; + gcw.ptszName = m_tszUserName; + gcw.ptszID = m_tszUserName; + CallServiceSync(MS_GC_NEWSESSION, 0, (LPARAM)&gcw); + + if(m_iStatus == ID_STATUS_OFFLINE) + return 0; + + // Create a group + GCDEST gcd = { m_szModuleName }; + gcd.ptszID = const_cast(m_tszUserName); + + GCEVENT gce = {sizeof(gce)}; + gce.pDest = &gcd; + gce.dwFlags = GC_TCHAR; + + gcd.iType = GC_EVENT_ADDGROUP; + + gce.ptszStatus = _T("Admin"); + CallServiceSync( MS_GC_EVENT, NULL, reinterpret_cast(&gce) ); + + gce.ptszStatus = _T("Normal"); + CallServiceSync( MS_GC_EVENT, NULL, reinterpret_cast(&gce) ); + + SetTopic(); + + // Note: Initialization will finish up in SetChatStatus, called separately + if(!suppress) + SetChatStatus(m_iStatus); + + return 0; +} + +void OmegleProto::SetTopic(const TCHAR *topic) +{ + GCDEST gcd = { m_szModuleName }; + gcd.ptszID = const_cast(m_tszUserName); + gcd.iType = GC_EVENT_TOPIC; + + GCEVENT gce = {sizeof(gce)}; + gce.pDest = &gcd; + gce.dwFlags = GC_TCHAR; + gce.time = ::time(NULL); + + if (topic == NULL) + gce.ptszText = TranslateT("Omegle is a great way of meeting new friends!"); + else + gce.ptszText = topic; + + CallServiceSync(MS_GC_EVENT,0, reinterpret_cast(&gce)); +} + +int OmegleProto::OnLeaveChat(WPARAM,LPARAM) +{ + GCDEST gcd = { m_szModuleName }; + gcd.ptszID = const_cast(m_tszUserName); + gcd.iType = GC_EVENT_CONTROL; + + GCEVENT gce = {sizeof(gce)}; + gce.dwFlags = GC_TCHAR; + gce.time = ::time(NULL); + gce.pDest = &gcd; + + CallServiceSync(MS_GC_EVENT,SESSION_OFFLINE, reinterpret_cast(&gce)); + CallServiceSync(MS_GC_EVENT,SESSION_TERMINATE,reinterpret_cast(&gce)); + + return 0; +} + +void OmegleProto::SetChatStatus(int status) +{ + GCDEST gcd = { m_szModuleName }; + gcd.ptszID = const_cast(m_tszUserName); + gcd.iType = GC_EVENT_CONTROL; + + GCEVENT gce = {sizeof(gce)}; + gce.dwFlags = GC_TCHAR; + gce.time = ::time(NULL); + gce.pDest = &gcd; + + if(status == ID_STATUS_ONLINE) + { + // Free previously loaded name + mir_free(facy.nick_); + + // Load actual name from database + DBVARIANT dbv; + if ( !DBGetContactSettingTString(NULL, m_szModuleName, OMEGLE_KEY_NAME, &dbv) ) + { + facy.nick_ = mir_tstrdup(dbv.ptszVal); + DBFreeVariant(&dbv); + } else { + facy.nick_ = mir_tstrdup(TranslateT("You")); + DBWriteContactSettingTString(NULL, m_szModuleName, OMEGLE_KEY_NAME, facy.nick_); + } + + // Add self contact + AddChatContact(facy.nick_); + + CallServiceSync(MS_GC_EVENT,SESSION_INITDONE,reinterpret_cast(&gce)); + CallServiceSync(MS_GC_EVENT,SESSION_ONLINE, reinterpret_cast(&gce)); + } + else + { + CallServiceSync(MS_GC_EVENT,SESSION_OFFLINE,reinterpret_cast(&gce)); + } +} + +void OmegleProto::ClearChat() +{ + if (getByte(OMEGLE_KEY_NO_CLEAR, 0)) + return; + + GCDEST gcd = { m_szModuleName }; + gcd.ptszID = const_cast(m_tszUserName); + gcd.iType = GC_EVENT_CONTROL; + + GCEVENT gce = {sizeof(gce)}; + gce.dwFlags = GC_TCHAR; + gce.pDest = &gcd; + + CallServiceSync(MS_GC_EVENT,WINDOW_CLEARLOG,reinterpret_cast(&gce)); +} \ No newline at end of file -- cgit v1.2.3