2 // This file is part of the aMule Project.
4 // Copyright (c) 2005-2008 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
32 #include <common/Format.h>
33 #include <common/StringFunctions.h>
34 #include <common/MD5Sum.h>
37 #include <include/common/EventIDs.h>
40 #include "amule.h" // Interface declarations.
41 #include "amuleDlg.h" // Needed for CamuleDlg
42 #include "ClientCredits.h"
43 #include "SourceListCtrl.h"
44 #include "DataToText.h" // Needed for GetSoftName()
45 #include "DownloadListCtrl.h" // Needed for CDownloadListCtrl
46 #include "GuiEvents.h"
47 #ifdef ENABLE_IP2COUNTRY
48 #include "IP2Country.h" // Needed for IP2Country
50 #include "InternalEvents.h" // Needed for wxEVT_CORE_FINISHED_HTTP_DOWNLOAD
52 #include "muuli_wdr.h" // Needed for IDs
53 #include "PartFile.h" // Needed for CPartFile
54 #include "SearchDlg.h" // Needed for CSearchDlg
55 #include "Server.h" // Needed for GetListName
56 #include "ServerWnd.h" // Needed for CServerWnd
57 #include "SharedFilesCtrl.h" // Needed for CSharedFilesCtrl
58 #include "SharedFilesWnd.h" // Needed for CSharedFilesWnd
59 #include "TransferWnd.h" // Needed for CTransferWnd
60 #include "updownclient.h"
61 #include "ServerListCtrl.h" // Needed for CServerListCtrl
62 #include "ScopedPtr.h"
65 CEConnectDlg::CEConnectDlg()
67 wxDialog(theApp
->amuledlg
, -1, _("Connect to remote amule"), wxDefaultPosition
)
69 CoreConnect(this, true);
71 wxString pref_host
, pref_port
;
72 wxConfig::Get()->Read(wxT("/EC/Host"), &pref_host
, wxT("localhost"));
73 wxConfig::Get()->Read(wxT("/EC/Port"), &pref_port
, wxT("4712"));
74 wxConfig::Get()->Read(wxT("/EC/Password"), &pwd_hash
);
76 CastChild(ID_REMOTE_HOST
, wxTextCtrl
)->SetValue(pref_host
);
77 CastChild(ID_REMOTE_PORT
, wxTextCtrl
)->SetValue(pref_port
);
78 CastChild(ID_EC_PASSWD
, wxTextCtrl
)->SetValue(pwd_hash
);
84 wxString
CEConnectDlg::PassHash()
90 BEGIN_EVENT_TABLE(CEConnectDlg
, wxDialog
)
91 EVT_BUTTON(wxID_OK
, CEConnectDlg::OnOK
)
95 void CEConnectDlg::OnOK(wxCommandEvent
& evt
)
97 wxString s_port
= CastChild(ID_REMOTE_PORT
, wxTextCtrl
)->GetValue();
98 port
= StrToLong(s_port
);
100 host
= CastChild(ID_REMOTE_HOST
, wxTextCtrl
)->GetValue();
101 passwd
= CastChild(ID_EC_PASSWD
, wxTextCtrl
)->GetValue();
103 if (passwd
!= pwd_hash
) {
104 pwd_hash
= MD5Sum(passwd
).GetHash();
106 m_save_user_pass
= CastChild(ID_EC_SAVE
, wxCheckBox
)->IsChecked();
111 DEFINE_LOCAL_EVENT_TYPE(wxEVT_EC_INIT_DONE
)
114 BEGIN_EVENT_TABLE(CamuleRemoteGuiApp
, wxApp
)
116 EVT_TIMER(ID_CORE_TIMER_EVENT
, CamuleRemoteGuiApp::OnPollTimer
)
118 EVT_CUSTOM(wxEVT_EC_CONNECTION
, -1, CamuleRemoteGuiApp::OnECConnection
)
119 EVT_CUSTOM(wxEVT_EC_INIT_DONE
, -1, CamuleRemoteGuiApp::OnECInitDone
)
121 EVT_MULE_NOTIFY(CamuleRemoteGuiApp::OnNotifyEvent
)
123 #ifdef ENABLE_IP2COUNTRY
124 // HTTPDownload finished
125 EVT_MULE_INTERNAL(wxEVT_CORE_FINISHED_HTTP_DOWNLOAD
, -1, CamuleRemoteGuiApp::OnFinishedHTTPDownload
)
130 IMPLEMENT_APP(CamuleRemoteGuiApp
)
133 int CamuleRemoteGuiApp::OnExit()
137 return wxApp::OnExit();
141 void CamuleRemoteGuiApp::OnPollTimer(wxTimerEvent
&)
143 static int request_step
= 0;
145 if (m_connect
->RequestFifoFull()) {
149 switch (request_step
) {
151 serverconnect
->ReQuery();
152 serverlist
->UpdateUserFileStatus(serverconnect
->GetCurrentServer());
156 CECPacket
stats_req(EC_OP_STAT_REQ
);
157 m_connect
->SendRequest(&m_stats_updater
, &stats_req
);
158 amuledlg
->ShowTransferRate();
163 if (amuledlg
->m_sharedfileswnd
->IsShown()) {
164 // update both downloads and shared files
165 knownfiles
->DoRequery(EC_OP_GET_UPDATE
, EC_TAG_KNOWNFILE
);
166 } else if (amuledlg
->m_serverwnd
->IsShown()) {
167 //serverlist->FullReload(EC_OP_GET_SERVER_LIST);
168 } else if (amuledlg
->m_transferwnd
->IsShown()) {
169 // update both downloads and shared files
170 knownfiles
->DoRequery(EC_OP_GET_UPDATE
, EC_TAG_KNOWNFILE
);
171 if (amuledlg
->m_transferwnd
->clientlistctrl
->GetShowing()) {
172 // Kry_GUI Request the client list.
174 amuledlg
->m_transferwnd
->ShowQueueCount(theStats::GetWaitingUserCount());
175 } else if (amuledlg
->m_searchwnd
->IsShown()) {
176 if (searchlist
->m_curr_search
!= -1) {
177 searchlist
->DoRequery(EC_OP_SEARCH_RESULTS
, EC_TAG_SEARCHFILE
);
188 // Check for new links once per second.
189 static uint32 lastED2KLinkCheck
= 0;
190 if (GetTickCount() - lastED2KLinkCheck
>= 1000) {
192 lastED2KLinkCheck
= GetTickCount();
197 void CamuleRemoteGuiApp::OnFinishedHTTPDownload(CMuleInternalEvent
& event
)
199 #ifdef ENABLE_IP2COUNTRY
200 if (event
.GetInt() == HTTP_GeoIP
) {
201 amuledlg
->IP2CountryDownloadFinished(event
.GetExtraLong());
202 // If we updated, the dialog is already up. Redraw it to show the flags.
209 void CamuleRemoteGuiApp::ShutDown(wxCloseEvent
&WXUNUSED(evt
))
211 // Stop the Core Timer
215 // Destroy the EC socket
216 m_connect
->Destroy();
221 amuledlg
->DlgShutDown();
228 bool CamuleRemoteGuiApp::OnInit()
234 theApp
= &wxGetApp();
236 // Handle uncaught exceptions
237 InstallMuleExceptionHandler();
239 // Parse cmdline arguments.
240 if (!InitCommon(AMULE_APP_BASE::argc
, AMULE_APP_BASE::argv
)) {
244 // Create the polling timer
245 poll_timer
= new wxTimer(this,ID_CORE_TIMER_EVENT
);
247 AddLogLineCS(_("Fatal Error: Failed to create Poll Timer"));
251 m_connect
= new CRemoteConnect(this);
253 glob_prefs
= new CPreferencesRem(m_connect
);
255 wxConfig::Get()->Read(wxT("/EC/ZLIB"), &enableZLIB
, 1);
256 m_connect
->SetCapabilities(enableZLIB
!= 0, true, false); // ZLIB, UTF8 numbers, notification
258 InitCustomLanguages();
259 InitLocale(m_locale
, StrLang2wx(thePrefs::GetLanguageID()));
261 if (ShowConnectionDialog()) {
262 AddLogLineNS(_("Going to event loop..."));
270 bool CamuleRemoteGuiApp::CryptoAvailable() const
272 return thePrefs::IsSecureIdentEnabled(); // good enough
276 bool CamuleRemoteGuiApp::ShowConnectionDialog()
278 dialog
= new CEConnectDlg
;
280 if (m_skipConnectionDialog
) {
283 } else if (dialog
->ShowModal() != wxID_OK
) {
288 AddLogLineNS(_("Connecting..."));
289 if (!m_connect
->ConnectToCore(dialog
->Host(), dialog
->Port(),
290 dialog
->Login(), dialog
->PassHash(),
291 wxT("amule-remote"), wxT("0x0001"))) {
292 wxMessageBox(_("Connection failed "),_("ERROR"),wxOK
);
301 void CamuleRemoteGuiApp::OnECConnection(wxEvent
& event
) {
302 wxECSocketEvent
& evt
= *((wxECSocketEvent
*)&event
);
303 AddLogLineNS(_("Remote GUI EC event handler"));
304 wxString reply
= evt
.GetServerReply();
306 if (evt
.GetResult() == true) {
307 // Connected - go to next init step
308 glob_prefs
->LoadRemote();
310 AddLogLineNS(_("Going down"));
311 if (dialog
) { // connect failed
313 (CFormat(_("Connection Failed. Unable to connect to %s:%d\n")) % dialog
->Host() % dialog
->Port()) + reply
,
315 } else { // server disconnected (probably terminated) later
316 wxMessageBox(_("Connection closed - aMule has terminated probably."), _("ERROR"), wxOK
);
323 void CamuleRemoteGuiApp::OnECInitDone(wxEvent
& )
329 void CamuleRemoteGuiApp::OnNotifyEvent(CMuleGUIEvent
& evt
)
335 void CamuleRemoteGuiApp::Startup() {
337 if (dialog
->SaveUserPass()) {
338 wxConfig::Get()->Write(wxT("/EC/Host"), dialog
->Host());
339 wxConfig::Get()->Write(wxT("/EC/Port"), dialog
->Port());
340 wxConfig::Get()->Write(wxT("/EC/Password"), dialog
->PassHash());
348 serverconnect
= new CServerConnectRem(m_connect
);
349 m_statistics
= new CStatistics(*m_connect
);
351 clientlist
= new CUpDownClientListRem(m_connect
);
352 searchlist
= new CSearchListRem(m_connect
);
353 serverlist
= new CServerListRem(m_connect
);
355 sharedfiles
= new CSharedFilesRem(m_connect
);
356 knownfiles
= new CKnownFilesRem(m_connect
);
358 downloadqueue
= new CDownQueueRem(m_connect
);
359 ipfilter
= new CIPFilterRem(m_connect
);
361 // Create main dialog
362 InitGui(m_geometryEnabled
, m_geometryString
);
364 // Forward wxLog events to CLogger
365 wxLog::SetActiveTarget(new CLoggerTarget
);
366 serverlist
->FullReload(EC_OP_GET_SERVER_LIST
);
367 knownfiles
->DoRequery(EC_OP_GET_UPDATE
, EC_TAG_KNOWNFILE
);
369 // Start the Poll Timer
370 poll_timer
->Start(1000);
371 amuledlg
->StartGuiTimer();
373 // Now activate GeoIP, so that the download dialog doesn't get destroyed immediately
374 #ifdef ENABLE_IP2COUNTRY
375 if (thePrefs::IsGeoIPEnabled()) {
376 amuledlg
->m_IP2Country
->Enable();
382 int CamuleRemoteGuiApp::ShowAlert(wxString msg
, wxString title
, int flags
)
384 return CamuleGuiBase::ShowAlert(msg
, title
, flags
);
388 void CamuleRemoteGuiApp::AddRemoteLogLine(const wxString
& line
)
390 amuledlg
->AddLogLine(line
);
393 int CamuleRemoteGuiApp::InitGui(bool geometry_enabled
, wxString
&geom_string
)
395 CamuleGuiBase::InitGui(geometry_enabled
, geom_string
);
396 SetTopWindow(amuledlg
);
397 AddLogLineN(_("Ready")); // The first log line after the window is up triggers output of all the ones before
402 bool CamuleRemoteGuiApp::CopyTextToClipboard(wxString strText
)
404 return CamuleGuiBase::CopyTextToClipboard(strText
);
408 uint32
CamuleRemoteGuiApp::GetPublicIP()
414 wxString
CamuleRemoteGuiApp::GetLog(bool reset
)
417 amuledlg
->ResetLog(ID_LOGVIEW
);
418 CECPacket
req(EC_OP_RESET_LOG
);
419 m_connect
->SendPacket(&req
);
421 return wxEmptyString
;
425 wxString
CamuleRemoteGuiApp::GetServerLog(bool)
427 return wxEmptyString
;
431 bool CamuleRemoteGuiApp::AddServer(CServer
* server
, bool)
433 CECPacket
req(EC_OP_SERVER_ADD
);
434 req
.AddTag(CECTag(EC_TAG_SERVER_ADDRESS
, CFormat(wxT("%s:%d")) % server
->GetAddress() % server
->GetPort()));
435 req
.AddTag(CECTag(EC_TAG_SERVER_NAME
, server
->GetListName()));
436 m_connect
->SendPacket(&req
);
438 serverlist
->FullReload(EC_OP_GET_SERVER_LIST
);
444 bool CamuleRemoteGuiApp::IsFirewalled() const
446 if (IsConnectedED2K() && !serverconnect
->IsLowID()) {
450 return IsFirewalledKad();
454 bool CamuleRemoteGuiApp::IsConnectedED2K() const {
455 return serverconnect
&& serverconnect
->IsConnected();
459 void CamuleRemoteGuiApp::StartKad() {
460 m_connect
->StartKad();
464 void CamuleRemoteGuiApp::StopKad() {
465 m_connect
->StopKad();
469 void CamuleRemoteGuiApp::BootstrapKad(uint32 ip
, uint16 port
)
471 CECPacket
req(EC_OP_KAD_BOOTSTRAP_FROM_IP
);
472 req
.AddTag(CECTag(EC_TAG_BOOTSTRAP_IP
, ip
));
473 req
.AddTag(CECTag(EC_TAG_BOOTSTRAP_PORT
, port
));
475 m_connect
->SendPacket(&req
);
479 void CamuleRemoteGuiApp::UpdateNotesDat(const wxString
& url
)
481 CECPacket
req(EC_OP_KAD_UPDATE_FROM_URL
);
482 req
.AddTag(CECTag(EC_TAG_KADEMLIA_UPDATE_URL
, url
));
484 m_connect
->SendPacket(&req
);
488 void CamuleRemoteGuiApp::DisconnectED2K() {
489 if (IsConnectedED2K()) {
490 m_connect
->DisconnectED2K();
495 uint32
CamuleRemoteGuiApp::GetED2KID() const
497 return serverconnect
? serverconnect
->GetClientID() : 0;
501 uint32
CamuleRemoteGuiApp::GetID() const
507 void CamuleRemoteGuiApp::ShowUserCount() {
510 static const wxString s_singlenetstatusformat
= _("Users: %s | Files: %s");
511 static const wxString s_bothnetstatusformat
= _("Users: E: %s K: %s | Files: E: %s K: %s");
513 if (thePrefs::GetNetworkED2K() && thePrefs::GetNetworkKademlia()) {
514 buffer
= CFormat(s_bothnetstatusformat
) % CastItoIShort(theStats::GetED2KUsers()) % CastItoIShort(theStats::GetKadUsers()) % CastItoIShort(theStats::GetED2KFiles()) % CastItoIShort(theStats::GetKadFiles());
515 } else if (thePrefs::GetNetworkED2K()) {
516 buffer
= CFormat(s_singlenetstatusformat
) % CastItoIShort(theStats::GetED2KUsers()) % CastItoIShort(theStats::GetED2KFiles());
517 } else if (thePrefs::GetNetworkKademlia()) {
518 buffer
= CFormat(s_singlenetstatusformat
) % CastItoIShort(theStats::GetKadUsers()) % CastItoIShort(theStats::GetKadFiles());
520 buffer
= _("No networks selected");
523 Notify_ShowUserCount(buffer
);
528 * Preferences: holds both local and remote settings.
530 * First, everything is loaded from local config file. Later, settings
531 * that are relevant on remote side only are loaded thru EC
533 CPreferencesRem::CPreferencesRem(CRemoteConnect
*conn
)
538 // Settings queried from remote side
540 m_exchange_send_selected_prefs
=
542 EC_PREFS_CONNECTIONS
|
543 EC_PREFS_MESSAGEFILTER
|
548 EC_PREFS_DIRECTORIES
|
550 EC_PREFS_CORETWEAKS
|
551 EC_PREFS_REMOTECONTROLS
|
553 m_exchange_recv_selected_prefs
=
554 m_exchange_send_selected_prefs
|
559 void CPreferencesRem::HandlePacket(const CECPacket
*packet
)
561 ((CEC_Prefs_Packet
*)packet
)->Apply();
563 const CECTag
*cat_tags
= packet
->GetTagByName(EC_TAG_PREFS_CATEGORIES
);
565 for (CECTag::const_iterator it
= cat_tags
->begin(); it
!= cat_tags
->end(); it
++) {
566 const CECTag
&cat_tag
= *it
;
567 Category_Struct
*cat
= new Category_Struct
;
568 cat
->title
= cat_tag
.GetTagByName(EC_TAG_CATEGORY_TITLE
)->GetStringData();
569 cat
->path
= CPath(cat_tag
.GetTagByName(EC_TAG_CATEGORY_PATH
)->GetStringData());
570 cat
->comment
= cat_tag
.GetTagByName(EC_TAG_CATEGORY_COMMENT
)->GetStringData();
571 cat
->color
= cat_tag
.GetTagByName(EC_TAG_CATEGORY_COLOR
)->GetInt();
572 cat
->prio
= cat_tag
.GetTagByName(EC_TAG_CATEGORY_PRIO
)->GetInt();
573 theApp
->glob_prefs
->AddCat(cat
);
576 Category_Struct
*cat
= new Category_Struct
;
577 cat
->title
= _("All");
579 cat
->prio
= PR_NORMAL
;
580 theApp
->glob_prefs
->AddCat(cat
);
582 wxECInitDoneEvent event
;
583 theApp
->AddPendingEvent(event
);
588 bool CPreferencesRem::LoadRemote()
591 // override local settings with remote
592 CECPacket
req(EC_OP_GET_PREFERENCES
, EC_DETAIL_UPDATE
);
594 // bring categories too
595 req
.AddTag(CECTag(EC_TAG_SELECT_PREFS
, m_exchange_recv_selected_prefs
));
597 m_conn
->SendRequest(this, &req
);
603 void CPreferencesRem::SendToRemote()
605 CEC_Prefs_Packet
pref_packet(m_exchange_send_selected_prefs
, EC_DETAIL_UPDATE
, EC_DETAIL_FULL
);
606 m_conn
->SendPacket(&pref_packet
);
610 class CCatHandler
: public CECPacketHandlerBase
{
611 virtual void HandlePacket(const CECPacket
*packet
);
615 void CCatHandler::HandlePacket(const CECPacket
*packet
)
617 if (packet
->GetOpCode() == EC_OP_FAILED
) {
618 const CECTag
* catTag
= packet
->GetTagByName(EC_TAG_CATEGORY
);
619 const CECTag
* pathTag
= packet
->GetTagByName(EC_TAG_CATEGORY_PATH
);
620 if (catTag
&& pathTag
&& catTag
->GetInt() < theApp
->glob_prefs
->GetCatCount()) {
621 int cat
= catTag
->GetInt();
622 Category_Struct
* cs
= theApp
->glob_prefs
->GetCategory(cat
);
623 wxMessageBox(CFormat(_("Can't create directory '%s' for category '%s', keeping directory '%s'."))
624 % cs
->path
.GetPrintable() % cs
->title
% pathTag
->GetStringData(),
626 cs
->path
= CPath(pathTag
->GetStringData());
627 theApp
->amuledlg
->m_transferwnd
->UpdateCategory(cat
);
628 theApp
->amuledlg
->m_transferwnd
->downloadlistctrl
->Refresh();
635 bool CPreferencesRem::CreateCategory(
636 Category_Struct
*& category
,
637 const wxString
& name
,
639 const wxString
& comment
,
643 CECPacket
req(EC_OP_CREATE_CATEGORY
);
644 CEC_Category_Tag
tag(0xffffffff, name
, path
.GetRaw(), comment
, color
, prio
);
646 m_conn
->SendRequest(new CCatHandler
, &req
);
648 category
= new Category_Struct();
649 category
->path
= path
;
650 category
->title
= name
;
651 category
->comment
= comment
;
652 category
->color
= color
;
653 category
->prio
= prio
;
661 bool CPreferencesRem::UpdateCategory(
663 const wxString
& name
,
665 const wxString
& comment
,
669 CECPacket
req(EC_OP_UPDATE_CATEGORY
);
670 CEC_Category_Tag
tag(cat
, name
, path
.GetRaw(), comment
, color
, prio
);
672 m_conn
->SendRequest(new CCatHandler
, &req
);
674 Category_Struct
*category
= m_CatList
[cat
];
675 category
->path
= path
;
676 category
->title
= name
;
677 category
->comment
= comment
;
678 category
->color
= color
;
679 category
->prio
= prio
;
685 void CPreferencesRem::RemoveCat(uint8 cat
)
687 CECPacket
req(EC_OP_DELETE_CATEGORY
);
688 CEC_Category_Tag
tag(cat
, EC_DETAIL_CMD
);
690 m_conn
->SendPacket(&req
);
691 CPreferences::RemoveCat(cat
);
696 // Container implementation
698 CServerConnectRem::CServerConnectRem(CRemoteConnect
*conn
)
705 void CServerConnectRem::ConnectToAnyServer()
707 CECPacket
req(EC_OP_SERVER_CONNECT
);
708 m_Conn
->SendPacket(&req
);
712 void CServerConnectRem::StopConnectionTry()
714 // lfroen: isn't Disconnect the same ?
718 void CServerConnectRem::Disconnect()
720 CECPacket
req(EC_OP_SERVER_DISCONNECT
);
721 m_Conn
->SendPacket(&req
);
725 void CServerConnectRem::ConnectToServer(CServer
*server
)
727 m_Conn
->ConnectED2K(server
->GetIP(), server
->GetPort());
731 bool CServerConnectRem::ReQuery()
733 CECPacket
stat_req(EC_OP_GET_CONNSTATE
);
734 m_Conn
->SendRequest(this, &stat_req
);
740 void CServerConnectRem::HandlePacket(const CECPacket
*packet
)
742 CEC_ConnState_Tag
*tag
=
743 (CEC_ConnState_Tag
*)packet
->GetTagByName(EC_TAG_CONNSTATE
);
748 theApp
->m_ConnState
= 0;
750 m_ID
= tag
->GetEd2kId();
751 theApp
->m_clientID
= tag
->GetClientId();
753 if (tag
->IsConnectedED2K()) {
754 CECTag
*srvtag
= tag
->GetTagByName(EC_TAG_SERVER
);
758 server
= theApp
->serverlist
->GetByID(srvtag
->GetIPv4Data().IP());
759 if (m_CurrServer
&& (server
!= m_CurrServer
)) {
760 theApp
->amuledlg
->m_serverwnd
->serverlistctrl
->
761 HighlightServer(m_CurrServer
, false);
763 theApp
->amuledlg
->m_serverwnd
->serverlistctrl
->
764 HighlightServer(server
, true);
765 m_CurrServer
= server
;
766 theApp
->m_ConnState
|= CONNECTED_ED2K
;
768 if ( m_CurrServer
) {
769 theApp
->amuledlg
->m_serverwnd
->serverlistctrl
->
770 HighlightServer(m_CurrServer
, false);
775 if (tag
->IsConnectedKademlia()) {
776 if (tag
->IsKadFirewalled()) {
777 theApp
->m_ConnState
|= CONNECTED_KAD_FIREWALLED
;
779 theApp
->m_ConnState
|= CONNECTED_KAD_OK
;
782 if (tag
->IsKadRunning()) {
783 theApp
->m_ConnState
|= CONNECTED_KAD_NOT
;
787 theApp
->amuledlg
->ShowConnectionState();
792 * Server list: host list of ed2k servers.
794 CServerListRem::CServerListRem(CRemoteConnect
*conn
)
796 CRemoteContainer
<CServer
, uint32
, CEC_Server_Tag
>(conn
, false)
801 void CServerListRem::HandlePacket(const CECPacket
*packet
)
803 CRemoteContainer
<CServer
, uint32
, CEC_Server_Tag
>::HandlePacket(packet
);
808 void CServerListRem::UpdateServerMetFromURL(wxString url
)
810 CECPacket
req(EC_OP_SERVER_UPDATE_FROM_URL
);
811 req
.AddTag(CECTag(EC_TAG_SERVERS_UPDATE_URL
, url
));
813 m_conn
->SendPacket(&req
);
817 void CServerListRem::SaveServerMet()
819 // lfroen: stub, nothing to do
823 void CServerListRem::FilterServers()
830 void CServerListRem::RemoveServer(CServer
* server
)
832 m_conn
->RemoveServer(server
->GetIP(),server
->GetPort());
836 void CServerListRem::UpdateUserFileStatus(CServer
*server
)
839 m_TotalUser
= server
->GetUsers();
840 m_TotalFile
= server
->GetFiles();
845 CServer
*CServerListRem::GetServerByAddress(const wxString
& WXUNUSED(address
), uint16
WXUNUSED(port
)) const
847 // It's ok to return 0 for context where this code is used in remote gui
851 CServer
*CServerListRem::GetServerByIPTCP(uint32
WXUNUSED(nIP
), uint16
WXUNUSED(nPort
)) const
853 // It's ok to return 0 for context where this code is used in remote gui
857 CServer
*CServerListRem::CreateItem(CEC_Server_Tag
*tag
)
859 return new CServer(tag
);
863 void CServerListRem::DeleteItem(CServer
*in_srv
)
865 CScopedPtr
<CServer
> srv(in_srv
);
866 theApp
->amuledlg
->m_serverwnd
->serverlistctrl
->RemoveServer(srv
.get());
870 uint32
CServerListRem::GetItemID(CServer
*server
)
872 return server
->GetIP();
876 void CServerListRem::ProcessItemUpdate(CEC_Server_Tag
*, CServer
*)
878 // server list is always realoaded from scratch
883 void CServerListRem::ReloadControl()
885 for(iterator it
= begin(); it
!= end(); it
++) {
887 theApp
->amuledlg
->m_serverwnd
->serverlistctrl
->RefreshServer(srv
);
892 CIPFilterRem::CIPFilterRem(CRemoteConnect
* conn
)
898 void CIPFilterRem::Reload()
900 CECPacket
req(EC_OP_IPFILTER_RELOAD
);
901 m_conn
->SendPacket(&req
);
905 void CIPFilterRem::Update(wxString url
)
907 CECPacket
req(EC_OP_IPFILTER_UPDATE
);
908 req
.AddTag(CECTag(EC_TAG_STRING
, url
));
910 m_conn
->SendPacket(&req
);
917 CSharedFilesRem::CSharedFilesRem(CRemoteConnect
*conn
)
923 void CSharedFilesRem::Reload(bool, bool)
925 CECPacket
req(EC_OP_SHAREDFILES_RELOAD
);
927 m_conn
->SendPacket(&req
);
931 void CSharedFilesRem::AddFilesFromDirectory(const CPath
& path
)
933 CECPacket
req(EC_OP_SHAREDFILES_ADD_DIRECTORY
);
935 req
.AddTag(CECTag(EC_TAG_PREFS_DIRECTORIES
, path
.GetRaw()));
937 m_conn
->SendPacket(&req
);
941 bool CSharedFilesRem::RenameFile(CKnownFile
* file
, const CPath
& newName
)
943 // We use the printable name, as the filename originated from user input,
944 // and the filesystem name might not be valid on the remote host.
945 const wxString strNewName
= newName
.GetPrintable();
947 CECPacket
request(EC_OP_RENAME_FILE
);
948 request
.AddTag(CECTag(EC_TAG_KNOWNFILE
, file
->GetFileHash()));
949 request
.AddTag(CECTag(EC_TAG_PARTFILE_NAME
, strNewName
));
951 m_conn
->SendPacket(&request
);
957 void CKnownFilesRem::DeleteItem(CKnownFile
* file
)
959 uint32 id
= file
->ECID();
960 if (theApp
->sharedfiles
->count(id
)) {
961 theApp
->amuledlg
->m_sharedfileswnd
->sharedfilesctrl
->RemoveFile(file
);
962 theApp
->sharedfiles
->erase(id
);
964 if (theApp
->downloadqueue
->count(id
)) {
965 theApp
->amuledlg
->m_transferwnd
->downloadlistctrl
->RemoveFile((CPartFile
*) file
);
966 theApp
->downloadqueue
->erase(id
);
972 uint32
CKnownFilesRem::GetItemID(CKnownFile
*file
)
978 void CKnownFilesRem::ProcessItemUpdate(CEC_SharedFile_Tag
*tag
, CKnownFile
*file
)
980 CECTag
*parttag
= tag
->GetTagByName(EC_TAG_PARTFILE_PART_STATUS
);
982 const uint8
*data
= file
->m_partStatus
.Decode(
983 (uint8
*)parttag
->GetTagData(),
984 parttag
->GetTagDataLen());
985 for(int i
= 0; i
< file
->GetPartCount(); ++i
) {
986 file
->m_AvailPartFrequency
[i
] = data
[i
];
990 if (tag
->FileName(fileName
)) {
991 file
->SetFileName(CPath(fileName
));
993 if (tag
->FilePath(fileName
)) {
994 file
->m_filePath
= CPath(fileName
);
996 tag
->UpPrio(&file
->m_iUpPriorityEC
);
997 tag
->GetAICHHash(file
->m_AICHMasterHash
);
998 tag
->GetRequests(&file
->statistic
.requested
);
999 tag
->GetAllRequests(&file
->statistic
.alltimerequested
);
1000 tag
->GetAccepts(&file
->statistic
.accepted
);
1001 tag
->GetAllAccepts(&file
->statistic
.alltimeaccepted
);
1002 tag
->GetXferred(&file
->statistic
.transferred
);
1003 tag
->GetAllXferred(&file
->statistic
.alltimetransferred
);
1004 tag
->UpPrio(&file
->m_iUpPriorityEC
);
1005 if (file
->m_iUpPriorityEC
>= 10) {
1006 file
->m_iUpPriority
= file
->m_iUpPriorityEC
- 10;
1007 file
->m_bAutoUpPriority
= true;
1009 file
->m_iUpPriority
= file
->m_iUpPriorityEC
;
1010 file
->m_bAutoUpPriority
= false;
1012 tag
->GetCompleteSourcesLow(&file
->m_nCompleteSourcesCountLo
);
1013 tag
->GetCompleteSourcesHigh(&file
->m_nCompleteSourcesCountHi
);
1014 tag
->GetCompleteSources(&file
->m_nCompleteSourcesCount
);
1016 tag
->GetOnQueue(&file
->m_queuedCount
);
1018 requested
+= file
->statistic
.requested
;
1019 transferred
+= file
->statistic
.transferred
;
1020 accepted
+= file
->statistic
.transferred
;
1022 theApp
->amuledlg
->m_sharedfileswnd
->sharedfilesctrl
->UpdateItem(file
);
1024 if (file
->IsPartFile()) {
1025 ProcessItemUpdatePartfile((CEC_PartFile_Tag
*) tag
, (CPartFile
*) file
);
1029 void CSharedFilesRem::SetFilePrio(CKnownFile
*file
, uint8 prio
)
1031 CECPacket
req(EC_OP_SHARED_SET_PRIO
);
1033 CECTag
hashtag(EC_TAG_PARTFILE
, file
->GetFileHash());
1034 hashtag
.AddTag(CECTag(EC_TAG_PARTFILE_PRIO
, prio
));
1036 req
.AddTag(hashtag
);
1038 m_conn
->SendPacket(&req
);
1041 void CKnownFilesRem::ProcessUpdate(const CECTag
*reply
, CECPacket
*, int)
1047 std::set
<uint32
> core_files
;
1048 for (CECPacket::const_iterator it
= reply
->begin(); it
!= reply
->end(); it
++) {
1049 const CECTag
* curTag
= &*it
;
1050 ec_tagname_t tagname
= curTag
->GetTagName();
1051 if (tagname
== EC_TAG_CLIENT
) {
1052 theApp
->clientlist
->ProcessUpdate(curTag
, NULL
, EC_TAG_CLIENT
);
1053 } else if (tagname
== EC_TAG_KNOWNFILE
|| tagname
== EC_TAG_PARTFILE
) {
1054 CEC_SharedFile_Tag
*tag
= (CEC_SharedFile_Tag
*) curTag
;
1055 uint32 id
= tag
->ID();
1056 core_files
.insert(id
);
1057 if ( m_items_hash
.count(id
) ) {
1058 // Item already known: update it
1059 ProcessItemUpdate(tag
, m_items_hash
[id
]);
1061 CKnownFile
* newFile
;
1062 if (tag
->GetTagName() == EC_TAG_PARTFILE
) {
1063 CPartFile
*file
= new CPartFile((CEC_PartFile_Tag
*) tag
);
1064 ProcessItemUpdate(tag
, file
);
1065 // GUI doesn't allow clear finished files well at the moment,
1066 // so don't show finished files for now until GUI gets unlocked.
1067 // Files completing while GUI is open will still show.
1068 if (file
->IsPartFile()) {
1069 (*theApp
->downloadqueue
)[id
] = file
;
1070 theApp
->amuledlg
->m_transferwnd
->downloadlistctrl
->AddFile(file
);
1074 newFile
= new CKnownFile(tag
);
1075 ProcessItemUpdate(tag
, newFile
);
1076 (*theApp
->sharedfiles
)[id
] = newFile
;
1077 theApp
->amuledlg
->m_sharedfileswnd
->sharedfilesctrl
->ShowFile(newFile
);
1083 // remove items no longer present
1084 for(iterator it
= begin(); it
!= end();) {
1085 iterator it2
= it
++;
1086 if (!core_files
.count(GetItemID(*it2
))) {
1087 RemoveItem(it2
); // This calls DeleteItem, where it is removed from lists and views.
1092 CKnownFilesRem::CKnownFilesRem(CRemoteConnect
* conn
) : CRemoteContainer
<CKnownFile
, uint32
, CEC_SharedFile_Tag
>(conn
, true)
1101 * List of uploading and waiting clients.
1103 CUpDownClientListRem::CUpDownClientListRem(CRemoteConnect
*conn
)
1105 CRemoteContainer
<CUpDownClient
, uint32
, CEC_UpDownClient_Tag
>(conn
, true)
1110 CUpDownClient::CUpDownClient(CEC_UpDownClient_Tag
*tag
) : CECID(tag
->ID())
1112 // Clients start up empty, then get asked for their data.
1113 // So all data here is processed in ProcessItemUpdate and thus updatable.
1114 m_bRemoteQueueFull
= false;
1115 m_nUserIDHybrid
= 0;
1117 m_bEmuleProtocol
= false;
1129 m_waitingPosition
= 0;
1131 m_identState
= IS_NOTAVAILABLE
;
1132 m_obfuscationStatus
= 0;
1134 m_nSourceFrom
= SF_NONE
;
1138 m_nCurSessionUp
= 0;
1140 m_uploadingfile
= NULL
;
1141 m_lastDownloadingPart
= 0xffff;
1142 m_nextRequestedPart
= 0xffff;
1144 credits
= new CClientCredits(new CreditStruct());
1147 /* Warning: do common base */
1150 bool CUpDownClient::IsIdentified() const
1152 return m_identState
== IS_IDENTIFIED
;
1156 bool CUpDownClient::IsBadGuy() const
1158 return m_identState
== IS_IDBADGUY
;
1162 bool CUpDownClient::SUIFailed() const
1164 return m_identState
== IS_IDFAILED
;
1168 bool CUpDownClient::SUINeeded() const
1170 return m_identState
== IS_IDNEEDED
;
1174 bool CUpDownClient::SUINotSupported() const
1176 return m_identState
== IS_NOTAVAILABLE
;
1180 uint64
CUpDownClient::GetDownloadedTotal() const
1182 return credits
->GetDownloadedTotal();
1186 uint64
CUpDownClient::GetUploadedTotal() const
1188 return credits
->GetUploadedTotal();
1192 double CUpDownClient::GetScoreRatio() const
1194 return credits
->GetScoreRatio(GetIP(), theApp
->CryptoAvailable());
1200 CUpDownClient::~CUpDownClient()
1206 CUpDownClient
*CUpDownClientListRem::CreateItem(CEC_UpDownClient_Tag
*tag
)
1208 CUpDownClient
*client
= new CUpDownClient(tag
);
1209 ProcessItemUpdate(tag
, client
);
1210 if (client
->m_reqfile
) {
1211 Notify_SourceCtrlAddSource(client
->m_reqfile
, client
, A4AF_SOURCE
);
1218 void CUpDownClientListRem::DeleteItem(CUpDownClient
*client
)
1220 if (client
->m_reqfile
) {
1221 Notify_SourceCtrlRemoveSource(client
, client
->m_reqfile
);
1222 client
->m_reqfile
->DelSource(client
);
1223 client
->m_reqfile
= NULL
;
1229 uint32
CUpDownClientListRem::GetItemID(CUpDownClient
*client
)
1231 return client
->ECID();
1235 void CUpDownClientListRem::ProcessItemUpdate(
1236 CEC_UpDownClient_Tag
*tag
,
1237 CUpDownClient
*client
)
1239 if (!tag
->HasChildTags()) {
1240 return; // speed exit for clients without any change
1242 tag
->UserID(&client
->m_nUserIDHybrid
);
1243 tag
->ClientName(&client
->m_Username
);
1245 bool sw_updated
= false;
1246 if (tag
->ClientSoftware(client
->m_clientSoft
)) {
1247 client
->m_clientVersionString
= GetSoftName(client
->m_clientSoft
);
1248 client
->m_clientSoftString
= client
->m_clientVersionString
;
1251 if (tag
->SoftVerStr(client
->m_clientVerString
) || sw_updated
) {
1252 if (client
->m_clientVersionString
== _("Unknown")) {
1253 client
->m_fullClientVerString
= client
->m_clientVersionString
;
1255 client
->m_fullClientVerString
= client
->m_clientVersionString
+ wxT(" ") + client
->m_clientVerString
;
1259 tag
->UserHash(&client
->m_UserHash
);
1262 if (tag
->UserIP(client
->m_dwUserIP
)) {
1263 client
->m_nConnectIP
= client
->m_dwUserIP
;
1264 client
->m_FullUserIP
= client
->m_dwUserIP
;
1266 tag
->UserPort(&client
->m_nUserPort
);
1269 tag
->ServerIP(&client
->m_dwServerIP
);
1270 tag
->ServerPort(&client
->m_nServerPort
);
1271 tag
->ServerName(&client
->m_ServerName
);
1273 tag
->KadPort(client
->m_nKadPort
);
1275 tag
->GetCurrentIdentState(&client
->m_identState
);
1276 tag
->ObfuscationStatus(client
->m_obfuscationStatus
);
1277 tag
->HasExtendedProtocol(&client
->m_bEmuleProtocol
);
1279 tag
->WaitingPosition(&client
->m_waitingPosition
);
1280 tag
->RemoteQueueRank(&client
->m_nRemoteQueueRank
);
1281 client
->m_bRemoteQueueFull
= client
->m_nRemoteQueueRank
== 0xffff;
1282 tag
->OldRemoteQueueRank(&client
->m_nOldRemoteQueueRank
);
1283 tag
->AskedCount(&client
->m_cAsked
);
1285 tag
->ClientDownloadState(&client
->m_nDownloadState
);
1286 tag
->ClientUploadState(&client
->m_nUploadState
);
1288 tag
->SpeedUp(&client
->m_nUpDatarate
);
1289 if ( client
->m_nDownloadState
== DS_DOWNLOADING
) {
1290 tag
->SpeedDown(&client
->kBpsDown
);
1292 client
->kBpsDown
= 0;
1295 //tag->WaitTime(&client->m_WaitTime);
1296 //tag->XferTime(&client->m_UpStartTimeDelay);
1297 //tag->LastReqTime(&client->m_dwLastUpRequest);
1298 //tag->QueueTime(&client->m_WaitStartTime);
1300 CreditStruct
*credit_struct
=
1301 (CreditStruct
*)client
->credits
->GetDataStruct();
1302 tag
->XferUp(&credit_struct
->uploaded
);
1303 tag
->XferUpSession(&client
->m_nTransferredUp
);
1305 tag
->XferDown(&credit_struct
->downloaded
);
1306 tag
->XferDownSession(&client
->m_nTransferredDown
);
1308 tag
->Score(&client
->m_score
);
1310 tag
->NextRequestedPart(client
->m_nextRequestedPart
);
1311 tag
->LastDownloadingPart(client
->m_lastDownloadingPart
);
1313 uint8 sourceFrom
= 0;
1314 if (tag
->GetSourceFrom(sourceFrom
)) {
1315 client
->m_nSourceFrom
= (ESourceFrom
)sourceFrom
;
1320 bool notified
= false;
1321 if (tag
->RequestFile(fileID
)) {
1322 if (client
->m_reqfile
) {
1323 Notify_SourceCtrlRemoveSource(client
, client
->m_reqfile
);
1324 client
->m_reqfile
->DelSource(client
);
1325 client
->m_reqfile
= NULL
;
1326 client
->m_downPartStatus
.clear();
1328 CKnownFile
* kf
= theApp
->knownfiles
->GetByID(fileID
);
1329 if (kf
&& kf
->IsCPartFile()) {
1330 client
->m_reqfile
= (CPartFile
*) kf
;
1331 client
->m_reqfile
->AddSource(client
);
1332 client
->m_downPartStatus
.setsize(kf
->GetPartCount(), 0);
1333 Notify_SourceCtrlAddSource(client
->m_reqfile
, client
, A4AF_SOURCE
);
1339 CECTag
* partStatusTag
= tag
->GetTagByName(EC_TAG_CLIENT_PART_STATUS
);
1340 if (partStatusTag
) {
1341 if (partStatusTag
->GetTagDataLen() == 0) {
1342 // empty tag means full source
1343 client
->m_downPartStatus
.SetAllTrue();
1344 } else if (partStatusTag
->GetTagDataLen() == client
->m_downPartStatus
.SizeBuffer()) {
1345 client
->m_downPartStatus
.SetBuffer(partStatusTag
->GetTagData());
1350 if (!notified
&& client
->m_reqfile
&& client
->m_reqfile
->ShowSources()) {
1351 SourceItemType type
= A4AF_SOURCE
;
1352 switch (client
->GetDownloadState()) {
1353 case DS_DOWNLOADING
:
1355 // We will send A4AF, which will be checked.
1358 type
= UNAVAILABLE_SOURCE
;
1362 Notify_SourceCtrlUpdateSource(client
, type
);
1366 if (tag
->UploadFile(fileID
)) {
1367 if (client
->m_uploadingfile
) {
1368 client
->m_uploadingfile
->RemoveUploadingClient(client
); // this notifies
1369 client
->m_uploadingfile
= NULL
;
1370 //client->m_downPartStatus.clear();
1372 CKnownFile
* kf
= theApp
->knownfiles
->GetByID(fileID
);
1374 client
->m_uploadingfile
= kf
;
1375 client
->m_uploadingfile
->AddUploadingClient(client
); // this notifies
1376 //client->m_downPartStatus.setsize(kf->GetPartCount(), 0);
1383 * Download queue container: hold PartFiles with progress status
1388 bool CDownQueueRem::AddLink(const wxString
&link
, uint8 cat
)
1390 CECPacket
req(EC_OP_ADD_LINK
);
1391 CECTag
link_tag(EC_TAG_STRING
, link
);
1392 link_tag
.AddTag(CECTag(EC_TAG_PARTFILE_CAT
, cat
));
1393 req
.AddTag(link_tag
);
1395 m_conn
->SendPacket(&req
);
1400 void CDownQueueRem::ResetCatParts(int cat
)
1402 // Called when category is deleted. Command will be performed on the remote side,
1403 // but files still should be updated here right away, or drawing errors (colour not available)
1405 for (iterator it
= begin(); it
!= end(); it
++) {
1406 CPartFile
* file
= it
->second
;
1408 if ( file
->GetCategory() == cat
) {
1409 // Reset the category
1410 file
->SetCategory( 0 );
1411 } else if ( file
->GetCategory() > cat
) {
1412 // Set to the new position of the original category
1413 file
->SetCategory( file
->GetCategory() - 1 );
1420 void CKnownFilesRem::ProcessItemUpdatePartfile(CEC_PartFile_Tag
*tag
, CPartFile
*file
)
1425 tag
->Speed(&file
->m_kbpsDown
);
1426 file
->kBpsDown
= file
->m_kbpsDown
/ 1024.0;
1428 tag
->SizeXfer(&file
->transferred
);
1429 tag
->SizeDone(&file
->completedsize
);
1430 tag
->SourceXferCount(&file
->transferingsrc
);
1431 tag
->SourceNotCurrCount(&file
->m_notCurrentSources
);
1432 tag
->SourceCount(&file
->m_source_count
);
1433 tag
->SourceCountA4AF(&file
->m_a4af_source_count
);
1434 tag
->FileStatus(&file
->status
);
1435 tag
->Stopped(&file
->m_stopped
);
1437 tag
->LastSeenComplete(&file
->lastseencomplete
);
1438 tag
->LastDateChanged(&file
->m_lastDateChanged
);
1439 tag
->DownloadActiveTime(&file
->m_nDlActiveTime
);
1440 tag
->AvailablePartCount(&file
->m_availablePartsCount
);
1441 tag
->Shared(&file
->m_isShared
);
1442 tag
->A4AFAuto(file
->m_is_A4AF_auto
);
1444 tag
->GetLostDueToCorruption(&file
->m_iLostDueToCorruption
);
1445 tag
->GetGainDueToCompression(&file
->m_iGainDueToCompression
);
1446 tag
->TotalPacketsSavedDueToICH(&file
->m_iTotalPacketsSavedDueToICH
);
1448 tag
->FileCat(&file
->m_category
);
1450 tag
->DownPrio(&file
->m_iDownPriorityEC
);
1451 if ( file
->m_iDownPriorityEC
>= 10 ) {
1452 file
->m_iDownPriority
= file
->m_iDownPriorityEC
- 10;
1453 file
->m_bAutoDownPriority
= true;
1455 file
->m_iDownPriority
= file
->m_iDownPriorityEC
;
1456 file
->m_bAutoDownPriority
= false;
1459 file
->percentcompleted
= (100.0*file
->GetCompletedSize()) / file
->GetFileSize();
1462 // Copy part/gap status
1464 CECTag
*gaptag
= tag
->GetTagByName(EC_TAG_PARTFILE_GAP_STATUS
);
1465 CECTag
*parttag
= tag
->GetTagByName(EC_TAG_PARTFILE_PART_STATUS
);
1466 CECTag
*reqtag
= tag
->GetTagByName(EC_TAG_PARTFILE_REQ_STATUS
);
1467 if (gaptag
|| parttag
|| reqtag
) {
1468 PartFileEncoderData
&encoder
= file
->m_PartFileEncoderData
;
1471 ArrayOfUInts64 gaps
;
1472 encoder
.DecodeGaps(gaptag
, gaps
);
1473 int gap_size
= gaps
.size() / 2;
1475 file
->m_gaplist
.Init(file
->GetFileSize(), false);
1478 for (int j
= 0; j
< gap_size
; j
++) {
1479 file
->m_gaplist
.AddGap(gaps
[2*j
], gaps
[2*j
+1]);
1483 encoder
.DecodeParts(parttag
, file
->m_SrcpartFrequency
);
1485 wxASSERT (file
->m_SrcpartFrequency
.size() == file
->GetPartCount());
1488 ArrayOfUInts64 reqs
;
1489 encoder
.DecodeReqs(reqtag
, reqs
);
1490 int req_size
= reqs
.size() / 2;
1492 DeleteContents(file
->m_requestedblocks_list
);
1495 for (int j
= 0; j
< req_size
; j
++) {
1496 Requested_Block_Struct
* block
= new Requested_Block_Struct
;
1497 block
->StartOffset
= reqs
[2*j
];
1498 block
->EndOffset
= reqs
[2*j
+1];
1499 file
->m_requestedblocks_list
.push_back(block
);
1504 // Get source names and counts
1505 CECTag
*srcnametag
= tag
->GetTagByName(EC_TAG_PARTFILE_SOURCE_NAMES
);
1507 SourcenameItemMap
&map
= file
->GetSourcenameItemMap();
1508 for (CECTag::const_iterator it
= srcnametag
->begin(); it
!= srcnametag
->end(); it
++) {
1509 uint32 key
= it
->GetInt();
1510 int count
= it
->GetTagByNameSafe(EC_TAG_PARTFILE_SOURCE_NAMES_COUNTS
)->GetInt();
1514 SourcenameItem
&item
= map
[key
];
1516 const CECTag
*nametag
= it
->GetTagByName(EC_TAG_PARTFILE_SOURCE_NAMES
);
1518 item
.name
= nametag
->GetStringData();
1525 CECTag
*commenttag
= tag
->GetTagByName(EC_TAG_PARTFILE_COMMENTS
);
1527 file
->ClearFileRatingList();
1528 for (CECTag::const_iterator it
= commenttag
->begin(); it
!= commenttag
->end(); ) {
1529 wxString u
= (it
++)->GetStringData();
1530 wxString f
= (it
++)->GetStringData();
1531 int r
= (it
++)->GetInt();
1532 wxString c
= (it
++)->GetStringData();
1533 file
->AddFileRatingList(u
, f
, r
, c
);
1535 file
->UpdateFileRatingCommentAvail();
1538 theApp
->amuledlg
->m_transferwnd
->downloadlistctrl
->UpdateItem(file
);
1540 // If file is shared check if it is already listed in shared files.
1541 // If not, add it and show it.
1542 if (file
->IsShared() && !theApp
->sharedfiles
->count(file
->ECID())) {
1543 (*theApp
->sharedfiles
)[file
->ECID()] = file
;
1544 theApp
->amuledlg
->m_sharedfileswnd
->sharedfilesctrl
->ShowFile(file
);
1549 void CDownQueueRem::SendFileCommand(CPartFile
*file
, ec_tagname_t cmd
)
1552 req
.AddTag(CECTag(EC_TAG_PARTFILE
, file
->GetFileHash()));
1554 m_conn
->SendPacket(&req
);
1558 void CDownQueueRem::Prio(CPartFile
*file
, uint8 prio
)
1560 CECPacket
req(EC_OP_PARTFILE_PRIO_SET
);
1562 CECTag
hashtag(EC_TAG_PARTFILE
, file
->GetFileHash());
1563 hashtag
.AddTag(CECTag(EC_TAG_PARTFILE_PRIO
, prio
));
1564 req
.AddTag(hashtag
);
1566 m_conn
->SendPacket(&req
);
1570 void CDownQueueRem::AutoPrio(CPartFile
*file
, bool flag
)
1572 CECPacket
req(EC_OP_PARTFILE_PRIO_SET
);
1574 CECTag
hashtag(EC_TAG_PARTFILE
, file
->GetFileHash());
1576 hashtag
.AddTag(CECTag(EC_TAG_PARTFILE_PRIO
,
1577 (uint8
)(flag
? PR_AUTO
: file
->GetDownPriority())));
1578 req
.AddTag(hashtag
);
1580 m_conn
->SendPacket(&req
);
1584 void CDownQueueRem::Category(CPartFile
*file
, uint8 cat
)
1586 CECPacket
req(EC_OP_PARTFILE_SET_CAT
);
1587 file
->SetCategory(cat
);
1589 CECTag
hashtag(EC_TAG_PARTFILE
, file
->GetFileHash());
1590 hashtag
.AddTag(CECTag(EC_TAG_PARTFILE_CAT
, cat
));
1591 req
.AddTag(hashtag
);
1593 m_conn
->SendPacket(&req
);
1597 void CDownQueueRem::AddSearchToDownload(CSearchFile
* file
, uint8 category
)
1599 CECPacket
req(EC_OP_DOWNLOAD_SEARCH_RESULT
);
1600 CECTag
hashtag(EC_TAG_PARTFILE
, file
->GetFileHash());
1601 hashtag
.AddTag(CECTag(EC_TAG_PARTFILE_CAT
, category
));
1602 req
.AddTag(hashtag
);
1604 m_conn
->SendPacket(&req
);
1608 void CUpDownClientListRem::FilterQueues()
1615 CSearchListRem::CSearchListRem(CRemoteConnect
*conn
) : CRemoteContainer
<CSearchFile
, uint32
, CEC_SearchFile_Tag
>(conn
, true)
1621 wxString
CSearchListRem::StartNewSearch(
1622 uint32
* nSearchID
, SearchType search_type
,
1623 const CSearchList::CSearchParams
& params
)
1625 CECPacket
search_req(EC_OP_SEARCH_START
);
1626 EC_SEARCH_TYPE ec_search_type
= EC_SEARCH_LOCAL
;
1627 switch(search_type
) {
1628 case LocalSearch
: ec_search_type
= EC_SEARCH_LOCAL
; break;
1629 case GlobalSearch
: ec_search_type
= EC_SEARCH_GLOBAL
; break;
1630 case KadSearch
: ec_search_type
= EC_SEARCH_KAD
; break;
1633 CEC_Search_Tag(params
.searchString
, ec_search_type
,
1634 params
.typeText
, params
.extension
, params
.availability
,
1635 params
.minSize
, params
.maxSize
));
1637 m_conn
->SendPacket(&search_req
);
1638 m_curr_search
= *(nSearchID
); // No kad remote search yet.
1642 return wxEmptyString
; // EC reply will have the error mesg is needed.
1646 void CSearchListRem::StopGlobalSearch()
1648 if (m_curr_search
!= -1) {
1649 CECPacket
search_req(EC_OP_SEARCH_STOP
);
1650 m_conn
->SendPacket(&search_req
);
1655 void CSearchListRem::StopKadSearch()
1657 // FIXME implementation needed
1661 void CSearchListRem::HandlePacket(const CECPacket
*packet
)
1663 if ( packet
->GetOpCode() == EC_OP_SEARCH_PROGRESS
) {
1664 CoreNotify_Search_Update_Progress(packet
->GetFirstTagSafe()->GetInt());
1666 CRemoteContainer
<CSearchFile
, uint32
, CEC_SearchFile_Tag
>::HandlePacket(packet
);
1671 CSearchFile::CSearchFile(CEC_SearchFile_Tag
*tag
)
1675 m_showChildren(false),
1677 m_completeSourceCount(0),
1679 m_downloadStatus(NEW
),
1684 SetFileName(CPath(tag
->FileName()));
1685 m_abyFileHash
= tag
->FileHash();
1686 SetFileSize(tag
->SizeFull());
1688 m_searchID
= theApp
->searchlist
->m_curr_search
;
1693 // dtor is virtual - must be implemented
1694 CSearchFile::~CSearchFile()
1699 CSearchFile
*CSearchListRem::CreateItem(CEC_SearchFile_Tag
*tag
)
1701 CSearchFile
*file
= new CSearchFile(tag
);
1702 ProcessItemUpdate(tag
, file
);
1704 theApp
->amuledlg
->m_searchwnd
->AddResult(file
);
1710 void CSearchListRem::DeleteItem(CSearchFile
*file
)
1716 uint32
CSearchListRem::GetItemID(CSearchFile
*file
)
1718 return file
->ECID();
1722 void CSearchListRem::ProcessItemUpdate(CEC_SearchFile_Tag
*tag
, CSearchFile
*file
)
1724 uint32 sourceCount
= file
->m_sourceCount
;
1725 uint32 completeSourceCount
= file
->m_completeSourceCount
;
1726 CSearchFile::DownloadStatus status
= file
->m_downloadStatus
;
1727 tag
->SourceCount(&file
->m_sourceCount
);
1728 tag
->CompleteSourceCount(&file
->m_completeSourceCount
);
1729 tag
->DownloadStatus((uint32
*) &file
->m_downloadStatus
);
1731 if (file
->m_sourceCount
!= sourceCount
1732 || file
->m_completeSourceCount
!= completeSourceCount
1733 || file
->m_downloadStatus
!= status
) {
1734 if (theApp
->amuledlg
&& theApp
->amuledlg
->m_searchwnd
) {
1735 theApp
->amuledlg
->m_searchwnd
->UpdateResult(file
);
1741 bool CSearchListRem::Phase1Done(const CECPacket
*WXUNUSED(reply
))
1743 CECPacket
progress_req(EC_OP_SEARCH_PROGRESS
);
1744 m_conn
->SendRequest(this, &progress_req
);
1750 void CSearchListRem::RemoveResults(long nSearchID
)
1752 ResultMap::iterator it
= m_results
.find(nSearchID
);
1753 if (it
!= m_results
.end()) {
1754 CSearchResultList
& list
= it
->second
;
1755 for (unsigned int i
= 0; i
< list
.size(); ++i
) {
1758 m_results
.erase(it
);
1763 const CSearchResultList
& CSearchListRem::GetSearchResults(long nSearchID
)
1765 ResultMap::const_iterator it
= m_results
.find(nSearchID
);
1766 if (it
!= m_results
.end()) {
1770 // TODO: Should we assert in this case?
1771 static CSearchResultList list
;
1776 void CStatsUpdaterRem::HandlePacket(const CECPacket
*packet
)
1778 theStats::UpdateStats(packet
);
1779 theApp
->ShowUserCount(); // maybe there should be a check if a usercount changed ?
1783 bool CUpDownClient::IsBanned() const
1791 // Those functions have different implementation in remote gui
1793 void CUpDownClient::Ban()
1800 void CUpDownClient::UnBan()
1807 void CUpDownClient::RequestSharedFileList()
1814 void CKnownFile::SetFileComment(const wxString
&)
1817 wxMessageBox(_("Comments and ratings are not supported on remote gui yet"), _("Information"), wxOK
| wxICON_INFORMATION
);
1821 void CKnownFile::SetFileRating(unsigned char)
1827 bool CUpDownClient::SwapToAnotherFile(
1828 bool WXUNUSED(bIgnoreNoNeeded
),
1829 bool WXUNUSED(ignoreSuspensions
),
1830 bool WXUNUSED(bRemoveCompletely
),
1831 CPartFile
* WXUNUSED(toFile
))
1840 // Those functions are virtual. So even they don't get called they must
1841 // be defined so linker will be happy
1843 CPacket
* CKnownFile::CreateSrcInfoPacket(const CUpDownClient
*, uint8
/*byRequestedVersion*/, uint16
/*nRequestedOptions*/)
1850 bool CKnownFile::LoadFromFile(const class CFileDataIO
*)
1857 void CKnownFile::UpdatePartsInfo()
1863 CPacket
* CPartFile::CreateSrcInfoPacket(CUpDownClient
const *, uint8
/*byRequestedVersion*/, uint16
/*nRequestedOptions*/)
1870 void CPartFile::UpdatePartsInfo()
1876 void CPartFile::UpdateFileRatingCommentAvail()
1878 bool prevComment
= m_hasComment
;
1879 int prevRating
= m_iUserRating
;
1881 m_hasComment
= false;
1883 int ratingCount
= 0;
1885 FileRatingList::iterator it
= m_FileRatingList
.begin();
1886 for (; it
!= m_FileRatingList
.end(); ++it
) {
1887 SFileRating
& cur_rat
= *it
;
1889 if (!cur_rat
.Comment
.IsEmpty()) {
1890 m_hasComment
= true;
1893 uint8 rating
= cur_rat
.Rating
;
1895 wxASSERT(rating
<= 5);
1898 m_iUserRating
+= rating
;
1903 m_iUserRating
/= ratingCount
;
1904 wxASSERT(m_iUserRating
> 0 && m_iUserRating
<= 5);
1907 if ((prevComment
!= m_hasComment
) || (prevRating
!= m_iUserRating
)) {
1908 UpdateDisplayedInfo();
1912 bool CPartFile::SavePartFile(bool)
1918 CamuleRemoteGuiApp
*theApp
;
1921 // since gui is not linked with amule.cpp - define events here
1923 DEFINE_LOCAL_EVENT_TYPE(wxEVT_CORE_FINISHED_HTTP_DOWNLOAD
)
1924 DEFINE_LOCAL_EVENT_TYPE(wxEVT_CORE_SOURCE_DNS_DONE
)
1925 DEFINE_LOCAL_EVENT_TYPE(wxEVT_CORE_UDP_DNS_DONE
)
1926 DEFINE_LOCAL_EVENT_TYPE(wxEVT_CORE_SERVER_DNS_DONE
)
1927 // File_checked_for_headers