⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ircmain.cpp

📁 eMule0.44b的原代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//this file is part of eMule
//Copyright (C)2002 Merkur ( devs@emule-project.net / http://www.emule-project.net )
//
//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, write to the Free Software
//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

//A lot of documentation for the IRC protocol within this code came
//directly from http://www.irchelp.org/irchelp/rfc/rfc2812.txt
//Much of it may never be used, but it's here just in case..
#include "stdafx.h"
#include <Mmsystem.h>
#include "emule.h"
#include "IRCMain.h"
#include "OtherFunctions.h"
#include "ED2KLink.h"
#include "DownloadQueue.h"
#include "Server.h"
#include "IRCSocket.h"
#include "MenuCmds.h"
#include "Sockets.h"
#include "FriendList.h"
#include "emuledlg.h"
#include "ServerWnd.h"
#include "IRCWnd.h"
#include "StringConversion.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif


CIrcMain::CIrcMain(void)
{
	ircsocket = NULL;
	m_pwndIRC = 0; // i_a 
	preParseBuffer = "";
	srand( (unsigned)time( NULL ) );
	SetVerify();
}

CIrcMain::~CIrcMain(void)
{
}

void CIrcMain::PreParseMessage( CStringA buffer )
{
	try
	{
		CStringA rawMessage;
		preParseBuffer += buffer;
		int index = preParseBuffer.Find('\n');
		try
		{
			while( index != -1 )
			{
				rawMessage = preParseBuffer.Left(index);
				rawMessage.Remove('\n');
				rawMessage.Remove('\r');
				ParseMessage( rawMessage );
				if( preParseBuffer != _T("") )
					preParseBuffer = preParseBuffer.Mid(index+1);
				index = preParseBuffer.Find('\n');
			}
		}
		catch(...)
		{
			if (thePrefs.GetVerbose())
				AddDebugLogLine(false, _T("Exception in CIrcMain::PreParseMessage(1)"));
		}
	}
	catch(...)
	{
		if (thePrefs.GetVerbose())
			AddDebugLogLine(false, _T("Exception in CIrcMain::PreParseMessage(2)"));
	}
}

void CIrcMain::ProcessLink( CString ed2kLink ) 
{
	try 
	{
		CString link;
		link = OptUtf8ToStr(URLDecode(ed2kLink));
		CED2KLink* pLink = CED2KLink::CreateLinkFromUrl(link);
		_ASSERT( pLink !=0 );
		switch (pLink->GetKind()) 
		{
			case CED2KLink::kFile:
			{
				CED2KFileLink* pFileLink = pLink->GetFileLink();
				_ASSERT(pFileLink !=0);
				theApp.downloadqueue->AddFileLinkToDownload(pFileLink);
				break;
			}
			case CED2KLink::kServerList:
			{
				CED2KServerListLink* pListLink = pLink->GetServerListLink(); 
				_ASSERT( pListLink !=0 ); 
				CString strAddress = pListLink->GetAddress(); 
				if(strAddress.GetLength() != 0)
					theApp.emuledlg->serverwnd->UpdateServerMetFromURL(strAddress);
				break;
			}
			case CED2KLink::kServer:
			{
				CString defName;
				CED2KServerLink* pSrvLink = pLink->GetServerLink();
				_ASSERT( pSrvLink !=0 );
				CServer* pSrv = new CServer(pSrvLink->GetPort(),ipstr(pSrvLink->GetIP()));
				_ASSERT( pSrv !=0 );
				pSrvLink->GetDefaultName(defName);
				pSrv->SetListName(defName.GetBuffer());

				// Barry - Default all new irc servers to high priority
				if( thePrefs.GetManualHighPrio() )
					pSrv->SetPreference(SRV_PR_HIGH);

				if (!theApp.emuledlg->serverwnd->serverlistctrl.AddServer(pSrv,true)) 
					delete pSrv; 
				else
					AddLogLine(true,GetResString(IDS_SERVERADDED), pSrv->GetListName());
				break;
			}
			default:
				break;
		}
		delete pLink;
	} 
	catch(...) 
	{
		AddLogLine(true, GetResString(IDS_LINKNOTADDED));
		ASSERT(0);
	}
}

void CIrcMain::ParseMessage( CStringA rawMessage )
{
	try
	{
		if( rawMessage.GetLength() < 6 )
		{
			//TODO : We probably should disconnect here as I don't know of anything that should
			//come from the server this small..
			return;
		}
		if( rawMessage.Left(6) == "PING :" )
		{
			//If the server pinged us, we must pong back or get disconnected..
			//Anything after the ":" must be sent back or it will fail..
			ircsocket->SendString( CString("PONG " + rawMessage.Right(rawMessage.GetLength()-6)) );
			m_pwndIRC->AddStatus(  _T("PING?/PONG") );
			return;
		}
		//I temp replace % with \004 as it will mess up sending this string with parameters later.
		rawMessage.Replace( "%", "\004" );
		//Source of the message
		CString source;
		int sourceIndex = -1;
		//IP address of the source of the message
		CString sourceIp;
		//Command that the message is sending
		CString command;
		int commandIndex = -1;
		//Target of the message
		CString target;
		int targetIndex = -1;
		CString target2;
		int target2Index = -1;
		//The actual message
		CString message;
		int messageIndex = -1;
		//Check if there is a source which always ends with a !
		//Messages without a source is usually a server message.
		sourceIndex = rawMessage.Find( '!' );
		if( rawMessage.Left(1) == ":" )
		{
			//If the message starts with a ":", the first space must be the beginning of the command
			//Although, it seems some servers are miscofigured..
			commandIndex = rawMessage.Find( ' ' );
		}
		else
		{
			//If the message doesn't start with a ":", the first word is the command.
			commandIndex = 0;
		}
		if( commandIndex == -1 )
			throw CString(_T("SMIRC Error: Received a message had no command."));
		//The second space is the beginning of the target or message
		targetIndex = rawMessage.Find( ' ', commandIndex + 1);
		if( targetIndex == -1 )
			throw CString(_T("SMIRC Errow: Received a message with no target or message."));
		//This will pull out the command
		if( commandIndex == 0 )
		{
			//Command is the first word.. Strange as I don't see this in any standard..
			command = rawMessage.Mid( commandIndex, targetIndex - commandIndex);
		}
		else
		{
			//Command is where it should be.
			command = rawMessage.Mid( commandIndex + 1, targetIndex - commandIndex - 1);
		}
		if( sourceIndex < commandIndex && sourceIndex > 0)
		{
			//Raw message had a source.

			//Get source and IP of source
			source = rawMessage.Mid( 1, sourceIndex - 1);
			sourceIp = rawMessage.Mid( sourceIndex + 1, commandIndex - sourceIndex - 1);
			messageIndex = rawMessage.Find( ' ', targetIndex + 1);
			if( messageIndex > sourceIndex )
			{
				//Raw message had a message

				//Get target and message
				target = rawMessage.Mid( targetIndex + 1, messageIndex - targetIndex - 1);
				message = rawMessage.Mid( messageIndex );
				//I'm not sure why some messages have different formats, but this cleans them up.
				if( target.Left(1) == _T(":") )
					target = target.Mid(1);
				if( message.Left(1) == _T(":") )
					message = message.Mid(1);
				if( target.Left(2) == _T(" :") )
					target = target.Mid(2);
				if( message.Left(2) == _T(" :") )
					message = message.Mid(2);
			}
			else
			{
				//Raw message had no message

				//Get target
				target = rawMessage.Mid( targetIndex + 1, rawMessage.GetLength() - targetIndex - 1);
				//I'm not sure why some messages have different formats, but this cleans them up.
				if( target.Left(1) == _T(":") )
					target = target.Mid(1);
				if( target.Left(2) == _T(" :") )
					target = target.Mid(2);
			}
		}
		else
		{
			if( commandIndex == 0 )
			{
				//Raw message had no source, must be from the server
				source = _T("");
			}
			else
			{
				//Get source
				source = rawMessage.Mid( 1, commandIndex - 1);
			}
			message = rawMessage.Mid( targetIndex + 1);
		}

		if( command == _T("PRIVMSG") )
		{
			// Messages
			if ( target.Left(1) == _T("#") )
			{
				//Belongs to a channel..
				if( message.Left(1) == _T("\001") )
				{
					//This is a specal message.. Find out what kind..
					if( message.GetLength() < 4 )
						throw CString( _T("SMIRC Error: Received Invalid special channel message") );
					message = message.Mid( 1, message.GetLength() - 2);
					if( message.Left(6) == _T("ACTION") )
					{
						//Channel Action..
						if( message.GetLength() < 8 )
							throw CString( _T("SMIRC Error: Received Invalid channel action") );
						m_pwndIRC->AddInfoMessage( target, _T("* %s %s"), source, message.Mid(7) );
						return;
					}
					if( message.Left(5) == _T("SOUND"))
					{
						//Sound
						if( message.GetLength() < 7 )
							throw CString( _T("SMIRC Error: Received Invalid channel sound") );
						message = message.Mid(6);
						int soundlen = message.Find( _T(" ") );
						CString sound;
						CString strFileName;
						if( soundlen != -1 )
						{
							//Sound event also had a message
							strFileName = message.Left(soundlen);
							message = message.Mid(soundlen);
						}
						else
						{
							//Sound event didn't have a message
							strFileName = message;
							message = _T(" [SOUND]");
						}
						//Check for proper form.
						strFileName.Remove(_T('\\'));
						strFileName.Remove(_T('/'));
						if( (strFileName.Right(4) != _T(".wav")) && (strFileName.Right(4) != _T(".mp3")) && (strFileName.Right(4) != _T(".WAV")) && (strFileName.Right(4) != _T(".MP3")) )
							throw CString( _T("SMIRC Error: Received invalid sound event.") );
						sound.Format(_T("%sSounds\\IRC\\%s"), thePrefs.GetAppDir(), strFileName);
						if(thePrefs.GetIrcSoundEvents())
						{
							PlaySound(sound, NULL, SND_FILENAME | SND_NOSTOP | SND_NOWAIT | SND_ASYNC);
						}
						m_pwndIRC->AddInfoMessage( target, _T("* %s%s"), source, message );
						return;
					}
					if( message.Left(7) == _T("VERSION"))
					{
						//Get client version.
						version = _T("eMule") + theApp.m_strCurVersionLong + _T(Irc_Version);
						CString build;
						build.Format( _T("NOTICE %s :\001VERSION %s\001"), source, version );
						ircsocket->SendString( build );
						return;
					}
					if( message.Left(4) == _T("PING"))
					{
						//TODO - Respond to a user ping.
						return;
					}
				}
				else
				{
					//This is a normal channel message.. 
	                m_pwndIRC->AddMessage( target, source, message);
					return;
				}
			}
			else
			{
				//Private Message
				if( message.Left(1) == _T("\001") ){
					//Special message
					if( message.GetLength() < 4 )
						throw CString( _T("SMIRC Error: Received Invalid special private message") );
					message = message.Mid(1, message.GetLength() -2);
					if( message.Left(6) == _T("ACTION"))
					{
						//Action
						if( message.GetLength() < 8 )
							throw CString( _T("SMIRC Error: Received Invalid private action") );
						m_pwndIRC->AddInfoMessage( source, _T("* %s %s"), source, message.Mid(7) );
						return;
					}
					if( message.Left(5) == _T("SOUND"))
					{
						//sound event
						if( message.GetLength() < 7 )
							throw CString( _T("SMIRC Error: Received Invalid private sound") );
						message = message.Mid(6);
						int soundlen = message.Find( _T(" ") );
						CString sound;
						CString strFileName;
						if( soundlen != -1 )
						{
							//Sound event also had a message
							strFileName = message.Left(soundlen);
							message = message.Mid(soundlen);
						}
						else
						{
							//Sound event didn't have a message
							strFileName = message;
							message = _T(" [sound]");
						}
						//Check for proper form.
						strFileName.Remove(_T('\\'));
						strFileName.Remove(_T('/'));
						if( (strFileName.Right(4) != _T(".wav")) && (strFileName.Right(4) != _T(".mp3")) && (strFileName.Right(4) != _T(".WAV")) && (strFileName.Right(4) != _T(".MP3")) )
							throw CString( _T("SMIRC Error: Received invalid sound event") );
						sound.Format(_T("%sSounds\\IRC\\%s"), thePrefs.GetAppDir(), strFileName);
						if(thePrefs.GetIrcSoundEvents())
						{
							PlaySound(sound, NULL, SND_FILENAME | SND_NOSTOP | SND_NOWAIT | SND_ASYNC);
						}
						m_pwndIRC->AddInfoMessage( source, _T("* %s%s"), source, message );
						return;
					}
					if( message.Left(7) == _T("VERSION"))
					{
						//Get client version.
						version = _T("eMule") + theApp.m_strCurVersionLong + _T(Irc_Version);
						CString build;
						build.Format( _T("NOTICE %s :\001VERSION %s\001"), source, version );
						ircsocket->SendString( build );
						return;
					}
					if( message.Left(4) == _T("PING"))
					{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -