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)
416 return wxEmptyString
;
420 wxString
CamuleRemoteGuiApp::GetServerLog(bool)
422 return wxEmptyString
;
426 bool CamuleRemoteGuiApp::AddServer(CServer
* server
, bool)
428 CECPacket
req(EC_OP_SERVER_ADD
);
429 req
.AddTag(CECTag(EC_TAG_SERVER_ADDRESS
, CFormat(wxT("%s:%d")) % server
->GetAddress() % server
->GetPort()));
430 req
.AddTag(CECTag(EC_TAG_SERVER_NAME
, server
->GetListName()));
431 m_connect
->SendPacket(&req
);
433 serverlist
->FullReload(EC_OP_GET_SERVER_LIST
);
439 bool CamuleRemoteGuiApp::IsFirewalled() const
441 if (IsConnectedED2K() && !serverconnect
->IsLowID()) {
445 return IsFirewalledKad();
449 bool CamuleRemoteGuiApp::IsConnectedED2K() const {
450 return serverconnect
&& serverconnect
->IsConnected();
454 void CamuleRemoteGuiApp::StartKad() {
455 m_connect
->StartKad();
459 void CamuleRemoteGuiApp::StopKad() {
460 m_connect
->StopKad();
464 void CamuleRemoteGuiApp::BootstrapKad(uint32 ip
, uint16 port
)
466 CECPacket
req(EC_OP_KAD_BOOTSTRAP_FROM_IP
);
467 req
.AddTag(CECTag(EC_TAG_BOOTSTRAP_IP
, ip
));
468 req
.AddTag(CECTag(EC_TAG_BOOTSTRAP_PORT
, port
));
470 m_connect
->SendPacket(&req
);
474 void CamuleRemoteGuiApp::UpdateNotesDat(const wxString
& url
)
476 CECPacket
req(EC_OP_KAD_UPDATE_FROM_URL
);
477 req
.AddTag(CECTag(EC_TAG_KADEMLIA_UPDATE_URL
, url
));
479 m_connect
->SendPacket(&req
);
483 void CamuleRemoteGuiApp::DisconnectED2K() {
484 if (IsConnectedED2K()) {
485 m_connect
->DisconnectED2K();
490 uint32
CamuleRemoteGuiApp::GetED2KID() const
492 return serverconnect
? serverconnect
->GetClientID() : 0;
496 uint32
CamuleRemoteGuiApp::GetID() const
502 void CamuleRemoteGuiApp::ShowUserCount() {
505 static const wxString s_singlenetstatusformat
= _("Users: %s | Files: %s");
506 static const wxString s_bothnetstatusformat
= _("Users: E: %s K: %s | Files: E: %s K: %s");
508 if (thePrefs::GetNetworkED2K() && thePrefs::GetNetworkKademlia()) {
509 buffer
= CFormat(s_bothnetstatusformat
) % CastItoIShort(theStats::GetED2KUsers()) % CastItoIShort(theStats::GetKadUsers()) % CastItoIShort(theStats::GetED2KFiles()) % CastItoIShort(theStats::GetKadFiles());
510 } else if (thePrefs::GetNetworkED2K()) {
511 buffer
= CFormat(s_singlenetstatusformat
) % CastItoIShort(theStats::GetED2KUsers()) % CastItoIShort(theStats::GetED2KFiles());
512 } else if (thePrefs::GetNetworkKademlia()) {
513 buffer
= CFormat(s_singlenetstatusformat
) % CastItoIShort(theStats::GetKadUsers()) % CastItoIShort(theStats::GetKadFiles());
515 buffer
= _("No networks selected");
518 Notify_ShowUserCount(buffer
);
523 * Preferences: holds both local and remote settings.
525 * First, everything is loaded from local config file. Later, settings
526 * that are relevant on remote side only are loaded thru EC
528 CPreferencesRem::CPreferencesRem(CRemoteConnect
*conn
)
533 // Settings queried from remote side
535 m_exchange_send_selected_prefs
=
537 EC_PREFS_CONNECTIONS
|
538 EC_PREFS_MESSAGEFILTER
|
543 EC_PREFS_DIRECTORIES
|
545 EC_PREFS_CORETWEAKS
|
546 EC_PREFS_REMOTECONTROLS
|
548 m_exchange_recv_selected_prefs
=
549 m_exchange_send_selected_prefs
|
554 void CPreferencesRem::HandlePacket(const CECPacket
*packet
)
556 ((CEC_Prefs_Packet
*)packet
)->Apply();
558 const CECTag
*cat_tags
= packet
->GetTagByName(EC_TAG_PREFS_CATEGORIES
);
560 for (CECTag::const_iterator it
= cat_tags
->begin(); it
!= cat_tags
->end(); it
++) {
561 const CECTag
&cat_tag
= *it
;
562 Category_Struct
*cat
= new Category_Struct
;
563 cat
->title
= cat_tag
.GetTagByName(EC_TAG_CATEGORY_TITLE
)->GetStringData();
564 cat
->path
= CPath(cat_tag
.GetTagByName(EC_TAG_CATEGORY_PATH
)->GetStringData());
565 cat
->comment
= cat_tag
.GetTagByName(EC_TAG_CATEGORY_COMMENT
)->GetStringData();
566 cat
->color
= cat_tag
.GetTagByName(EC_TAG_CATEGORY_COLOR
)->GetInt();
567 cat
->prio
= cat_tag
.GetTagByName(EC_TAG_CATEGORY_PRIO
)->GetInt();
568 theApp
->glob_prefs
->AddCat(cat
);
571 Category_Struct
*cat
= new Category_Struct
;
572 cat
->title
= _("All");
574 cat
->prio
= PR_NORMAL
;
575 theApp
->glob_prefs
->AddCat(cat
);
577 wxECInitDoneEvent event
;
578 theApp
->AddPendingEvent(event
);
583 bool CPreferencesRem::LoadRemote()
586 // override local settings with remote
587 CECPacket
req(EC_OP_GET_PREFERENCES
, EC_DETAIL_UPDATE
);
589 // bring categories too
590 req
.AddTag(CECTag(EC_TAG_SELECT_PREFS
, m_exchange_recv_selected_prefs
));
592 m_conn
->SendRequest(this, &req
);
598 void CPreferencesRem::SendToRemote()
600 CEC_Prefs_Packet
pref_packet(m_exchange_send_selected_prefs
, EC_DETAIL_UPDATE
, EC_DETAIL_FULL
);
601 m_conn
->SendPacket(&pref_packet
);
605 class CCatHandler
: public CECPacketHandlerBase
{
606 virtual void HandlePacket(const CECPacket
*packet
);
610 void CCatHandler::HandlePacket(const CECPacket
*packet
)
612 if (packet
->GetOpCode() == EC_OP_FAILED
) {
613 const CECTag
* catTag
= packet
->GetTagByName(EC_TAG_CATEGORY
);
614 const CECTag
* pathTag
= packet
->GetTagByName(EC_TAG_CATEGORY_PATH
);
615 if (catTag
&& pathTag
&& catTag
->GetInt() < theApp
->glob_prefs
->GetCatCount()) {
616 int cat
= catTag
->GetInt();
617 Category_Struct
* cs
= theApp
->glob_prefs
->GetCategory(cat
);
618 wxMessageBox(CFormat(_("Can't create directory '%s' for category '%s', keeping directory '%s'."))
619 % cs
->path
.GetPrintable() % cs
->title
% pathTag
->GetStringData(),
621 cs
->path
= CPath(pathTag
->GetStringData());
622 theApp
->amuledlg
->m_transferwnd
->UpdateCategory(cat
);
623 theApp
->amuledlg
->m_transferwnd
->downloadlistctrl
->Refresh();
630 bool CPreferencesRem::CreateCategory(
631 Category_Struct
*& category
,
632 const wxString
& name
,
634 const wxString
& comment
,
638 CECPacket
req(EC_OP_CREATE_CATEGORY
);
639 CEC_Category_Tag
tag(0xffffffff, name
, path
.GetRaw(), comment
, color
, prio
);
641 m_conn
->SendRequest(new CCatHandler
, &req
);
643 category
= new Category_Struct();
644 category
->path
= path
;
645 category
->title
= name
;
646 category
->comment
= comment
;
647 category
->color
= color
;
648 category
->prio
= prio
;
656 bool CPreferencesRem::UpdateCategory(
658 const wxString
& name
,
660 const wxString
& comment
,
664 CECPacket
req(EC_OP_UPDATE_CATEGORY
);
665 CEC_Category_Tag
tag(cat
, name
, path
.GetRaw(), comment
, color
, prio
);
667 m_conn
->SendRequest(new CCatHandler
, &req
);
669 Category_Struct
*category
= m_CatList
[cat
];
670 category
->path
= path
;
671 category
->title
= name
;
672 category
->comment
= comment
;
673 category
->color
= color
;
674 category
->prio
= prio
;
680 void CPreferencesRem::RemoveCat(uint8 cat
)
682 CECPacket
req(EC_OP_DELETE_CATEGORY
);
683 CEC_Category_Tag
tag(cat
, EC_DETAIL_CMD
);
685 m_conn
->SendPacket(&req
);
686 CPreferences::RemoveCat(cat
);
691 // Container implementation
693 CServerConnectRem::CServerConnectRem(CRemoteConnect
*conn
)
700 void CServerConnectRem::ConnectToAnyServer()
702 CECPacket
req(EC_OP_SERVER_CONNECT
);
703 m_Conn
->SendPacket(&req
);
707 void CServerConnectRem::StopConnectionTry()
709 // lfroen: isn't Disconnect the same ?
713 void CServerConnectRem::Disconnect()
715 CECPacket
req(EC_OP_SERVER_DISCONNECT
);
716 m_Conn
->SendPacket(&req
);
720 void CServerConnectRem::ConnectToServer(CServer
*server
)
722 m_Conn
->ConnectED2K(server
->GetIP(), server
->GetPort());
726 bool CServerConnectRem::ReQuery()
728 CECPacket
stat_req(EC_OP_GET_CONNSTATE
);
729 m_Conn
->SendRequest(this, &stat_req
);
735 void CServerConnectRem::HandlePacket(const CECPacket
*packet
)
737 CEC_ConnState_Tag
*tag
=
738 (CEC_ConnState_Tag
*)packet
->GetTagByName(EC_TAG_CONNSTATE
);
743 theApp
->m_ConnState
= 0;
745 m_ID
= tag
->GetEd2kId();
746 theApp
->m_clientID
= tag
->GetClientId();
748 if (tag
->IsConnectedED2K()) {
749 CECTag
*srvtag
= tag
->GetTagByName(EC_TAG_SERVER
);
753 server
= theApp
->serverlist
->GetByID(srvtag
->GetIPv4Data().IP());
754 if (m_CurrServer
&& (server
!= m_CurrServer
)) {
755 theApp
->amuledlg
->m_serverwnd
->serverlistctrl
->
756 HighlightServer(m_CurrServer
, false);
758 theApp
->amuledlg
->m_serverwnd
->serverlistctrl
->
759 HighlightServer(server
, true);
760 m_CurrServer
= server
;
761 theApp
->m_ConnState
|= CONNECTED_ED2K
;
763 if ( m_CurrServer
) {
764 theApp
->amuledlg
->m_serverwnd
->serverlistctrl
->
765 HighlightServer(m_CurrServer
, false);
770 if (tag
->IsConnectedKademlia()) {
771 if (tag
->IsKadFirewalled()) {
772 theApp
->m_ConnState
|= CONNECTED_KAD_FIREWALLED
;
774 theApp
->m_ConnState
|= CONNECTED_KAD_OK
;
777 if (tag
->IsKadRunning()) {
778 theApp
->m_ConnState
|= CONNECTED_KAD_NOT
;
782 theApp
->amuledlg
->ShowConnectionState();
787 * Server list: host list of ed2k servers.
789 CServerListRem::CServerListRem(CRemoteConnect
*conn
)
791 CRemoteContainer
<CServer
, uint32
, CEC_Server_Tag
>(conn
, false)
796 void CServerListRem::HandlePacket(const CECPacket
*packet
)
798 CRemoteContainer
<CServer
, uint32
, CEC_Server_Tag
>::HandlePacket(packet
);
803 void CServerListRem::UpdateServerMetFromURL(wxString url
)
805 CECPacket
req(EC_OP_SERVER_UPDATE_FROM_URL
);
806 req
.AddTag(CECTag(EC_TAG_SERVERS_UPDATE_URL
, url
));
808 m_conn
->SendPacket(&req
);
812 void CServerListRem::SaveServerMet()
814 // lfroen: stub, nothing to do
818 void CServerListRem::FilterServers()
825 void CServerListRem::RemoveServer(CServer
* server
)
827 m_conn
->RemoveServer(server
->GetIP(),server
->GetPort());
831 void CServerListRem::UpdateUserFileStatus(CServer
*server
)
834 m_TotalUser
= server
->GetUsers();
835 m_TotalFile
= server
->GetFiles();
840 CServer
*CServerListRem::GetServerByAddress(const wxString
& WXUNUSED(address
), uint16
WXUNUSED(port
)) const
842 // It's ok to return 0 for context where this code is used in remote gui
846 CServer
*CServerListRem::GetServerByIPTCP(uint32
WXUNUSED(nIP
), uint16
WXUNUSED(nPort
)) const
848 // It's ok to return 0 for context where this code is used in remote gui
852 CServer
*CServerListRem::CreateItem(CEC_Server_Tag
*tag
)
854 return new CServer(tag
);
858 void CServerListRem::DeleteItem(CServer
*in_srv
)
860 CScopedPtr
<CServer
> srv(in_srv
);
861 theApp
->amuledlg
->m_serverwnd
->serverlistctrl
->RemoveServer(srv
.get());
865 uint32
CServerListRem::GetItemID(CServer
*server
)
867 return server
->GetIP();
871 void CServerListRem::ProcessItemUpdate(CEC_Server_Tag
*, CServer
*)
873 // server list is always realoaded from scratch
878 void CServerListRem::ReloadControl()
880 for(iterator it
= begin(); it
!= end(); it
++) {
882 theApp
->amuledlg
->m_serverwnd
->serverlistctrl
->RefreshServer(srv
);
887 CIPFilterRem::CIPFilterRem(CRemoteConnect
* conn
)
893 void CIPFilterRem::Reload()
895 CECPacket
req(EC_OP_IPFILTER_RELOAD
);
896 m_conn
->SendPacket(&req
);
900 void CIPFilterRem::Update(wxString url
)
902 CECPacket
req(EC_OP_IPFILTER_UPDATE
);
903 req
.AddTag(CECTag(EC_TAG_STRING
, url
));
905 m_conn
->SendPacket(&req
);
912 CSharedFilesRem::CSharedFilesRem(CRemoteConnect
*conn
)
918 void CSharedFilesRem::Reload(bool, bool)
920 CECPacket
req(EC_OP_SHAREDFILES_RELOAD
);
922 m_conn
->SendPacket(&req
);
926 void CSharedFilesRem::AddFilesFromDirectory(const CPath
& path
)
928 CECPacket
req(EC_OP_SHAREDFILES_ADD_DIRECTORY
);
930 req
.AddTag(CECTag(EC_TAG_PREFS_DIRECTORIES
, path
.GetRaw()));
932 m_conn
->SendPacket(&req
);
936 bool CSharedFilesRem::RenameFile(CKnownFile
* file
, const CPath
& newName
)
938 // We use the printable name, as the filename originated from user input,
939 // and the filesystem name might not be valid on the remote host.
940 const wxString strNewName
= newName
.GetPrintable();
942 CECPacket
request(EC_OP_RENAME_FILE
);
943 request
.AddTag(CECTag(EC_TAG_KNOWNFILE
, file
->GetFileHash()));
944 request
.AddTag(CECTag(EC_TAG_PARTFILE_NAME
, strNewName
));
946 m_conn
->SendPacket(&request
);
952 void CKnownFilesRem::DeleteItem(CKnownFile
* file
)
954 uint32 id
= file
->ECID();
955 if (theApp
->sharedfiles
->count(id
)) {
956 theApp
->amuledlg
->m_sharedfileswnd
->sharedfilesctrl
->RemoveFile(file
);
957 theApp
->sharedfiles
->erase(id
);
959 if (theApp
->downloadqueue
->count(id
)) {
960 theApp
->amuledlg
->m_transferwnd
->downloadlistctrl
->RemoveFile((CPartFile
*) file
);
961 theApp
->downloadqueue
->erase(id
);
967 uint32
CKnownFilesRem::GetItemID(CKnownFile
*file
)
973 void CKnownFilesRem::ProcessItemUpdate(CEC_SharedFile_Tag
*tag
, CKnownFile
*file
)
975 CECTag
*parttag
= tag
->GetTagByName(EC_TAG_PARTFILE_PART_STATUS
);
977 const uint8
*data
= file
->m_partStatus
.Decode(
978 (uint8
*)parttag
->GetTagData(),
979 parttag
->GetTagDataLen());
980 for(int i
= 0; i
< file
->GetPartCount(); ++i
) {
981 file
->m_AvailPartFrequency
[i
] = data
[i
];
985 if (tag
->FileName(fileName
)) {
986 file
->SetFileName(CPath(fileName
));
988 if (tag
->FilePath(fileName
)) {
989 file
->m_filePath
= CPath(fileName
);
991 tag
->UpPrio(&file
->m_iUpPriorityEC
);
992 tag
->GetAICHHash(file
->m_AICHMasterHash
);
993 tag
->GetRequests(&file
->statistic
.requested
);
994 tag
->GetAllRequests(&file
->statistic
.alltimerequested
);
995 tag
->GetAccepts(&file
->statistic
.accepted
);
996 tag
->GetAllAccepts(&file
->statistic
.alltimeaccepted
);
997 tag
->GetXferred(&file
->statistic
.transferred
);
998 tag
->GetAllXferred(&file
->statistic
.alltimetransferred
);
999 tag
->UpPrio(&file
->m_iUpPriorityEC
);
1000 if (file
->m_iUpPriorityEC
>= 10) {
1001 file
->m_iUpPriority
= file
->m_iUpPriorityEC
- 10;
1002 file
->m_bAutoUpPriority
= true;
1004 file
->m_iUpPriority
= file
->m_iUpPriorityEC
;
1005 file
->m_bAutoUpPriority
= false;
1007 tag
->GetCompleteSourcesLow(&file
->m_nCompleteSourcesCountLo
);
1008 tag
->GetCompleteSourcesHigh(&file
->m_nCompleteSourcesCountHi
);
1009 tag
->GetCompleteSources(&file
->m_nCompleteSourcesCount
);
1011 tag
->GetOnQueue(&file
->m_queuedCount
);
1013 requested
+= file
->statistic
.requested
;
1014 transferred
+= file
->statistic
.transferred
;
1015 accepted
+= file
->statistic
.transferred
;
1017 theApp
->amuledlg
->m_sharedfileswnd
->sharedfilesctrl
->UpdateItem(file
);
1019 if (file
->IsPartFile()) {
1020 ProcessItemUpdatePartfile((CEC_PartFile_Tag
*) tag
, (CPartFile
*) file
);
1024 void CSharedFilesRem::SetFilePrio(CKnownFile
*file
, uint8 prio
)
1026 CECPacket
req(EC_OP_SHARED_SET_PRIO
);
1028 CECTag
hashtag(EC_TAG_PARTFILE
, file
->GetFileHash());
1029 hashtag
.AddTag(CECTag(EC_TAG_PARTFILE_PRIO
, prio
));
1031 req
.AddTag(hashtag
);
1033 m_conn
->SendPacket(&req
);
1036 void CKnownFilesRem::ProcessUpdate(const CECTag
*reply
, CECPacket
*, int)
1042 std::set
<uint32
> core_files
;
1043 for (CECPacket::const_iterator it
= reply
->begin(); it
!= reply
->end(); it
++) {
1044 const CECTag
* curTag
= &*it
;
1045 ec_tagname_t tagname
= curTag
->GetTagName();
1046 if (tagname
== EC_TAG_CLIENT
) {
1047 theApp
->clientlist
->ProcessUpdate(curTag
, NULL
, EC_TAG_CLIENT
);
1048 } else if (tagname
== EC_TAG_KNOWNFILE
|| tagname
== EC_TAG_PARTFILE
) {
1049 CEC_SharedFile_Tag
*tag
= (CEC_SharedFile_Tag
*) curTag
;
1050 uint32 id
= tag
->ID();
1051 core_files
.insert(id
);
1052 if ( m_items_hash
.count(id
) ) {
1053 // Item already known: update it
1054 ProcessItemUpdate(tag
, m_items_hash
[id
]);
1056 CKnownFile
* newFile
;
1057 if (tag
->GetTagName() == EC_TAG_PARTFILE
) {
1058 CPartFile
*file
= new CPartFile((CEC_PartFile_Tag
*) tag
);
1059 ProcessItemUpdate(tag
, file
);
1060 // GUI doesn't allow clear finished files well at the moment,
1061 // so don't show finished files for now until GUI gets unlocked.
1062 // Files completing while GUI is open will still show.
1063 if (file
->IsPartFile()) {
1064 (*theApp
->downloadqueue
)[id
] = file
;
1065 theApp
->amuledlg
->m_transferwnd
->downloadlistctrl
->AddFile(file
);
1069 newFile
= new CKnownFile(tag
);
1070 ProcessItemUpdate(tag
, newFile
);
1071 (*theApp
->sharedfiles
)[id
] = newFile
;
1072 theApp
->amuledlg
->m_sharedfileswnd
->sharedfilesctrl
->ShowFile(newFile
);
1078 // remove items no longer present
1079 for(iterator it
= begin(); it
!= end();) {
1080 iterator it2
= it
++;
1081 if (!core_files
.count(GetItemID(*it2
))) {
1082 RemoveItem(it2
); // This calls DeleteItem, where it is removed from lists and views.
1087 CKnownFilesRem::CKnownFilesRem(CRemoteConnect
* conn
) : CRemoteContainer
<CKnownFile
, uint32
, CEC_SharedFile_Tag
>(conn
, true)
1096 * List of uploading and waiting clients.
1098 CUpDownClientListRem::CUpDownClientListRem(CRemoteConnect
*conn
)
1100 CRemoteContainer
<CUpDownClient
, uint32
, CEC_UpDownClient_Tag
>(conn
, true)
1105 CUpDownClient::CUpDownClient(CEC_UpDownClient_Tag
*tag
) : CECID(tag
->ID())
1107 // Clients start up empty, then get asked for their data.
1108 // So all data here is processed in ProcessItemUpdate and thus updatable.
1109 m_bRemoteQueueFull
= false;
1110 m_nUserIDHybrid
= 0;
1112 m_bEmuleProtocol
= false;
1124 m_waitingPosition
= 0;
1126 m_identState
= IS_NOTAVAILABLE
;
1127 m_obfuscationStatus
= 0;
1129 m_nSourceFrom
= SF_NONE
;
1133 m_nCurSessionUp
= 0;
1135 m_uploadingfile
= NULL
;
1136 m_lastDownloadingPart
= 0xffff;
1137 m_nextRequestedPart
= 0xffff;
1139 credits
= new CClientCredits(new CreditStruct());
1142 /* Warning: do common base */
1145 bool CUpDownClient::IsIdentified() const
1147 return m_identState
== IS_IDENTIFIED
;
1151 bool CUpDownClient::IsBadGuy() const
1153 return m_identState
== IS_IDBADGUY
;
1157 bool CUpDownClient::SUIFailed() const
1159 return m_identState
== IS_IDFAILED
;
1163 bool CUpDownClient::SUINeeded() const
1165 return m_identState
== IS_IDNEEDED
;
1169 bool CUpDownClient::SUINotSupported() const
1171 return m_identState
== IS_NOTAVAILABLE
;
1175 uint64
CUpDownClient::GetDownloadedTotal() const
1177 return credits
->GetDownloadedTotal();
1181 uint64
CUpDownClient::GetUploadedTotal() const
1183 return credits
->GetUploadedTotal();
1187 double CUpDownClient::GetScoreRatio() const
1189 return credits
->GetScoreRatio(GetIP(), theApp
->CryptoAvailable());
1195 CUpDownClient::~CUpDownClient()
1201 CUpDownClient
*CUpDownClientListRem::CreateItem(CEC_UpDownClient_Tag
*tag
)
1203 CUpDownClient
*client
= new CUpDownClient(tag
);
1204 ProcessItemUpdate(tag
, client
);
1205 if (client
->m_reqfile
) {
1206 Notify_SourceCtrlAddSource(client
->m_reqfile
, client
, A4AF_SOURCE
);
1213 void CUpDownClientListRem::DeleteItem(CUpDownClient
*client
)
1215 if (client
->m_reqfile
) {
1216 Notify_SourceCtrlRemoveSource(client
, client
->m_reqfile
);
1217 client
->m_reqfile
->DelSource(client
);
1218 client
->m_reqfile
= NULL
;
1224 uint32
CUpDownClientListRem::GetItemID(CUpDownClient
*client
)
1226 return client
->ECID();
1230 void CUpDownClientListRem::ProcessItemUpdate(
1231 CEC_UpDownClient_Tag
*tag
,
1232 CUpDownClient
*client
)
1234 if (!tag
->HasChildTags()) {
1235 return; // speed exit for clients without any change
1237 tag
->UserID(&client
->m_nUserIDHybrid
);
1238 tag
->ClientName(&client
->m_Username
);
1240 bool sw_updated
= false;
1241 if (tag
->ClientSoftware(client
->m_clientSoft
)) {
1242 client
->m_clientVersionString
= GetSoftName(client
->m_clientSoft
);
1243 client
->m_clientSoftString
= client
->m_clientVersionString
;
1246 if (tag
->SoftVerStr(client
->m_clientVerString
) || sw_updated
) {
1247 if (client
->m_clientVersionString
== _("Unknown")) {
1248 client
->m_fullClientVerString
= client
->m_clientVersionString
;
1250 client
->m_fullClientVerString
= client
->m_clientVersionString
+ wxT(" ") + client
->m_clientVerString
;
1254 tag
->UserHash(&client
->m_UserHash
);
1257 if (tag
->UserIP(client
->m_dwUserIP
)) {
1258 client
->m_nConnectIP
= client
->m_dwUserIP
;
1259 client
->m_FullUserIP
= client
->m_dwUserIP
;
1261 tag
->UserPort(&client
->m_nUserPort
);
1264 tag
->ServerIP(&client
->m_dwServerIP
);
1265 tag
->ServerPort(&client
->m_nServerPort
);
1266 tag
->ServerName(&client
->m_ServerName
);
1268 tag
->KadPort(client
->m_nKadPort
);
1270 tag
->GetCurrentIdentState(&client
->m_identState
);
1271 tag
->ObfuscationStatus(client
->m_obfuscationStatus
);
1272 tag
->HasExtendedProtocol(&client
->m_bEmuleProtocol
);
1274 tag
->WaitingPosition(&client
->m_waitingPosition
);
1275 tag
->RemoteQueueRank(&client
->m_nRemoteQueueRank
);
1276 client
->m_bRemoteQueueFull
= client
->m_nRemoteQueueRank
== 0xffff;
1277 tag
->OldRemoteQueueRank(&client
->m_nOldRemoteQueueRank
);
1278 tag
->AskedCount(&client
->m_cAsked
);
1280 tag
->ClientDownloadState(&client
->m_nDownloadState
);
1281 tag
->ClientUploadState(&client
->m_nUploadState
);
1283 tag
->SpeedUp(&client
->m_nUpDatarate
);
1284 if ( client
->m_nDownloadState
== DS_DOWNLOADING
) {
1285 tag
->SpeedDown(&client
->kBpsDown
);
1287 client
->kBpsDown
= 0;
1290 //tag->WaitTime(&client->m_WaitTime);
1291 //tag->XferTime(&client->m_UpStartTimeDelay);
1292 //tag->LastReqTime(&client->m_dwLastUpRequest);
1293 //tag->QueueTime(&client->m_WaitStartTime);
1295 CreditStruct
*credit_struct
=
1296 (CreditStruct
*)client
->credits
->GetDataStruct();
1297 tag
->XferUp(&credit_struct
->uploaded
);
1298 tag
->XferUpSession(&client
->m_nTransferredUp
);
1300 tag
->XferDown(&credit_struct
->downloaded
);
1301 tag
->XferDownSession(&client
->m_nTransferredDown
);
1303 tag
->Score(&client
->m_score
);
1305 tag
->NextRequestedPart(client
->m_nextRequestedPart
);
1306 tag
->LastDownloadingPart(client
->m_lastDownloadingPart
);
1308 uint8 sourceFrom
= 0;
1309 if (tag
->GetSourceFrom(sourceFrom
)) {
1310 client
->m_nSourceFrom
= (ESourceFrom
)sourceFrom
;
1315 bool notified
= false;
1316 if (tag
->RequestFile(fileID
)) {
1317 if (client
->m_reqfile
) {
1318 Notify_SourceCtrlRemoveSource(client
, client
->m_reqfile
);
1319 client
->m_reqfile
->DelSource(client
);
1320 client
->m_reqfile
= NULL
;
1321 client
->m_downPartStatus
.clear();
1323 CKnownFile
* kf
= theApp
->knownfiles
->GetByID(fileID
);
1324 if (kf
&& kf
->IsCPartFile()) {
1325 client
->m_reqfile
= (CPartFile
*) kf
;
1326 client
->m_reqfile
->AddSource(client
);
1327 client
->m_downPartStatus
.setsize(kf
->GetPartCount(), 0);
1328 Notify_SourceCtrlAddSource(client
->m_reqfile
, client
, A4AF_SOURCE
);
1334 CECTag
* partStatusTag
= tag
->GetTagByName(EC_TAG_CLIENT_PART_STATUS
);
1335 if (partStatusTag
) {
1336 if (partStatusTag
->GetTagDataLen() == 0) {
1337 // empty tag means full source
1338 client
->m_downPartStatus
.SetAllTrue();
1339 } else if (partStatusTag
->GetTagDataLen() == client
->m_downPartStatus
.SizeBuffer()) {
1340 client
->m_downPartStatus
.SetBuffer(partStatusTag
->GetTagData());
1345 if (!notified
&& client
->m_reqfile
&& client
->m_reqfile
->ShowSources()) {
1346 SourceItemType type
= A4AF_SOURCE
;
1347 switch (client
->GetDownloadState()) {
1348 case DS_DOWNLOADING
:
1350 // We will send A4AF, which will be checked.
1353 type
= UNAVAILABLE_SOURCE
;
1357 Notify_SourceCtrlUpdateSource(client
, type
);
1361 if (tag
->UploadFile(fileID
)) {
1362 if (client
->m_uploadingfile
) {
1363 client
->m_uploadingfile
->RemoveUploadingClient(client
); // this notifies
1364 client
->m_uploadingfile
= NULL
;
1365 //client->m_downPartStatus.clear();
1367 CKnownFile
* kf
= theApp
->knownfiles
->GetByID(fileID
);
1369 client
->m_uploadingfile
= kf
;
1370 client
->m_uploadingfile
->AddUploadingClient(client
); // this notifies
1371 //client->m_downPartStatus.setsize(kf->GetPartCount(), 0);
1378 * Download queue container: hold PartFiles with progress status
1383 bool CDownQueueRem::AddLink(const wxString
&link
, uint8 cat
)
1385 CECPacket
req(EC_OP_ADD_LINK
);
1386 CECTag
link_tag(EC_TAG_STRING
, link
);
1387 link_tag
.AddTag(CECTag(EC_TAG_PARTFILE_CAT
, cat
));
1388 req
.AddTag(link_tag
);
1390 m_conn
->SendPacket(&req
);
1395 void CDownQueueRem::ResetCatParts(int cat
)
1397 // Called when category is deleted. Command will be performed on the remote side,
1398 // but files still should be updated here right away, or drawing errors (colour not available)
1400 for (iterator it
= begin(); it
!= end(); it
++) {
1401 CPartFile
* file
= it
->second
;
1403 if ( file
->GetCategory() == cat
) {
1404 // Reset the category
1405 file
->SetCategory( 0 );
1406 } else if ( file
->GetCategory() > cat
) {
1407 // Set to the new position of the original category
1408 file
->SetCategory( file
->GetCategory() - 1 );
1415 void CKnownFilesRem::ProcessItemUpdatePartfile(CEC_PartFile_Tag
*tag
, CPartFile
*file
)
1420 tag
->Speed(&file
->m_kbpsDown
);
1421 file
->kBpsDown
= file
->m_kbpsDown
/ 1024.0;
1423 tag
->SizeXfer(&file
->transferred
);
1424 tag
->SizeDone(&file
->completedsize
);
1425 tag
->SourceXferCount(&file
->transferingsrc
);
1426 tag
->SourceNotCurrCount(&file
->m_notCurrentSources
);
1427 tag
->SourceCount(&file
->m_source_count
);
1428 tag
->SourceCountA4AF(&file
->m_a4af_source_count
);
1429 tag
->FileStatus(&file
->status
);
1430 tag
->Stopped(&file
->m_stopped
);
1432 tag
->LastSeenComplete(&file
->lastseencomplete
);
1433 tag
->LastDateChanged(&file
->m_lastDateChanged
);
1434 tag
->DownloadActiveTime(&file
->m_nDlActiveTime
);
1435 tag
->AvailablePartCount(&file
->m_availablePartsCount
);
1436 tag
->Shared(&file
->m_isShared
);
1437 tag
->A4AFAuto(file
->m_is_A4AF_auto
);
1439 tag
->GetLostDueToCorruption(&file
->m_iLostDueToCorruption
);
1440 tag
->GetGainDueToCompression(&file
->m_iGainDueToCompression
);
1441 tag
->TotalPacketsSavedDueToICH(&file
->m_iTotalPacketsSavedDueToICH
);
1443 tag
->FileCat(&file
->m_category
);
1445 tag
->DownPrio(&file
->m_iDownPriorityEC
);
1446 if ( file
->m_iDownPriorityEC
>= 10 ) {
1447 file
->m_iDownPriority
= file
->m_iDownPriorityEC
- 10;
1448 file
->m_bAutoDownPriority
= true;
1450 file
->m_iDownPriority
= file
->m_iDownPriorityEC
;
1451 file
->m_bAutoDownPriority
= false;
1454 file
->percentcompleted
= (100.0*file
->GetCompletedSize()) / file
->GetFileSize();
1457 // Copy part/gap status
1459 CECTag
*gaptag
= tag
->GetTagByName(EC_TAG_PARTFILE_GAP_STATUS
);
1460 CECTag
*parttag
= tag
->GetTagByName(EC_TAG_PARTFILE_PART_STATUS
);
1461 CECTag
*reqtag
= tag
->GetTagByName(EC_TAG_PARTFILE_REQ_STATUS
);
1462 if (gaptag
|| parttag
|| reqtag
) {
1463 PartFileEncoderData
&encoder
= file
->m_PartFileEncoderData
;
1466 ArrayOfUInts64 gaps
;
1467 encoder
.DecodeGaps(gaptag
, gaps
);
1468 int gap_size
= gaps
.size() / 2;
1470 file
->m_gaplist
.Init(file
->GetFileSize(), false);
1473 for (int j
= 0; j
< gap_size
; j
++) {
1474 file
->m_gaplist
.AddGap(gaps
[2*j
], gaps
[2*j
+1]);
1478 encoder
.DecodeParts(parttag
, file
->m_SrcpartFrequency
);
1480 wxASSERT (file
->m_SrcpartFrequency
.size() == file
->GetPartCount());
1483 ArrayOfUInts64 reqs
;
1484 encoder
.DecodeReqs(reqtag
, reqs
);
1485 int req_size
= reqs
.size() / 2;
1487 DeleteContents(file
->m_requestedblocks_list
);
1490 for (int j
= 0; j
< req_size
; j
++) {
1491 Requested_Block_Struct
* block
= new Requested_Block_Struct
;
1492 block
->StartOffset
= reqs
[2*j
];
1493 block
->EndOffset
= reqs
[2*j
+1];
1494 file
->m_requestedblocks_list
.push_back(block
);
1499 // Get source names and counts
1500 CECTag
*srcnametag
= tag
->GetTagByName(EC_TAG_PARTFILE_SOURCE_NAMES
);
1502 SourcenameItemMap
&map
= file
->GetSourcenameItemMap();
1503 for (CECTag::const_iterator it
= srcnametag
->begin(); it
!= srcnametag
->end(); it
++) {
1504 uint32 key
= it
->GetInt();
1505 int count
= it
->GetTagByNameSafe(EC_TAG_PARTFILE_SOURCE_NAMES_COUNTS
)->GetInt();
1509 SourcenameItem
&item
= map
[key
];
1511 const CECTag
*nametag
= it
->GetTagByName(EC_TAG_PARTFILE_SOURCE_NAMES
);
1513 item
.name
= nametag
->GetStringData();
1520 CECTag
*commenttag
= tag
->GetTagByName(EC_TAG_PARTFILE_COMMENTS
);
1522 file
->ClearFileRatingList();
1523 for (CECTag::const_iterator it
= commenttag
->begin(); it
!= commenttag
->end(); ) {
1524 wxString u
= (it
++)->GetStringData();
1525 wxString f
= (it
++)->GetStringData();
1526 int r
= (it
++)->GetInt();
1527 wxString c
= (it
++)->GetStringData();
1528 file
->AddFileRatingList(u
, f
, r
, c
);
1530 file
->UpdateFileRatingCommentAvail();
1533 theApp
->amuledlg
->m_transferwnd
->downloadlistctrl
->UpdateItem(file
);
1535 // If file is shared check if it is already listed in shared files.
1536 // If not, add it and show it.
1537 if (file
->IsShared() && !theApp
->sharedfiles
->count(file
->ECID())) {
1538 (*theApp
->sharedfiles
)[file
->ECID()] = file
;
1539 theApp
->amuledlg
->m_sharedfileswnd
->sharedfilesctrl
->ShowFile(file
);
1544 void CDownQueueRem::SendFileCommand(CPartFile
*file
, ec_tagname_t cmd
)
1547 req
.AddTag(CECTag(EC_TAG_PARTFILE
, file
->GetFileHash()));
1549 m_conn
->SendPacket(&req
);
1553 void CDownQueueRem::Prio(CPartFile
*file
, uint8 prio
)
1555 CECPacket
req(EC_OP_PARTFILE_PRIO_SET
);
1557 CECTag
hashtag(EC_TAG_PARTFILE
, file
->GetFileHash());
1558 hashtag
.AddTag(CECTag(EC_TAG_PARTFILE_PRIO
, prio
));
1559 req
.AddTag(hashtag
);
1561 m_conn
->SendPacket(&req
);
1565 void CDownQueueRem::AutoPrio(CPartFile
*file
, bool flag
)
1567 CECPacket
req(EC_OP_PARTFILE_PRIO_SET
);
1569 CECTag
hashtag(EC_TAG_PARTFILE
, file
->GetFileHash());
1571 hashtag
.AddTag(CECTag(EC_TAG_PARTFILE_PRIO
,
1572 (uint8
)(flag
? PR_AUTO
: file
->GetDownPriority())));
1573 req
.AddTag(hashtag
);
1575 m_conn
->SendPacket(&req
);
1579 void CDownQueueRem::Category(CPartFile
*file
, uint8 cat
)
1581 CECPacket
req(EC_OP_PARTFILE_SET_CAT
);
1582 file
->SetCategory(cat
);
1584 CECTag
hashtag(EC_TAG_PARTFILE
, file
->GetFileHash());
1585 hashtag
.AddTag(CECTag(EC_TAG_PARTFILE_CAT
, cat
));
1586 req
.AddTag(hashtag
);
1588 m_conn
->SendPacket(&req
);
1592 void CDownQueueRem::AddSearchToDownload(CSearchFile
* file
, uint8 category
)
1594 CECPacket
req(EC_OP_DOWNLOAD_SEARCH_RESULT
);
1595 CECTag
hashtag(EC_TAG_PARTFILE
, file
->GetFileHash());
1596 hashtag
.AddTag(CECTag(EC_TAG_PARTFILE_CAT
, category
));
1597 req
.AddTag(hashtag
);
1599 m_conn
->SendPacket(&req
);
1603 void CUpDownClientListRem::FilterQueues()
1610 CSearchListRem::CSearchListRem(CRemoteConnect
*conn
) : CRemoteContainer
<CSearchFile
, uint32
, CEC_SearchFile_Tag
>(conn
, true)
1616 wxString
CSearchListRem::StartNewSearch(
1617 uint32
* nSearchID
, SearchType search_type
,
1618 const CSearchList::CSearchParams
& params
)
1620 CECPacket
search_req(EC_OP_SEARCH_START
);
1621 EC_SEARCH_TYPE ec_search_type
= EC_SEARCH_LOCAL
;
1622 switch(search_type
) {
1623 case LocalSearch
: ec_search_type
= EC_SEARCH_LOCAL
; break;
1624 case GlobalSearch
: ec_search_type
= EC_SEARCH_GLOBAL
; break;
1625 case KadSearch
: ec_search_type
= EC_SEARCH_KAD
; break;
1628 CEC_Search_Tag(params
.searchString
, ec_search_type
,
1629 params
.typeText
, params
.extension
, params
.availability
,
1630 params
.minSize
, params
.maxSize
));
1632 m_conn
->SendPacket(&search_req
);
1633 m_curr_search
= *(nSearchID
); // No kad remote search yet.
1637 return wxEmptyString
; // EC reply will have the error mesg is needed.
1641 void CSearchListRem::StopGlobalSearch()
1643 if (m_curr_search
!= -1) {
1644 CECPacket
search_req(EC_OP_SEARCH_STOP
);
1645 m_conn
->SendPacket(&search_req
);
1650 void CSearchListRem::StopKadSearch()
1652 // FIXME implementation needed
1656 void CSearchListRem::HandlePacket(const CECPacket
*packet
)
1658 if ( packet
->GetOpCode() == EC_OP_SEARCH_PROGRESS
) {
1659 CoreNotify_Search_Update_Progress(packet
->GetFirstTagSafe()->GetInt());
1661 CRemoteContainer
<CSearchFile
, uint32
, CEC_SearchFile_Tag
>::HandlePacket(packet
);
1666 CSearchFile::CSearchFile(CEC_SearchFile_Tag
*tag
)
1670 m_showChildren(false),
1672 m_completeSourceCount(0),
1674 m_downloadStatus(NEW
),
1679 SetFileName(CPath(tag
->FileName()));
1680 m_abyFileHash
= tag
->FileHash();
1681 SetFileSize(tag
->SizeFull());
1683 m_searchID
= theApp
->searchlist
->m_curr_search
;
1688 // dtor is virtual - must be implemented
1689 CSearchFile::~CSearchFile()
1694 CSearchFile
*CSearchListRem::CreateItem(CEC_SearchFile_Tag
*tag
)
1696 CSearchFile
*file
= new CSearchFile(tag
);
1697 ProcessItemUpdate(tag
, file
);
1699 theApp
->amuledlg
->m_searchwnd
->AddResult(file
);
1705 void CSearchListRem::DeleteItem(CSearchFile
*file
)
1711 uint32
CSearchListRem::GetItemID(CSearchFile
*file
)
1713 return file
->ECID();
1717 void CSearchListRem::ProcessItemUpdate(CEC_SearchFile_Tag
*tag
, CSearchFile
*file
)
1719 uint32 sourceCount
= file
->m_sourceCount
;
1720 uint32 completeSourceCount
= file
->m_completeSourceCount
;
1721 CSearchFile::DownloadStatus status
= file
->m_downloadStatus
;
1722 tag
->SourceCount(&file
->m_sourceCount
);
1723 tag
->CompleteSourceCount(&file
->m_completeSourceCount
);
1724 tag
->DownloadStatus((uint32
*) &file
->m_downloadStatus
);
1726 if (file
->m_sourceCount
!= sourceCount
1727 || file
->m_completeSourceCount
!= completeSourceCount
1728 || file
->m_downloadStatus
!= status
) {
1729 if (theApp
->amuledlg
&& theApp
->amuledlg
->m_searchwnd
) {
1730 theApp
->amuledlg
->m_searchwnd
->UpdateResult(file
);
1736 bool CSearchListRem::Phase1Done(const CECPacket
*WXUNUSED(reply
))
1738 CECPacket
progress_req(EC_OP_SEARCH_PROGRESS
);
1739 m_conn
->SendRequest(this, &progress_req
);
1745 void CSearchListRem::RemoveResults(long nSearchID
)
1747 ResultMap::iterator it
= m_results
.find(nSearchID
);
1748 if (it
!= m_results
.end()) {
1749 CSearchResultList
& list
= it
->second
;
1750 for (unsigned int i
= 0; i
< list
.size(); ++i
) {
1753 m_results
.erase(it
);
1758 const CSearchResultList
& CSearchListRem::GetSearchResults(long nSearchID
)
1760 ResultMap::const_iterator it
= m_results
.find(nSearchID
);
1761 if (it
!= m_results
.end()) {
1765 // TODO: Should we assert in this case?
1766 static CSearchResultList list
;
1771 void CStatsUpdaterRem::HandlePacket(const CECPacket
*packet
)
1773 theStats::UpdateStats(packet
);
1774 theApp
->ShowUserCount(); // maybe there should be a check if a usercount changed ?
1778 bool CUpDownClient::IsBanned() const
1786 // Those functions have different implementation in remote gui
1788 void CUpDownClient::Ban()
1795 void CUpDownClient::UnBan()
1802 void CUpDownClient::RequestSharedFileList()
1809 void CKnownFile::SetFileComment(const wxString
&)
1812 wxMessageBox(_("Comments and ratings are not supported on remote gui yet"), _("Information"), wxOK
| wxICON_INFORMATION
);
1816 void CKnownFile::SetFileRating(unsigned char)
1822 bool CUpDownClient::SwapToAnotherFile(
1823 bool WXUNUSED(bIgnoreNoNeeded
),
1824 bool WXUNUSED(ignoreSuspensions
),
1825 bool WXUNUSED(bRemoveCompletely
),
1826 CPartFile
* WXUNUSED(toFile
))
1835 // Those functions are virtual. So even they don't get called they must
1836 // be defined so linker will be happy
1838 CPacket
* CKnownFile::CreateSrcInfoPacket(const CUpDownClient
*, uint8
/*byRequestedVersion*/, uint16
/*nRequestedOptions*/)
1845 bool CKnownFile::LoadFromFile(const class CFileDataIO
*)
1852 void CKnownFile::UpdatePartsInfo()
1858 CPacket
* CPartFile::CreateSrcInfoPacket(CUpDownClient
const *, uint8
/*byRequestedVersion*/, uint16
/*nRequestedOptions*/)
1865 void CPartFile::UpdatePartsInfo()
1871 void CPartFile::UpdateFileRatingCommentAvail()
1873 bool prevComment
= m_hasComment
;
1874 int prevRating
= m_iUserRating
;
1876 m_hasComment
= false;
1878 int ratingCount
= 0;
1880 FileRatingList::iterator it
= m_FileRatingList
.begin();
1881 for (; it
!= m_FileRatingList
.end(); ++it
) {
1882 SFileRating
& cur_rat
= *it
;
1884 if (!cur_rat
.Comment
.IsEmpty()) {
1885 m_hasComment
= true;
1888 uint8 rating
= cur_rat
.Rating
;
1890 wxASSERT(rating
<= 5);
1893 m_iUserRating
+= rating
;
1898 m_iUserRating
/= ratingCount
;
1899 wxASSERT(m_iUserRating
> 0 && m_iUserRating
<= 5);
1902 if ((prevComment
!= m_hasComment
) || (prevRating
!= m_iUserRating
)) {
1903 UpdateDisplayedInfo();
1907 bool CPartFile::SavePartFile(bool)
1913 CamuleRemoteGuiApp
*theApp
;
1916 // since gui is not linked with amule.cpp - define events here
1918 DEFINE_LOCAL_EVENT_TYPE(wxEVT_CORE_FINISHED_HTTP_DOWNLOAD
)
1919 DEFINE_LOCAL_EVENT_TYPE(wxEVT_CORE_SOURCE_DNS_DONE
)
1920 DEFINE_LOCAL_EVENT_TYPE(wxEVT_CORE_UDP_DNS_DONE
)
1921 DEFINE_LOCAL_EVENT_TYPE(wxEVT_CORE_SERVER_DNS_DONE
)
1922 // File_checked_for_headers