remoteconnect.cpp
来自「wxWidgets写的电驴」· C++ 代码 · 共 261 行
CPP
261 行
//// This file is part of the aMule Project.//// Copyright (c) 2004-2006 aMule Team ( admin@amule.org / http://www.amule.org )// Copyright (c) 2004-2006 Angel Vidal Veiga ( kry@users.sourceforge.net )//// Any parts of this program derived from the xMule, lMule or eMule project,// or contributed by third-party developers are copyrighted by their// respective authors.//// 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA//#include "RemoteConnect.h"#include <memory> // Needed for auto_ptrusing std::auto_ptr;#include <wx/intl.h> // Needed for i18n#include "ECVersion.h" // Needed for EC_VERSION_ID#include "ECPacket.h" // Needed for CECPacketDEFINE_LOCAL_EVENT_TYPE(wxEVT_EC_CONNECTION);CECLoginPacket::CECLoginPacket(const wxString &pass, const wxString& client, const wxString& version) : CECPacket(EC_OP_AUTH_REQ){ AddTag(CECTag(EC_TAG_CLIENT_NAME, client)); AddTag(CECTag(EC_TAG_CLIENT_VERSION, version)); AddTag(CECTag(EC_TAG_PROTOCOL_VERSION, (uint16)EC_CURRENT_PROTOCOL_VERSION)); CMD4Hash passhash; wxCHECK2(passhash.Decode(pass), /* Do nothing. */); AddTag(CECTag(EC_TAG_PASSWD_HASH, passhash)); #ifdef EC_VERSION_ID CMD4Hash versionhash; wxCHECK2(versionhash.Decode(wxT(EC_VERSION_ID)), /* Do nothing. */); AddTag(CECTag(EC_TAG_VERSION_ID, versionhash)); #endif}/*! * Connection to remote core * */CRemoteConnect::CRemoteConnect(wxEvtHandler* evt_handler) : CECSocket(evt_handler != 0){ notifier = evt_handler; m_ec_state = EC_INIT; // // Give application some indication about how fast requests are served // When request fifo contain more that certain number of entries, it may // indicate that either core or network is slowing us down m_req_count = 0; // This is not mean to be absolute limit, because we can't drop requests // out of calling context; it is just signal to application to slow down m_req_fifo_thr = 20;}bool CRemoteConnect::ConnectToCore(const wxString &host, int port, const wxString &WXUNUSED(login), const wxString &pass, const wxString& client, const wxString& version){ ConnectionPassword = pass; m_client = client; m_version = version; // don't even try to connect without a valid password if (ConnectionPassword.IsEmpty() || ConnectionPassword == wxT("d41d8cd98f00b204e9800998ecf8427e")) { server_reply = _("You must specify a non-empty password."); return false; } else { CMD4Hash hash; if (not hash.Decode(ConnectionPassword)) { server_reply = _("Invalid password, not a MD5 hash!"); return false; } else if (hash.IsEmpty()) { server_reply = _("You must specify a non-empty password."); return false; } } wxIPV4address addr; addr.Hostname(host); addr.Service(port); if ( !Connect(addr) ) { return false; } // if we're using blocking calls - enter login sequence now. Else, // we will wait untill OnConnect gets called if ( !notifier ) { CECLoginPacket login_req(ConnectionPassword, m_client, m_version); std::auto_ptr<const CECPacket> reply(SendRecvPacket(&login_req)); return ConnectionEstablished(reply.get()); } else { m_ec_state = EC_CONNECT_SENT; } return true;}void CRemoteConnect::OnConnect() { if (notifier) { wxASSERT(m_ec_state == EC_CONNECT_SENT); CECLoginPacket login_req(ConnectionPassword, m_client, m_version); CECSocket::SendPacket(&login_req); m_ec_state = EC_REQ_SENT; } else { // do nothing, calling code will take from here }}void CRemoteConnect::OnClose() { if (notifier) { // Notify app of failure wxECSocketEvent event(wxEVT_EC_CONNECTION,false,_("Connection failure")); notifier->AddPendingEvent(event); } // FIXME: wtf is that ? //CECSocket::OnClose();}const CECPacket *CRemoteConnect::OnPacketReceived(const CECPacket *packet){ CECPacket *next_packet = 0; m_req_count--; switch(m_ec_state) { case EC_REQ_SENT: if ( ConnectionEstablished(packet) ) { m_ec_state = EC_OK; } else { m_ec_state = EC_FAIL; } break; case EC_OK: if ( !m_req_fifo.empty() ) { CECPacketHandlerBase *handler = m_req_fifo.front(); m_req_fifo.pop_front(); if ( handler ) { handler->HandlePacket(packet); } } else { printf("EC error - packet received, but request fifo is empty\n"); } break; default: break; } // no reply by default return next_packet;}/* * Our requests are served by core in FCFS order. And core always replies. So, even * if we're not interested in reply, we preserve place in request fifo. */void CRemoteConnect::SendRequest(CECPacketHandlerBase *handler, CECPacket *request){ m_req_count++; m_req_fifo.push_back(handler); CECSocket::SendPacket(request);}void CRemoteConnect::SendPacket(CECPacket *request){ SendRequest(0, request);}bool CRemoteConnect::ConnectionEstablished(const CECPacket *reply) { bool result = false; if (!reply) { server_reply = _("EC Connection Failed. Empty reply."); Close(); } else { if (reply->GetOpCode() == EC_OP_AUTH_FAIL) { const CECTag *reason = reply->GetTagByName(EC_TAG_STRING); if (reason != NULL) { server_reply = wxString(_("ExternalConn: Access denied because: ")) + wxGetTranslation(reason->GetStringData()); } else { server_reply = _("ExternalConn: Access denied"); } Close(); } else if (reply->GetOpCode() != EC_OP_AUTH_OK) { server_reply = _("ExternalConn: Bad reply from server. Connection closed."); Close(); } else { if (reply->GetTagByName(EC_TAG_SERVER_VERSION)) { server_reply = _("Succeeded! Connection established to aMule ") + reply->GetTagByName(EC_TAG_SERVER_VERSION)->GetStringData(); } else { server_reply = _("Succeeded! Connection established."); } result = true; } } if ( notifier ) { wxECSocketEvent event(wxEVT_EC_CONNECTION, result, server_reply); notifier->AddPendingEvent(event); } return result;}/******************** EC API ***********************/void CRemoteConnect::StartKad() { CECPacket req(EC_OP_KAD_START); SendPacket(&req); }void CRemoteConnect::StopKad() { CECPacket req(EC_OP_KAD_STOP); SendPacket(&req); }void CRemoteConnect::ConnectED2K(uint32 ip, uint16 port) { CECPacket req(EC_OP_SERVER_CONNECT); if (ip && port) { req.AddTag(CECTag(EC_TAG_SERVER, EC_IPv4_t(ip, port))); } SendPacket(&req);}void CRemoteConnect::DisconnectED2K() { CECPacket req(EC_OP_SERVER_DISCONNECT); SendPacket(&req); }void CRemoteConnect::RemoveServer(uint32 ip, uint16 port) { CECPacket req(EC_OP_SERVER_REMOVE); if (ip && port) { req.AddTag(CECTag(EC_TAG_SERVER, EC_IPv4_t(ip, port))); } SendPacket(&req);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?