2 // This file is part of the aMule Project.
4 // Copyright (c) 2005-2011 aMule Team ( admin@amule.org / http://www.amule.org )
6 // Any parts of this program derived from the xMule, lMule or eMule project,
7 // or contributed by third-party developers are copyrighted by their
10 // This program is free software; you can redistribute it and/or modify
11 // it under the terms of the GNU General Public License as published by
12 // the Free Software Foundation; either version 2 of the License, or
13 // (at your option) any later version.
15 // This program is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
20 // You should have received a copy of the GNU General Public License
21 // along with this program; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #include <wx/cmdline.h> // Needed for wxCmdLineParser
28 #include <wx/config.h> // Do_not_auto_remove (win32)
29 #include <wx/fileconf.h> // Needed for wxFileConfig
30 #include <wx/socket.h> // Needed for wxSocketBase
33 #include <common/Format.h>
34 #include <common/StringFunctions.h>
35 #include <common/MD5Sum.h>
38 #include <include/common/EventIDs.h>
41 #include "amule.h" // Interface declarations.
42 #include "amuleDlg.h" // Needed for CamuleDlg
43 #include "ClientCredits.h"
44 #include "SourceListCtrl.h"
46 #include "DataToText.h" // Needed for GetSoftName()
47 #include "DownloadListCtrl.h" // Needed for CDownloadListCtrl
49 #include "GetTickCount.h" // Needed for GetTickCount
50 #include "GuiEvents.h"
51 #ifdef ENABLE_IP2COUNTRY
52 #include "IP2Country.h" // Needed for IP2Country
54 #include "InternalEvents.h" // Needed for wxEVT_CORE_FINISHED_HTTP_DOWNLOAD
56 #include "muuli_wdr.h" // Needed for IDs
57 #include "PartFile.h" // Needed for CPartFile
58 #include "SearchDlg.h" // Needed for CSearchDlg
59 #include "Server.h" // Needed for GetListName
60 #include "ServerWnd.h" // Needed for CServerWnd
61 #include "SharedFilesCtrl.h" // Needed for CSharedFilesCtrl
62 #include "SharedFilesWnd.h" // Needed for CSharedFilesWnd
63 #include "TransferWnd.h" // Needed for CTransferWnd
64 #include "UpDownClientEC.h" // Needed for CUpDownClient
65 #include "ServerListCtrl.h" // Needed for CServerListCtrl
66 #include "ScopedPtr.h"
67 #include "StatisticsDlg.h" // Needed for CStatisticsDlg
70 CEConnectDlg::CEConnectDlg()
72 wxDialog(theApp
->amuledlg
, -1, _("Connect to remote amule"), wxDefaultPosition
)
74 CoreConnect(this, true);
76 wxString pref_host
, pref_port
;
77 wxConfig::Get()->Read(wxT("/EC/Host"), &pref_host
, wxT("localhost"));
78 wxConfig::Get()->Read(wxT("/EC/Port"), &pref_port
, wxT("4712"));
79 wxConfig::Get()->Read(wxT("/EC/Password"), &pwd_hash
);
81 CastChild(ID_REMOTE_HOST
, wxTextCtrl
)->SetValue(pref_host
);
82 CastChild(ID_REMOTE_PORT
, wxTextCtrl
)->SetValue(pref_port
);
83 CastChild(ID_EC_PASSWD
, wxTextCtrl
)->SetValue(pwd_hash
);
89 wxString
CEConnectDlg::PassHash()
95 BEGIN_EVENT_TABLE(CEConnectDlg
, wxDialog
)
96 EVT_BUTTON(wxID_OK
, CEConnectDlg::OnOK
)
100 void CEConnectDlg::OnOK(wxCommandEvent
& evt
)
102 wxString s_port
= CastChild(ID_REMOTE_PORT
, wxTextCtrl
)->GetValue();
103 port
= StrToLong(s_port
);
105 host
= CastChild(ID_REMOTE_HOST
, wxTextCtrl
)->GetValue();
106 passwd
= CastChild(ID_EC_PASSWD
, wxTextCtrl
)->GetValue();
108 if (passwd
!= pwd_hash
) {
109 pwd_hash
= MD5Sum(passwd
).GetHash();
111 m_save_user_pass
= CastChild(ID_EC_SAVE
, wxCheckBox
)->IsChecked();
116 DEFINE_LOCAL_EVENT_TYPE(wxEVT_EC_INIT_DONE
)
119 BEGIN_EVENT_TABLE(CamuleRemoteGuiApp
, wxApp
)
121 EVT_TIMER(ID_CORE_TIMER_EVENT
, CamuleRemoteGuiApp::OnPollTimer
)
123 EVT_CUSTOM(wxEVT_EC_CONNECTION
, -1, CamuleRemoteGuiApp::OnECConnection
)
124 EVT_CUSTOM(wxEVT_EC_INIT_DONE
, -1, CamuleRemoteGuiApp::OnECInitDone
)
126 EVT_MULE_NOTIFY(CamuleRemoteGuiApp::OnNotifyEvent
)
128 #ifdef ENABLE_IP2COUNTRY
129 // HTTPDownload finished
130 EVT_MULE_INTERNAL(wxEVT_CORE_FINISHED_HTTP_DOWNLOAD
, -1, CamuleRemoteGuiApp::OnFinishedHTTPDownload
)
135 IMPLEMENT_APP(CamuleRemoteGuiApp
)
138 int CamuleRemoteGuiApp::OnExit()
142 wxSocketBase::Shutdown(); // needed because we also called Initialize() manually
144 return wxApp::OnExit();
148 void CamuleRemoteGuiApp::OnPollTimer(wxTimerEvent
&)
150 static int request_step
= 0;
151 static uint32 msPrevStats
= 0;
153 if (m_connect
->RequestFifoFull()) {
157 switch (request_step
) {
159 // We used to update the connection state here, but that's done with the stats in the next step now.
163 CECPacket
stats_req(EC_OP_STAT_REQ
, EC_DETAIL_INC_UPDATE
);
164 m_connect
->SendRequest(&m_stats_updater
, &stats_req
);
169 if (amuledlg
->m_sharedfileswnd
->IsShown()
170 || amuledlg
->m_chatwnd
->IsShown()
171 || amuledlg
->m_serverwnd
->IsShown()) {
172 // update downloads, shared files and servers
173 knownfiles
->DoRequery(EC_OP_GET_UPDATE
, EC_TAG_KNOWNFILE
);
174 } else if (amuledlg
->m_transferwnd
->IsShown()) {
175 // update both downloads and shared files
176 knownfiles
->DoRequery(EC_OP_GET_UPDATE
, EC_TAG_KNOWNFILE
);
177 } else if (amuledlg
->m_searchwnd
->IsShown()) {
178 if (searchlist
->m_curr_search
!= -1) {
179 searchlist
->DoRequery(EC_OP_SEARCH_RESULTS
, EC_TAG_SEARCHFILE
);
181 } else if (amuledlg
->m_statisticswnd
->IsShown()) {
182 int sStatsUpdate
= thePrefs::GetStatsInterval();
183 uint32 msCur
= theStats::GetUptimeMillis();
184 if ((sStatsUpdate
> 0) && ((int)(msCur
- msPrevStats
) > sStatsUpdate
*1000)) {
186 stattree
->DoRequery();
197 // Check for new links once per second.
198 static uint32 lastED2KLinkCheck
= 0;
199 if (GetTickCount() - lastED2KLinkCheck
>= 1000) {
201 lastED2KLinkCheck
= GetTickCount();
206 void CamuleRemoteGuiApp::OnFinishedHTTPDownload(CMuleInternalEvent
& event
)
208 if (event
.GetInt() == HTTP_GeoIP
) {
209 amuledlg
->IP2CountryDownloadFinished(event
.GetExtraLong());
210 // If we updated, the dialog is already up. Redraw it to show the flags.
216 void CamuleRemoteGuiApp::ShutDown(wxCloseEvent
&WXUNUSED(evt
))
218 // Stop the Core Timer
223 m_AsioService
->Stop();
224 delete m_AsioService
;
225 m_AsioService
= NULL
;
228 // Destroy the EC socket
229 m_connect
->Destroy();
234 amuledlg
->DlgShutDown();
238 delete m_allUploadingKnownFile
;
243 bool CamuleRemoteGuiApp::OnInit()
249 theApp
= &wxGetApp();
251 // Handle uncaught exceptions
252 InstallMuleExceptionHandler();
254 // Parse cmdline arguments.
255 if (!InitCommon(AMULE_APP_BASE::argc
, AMULE_APP_BASE::argv
)) {
259 // Initialize wx sockets (needed for http download in background with Asio sockets)
260 wxSocketBase::Initialize();
262 // Create the polling timer
263 poll_timer
= new wxTimer(this,ID_CORE_TIMER_EVENT
);
265 AddLogLineCS(_("Fatal Error: Failed to create Poll Timer"));
269 m_connect
= new CRemoteConnect(this);
272 m_AsioService
= new CAsioService
;
275 glob_prefs
= new CPreferencesRem(m_connect
);
277 wxConfig::Get()->Read(wxT("/EC/ZLIB"), &enableZLIB
, 1);
278 m_connect
->SetCapabilities(enableZLIB
!= 0, true, false); // ZLIB, UTF8 numbers, notification
280 InitCustomLanguages();
281 InitLocale(m_locale
, StrLang2wx(thePrefs::GetLanguageID()));
283 if (ShowConnectionDialog()) {
284 AddLogLineNS(_("Going to event loop..."));
292 bool CamuleRemoteGuiApp::CryptoAvailable() const
294 return thePrefs::IsSecureIdentEnabled(); // good enough
298 bool CamuleRemoteGuiApp::ShowConnectionDialog()
300 dialog
= new CEConnectDlg
;
302 if (m_skipConnectionDialog
) {
305 } else if (dialog
->ShowModal() != wxID_OK
) {
310 AddLogLineNS(_("Connecting..."));
311 if (!m_connect
->ConnectToCore(dialog
->Host(), dialog
->Port(),
312 dialog
->Login(), dialog
->PassHash(),
313 wxT("amule-remote"), wxT("0x0001"))) {
314 wxMessageBox(_("Connection failed "),_("ERROR"),wxOK
);
323 void CamuleRemoteGuiApp::OnECConnection(wxEvent
& event
) {
324 wxECSocketEvent
& evt
= *((wxECSocketEvent
*)&event
);
325 AddLogLineNS(_("Remote GUI EC event handler"));
326 wxString reply
= evt
.GetServerReply();
328 if (evt
.GetResult() == true) {
329 // Connected - go to next init step
330 glob_prefs
->LoadRemote();
332 AddLogLineNS(_("Going down"));
333 if (dialog
) { // connect failed
335 (CFormat(_("Connection Failed. Unable to connect to %s:%d\n")) % dialog
->Host() % dialog
->Port()) + reply
,
337 } else { // server disconnected (probably terminated) later
338 wxMessageBox(_("Connection closed - aMule has terminated probably."), _("ERROR"), wxOK
);
347 void CamuleRemoteGuiApp::OnECInitDone(wxEvent
& )
353 void CamuleRemoteGuiApp::OnNotifyEvent(CMuleGUIEvent
& evt
)
359 void CamuleRemoteGuiApp::Startup() {
361 if (dialog
->SaveUserPass()) {
362 wxConfig::Get()->Write(wxT("/EC/Host"), dialog
->Host());
363 wxConfig::Get()->Write(wxT("/EC/Port"), dialog
->Port());
364 wxConfig::Get()->Write(wxT("/EC/Password"), dialog
->PassHash());
372 serverconnect
= new CServerConnectRem(m_connect
);
373 m_statistics
= new CStatistics(*m_connect
);
374 stattree
= new CStatTreeRem(m_connect
);
376 clientlist
= new CUpDownClientListRem(m_connect
);
377 searchlist
= new CSearchListRem(m_connect
);
378 serverlist
= new CServerListRem(m_connect
);
379 friendlist
= new CFriendListRem(m_connect
);
382 sharedfiles
= new CSharedFilesRem(m_connect
);
383 knownfiles
= new CKnownFilesRem(m_connect
);
385 downloadqueue
= new CDownQueueRem(m_connect
);
386 ipfilter
= new CIPFilterRem(m_connect
);
388 m_allUploadingKnownFile
= new CKnownFile
;
390 // Create main dialog
391 InitGui(m_geometryEnabled
, m_geometryString
);
393 // Forward wxLog events to CLogger
394 wxLog::SetActiveTarget(new CLoggerTarget
);
395 knownfiles
->DoRequery(EC_OP_GET_UPDATE
, EC_TAG_KNOWNFILE
);
397 // Start the Poll Timer
398 poll_timer
->Start(1000);
399 amuledlg
->StartGuiTimer();
401 // Now activate GeoIP, so that the download dialog doesn't get destroyed immediately
402 #ifdef ENABLE_IP2COUNTRY
403 if (thePrefs::IsGeoIPEnabled()) {
404 amuledlg
->m_IP2Country
->Enable();
410 int CamuleRemoteGuiApp::ShowAlert(wxString msg
, wxString title
, int flags
)
412 return CamuleGuiBase::ShowAlert(msg
, title
, flags
);
416 void CamuleRemoteGuiApp::AddRemoteLogLine(const wxString
& line
)
418 amuledlg
->AddLogLine(line
);
421 int CamuleRemoteGuiApp::InitGui(bool geometry_enabled
, wxString
&geom_string
)
423 CamuleGuiBase::InitGui(geometry_enabled
, geom_string
);
424 SetTopWindow(amuledlg
);
425 AddLogLineN(_("Ready")); // The first log line after the window is up triggers output of all the ones before
430 bool CamuleRemoteGuiApp::CopyTextToClipboard(wxString strText
)
432 return CamuleGuiBase::CopyTextToClipboard(strText
);
436 uint32
CamuleRemoteGuiApp::GetPublicIP()
442 wxString
CamuleRemoteGuiApp::GetLog(bool reset
)
445 amuledlg
->ResetLog(ID_LOGVIEW
);
446 CECPacket
req(EC_OP_RESET_LOG
);
447 m_connect
->SendPacket(&req
);
449 return wxEmptyString
;
453 wxString
CamuleRemoteGuiApp::GetServerLog(bool)
455 return wxEmptyString
;
459 bool CamuleRemoteGuiApp::AddServer(CServer
* server
, bool)
461 CECPacket
req(EC_OP_SERVER_ADD
);
462 req
.AddTag(CECTag(EC_TAG_SERVER_ADDRESS
, CFormat(wxT("%s:%d")) % server
->GetAddress() % server
->GetPort()));
463 req
.AddTag(CECTag(EC_TAG_SERVER_NAME
, server
->GetListName()));
464 m_connect
->SendPacket(&req
);
470 bool CamuleRemoteGuiApp::IsFirewalled() const
472 if (IsConnectedED2K() && !serverconnect
->IsLowID()) {
476 return IsFirewalledKad();
480 bool CamuleRemoteGuiApp::IsConnectedED2K() const {
481 return serverconnect
&& serverconnect
->IsConnected();
485 void CamuleRemoteGuiApp::StartKad() {
486 m_connect
->StartKad();
490 void CamuleRemoteGuiApp::StopKad() {
491 m_connect
->StopKad();
495 void CamuleRemoteGuiApp::BootstrapKad(uint32 ip
, uint16 port
)
497 CECPacket
req(EC_OP_KAD_BOOTSTRAP_FROM_IP
);
498 req
.AddTag(CECTag(EC_TAG_BOOTSTRAP_IP
, ip
));
499 req
.AddTag(CECTag(EC_TAG_BOOTSTRAP_PORT
, port
));
501 m_connect
->SendPacket(&req
);
505 void CamuleRemoteGuiApp::UpdateNotesDat(const wxString
& url
)
507 CECPacket
req(EC_OP_KAD_UPDATE_FROM_URL
);
508 req
.AddTag(CECTag(EC_TAG_KADEMLIA_UPDATE_URL
, url
));
510 m_connect
->SendPacket(&req
);
514 void CamuleRemoteGuiApp::DisconnectED2K() {
515 if (IsConnectedED2K()) {
516 m_connect
->DisconnectED2K();
521 uint32
CamuleRemoteGuiApp::GetED2KID() const
523 return serverconnect
? serverconnect
->GetClientID() : 0;
527 uint32
CamuleRemoteGuiApp::GetID() const
533 void CamuleRemoteGuiApp::ShowUserCount() {
536 static const wxString s_singlenetstatusformat
= _("Users: %s | Files: %s");
537 static const wxString s_bothnetstatusformat
= _("Users: E: %s K: %s | Files: E: %s K: %s");
539 if (thePrefs::GetNetworkED2K() && thePrefs::GetNetworkKademlia()) {
540 buffer
= CFormat(s_bothnetstatusformat
) % CastItoIShort(theStats::GetED2KUsers()) % CastItoIShort(theStats::GetKadUsers()) % CastItoIShort(theStats::GetED2KFiles()) % CastItoIShort(theStats::GetKadFiles());
541 } else if (thePrefs::GetNetworkED2K()) {
542 buffer
= CFormat(s_singlenetstatusformat
) % CastItoIShort(theStats::GetED2KUsers()) % CastItoIShort(theStats::GetED2KFiles());
543 } else if (thePrefs::GetNetworkKademlia()) {
544 buffer
= CFormat(s_singlenetstatusformat
) % CastItoIShort(theStats::GetKadUsers()) % CastItoIShort(theStats::GetKadFiles());
546 buffer
= _("No networks selected");
549 Notify_ShowUserCount(buffer
);
554 * Preferences: holds both local and remote settings.
556 * First, everything is loaded from local config file. Later, settings
557 * that are relevant on remote side only are loaded thru EC
559 CPreferencesRem::CPreferencesRem(CRemoteConnect
*conn
)
564 // Settings queried from remote side
566 m_exchange_send_selected_prefs
=
568 EC_PREFS_CONNECTIONS
|
569 EC_PREFS_MESSAGEFILTER
|
573 EC_PREFS_DIRECTORIES
|
575 EC_PREFS_CORETWEAKS
|
576 EC_PREFS_REMOTECONTROLS
|
578 m_exchange_recv_selected_prefs
=
579 m_exchange_send_selected_prefs
|
584 void CPreferencesRem::HandlePacket(const CECPacket
*packet
)
586 static_cast<const CEC_Prefs_Packet
*>(packet
)->Apply();
588 const CECTag
*cat_tags
= packet
->GetTagByName(EC_TAG_PREFS_CATEGORIES
);
590 for (CECTag::const_iterator it
= cat_tags
->begin(); it
!= cat_tags
->end(); ++it
) {
591 const CECTag
&cat_tag
= *it
;
592 Category_Struct
*cat
= new Category_Struct
;
593 cat
->title
= cat_tag
.GetTagByName(EC_TAG_CATEGORY_TITLE
)->GetStringData();
594 cat
->path
= CPath(cat_tag
.GetTagByName(EC_TAG_CATEGORY_PATH
)->GetStringData());
595 cat
->comment
= cat_tag
.GetTagByName(EC_TAG_CATEGORY_COMMENT
)->GetStringData();
596 cat
->color
= cat_tag
.GetTagByName(EC_TAG_CATEGORY_COLOR
)->GetInt();
597 cat
->prio
= cat_tag
.GetTagByName(EC_TAG_CATEGORY_PRIO
)->GetInt();
598 theApp
->glob_prefs
->AddCat(cat
);
601 Category_Struct
*cat
= new Category_Struct
;
602 cat
->title
= _("All");
604 cat
->prio
= PR_NORMAL
;
605 theApp
->glob_prefs
->AddCat(cat
);
607 wxECInitDoneEvent event
;
608 theApp
->AddPendingEvent(event
);
613 bool CPreferencesRem::LoadRemote()
616 // override local settings with remote
617 CECPacket
req(EC_OP_GET_PREFERENCES
, EC_DETAIL_UPDATE
);
619 // bring categories too
620 req
.AddTag(CECTag(EC_TAG_SELECT_PREFS
, m_exchange_recv_selected_prefs
));
622 m_conn
->SendRequest(this, &req
);
628 void CPreferencesRem::SendToRemote()
630 CEC_Prefs_Packet
pref_packet(m_exchange_send_selected_prefs
, EC_DETAIL_UPDATE
, EC_DETAIL_FULL
);
631 m_conn
->SendPacket(&pref_packet
);
635 class CCatHandler
: public CECPacketHandlerBase
{
636 virtual void HandlePacket(const CECPacket
*packet
);
640 void CCatHandler::HandlePacket(const CECPacket
*packet
)
642 if (packet
->GetOpCode() == EC_OP_FAILED
) {
643 const CECTag
* catTag
= packet
->GetTagByName(EC_TAG_CATEGORY
);
644 const CECTag
* pathTag
= packet
->GetTagByName(EC_TAG_CATEGORY_PATH
);
645 if (catTag
&& pathTag
&& catTag
->GetInt() < theApp
->glob_prefs
->GetCatCount()) {
646 int cat
= catTag
->GetInt();
647 Category_Struct
* cs
= theApp
->glob_prefs
->GetCategory(cat
);
648 wxMessageBox(CFormat(_("Can't create directory '%s' for category '%s', keeping directory '%s'."))
649 % cs
->path
.GetPrintable() % cs
->title
% pathTag
->GetStringData(),
651 cs
->path
= CPath(pathTag
->GetStringData());
652 theApp
->amuledlg
->m_transferwnd
->UpdateCategory(cat
);
653 theApp
->amuledlg
->m_transferwnd
->downloadlistctrl
->Refresh();
660 bool CPreferencesRem::CreateCategory(
661 Category_Struct
*& category
,
662 const wxString
& name
,
664 const wxString
& comment
,
668 CECPacket
req(EC_OP_CREATE_CATEGORY
);
669 CEC_Category_Tag
tag(0xffffffff, name
, path
.GetRaw(), comment
, color
, prio
);
671 m_conn
->SendRequest(new CCatHandler
, &req
);
673 category
= new Category_Struct();
674 category
->path
= path
;
675 category
->title
= name
;
676 category
->comment
= comment
;
677 category
->color
= color
;
678 category
->prio
= prio
;
686 bool CPreferencesRem::UpdateCategory(
688 const wxString
& name
,
690 const wxString
& comment
,
694 CECPacket
req(EC_OP_UPDATE_CATEGORY
);
695 CEC_Category_Tag
tag(cat
, name
, path
.GetRaw(), comment
, color
, prio
);
697 m_conn
->SendRequest(new CCatHandler
, &req
);
699 Category_Struct
*category
= m_CatList
[cat
];
700 category
->path
= path
;
701 category
->title
= name
;
702 category
->comment
= comment
;
703 category
->color
= color
;
704 category
->prio
= prio
;
710 void CPreferencesRem::RemoveCat(uint8 cat
)
712 CECPacket
req(EC_OP_DELETE_CATEGORY
);
713 CEC_Category_Tag
tag(cat
, EC_DETAIL_CMD
);
715 m_conn
->SendPacket(&req
);
716 CPreferences::RemoveCat(cat
);
721 // Container implementation
723 CServerConnectRem::CServerConnectRem(CRemoteConnect
*conn
)
730 void CServerConnectRem::ConnectToAnyServer()
732 CECPacket
req(EC_OP_SERVER_CONNECT
);
733 m_Conn
->SendPacket(&req
);
737 void CServerConnectRem::StopConnectionTry()
739 // lfroen: isn't Disconnect the same ?
743 void CServerConnectRem::Disconnect()
745 CECPacket
req(EC_OP_SERVER_DISCONNECT
);
746 m_Conn
->SendPacket(&req
);
750 void CServerConnectRem::ConnectToServer(CServer
*server
)
752 m_Conn
->ConnectED2K(server
->GetIP(), server
->GetPort());
756 void CServerConnectRem::HandlePacket(const CECPacket
*packet
)
758 const CEC_ConnState_Tag
*tag
= static_cast<const CEC_ConnState_Tag
*>(packet
->GetTagByName(EC_TAG_CONNSTATE
));
763 theApp
->m_ConnState
= 0;
765 m_ID
= tag
->GetEd2kId();
766 theApp
->m_clientID
= tag
->GetClientId();
767 tag
->GetKadID(theApp
->m_kadID
);
769 if (tag
->IsConnectedED2K()) {
770 const CECTag
*srvtag
= tag
->GetTagByName(EC_TAG_SERVER
);
772 server
= theApp
->serverlist
->GetByID(srvtag
->GetInt());
773 if (server
!= m_CurrServer
) {
774 theApp
->amuledlg
->m_serverwnd
->serverlistctrl
->HighlightServer(server
, true);
775 m_CurrServer
= server
;
778 theApp
->m_ConnState
|= CONNECTED_ED2K
;
779 } else if ( m_CurrServer
) {
780 theApp
->amuledlg
->m_serverwnd
->serverlistctrl
->HighlightServer(m_CurrServer
, false);
784 if (tag
->IsConnectedKademlia()) {
785 if (tag
->IsKadFirewalled()) {
786 theApp
->m_ConnState
|= CONNECTED_KAD_FIREWALLED
;
788 theApp
->m_ConnState
|= CONNECTED_KAD_OK
;
791 if (tag
->IsKadRunning()) {
792 theApp
->m_ConnState
|= CONNECTED_KAD_NOT
;
796 theApp
->amuledlg
->ShowConnectionState();
801 * Server list: host list of ed2k servers.
803 CServerListRem::CServerListRem(CRemoteConnect
*conn
)
805 CRemoteContainer
<CServer
, uint32
, CEC_Server_Tag
>(conn
, true)
810 void CServerListRem::HandlePacket(const CECPacket
*)
812 // There is no packet for the server list, it is part of the general update packet
814 // CRemoteContainer<CServer, uint32, CEC_Server_Tag>::HandlePacket(packet);
818 void CServerListRem::UpdateServerMetFromURL(wxString url
)
820 CECPacket
req(EC_OP_SERVER_UPDATE_FROM_URL
);
821 req
.AddTag(CECTag(EC_TAG_SERVERS_UPDATE_URL
, url
));
823 m_conn
->SendPacket(&req
);
827 void CServerListRem::SetStaticServer(CServer
* server
, bool isStatic
)
829 // update display right away
830 server
->SetIsStaticMember(isStatic
);
831 Notify_ServerRefresh(server
);
833 CECPacket
req(EC_OP_SERVER_SET_STATIC_PRIO
);
834 req
.AddTag(CECTag(EC_TAG_SERVER
, server
->ECID()));
835 req
.AddTag(CECTag(EC_TAG_SERVER_STATIC
, isStatic
));
837 m_conn
->SendPacket(&req
);
841 void CServerListRem::SetServerPrio(CServer
* server
, uint32 prio
)
843 // update display right away
844 server
->SetPreference(prio
);
845 Notify_ServerRefresh(server
);
847 CECPacket
req(EC_OP_SERVER_SET_STATIC_PRIO
);
848 req
.AddTag(CECTag(EC_TAG_SERVER
, server
->ECID()));
849 req
.AddTag(CECTag(EC_TAG_SERVER_PRIO
, prio
));
851 m_conn
->SendPacket(&req
);
855 void CServerListRem::RemoveServer(CServer
* server
)
857 m_conn
->RemoveServer(server
->GetIP(),server
->GetPort());
861 void CServerListRem::UpdateUserFileStatus(CServer
*server
)
864 m_TotalUser
= server
->GetUsers();
865 m_TotalFile
= server
->GetFiles();
870 CServer
*CServerListRem::GetServerByAddress(const wxString
& WXUNUSED(address
), uint16
WXUNUSED(port
)) const
872 // It's ok to return 0 for context where this code is used in remote gui
876 CServer
*CServerListRem::GetServerByIPTCP(uint32
WXUNUSED(nIP
), uint16
WXUNUSED(nPort
)) const
878 // It's ok to return 0 for context where this code is used in remote gui
882 CServer
*CServerListRem::CreateItem(const CEC_Server_Tag
*tag
)
884 CServer
* server
= new CServer(tag
);
885 ProcessItemUpdate(tag
, server
);
890 void CServerListRem::DeleteItem(CServer
*in_srv
)
892 CScopedPtr
<CServer
> srv(in_srv
);
893 theApp
->amuledlg
->m_serverwnd
->serverlistctrl
->RemoveServer(srv
.get());
897 uint32
CServerListRem::GetItemID(CServer
*server
)
899 return server
->ECID();
903 void CServerListRem::ProcessItemUpdate(const CEC_Server_Tag
* tag
, CServer
* server
)
905 if (!tag
->HasChildTags()) {
908 tag
->ServerName(& server
->listname
);
909 tag
->ServerDesc(& server
->description
);
910 tag
->ServerVersion(& server
->m_strVersion
);
911 tag
->GetMaxUsers(& server
->maxusers
);
913 tag
->GetFiles(& server
->files
);
914 tag
->GetUsers(& server
->users
);
916 tag
->GetPrio(& server
->preferences
); // SRV_PR_NORMAL = 0, so it's ok
917 tag
->GetStatic(& server
->staticservermember
);
919 tag
->GetPing(& server
->ping
);
920 tag
->GetFailed(& server
->failedcount
);
922 theApp
->amuledlg
->m_serverwnd
->serverlistctrl
->RefreshServer(server
);
926 CServer::CServer(const CEC_Server_Tag
*tag
) : CECID(tag
->GetInt())
928 ip
= tag
->GetTagByNameSafe(EC_TAG_SERVER_IP
)->GetInt();
929 port
= tag
->GetTagByNameSafe(EC_TAG_SERVER_PORT
)->GetInt();
938 CIPFilterRem::CIPFilterRem(CRemoteConnect
* conn
)
944 void CIPFilterRem::Reload()
946 CECPacket
req(EC_OP_IPFILTER_RELOAD
);
947 m_conn
->SendPacket(&req
);
951 void CIPFilterRem::Update(wxString url
)
953 CECPacket
req(EC_OP_IPFILTER_UPDATE
);
954 req
.AddTag(CECTag(EC_TAG_STRING
, url
));
956 m_conn
->SendPacket(&req
);
963 CSharedFilesRem::CSharedFilesRem(CRemoteConnect
*conn
)
969 void CSharedFilesRem::Reload(bool, bool)
971 CECPacket
req(EC_OP_SHAREDFILES_RELOAD
);
973 m_conn
->SendPacket(&req
);
977 bool CSharedFilesRem::RenameFile(CKnownFile
* file
, const CPath
& newName
)
979 // We use the printable name, as the filename originated from user input,
980 // and the filesystem name might not be valid on the remote host.
981 const wxString strNewName
= newName
.GetPrintable();
983 CECPacket
request(EC_OP_RENAME_FILE
);
984 request
.AddTag(CECTag(EC_TAG_KNOWNFILE
, file
->GetFileHash()));
985 request
.AddTag(CECTag(EC_TAG_PARTFILE_NAME
, strNewName
));
987 m_conn
->SendPacket(&request
);
993 void CSharedFilesRem::SetFileCommentRating(CKnownFile
* file
, const wxString
& newComment
, int8 newRating
)
995 CECPacket
request(EC_OP_SHARED_FILE_SET_COMMENT
);
996 request
.AddTag(CECTag(EC_TAG_KNOWNFILE
, file
->GetFileHash()));
997 request
.AddTag(CECTag(EC_TAG_KNOWNFILE_COMMENT
, newComment
));
998 request
.AddTag(CECTag(EC_TAG_KNOWNFILE_RATING
, newRating
));
1000 m_conn
->SendPacket(&request
);
1004 void CSharedFilesRem::CopyFileList(std::vector
<CKnownFile
*>& out_list
) const
1006 out_list
.reserve(size());
1007 for (const_iterator it
= begin(); it
!= end(); ++it
) {
1008 out_list
.push_back(it
->second
);
1013 void CKnownFilesRem::DeleteItem(CKnownFile
* file
)
1015 uint32 id
= file
->ECID();
1016 if (theApp
->sharedfiles
->count(id
)) {
1017 theApp
->amuledlg
->m_sharedfileswnd
->sharedfilesctrl
->RemoveFile(file
);
1018 theApp
->sharedfiles
->erase(id
);
1020 if (theApp
->downloadqueue
->count(id
)) {
1021 theApp
->amuledlg
->m_transferwnd
->downloadlistctrl
->RemoveFile(static_cast<CPartFile
*>(file
));
1022 theApp
->downloadqueue
->erase(id
);
1028 uint32
CKnownFilesRem::GetItemID(CKnownFile
*file
)
1030 return file
->ECID();
1034 void CKnownFilesRem::ProcessItemUpdate(const CEC_SharedFile_Tag
*tag
, CKnownFile
*file
)
1036 const CECTag
*parttag
= tag
->GetTagByName(EC_TAG_PARTFILE_PART_STATUS
);
1038 const uint8
*data
= file
->m_partStatus
.Decode(
1039 (uint8
*)parttag
->GetTagData(),
1040 parttag
->GetTagDataLen());
1041 for(int i
= 0; i
< file
->GetPartCount(); ++i
) {
1042 file
->m_AvailPartFrequency
[i
] = data
[i
];
1046 if (tag
->FileName(fileName
)) {
1047 file
->SetFileName(CPath(fileName
));
1049 if (tag
->FilePath(fileName
)) {
1050 file
->m_filePath
= CPath(fileName
);
1052 tag
->UpPrio(&file
->m_iUpPriorityEC
);
1053 tag
->GetAICHHash(file
->m_AICHMasterHash
);
1054 // Bad thing - direct writing another class' members
1055 tag
->GetRequests(&file
->statistic
.requested
);
1056 tag
->GetAllRequests(&file
->statistic
.alltimerequested
);
1057 tag
->GetAccepts(&file
->statistic
.accepted
);
1058 tag
->GetAllAccepts(&file
->statistic
.alltimeaccepted
);
1059 tag
->GetXferred(&file
->statistic
.transferred
);
1060 tag
->GetAllXferred(&file
->statistic
.alltimetransferred
);
1061 tag
->UpPrio(&file
->m_iUpPriorityEC
);
1062 if (file
->m_iUpPriorityEC
>= 10) {
1063 file
->m_iUpPriority
= file
->m_iUpPriorityEC
- 10;
1064 file
->m_bAutoUpPriority
= true;
1066 file
->m_iUpPriority
= file
->m_iUpPriorityEC
;
1067 file
->m_bAutoUpPriority
= false;
1069 tag
->GetCompleteSourcesLow(&file
->m_nCompleteSourcesCountLo
);
1070 tag
->GetCompleteSourcesHigh(&file
->m_nCompleteSourcesCountHi
);
1071 tag
->GetCompleteSources(&file
->m_nCompleteSourcesCount
);
1073 tag
->GetOnQueue(&file
->m_queuedCount
);
1075 tag
->GetComment(file
->m_strComment
);
1076 tag
->GetRating(file
->m_iRating
);
1078 requested
+= file
->statistic
.requested
;
1079 transferred
+= file
->statistic
.transferred
;
1080 accepted
+= file
->statistic
.transferred
;
1082 if (!m_initialUpdate
) {
1083 theApp
->amuledlg
->m_sharedfileswnd
->sharedfilesctrl
->UpdateItem(file
);
1086 if (file
->IsPartFile()) {
1087 ProcessItemUpdatePartfile(static_cast<const CEC_PartFile_Tag
*>(tag
), static_cast<CPartFile
*>(file
));
1091 void CSharedFilesRem::SetFilePrio(CKnownFile
*file
, uint8 prio
)
1093 CECPacket
req(EC_OP_SHARED_SET_PRIO
);
1095 CECTag
hashtag(EC_TAG_PARTFILE
, file
->GetFileHash());
1096 hashtag
.AddTag(CECTag(EC_TAG_PARTFILE_PRIO
, prio
));
1098 req
.AddTag(hashtag
);
1100 m_conn
->SendPacket(&req
);
1103 void CKnownFilesRem::ProcessUpdate(const CECTag
*reply
, CECPacket
*, int)
1109 std::set
<uint32
> core_files
;
1110 for (CECPacket::const_iterator it
= reply
->begin(); it
!= reply
->end(); ++it
) {
1111 const CECTag
* curTag
= &*it
;
1112 ec_tagname_t tagname
= curTag
->GetTagName();
1113 if (tagname
== EC_TAG_CLIENT
) {
1114 theApp
->clientlist
->ProcessUpdate(curTag
, NULL
, EC_TAG_CLIENT
);
1115 } else if (tagname
== EC_TAG_SERVER
) {
1116 theApp
->serverlist
->ProcessUpdate(curTag
, NULL
, EC_TAG_SERVER
);
1117 } else if (tagname
== EC_TAG_FRIEND
) {
1118 theApp
->friendlist
->ProcessUpdate(curTag
, NULL
, EC_TAG_FRIEND
);
1119 } else if (tagname
== EC_TAG_KNOWNFILE
|| tagname
== EC_TAG_PARTFILE
) {
1120 const CEC_SharedFile_Tag
*tag
= static_cast<const CEC_SharedFile_Tag
*>(curTag
);
1121 uint32 id
= tag
->ID();
1123 if (!m_initialUpdate
) {
1124 core_files
.insert(id
);
1125 std::map
<uint32
, CKnownFile
*>::iterator it2
= m_items_hash
.find(id
);
1126 if (it2
!= m_items_hash
.end() ) {
1127 // Item already known: update it
1128 if (tag
->HasChildTags()) {
1129 ProcessItemUpdate(tag
, it2
->second
);
1135 CKnownFile
* newFile
;
1136 if (tag
->GetTagName() == EC_TAG_PARTFILE
) {
1137 CPartFile
*file
= new CPartFile(static_cast<const CEC_PartFile_Tag
*>(tag
));
1138 ProcessItemUpdate(tag
, file
);
1139 (*theApp
->downloadqueue
)[id
] = file
;
1140 theApp
->amuledlg
->m_transferwnd
->downloadlistctrl
->AddFile(file
);
1143 newFile
= new CKnownFile(tag
);
1144 ProcessItemUpdate(tag
, newFile
);
1145 (*theApp
->sharedfiles
)[id
] = newFile
;
1146 if (!m_initialUpdate
) {
1147 theApp
->amuledlg
->m_sharedfileswnd
->sharedfilesctrl
->ShowFile(newFile
);
1155 if (m_initialUpdate
) {
1156 theApp
->amuledlg
->m_sharedfileswnd
->sharedfilesctrl
->ShowFileList();
1157 m_initialUpdate
= false;
1159 // remove items no longer present
1160 for(iterator it
= begin(); it
!= end();) {
1161 iterator it2
= it
++;
1162 if (!core_files
.count(GetItemID(*it2
))) {
1163 RemoveItem(it2
); // This calls DeleteItem, where it is removed from lists and views.
1169 CKnownFilesRem::CKnownFilesRem(CRemoteConnect
* conn
) : CRemoteContainer
<CKnownFile
, uint32
, CEC_SharedFile_Tag
>(conn
, true)
1174 m_initialUpdate
= true;
1179 * List of uploading and waiting clients.
1181 CUpDownClientListRem::CUpDownClientListRem(CRemoteConnect
*conn
)
1183 CRemoteContainer
<CClientRef
, uint32
, CEC_UpDownClient_Tag
>(conn
, true)
1188 CClientRef::CClientRef(const CEC_UpDownClient_Tag
*tag
)
1190 m_client
= new CUpDownClient(tag
);
1191 #ifdef DEBUG_ZOMBIE_CLIENTS
1192 m_client
->Link(wxT("TAG"));
1199 CUpDownClient::CUpDownClient(const CEC_UpDownClient_Tag
*tag
) : CECID(tag
->ID())
1202 #ifdef DEBUG_ZOMBIE_CLIENTS
1203 m_linkedDebug
= false;
1205 // Clients start up empty, then get asked for their data.
1206 // So all data here is processed in ProcessItemUpdate and thus updatable.
1207 m_bEmuleProtocol
= false;
1208 m_AvailPartCount
= 0;
1210 m_nDownloadState
= 0;
1212 m_bFriendSlot
= false;
1216 m_lastDownloadingPart
= 0xffff;
1217 m_nextRequestedPart
= 0xffff;
1218 m_obfuscationStatus
= 0;
1219 m_nOldRemoteQueueRank
= 0;
1220 m_nRemoteQueueRank
= 0;
1225 m_nSourceFrom
= SF_NONE
;
1226 m_nTransferredDown
= 0;
1227 m_nTransferredUp
= 0;
1229 m_uploadingfile
= NULL
;
1230 m_waitingPosition
= 0;
1232 m_nUserIDHybrid
= 0;
1234 m_nClientVersion
= 0;
1235 m_fNoViewSharedFiles
= true;
1236 m_identState
= IS_NOTAVAILABLE
;
1237 m_bRemoteQueueFull
= false;
1239 credits
= new CClientCredits(new CreditStruct());
1242 #ifdef DEBUG_ZOMBIE_CLIENTS
1243 void CUpDownClient::Unlink(const wxString
& from
)
1245 std::multiset
<wxString
>::iterator it
= m_linkedFrom
.find(from
);
1246 if (it
!= m_linkedFrom
.end()) {
1247 m_linkedFrom
.erase(it
);
1251 if (m_linkedDebug
) {
1252 AddLogLineN(CFormat(wxT("Last reference to client %d %p unlinked, delete it.")) % ECID() % this);
1260 void CUpDownClient::Unlink()
1270 uint64
CUpDownClient::GetDownloadedTotal() const
1272 return credits
->GetDownloadedTotal();
1276 uint64
CUpDownClient::GetUploadedTotal() const
1278 return credits
->GetUploadedTotal();
1282 double CUpDownClient::GetScoreRatio() const
1284 return credits
->GetScoreRatio(GetIP(), theApp
->CryptoAvailable());
1290 CUpDownClient::~CUpDownClient()
1296 CClientRef
*CUpDownClientListRem::CreateItem(const CEC_UpDownClient_Tag
*tag
)
1298 CClientRef
*client
= new CClientRef(tag
);
1299 ProcessItemUpdate(tag
, client
);
1305 void CUpDownClientListRem::DeleteItem(CClientRef
*clientref
)
1307 CUpDownClient
* client
= clientref
->GetClient();
1308 if (client
->m_reqfile
) {
1309 client
->m_reqfile
->DelSource(client
);
1310 client
->m_reqfile
= NULL
;
1312 Notify_SourceCtrlRemoveSource(client
->ECID(), (CPartFile
*) NULL
);
1314 if (client
->m_uploadingfile
) {
1315 client
->m_uploadingfile
->RemoveUploadingClient(client
); // this notifies
1316 client
->m_uploadingfile
= NULL
;
1318 theApp
->m_allUploadingKnownFile
->RemoveUploadingClient(client
); // in case it vanished directly while uploading
1319 Notify_SharedCtrlRemoveClient(client
->ECID(), (CKnownFile
*) NULL
);
1321 if (client
->m_Friend
) {
1322 client
->m_Friend
->UnLinkClient(); // this notifies
1323 client
->m_Friend
= NULL
;
1326 #ifdef DEBUG_ZOMBIE_CLIENTS
1327 if (client
->m_linked
> 1) {
1328 AddLogLineC(CFormat(wxT("Client %d still linked in %d places: %s")) % client
->ECID() % (client
->m_linked
- 1) % client
->GetLinkedFrom());
1329 client
->m_linkedDebug
= true;
1337 uint32
CUpDownClientListRem::GetItemID(CClientRef
*client
)
1339 return client
->ECID();
1343 void CUpDownClientListRem::ProcessItemUpdate(
1344 const CEC_UpDownClient_Tag
*tag
,
1345 CClientRef
*clientref
)
1347 if (!tag
->HasChildTags()) {
1348 return; // speed exit for clients without any change
1350 CUpDownClient
*client
= clientref
->GetClient();
1352 tag
->UserID(&client
->m_nUserIDHybrid
);
1353 tag
->ClientName(&client
->m_Username
);
1355 bool sw_updated
= false;
1356 if (tag
->ClientSoftware(client
->m_clientSoft
)) {
1357 client
->m_clientSoftString
= GetSoftName(client
->m_clientSoft
);
1360 if (tag
->SoftVerStr(client
->m_clientVerString
) || sw_updated
) {
1361 if (client
->m_clientSoftString
== _("Unknown")) {
1362 client
->m_fullClientVerString
= client
->m_clientSoftString
;
1364 client
->m_fullClientVerString
= client
->m_clientSoftString
+ wxT(" ") + client
->m_clientVerString
;
1368 tag
->UserHash(&client
->m_UserHash
);
1371 tag
->UserIP(client
->m_dwUserIP
);
1372 tag
->UserPort(&client
->m_nUserPort
);
1375 tag
->ServerIP(&client
->m_dwServerIP
);
1376 tag
->ServerPort(&client
->m_nServerPort
);
1377 tag
->ServerName(&client
->m_ServerName
);
1379 tag
->KadPort(client
->m_nKadPort
);
1380 tag
->FriendSlot(client
->m_bFriendSlot
);
1382 tag
->GetCurrentIdentState(&client
->m_identState
);
1383 tag
->ObfuscationStatus(client
->m_obfuscationStatus
);
1384 tag
->HasExtendedProtocol(&client
->m_bEmuleProtocol
);
1386 tag
->WaitingPosition(&client
->m_waitingPosition
);
1387 tag
->RemoteQueueRank(&client
->m_nRemoteQueueRank
);
1388 client
->m_bRemoteQueueFull
= client
->m_nRemoteQueueRank
== 0xffff;
1389 tag
->OldRemoteQueueRank(&client
->m_nOldRemoteQueueRank
);
1391 tag
->ClientDownloadState(client
->m_nDownloadState
);
1392 if (tag
->ClientUploadState(client
->m_nUploadState
)) {
1393 if (client
->m_nUploadState
== US_UPLOADING
) {
1394 theApp
->m_allUploadingKnownFile
->AddUploadingClient(client
);
1396 theApp
->m_allUploadingKnownFile
->RemoveUploadingClient(client
);
1400 tag
->SpeedUp(&client
->m_nUpDatarate
);
1401 if ( client
->m_nDownloadState
== DS_DOWNLOADING
) {
1402 tag
->SpeedDown(&client
->m_kBpsDown
);
1404 client
->m_kBpsDown
= 0;
1407 //tag->WaitTime(&client->m_WaitTime);
1408 //tag->XferTime(&client->m_UpStartTimeDelay);
1409 //tag->LastReqTime(&client->m_dwLastUpRequest);
1410 //tag->QueueTime(&client->m_WaitStartTime);
1412 CreditStruct
*credit_struct
= const_cast<CreditStruct
*>(client
->credits
->GetDataStruct());
1413 tag
->XferUp(&credit_struct
->uploaded
);
1414 tag
->XferUpSession(&client
->m_nTransferredUp
);
1416 tag
->XferDown(&credit_struct
->downloaded
);
1417 tag
->XferDownSession(&client
->m_nTransferredDown
);
1419 tag
->Score(&client
->m_score
);
1421 tag
->NextRequestedPart(client
->m_nextRequestedPart
);
1422 tag
->LastDownloadingPart(client
->m_lastDownloadingPart
);
1424 uint8 sourceFrom
= 0;
1425 if (tag
->GetSourceFrom(sourceFrom
)) {
1426 client
->m_nSourceFrom
= (ESourceFrom
)sourceFrom
;
1429 tag
->RemoteFilename(client
->m_clientFilename
);
1430 tag
->DisableViewShared(client
->m_fNoViewSharedFiles
);
1431 tag
->Version(client
->m_nClientVersion
);
1432 tag
->ModVersion(client
->m_strModVersion
);
1433 tag
->OSInfo(client
->m_sClientOSInfo
);
1434 tag
->AvailableParts(client
->m_AvailPartCount
);
1438 bool notified
= false;
1439 if (tag
->RequestFile(fileID
)) {
1440 if (client
->m_reqfile
) {
1441 Notify_SourceCtrlRemoveSource(client
->ECID(), client
->m_reqfile
);
1442 client
->m_reqfile
->DelSource(client
);
1443 client
->m_reqfile
= NULL
;
1444 client
->m_downPartStatus
.clear();
1446 CKnownFile
* kf
= theApp
->knownfiles
->GetByID(fileID
);
1447 if (kf
&& kf
->IsCPartFile()) {
1448 client
->m_reqfile
= static_cast<CPartFile
*>(kf
);
1449 client
->m_reqfile
->AddSource(client
);
1450 client
->m_downPartStatus
.setsize(kf
->GetPartCount(), 0);
1451 Notify_SourceCtrlAddSource(client
->m_reqfile
, CCLIENTREF(client
, wxT("AddSource")), A4AF_SOURCE
);
1457 const CECTag
* partStatusTag
= tag
->GetTagByName(EC_TAG_CLIENT_PART_STATUS
);
1458 if (partStatusTag
) {
1459 if (partStatusTag
->GetTagDataLen() == 0) {
1460 // empty tag means full source
1461 client
->m_downPartStatus
.SetAllTrue();
1462 } else if (partStatusTag
->GetTagDataLen() == client
->m_downPartStatus
.SizeBuffer()) {
1463 client
->m_downPartStatus
.SetBuffer(partStatusTag
->GetTagData());
1468 if (!notified
&& client
->m_reqfile
&& client
->m_reqfile
->ShowSources()) {
1469 SourceItemType type
;
1470 switch (client
->GetDownloadState()) {
1471 case DS_DOWNLOADING
:
1473 // We will send A4AF, which will be checked.
1477 type
= UNAVAILABLE_SOURCE
;
1481 Notify_SourceCtrlUpdateSource(client
->ECID(), type
);
1486 if (tag
->UploadFile(fileID
)) {
1487 if (client
->m_uploadingfile
) {
1488 client
->m_uploadingfile
->RemoveUploadingClient(client
); // this notifies
1490 client
->m_uploadingfile
= NULL
;
1492 CKnownFile
* kf
= theApp
->knownfiles
->GetByID(fileID
);
1494 client
->m_uploadingfile
= kf
;
1495 client
->m_upPartStatus
.setsize(kf
->GetPartCount(), 0);
1496 client
->m_uploadingfile
->AddUploadingClient(client
); // this notifies
1502 partStatusTag
= tag
->GetTagByName(EC_TAG_CLIENT_UPLOAD_PART_STATUS
);
1503 if (partStatusTag
) {
1504 if (partStatusTag
->GetTagDataLen() == client
->m_upPartStatus
.SizeBuffer()) {
1505 client
->m_upPartStatus
.SetBuffer(partStatusTag
->GetTagData());
1510 if (!notified
&& client
->m_uploadingfile
1511 && (client
->m_uploadingfile
->ShowPeers() || (client
->m_nUploadState
== US_UPLOADING
))) {
1512 // notify if KnowFile is selected, or if it's uploading (in case clients are in show uploading mode)
1513 SourceItemType type
;
1514 switch (client
->GetUploadState()) {
1516 case US_ONUPLOADQUEUE
:
1517 type
= AVAILABLE_SOURCE
;
1520 type
= UNAVAILABLE_SOURCE
;
1523 Notify_SharedCtrlRefreshClient(client
->ECID(), type
);
1529 * Download queue container: hold PartFiles with progress status
1534 bool CDownQueueRem::AddLink(const wxString
&link
, uint8 cat
)
1536 CECPacket
req(EC_OP_ADD_LINK
);
1537 CECTag
link_tag(EC_TAG_STRING
, link
);
1538 link_tag
.AddTag(CECTag(EC_TAG_PARTFILE_CAT
, cat
));
1539 req
.AddTag(link_tag
);
1541 m_conn
->SendPacket(&req
);
1546 void CDownQueueRem::ResetCatParts(int cat
)
1548 // Called when category is deleted. Command will be performed on the remote side,
1549 // but files still should be updated here right away, or drawing errors (colour not available)
1551 for (iterator it
= begin(); it
!= end(); ++it
) {
1552 CPartFile
* file
= it
->second
;
1553 file
->RemoveCategory(cat
);
1559 void CKnownFilesRem::ProcessItemUpdatePartfile(const CEC_PartFile_Tag
*tag
, CPartFile
*file
)
1564 tag
->Speed(&file
->m_kbpsDown
);
1565 file
->kBpsDown
= file
->m_kbpsDown
/ 1024.0;
1567 tag
->SizeXfer(&file
->transferred
);
1568 tag
->SizeDone(&file
->completedsize
);
1569 tag
->SourceXferCount(&file
->transferingsrc
);
1570 tag
->SourceNotCurrCount(&file
->m_notCurrentSources
);
1571 tag
->SourceCount(&file
->m_source_count
);
1572 tag
->SourceCountA4AF(&file
->m_a4af_source_count
);
1573 tag
->FileStatus(&file
->status
);
1574 tag
->Stopped(&file
->m_stopped
);
1576 tag
->LastSeenComplete(&file
->lastseencomplete
);
1577 tag
->LastDateChanged(&file
->m_lastDateChanged
);
1578 tag
->DownloadActiveTime(&file
->m_nDlActiveTime
);
1579 tag
->AvailablePartCount(&file
->m_availablePartsCount
);
1580 tag
->Shared(&file
->m_isShared
);
1581 tag
->A4AFAuto(file
->m_is_A4AF_auto
);
1582 tag
->HashingProgress(file
->m_hashingProgress
);
1584 tag
->GetLostDueToCorruption(&file
->m_iLostDueToCorruption
);
1585 tag
->GetGainDueToCompression(&file
->m_iGainDueToCompression
);
1586 tag
->TotalPacketsSavedDueToICH(&file
->m_iTotalPacketsSavedDueToICH
);
1588 tag
->FileCat(&file
->m_category
);
1590 tag
->DownPrio(&file
->m_iDownPriorityEC
);
1591 if ( file
->m_iDownPriorityEC
>= 10 ) {
1592 file
->m_iDownPriority
= file
->m_iDownPriorityEC
- 10;
1593 file
->m_bAutoDownPriority
= true;
1595 file
->m_iDownPriority
= file
->m_iDownPriorityEC
;
1596 file
->m_bAutoDownPriority
= false;
1599 file
->percentcompleted
= (100.0*file
->GetCompletedSize()) / file
->GetFileSize();
1602 // Copy part/gap status
1604 const CECTag
*gaptag
= tag
->GetTagByName(EC_TAG_PARTFILE_GAP_STATUS
);
1605 const CECTag
*parttag
= tag
->GetTagByName(EC_TAG_PARTFILE_PART_STATUS
);
1606 const CECTag
*reqtag
= tag
->GetTagByName(EC_TAG_PARTFILE_REQ_STATUS
);
1607 if (gaptag
|| parttag
|| reqtag
) {
1608 PartFileEncoderData
&encoder
= file
->m_PartFileEncoderData
;
1611 ArrayOfUInts64 gaps
;
1612 encoder
.DecodeGaps(gaptag
, gaps
);
1613 int gap_size
= gaps
.size() / 2;
1615 file
->m_gaplist
.Init(file
->GetFileSize(), false);
1618 for (int j
= 0; j
< gap_size
; j
++) {
1619 file
->m_gaplist
.AddGap(gaps
[2*j
], gaps
[2*j
+1]);
1623 encoder
.DecodeParts(parttag
, file
->m_SrcpartFrequency
);
1625 wxASSERT (file
->m_SrcpartFrequency
.size() == file
->GetPartCount());
1628 ArrayOfUInts64 reqs
;
1629 encoder
.DecodeReqs(reqtag
, reqs
);
1630 int req_size
= reqs
.size() / 2;
1632 DeleteContents(file
->m_requestedblocks_list
);
1635 for (int j
= 0; j
< req_size
; j
++) {
1636 Requested_Block_Struct
* block
= new Requested_Block_Struct
;
1637 block
->StartOffset
= reqs
[2*j
];
1638 block
->EndOffset
= reqs
[2*j
+1];
1639 file
->m_requestedblocks_list
.push_back(block
);
1644 // Get source names and counts
1645 const CECTag
*srcnametag
= tag
->GetTagByName(EC_TAG_PARTFILE_SOURCE_NAMES
);
1647 SourcenameItemMap
&map
= file
->GetSourcenameItemMap();
1648 for (CECTag::const_iterator it
= srcnametag
->begin(); it
!= srcnametag
->end(); ++it
) {
1649 uint32 key
= it
->GetInt();
1650 int count
= it
->GetTagByNameSafe(EC_TAG_PARTFILE_SOURCE_NAMES_COUNTS
)->GetInt();
1654 SourcenameItem
&item
= map
[key
];
1656 const CECTag
*nametag
= it
->GetTagByName(EC_TAG_PARTFILE_SOURCE_NAMES
);
1658 item
.name
= nametag
->GetStringData();
1665 const CECTag
*commenttag
= tag
->GetTagByName(EC_TAG_PARTFILE_COMMENTS
);
1667 file
->ClearFileRatingList();
1668 for (CECTag::const_iterator it
= commenttag
->begin(); it
!= commenttag
->end(); ) {
1669 wxString u
= (it
++)->GetStringData();
1670 wxString f
= (it
++)->GetStringData();
1671 int r
= (it
++)->GetInt();
1672 wxString c
= (it
++)->GetStringData();
1673 file
->AddFileRatingList(u
, f
, r
, c
);
1675 file
->UpdateFileRatingCommentAvail();
1678 // Update A4AF sources
1679 ListOfUInts32
& clientIDs
= file
->GetA4AFClientIDs();
1680 const CECTag
*a4aftag
= tag
->GetTagByName(EC_TAG_PARTFILE_A4AF_SOURCES
);
1682 file
->ClearA4AFList();
1684 for (CECTag::const_iterator it
= a4aftag
->begin(); it
!= a4aftag
->end(); ++it
) {
1685 if (it
->GetTagName() != EC_TAG_ECID
) { // should always be this
1688 uint32 id
= it
->GetInt();
1689 CClientRef
* src
= theApp
->clientlist
->GetByID(id
);
1691 file
->AddA4AFSource(src
->GetClient());
1693 // client wasn't transmitted yet, try it later
1694 clientIDs
.push_back(id
);
1697 } else if (!clientIDs
.empty()) {
1698 // Process clients from the last pass whose ids were still unknown then
1699 for (ListOfUInts32::iterator it
= clientIDs
.begin(); it
!= clientIDs
.end(); ) {
1700 ListOfUInts32::iterator it1
= it
++;
1702 CClientRef
* src
= theApp
->clientlist
->GetByID(id
);
1704 file
->AddA4AFSource(src
->GetClient());
1705 clientIDs
.erase(it1
);
1710 theApp
->amuledlg
->m_transferwnd
->downloadlistctrl
->UpdateItem(file
);
1712 // If file is shared check if it is already listed in shared files.
1713 // If not, add it and show it.
1714 if (file
->IsShared() && !theApp
->sharedfiles
->count(file
->ECID())) {
1715 (*theApp
->sharedfiles
)[file
->ECID()] = file
;
1716 theApp
->amuledlg
->m_sharedfileswnd
->sharedfilesctrl
->ShowFile(file
);
1721 void CDownQueueRem::SendFileCommand(CPartFile
*file
, ec_tagname_t cmd
)
1724 req
.AddTag(CECTag(EC_TAG_PARTFILE
, file
->GetFileHash()));
1726 m_conn
->SendPacket(&req
);
1730 void CDownQueueRem::Prio(CPartFile
*file
, uint8 prio
)
1732 CECPacket
req(EC_OP_PARTFILE_PRIO_SET
);
1734 CECTag
hashtag(EC_TAG_PARTFILE
, file
->GetFileHash());
1735 hashtag
.AddTag(CECTag(EC_TAG_PARTFILE_PRIO
, prio
));
1736 req
.AddTag(hashtag
);
1738 m_conn
->SendPacket(&req
);
1742 void CDownQueueRem::AutoPrio(CPartFile
*file
, bool flag
)
1744 CECPacket
req(EC_OP_PARTFILE_PRIO_SET
);
1746 CECTag
hashtag(EC_TAG_PARTFILE
, file
->GetFileHash());
1748 hashtag
.AddTag(CECTag(EC_TAG_PARTFILE_PRIO
,
1749 (uint8
)(flag
? PR_AUTO
: file
->GetDownPriority())));
1750 req
.AddTag(hashtag
);
1752 m_conn
->SendPacket(&req
);
1756 void CDownQueueRem::Category(CPartFile
*file
, uint8 cat
)
1758 CECPacket
req(EC_OP_PARTFILE_SET_CAT
);
1759 file
->SetCategory(cat
);
1761 CECTag
hashtag(EC_TAG_PARTFILE
, file
->GetFileHash());
1762 hashtag
.AddTag(CECTag(EC_TAG_PARTFILE_CAT
, cat
));
1763 req
.AddTag(hashtag
);
1765 m_conn
->SendPacket(&req
);
1769 void CDownQueueRem::AddSearchToDownload(CSearchFile
* file
, uint8 category
)
1771 CECPacket
req(EC_OP_DOWNLOAD_SEARCH_RESULT
);
1772 CECTag
hashtag(EC_TAG_PARTFILE
, file
->GetFileHash());
1773 hashtag
.AddTag(CECTag(EC_TAG_PARTFILE_CAT
, category
));
1774 req
.AddTag(hashtag
);
1776 m_conn
->SendPacket(&req
);
1780 void CDownQueueRem::ClearCompleted(const ListOfUInts32
& ecids
)
1782 CECPacket
req(EC_OP_CLEAR_COMPLETED
);
1783 for (ListOfUInts32::const_iterator it
= ecids
.begin(); it
!= ecids
.end(); ++it
) {
1784 req
.AddTag(CECTag(EC_TAG_ECID
, *it
));
1787 m_conn
->SendPacket(&req
);
1794 CFriendListRem::CFriendListRem(CRemoteConnect
*conn
)
1796 CRemoteContainer
<CFriend
, uint32
, CEC_Friend_Tag
>(conn
, true)
1801 void CFriendListRem::HandlePacket(const CECPacket
*)
1803 wxFAIL
; // not needed
1807 CFriend
* CFriendListRem::CreateItem(const CEC_Friend_Tag
* tag
)
1809 CFriend
* Friend
= new CFriend(tag
->ID());
1810 ProcessItemUpdate(tag
, Friend
);
1815 void CFriendListRem::DeleteItem(CFriend
* Friend
)
1817 Friend
->UnLinkClient(false);
1818 Notify_ChatRemoveFriend(Friend
);
1822 uint32
CFriendListRem::GetItemID(CFriend
* Friend
)
1824 return Friend
->ECID();
1828 void CFriendListRem::ProcessItemUpdate(const CEC_Friend_Tag
* tag
, CFriend
* Friend
)
1830 if (!tag
->HasChildTags()) {
1833 tag
->Name(Friend
->m_strName
);
1834 tag
->UserHash(Friend
->m_UserHash
);
1835 tag
->IP(Friend
->m_dwLastUsedIP
);
1836 tag
->Port(Friend
->m_nLastUsedPort
);
1838 bool notified
= false;
1839 if (tag
->Client(clientID
)) {
1841 CClientRef
* client
= theApp
->clientlist
->GetByID(clientID
);
1843 Friend
->LinkClient(*client
); // this notifies
1848 Friend
->UnLinkClient(false);
1852 Notify_ChatUpdateFriend(Friend
);
1857 void CFriendListRem::AddFriend(const CClientRef
& toadd
)
1859 CECPacket
req(EC_OP_FRIEND
);
1861 CECEmptyTag
addtag(EC_TAG_FRIEND_ADD
);
1862 addtag
.AddTag(CECTag(EC_TAG_CLIENT
, toadd
.ECID()));
1865 m_conn
->SendPacket(&req
);
1869 void CFriendListRem::AddFriend(const CMD4Hash
& userhash
, uint32 lastUsedIP
, uint32 lastUsedPort
, const wxString
& name
)
1871 CECPacket
req(EC_OP_FRIEND
);
1873 CECEmptyTag
addtag(EC_TAG_FRIEND_ADD
);
1874 addtag
.AddTag(CECTag(EC_TAG_FRIEND_HASH
, userhash
));
1875 addtag
.AddTag(CECTag(EC_TAG_FRIEND_IP
, lastUsedIP
));
1876 addtag
.AddTag(CECTag(EC_TAG_FRIEND_PORT
, lastUsedPort
));
1877 addtag
.AddTag(CECTag(EC_TAG_FRIEND_NAME
, name
));
1880 m_conn
->SendPacket(&req
);
1884 void CFriendListRem::RemoveFriend(CFriend
* toremove
)
1886 CECPacket
req(EC_OP_FRIEND
);
1888 CECEmptyTag
removetag(EC_TAG_FRIEND_REMOVE
);
1889 removetag
.AddTag(CECTag(EC_TAG_FRIEND
, toremove
->ECID()));
1890 req
.AddTag(removetag
);
1892 m_conn
->SendPacket(&req
);
1896 void CFriendListRem::SetFriendSlot(CFriend
* Friend
, bool new_state
)
1898 CECPacket
req(EC_OP_FRIEND
);
1900 CECTag
slottag(EC_TAG_FRIEND_FRIENDSLOT
, new_state
);
1901 slottag
.AddTag(CECTag(EC_TAG_FRIEND
, Friend
->ECID()));
1902 req
.AddTag(slottag
);
1904 m_conn
->SendPacket(&req
);
1908 void CFriendListRem::RequestSharedFileList(CFriend
* Friend
)
1910 CECPacket
req(EC_OP_FRIEND
);
1912 CECEmptyTag
sharedtag(EC_TAG_FRIEND_SHARED
);
1913 sharedtag
.AddTag(CECTag(EC_TAG_FRIEND
, Friend
->ECID()));
1914 req
.AddTag(sharedtag
);
1916 m_conn
->SendPacket(&req
);
1920 void CFriendListRem::RequestSharedFileList(CClientRef
& client
)
1922 CECPacket
req(EC_OP_FRIEND
);
1924 CECEmptyTag
sharedtag(EC_TAG_FRIEND_SHARED
);
1925 sharedtag
.AddTag(CECTag(EC_TAG_CLIENT
, client
.ECID()));
1926 req
.AddTag(sharedtag
);
1928 m_conn
->SendPacket(&req
);
1936 CSearchListRem::CSearchListRem(CRemoteConnect
*conn
) : CRemoteContainer
<CSearchFile
, uint32
, CEC_SearchFile_Tag
>(conn
, true)
1942 wxString
CSearchListRem::StartNewSearch(
1943 uint32
* nSearchID
, SearchType search_type
,
1944 const CSearchList::CSearchParams
& params
)
1946 CECPacket
search_req(EC_OP_SEARCH_START
);
1947 EC_SEARCH_TYPE ec_search_type
= EC_SEARCH_LOCAL
;
1948 switch(search_type
) {
1949 case LocalSearch
: ec_search_type
= EC_SEARCH_LOCAL
; break;
1950 case GlobalSearch
: ec_search_type
= EC_SEARCH_GLOBAL
; break;
1951 case KadSearch
: ec_search_type
= EC_SEARCH_KAD
; break;
1954 CEC_Search_Tag(params
.searchString
, ec_search_type
,
1955 params
.typeText
, params
.extension
, params
.availability
,
1956 params
.minSize
, params
.maxSize
));
1958 m_conn
->SendPacket(&search_req
);
1959 m_curr_search
= *(nSearchID
); // No kad remote search yet.
1963 return wxEmptyString
; // EC reply will have the error mesg is needed.
1967 void CSearchListRem::StopSearch(bool)
1969 if (m_curr_search
!= -1) {
1970 CECPacket
search_req(EC_OP_SEARCH_STOP
);
1971 m_conn
->SendPacket(&search_req
);
1976 void CSearchListRem::HandlePacket(const CECPacket
*packet
)
1978 if ( packet
->GetOpCode() == EC_OP_SEARCH_PROGRESS
) {
1979 CoreNotify_Search_Update_Progress(packet
->GetFirstTagSafe()->GetInt());
1981 CRemoteContainer
<CSearchFile
, uint32
, CEC_SearchFile_Tag
>::HandlePacket(packet
);
1986 CSearchFile::CSearchFile(const CEC_SearchFile_Tag
*tag
)
1990 m_showChildren(false),
1992 m_completeSourceCount(0),
1994 m_downloadStatus(NEW
),
1999 SetFileName(CPath(tag
->FileName()));
2000 m_abyFileHash
= tag
->FileHash();
2001 SetFileSize(tag
->SizeFull());
2003 m_searchID
= theApp
->searchlist
->m_curr_search
;
2004 uint32 parentID
= tag
->ParentID();
2006 CSearchFile
* parent
= theApp
->searchlist
->GetByID(parentID
);
2008 parent
->AddChild(this);
2014 void CSearchFile::AddChild(CSearchFile
* file
)
2016 m_children
.push_back(file
);
2017 file
->m_parent
= this;
2021 // dtor is virtual - must be implemented
2022 CSearchFile::~CSearchFile()
2027 CSearchFile
*CSearchListRem::CreateItem(const CEC_SearchFile_Tag
*tag
)
2029 CSearchFile
*file
= new CSearchFile(tag
);
2030 ProcessItemUpdate(tag
, file
);
2032 theApp
->amuledlg
->m_searchwnd
->AddResult(file
);
2038 void CSearchListRem::DeleteItem(CSearchFile
*file
)
2044 uint32
CSearchListRem::GetItemID(CSearchFile
*file
)
2046 return file
->ECID();
2050 void CSearchListRem::ProcessItemUpdate(const CEC_SearchFile_Tag
*tag
, CSearchFile
*file
)
2052 uint32 sourceCount
= file
->m_sourceCount
;
2053 uint32 completeSourceCount
= file
->m_completeSourceCount
;
2054 CSearchFile::DownloadStatus status
= file
->m_downloadStatus
;
2055 tag
->SourceCount(&file
->m_sourceCount
);
2056 tag
->CompleteSourceCount(&file
->m_completeSourceCount
);
2057 tag
->DownloadStatus((uint32
*) &file
->m_downloadStatus
);
2059 if (file
->m_sourceCount
!= sourceCount
2060 || file
->m_completeSourceCount
!= completeSourceCount
2061 || file
->m_downloadStatus
!= status
) {
2062 if (theApp
->amuledlg
&& theApp
->amuledlg
->m_searchwnd
) {
2063 theApp
->amuledlg
->m_searchwnd
->UpdateResult(file
);
2069 bool CSearchListRem::Phase1Done(const CECPacket
*WXUNUSED(reply
))
2071 CECPacket
progress_req(EC_OP_SEARCH_PROGRESS
);
2072 m_conn
->SendRequest(this, &progress_req
);
2078 void CSearchListRem::RemoveResults(long nSearchID
)
2080 ResultMap::iterator it
= m_results
.find(nSearchID
);
2081 if (it
!= m_results
.end()) {
2082 CSearchResultList
& list
= it
->second
;
2083 for (unsigned int i
= 0; i
< list
.size(); ++i
) {
2086 m_results
.erase(it
);
2091 const CSearchResultList
& CSearchListRem::GetSearchResults(long nSearchID
)
2093 ResultMap::const_iterator it
= m_results
.find(nSearchID
);
2094 if (it
!= m_results
.end()) {
2098 // TODO: Should we assert in this case?
2099 static CSearchResultList list
;
2104 void CStatsUpdaterRem::HandlePacket(const CECPacket
*packet
)
2106 theStats::UpdateStats(packet
);
2107 theApp
->amuledlg
->ShowTransferRate();
2108 theApp
->ShowUserCount(); // maybe there should be a check if a usercount changed ?
2109 // handle the connstate tag which is included in the stats packet
2110 theApp
->serverconnect
->HandlePacket(packet
);
2114 void CUpDownClient::RequestSharedFileList()
2116 CClientRef ref
= CCLIENTREF(this, wxEmptyString
);
2117 theApp
->friendlist
->RequestSharedFileList(ref
);
2121 bool CUpDownClient::SwapToAnotherFile(
2122 bool WXUNUSED(bIgnoreNoNeeded
),
2123 bool WXUNUSED(ignoreSuspensions
),
2124 bool WXUNUSED(bRemoveCompletely
),
2127 CECPacket
req(EC_OP_CLIENT_SWAP_TO_ANOTHER_FILE
);
2128 req
.AddTag(CECTag(EC_TAG_CLIENT
, ECID()));
2129 req
.AddTag(CECTag(EC_TAG_PARTFILE
, toFile
->GetFileHash()));
2130 theApp
->m_connect
->SendPacket(&req
);
2136 wxString
CAICHHash::GetString() const
2138 return EncodeBase32(m_abyBuffer
, HASHSIZE
);
2143 // Those functions are virtual. So even they don't get called they must
2144 // be defined so linker will be happy
2146 CPacket
* CKnownFile::CreateSrcInfoPacket(const CUpDownClient
*, uint8
/*byRequestedVersion*/, uint16
/*nRequestedOptions*/)
2153 bool CKnownFile::LoadFromFile(const class CFileDataIO
*)
2160 void CKnownFile::UpdatePartsInfo()
2166 CPacket
* CPartFile::CreateSrcInfoPacket(CUpDownClient
const *, uint8
/*byRequestedVersion*/, uint16
/*nRequestedOptions*/)
2173 void CPartFile::UpdatePartsInfo()
2180 void CPartFile::UpdateFileRatingCommentAvail()
2182 bool prevComment
= m_hasComment
;
2183 int prevRating
= m_iUserRating
;
2185 m_hasComment
= false;
2187 int ratingCount
= 0;
2189 FileRatingList::iterator it
= m_FileRatingList
.begin();
2190 for (; it
!= m_FileRatingList
.end(); ++it
) {
2191 SFileRating
& cur_rat
= *it
;
2193 if (!cur_rat
.Comment
.IsEmpty()) {
2194 m_hasComment
= true;
2197 uint8 rating
= cur_rat
.Rating
;
2199 wxASSERT(rating
<= 5);
2202 m_iUserRating
+= rating
;
2207 m_iUserRating
/= ratingCount
;
2208 wxASSERT(m_iUserRating
> 0 && m_iUserRating
<= 5);
2211 if ((prevComment
!= m_hasComment
) || (prevRating
!= m_iUserRating
)) {
2212 UpdateDisplayedInfo();
2217 void CStatTreeRem::DoRequery()
2219 CECPacket
request(EC_OP_GET_STATSTREE
);
2220 if (thePrefs::GetMaxClientVersions() != 0) {
2221 request
.AddTag(CECTag(EC_TAG_STATTREE_CAPPING
, (uint8
)thePrefs::GetMaxClientVersions()));
2223 m_conn
->SendRequest(this, &request
);
2226 void CStatTreeRem::HandlePacket(const CECPacket
* p
)
2228 const CECTag
* treeRoot
= p
->GetTagByName(EC_TAG_STATTREE_NODE
);
2230 theApp
->amuledlg
->m_statisticswnd
->RebuildStatTreeRemote(treeRoot
);
2231 theApp
->amuledlg
->m_statisticswnd
->ShowStatistics();
2235 CamuleRemoteGuiApp
*theApp
;
2238 // since gui is not linked with amule.cpp - define events here
2240 DEFINE_LOCAL_EVENT_TYPE(wxEVT_CORE_FINISHED_HTTP_DOWNLOAD
)
2241 DEFINE_LOCAL_EVENT_TYPE(wxEVT_CORE_SOURCE_DNS_DONE
)
2242 DEFINE_LOCAL_EVENT_TYPE(wxEVT_CORE_UDP_DNS_DONE
)
2243 DEFINE_LOCAL_EVENT_TYPE(wxEVT_CORE_SERVER_DNS_DONE
)
2244 // File_checked_for_headers