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
26 #define AMULE_REMOTE_GUI_CPP
30 #include <wx/cmdline.h> // Needed for wxCmdLineParser
31 #include <wx/config.h> // Do_not_auto_remove (win32)
32 #include <wx/fileconf.h> // Needed for wxFileConfig
35 #include <common/Format.h>
36 #include <common/StringFunctions.h>
37 #include <common/MD5Sum.h>
40 #include <include/common/EventIDs.h>
43 #include "amule.h" // Interface declarations.
44 #include "amuleDlg.h" // Needed for CamuleDlg
45 #include "ClientCredits.h"
46 #include "ClientListCtrl.h"
47 #include "DataToText.h" // Needed for GetSoftName()
48 #include "DownloadListCtrl.h" // Needed for CDownloadListCtrl
49 #include "GuiEvents.h"
50 #ifdef ENABLE_IP2COUNTRY
51 #include "IP2Country.h" // Needed for IP2Country
53 #include "InternalEvents.h" // Needed for wxEVT_CORE_FINISHED_HTTP_DOWNLOAD
55 #include "muuli_wdr.h" // Needed for IDs
56 #include "PartFile.h" // Needed for CPartFile
57 #include "SearchDlg.h" // Needed for CSearchDlg
58 #include "Server.h" // Needed for GetListName
59 #include "ServerWnd.h" // Needed for CServerWnd
60 #include "SharedFilesCtrl.h" // Needed for CSharedFilesCtrl
61 #include "SharedFilesWnd.h" // Needed for CSharedFilesWnd
62 #include "TransferWnd.h" // Needed for CTransferWnd
63 #include "updownclient.h"
64 #include "ServerListCtrl.h" // Needed for CServerListCtrl
65 #include "MagnetURI.h" // Needed for CMagnetURI
66 #include "ScopedPtr.h"
69 CEConnectDlg::CEConnectDlg()
71 wxDialog(theApp
->amuledlg
, -1, _("Connect to remote amule"), wxDefaultPosition
)
73 CoreConnect(this, true);
75 wxString pref_host
, pref_port
;
76 wxConfig::Get()->Read(wxT("/EC/Host"), &pref_host
, wxT("localhost"));
77 wxConfig::Get()->Read(wxT("/EC/Port"), &pref_port
, wxT("4712"));
78 wxConfig::Get()->Read(wxT("/EC/Password"), &pwd_hash
);
80 CastChild(ID_REMOTE_HOST
, wxTextCtrl
)->SetValue(pref_host
);
81 CastChild(ID_REMOTE_PORT
, wxTextCtrl
)->SetValue(pref_port
);
82 CastChild(ID_EC_PASSWD
, wxTextCtrl
)->SetValue(pwd_hash
);
88 wxString
CEConnectDlg::PassHash()
94 BEGIN_EVENT_TABLE(CEConnectDlg
, wxDialog
)
95 EVT_BUTTON(wxID_OK
, CEConnectDlg::OnOK
)
99 void CEConnectDlg::OnOK(wxCommandEvent
& evt
)
101 wxString s_port
= CastChild(ID_REMOTE_PORT
, wxTextCtrl
)->GetValue();
102 port
= StrToLong(s_port
);
104 host
= CastChild(ID_REMOTE_HOST
, wxTextCtrl
)->GetValue();
105 passwd
= CastChild(ID_EC_PASSWD
, wxTextCtrl
)->GetValue();
107 if (passwd
!= pwd_hash
) {
108 pwd_hash
= MD5Sum(passwd
).GetHash();
110 m_save_user_pass
= CastChild(ID_EC_SAVE
, wxCheckBox
)->IsChecked();
115 DEFINE_LOCAL_EVENT_TYPE(wxEVT_EC_INIT_DONE
)
118 BEGIN_EVENT_TABLE(CamuleRemoteGuiApp
, wxApp
)
120 EVT_TIMER(ID_CORE_TIMER_EVENT
, CamuleRemoteGuiApp::OnPollTimer
)
122 EVT_CUSTOM(wxEVT_EC_CONNECTION
, -1, CamuleRemoteGuiApp::OnECConnection
)
123 EVT_CUSTOM(wxEVT_EC_INIT_DONE
, -1, CamuleRemoteGuiApp::OnECInitDone
)
125 EVT_MULE_NOTIFY(CamuleRemoteGuiApp::OnNotifyEvent
)
127 #ifdef ENABLE_IP2COUNTRY
128 // HTTPDownload finished
129 EVT_MULE_INTERNAL(wxEVT_CORE_FINISHED_HTTP_DOWNLOAD
, -1, CamuleRemoteGuiApp::OnFinishedHTTPDownload
)
134 IMPLEMENT_APP(CamuleRemoteGuiApp
)
137 int CamuleRemoteGuiApp::OnExit()
141 return wxApp::OnExit();
145 void CamuleRemoteGuiApp::OnPollTimer(wxTimerEvent
&)
147 static int request_step
= 0;
149 if (m_connect
->RequestFifoFull()) {
153 switch (request_step
) {
155 serverconnect
->ReQuery();
156 serverlist
->UpdateUserFileStatus(serverconnect
->GetCurrentServer());
160 CECPacket
stats_req(EC_OP_STAT_REQ
);
161 m_connect
->SendRequest(&m_stats_updater
, &stats_req
);
162 amuledlg
->ShowTransferRate();
167 if (amuledlg
->m_sharedfileswnd
->IsShown()) {
168 sharedfiles
->DoRequery(EC_OP_GET_SHARED_FILES
, EC_TAG_KNOWNFILE
);
169 } else if (amuledlg
->m_serverwnd
->IsShown()) {
170 //serverlist->FullReload(EC_OP_GET_SERVER_LIST);
171 } else if (amuledlg
->m_transferwnd
->IsShown()) {
172 static bool firstcall
= true;
173 downloadqueue
->DoRequery(
174 theApp
->m_FileDetailDialogActive
|| firstcall
?
175 EC_OP_GET_DLOAD_QUEUE_DETAIL
: EC_OP_GET_DLOAD_QUEUE
,
178 switch(amuledlg
->m_transferwnd
->clientlistctrl
->GetListView()) {
180 uploadqueue
->ReQueryUp();
183 uploadqueue
->ReQueryWait();
190 amuledlg
->m_transferwnd
->ShowQueueCount(theStats::GetWaitingUserCount());
191 } else if (amuledlg
->m_searchwnd
->IsShown()) {
192 if (searchlist
->m_curr_search
!= -1) {
193 searchlist
->DoRequery(EC_OP_SEARCH_RESULTS
, EC_TAG_SEARCHFILE
);
200 AddLogLineCS(wxT("WTF?")); // should not happen. :-)
206 void CamuleRemoteGuiApp::OnFinishedHTTPDownload(CMuleInternalEvent
& event
)
208 #ifdef ENABLE_IP2COUNTRY
209 if (event
.GetInt() == HTTP_GeoIP
) {
210 amuledlg
->IP2CountryDownloadFinished(event
.GetExtraLong());
211 // If we updated, the dialog is already up. Redraw it to show the flags.
218 void CamuleRemoteGuiApp::ShutDown(wxCloseEvent
&WXUNUSED(evt
))
220 // Stop the Core Timer
224 // Destroy the EC socket
225 m_connect
->Destroy();
230 amuledlg
->DlgShutDown();
237 bool CamuleRemoteGuiApp::OnInit()
241 if ( !wxApp::OnInit() ) {
246 theApp
= &wxGetApp();
248 // Handle uncaught exceptions
249 InstallMuleExceptionHandler();
251 // Create the polling timer
252 poll_timer
= new wxTimer(this,ID_CORE_TIMER_EVENT
);
254 AddLogLineCS(_("Fatal Error: Failed to create Poll Timer"));
258 m_connect
= new CRemoteConnect(this);
259 SetAppName(wxT("aMule"));
262 // This creates the CFG file we shall use
263 ConfigDir
= GetConfigDir();
264 if (!wxDirExists(ConfigDir
)) {
268 wxConfig::Set(new wxFileConfig(wxEmptyString
, wxEmptyString
,
269 ConfigDir
+ wxT("remote.conf")));
271 glob_prefs
= new CPreferencesRem(m_connect
);
273 InitCustomLanguages();
274 InitLocale(m_locale
, StrLang2wx(thePrefs::GetLanguageID()));
276 bool result
= ShowConnectionDialog();
278 AddLogLineNS(_("Going to event loop..."));
284 bool CamuleRemoteGuiApp::CryptoAvailable() const
286 return clientcredits
&& clientcredits
->CryptoAvailable();
290 bool CamuleRemoteGuiApp::ShowConnectionDialog() {
292 dialog
= new CEConnectDlg
;
294 if (dialog
->ShowModal() != wxID_OK
) {
299 AddLogLineNS(_("Connecting..."));
300 if (!m_connect
->ConnectToCore(dialog
->Host(), dialog
->Port(),
301 dialog
->Login(), dialog
->PassHash(),
302 wxT("amule-remote"), wxT("0x0001"))) {
303 wxMessageBox(_("Connection failed "),_("ERROR"),wxOK
);
312 void CamuleRemoteGuiApp::OnECConnection(wxEvent
& event
) {
313 wxECSocketEvent
& evt
= *((wxECSocketEvent
*)&event
);
314 AddLogLineNS(_("Remote GUI EC event handler"));
315 wxString reply
= evt
.GetServerReply();
316 AddLogLineM(true, reply
);
317 if (evt
.GetResult() == true) {
318 // Connected - go to next init step
319 glob_prefs
->LoadRemote();
321 AddLogLineNS(_("Going down"));
322 if (dialog
) { // can otherwise crash here on disconnect
324 (CFormat(_("Connection Failed. Unable to connect to %s:%d\n")) % dialog
->Host() % dialog
->Port()) + reply
,
332 void CamuleRemoteGuiApp::OnECInitDone(wxEvent
& )
338 void CamuleRemoteGuiApp::OnNotifyEvent(CMuleGUIEvent
& evt
)
344 void CamuleRemoteGuiApp::Startup() {
346 if (dialog
->SaveUserPass()) {
347 wxConfig::Get()->Write(wxT("/EC/Host"), dialog
->Host());
348 wxConfig::Get()->Write(wxT("/EC/Port"), dialog
->Port());
349 wxConfig::Get()->Write(wxT("/EC/Password"), dialog
->PassHash());
356 serverconnect
= new CServerConnectRem(m_connect
);
357 m_statistics
= new CStatistics(*m_connect
);
359 clientlist
= new CClientListRem(m_connect
);
360 searchlist
= new CSearchListRem(m_connect
);
361 serverlist
= new CServerListRem(m_connect
);
363 sharedfiles
= new CSharedFilesRem(m_connect
);
364 knownfiles
= new CKnownFilesRem(sharedfiles
);
366 clientcredits
= new CClientCreditsRem();
368 // bugfix - do this before creating the uploadqueue
369 downloadqueue
= new CDownQueueRem(m_connect
);
370 uploadqueue
= new CUpQueueRem(m_connect
);
371 ipfilter
= new CIPFilterRem(m_connect
);
373 // Parse cmdline arguments.
374 wxCmdLineParser
cmdline(wxApp::argc
, wxApp::argv
);
375 cmdline
.AddSwitch(wxT("v"), wxT("version"),
376 wxT("Displays the current version number."));
377 cmdline
.AddSwitch(wxT("h"), wxT("help"),
378 wxT("Displays this information."));
379 cmdline
.AddOption(wxT("geometry"), wxEmptyString
, wxT("Sets the geometry of the app.\n\t\t\t<str> uses the same format as standard X11 apps:\n\t\t\t[=][<width>{xX}<height>][{+-}<xoffset>{+-}<yoffset>]"));
382 bool geometry_enabled
= false;
383 wxString geom_string
;
384 if (cmdline
.Found(wxT("geometry"), &geom_string
)) {
385 geometry_enabled
= true;
388 // Create main dialog
389 InitGui(0, geom_string
);
391 // Forward wxLog events to CLogger
392 wxLog::SetActiveTarget(new CLoggerTarget
);
393 serverlist
->FullReload(EC_OP_GET_SERVER_LIST
);
394 sharedfiles
->DoRequery(EC_OP_GET_SHARED_FILES
, EC_TAG_KNOWNFILE
);
396 // Start the Poll Timer
397 poll_timer
->Start(1000);
398 amuledlg
->StartGuiTimer();
400 // Now activate GeoIP, so that the download dialog doesn't get destroyed immediately
401 #ifdef ENABLE_IP2COUNTRY
402 if (thePrefs::IsGeoIPEnabled()) {
403 amuledlg
->m_IP2Country
->Enable();
409 void CamuleRemoteGuiApp::ShowAlert(wxString msg
, wxString title
, int flags
)
411 CamuleGuiBase::ShowAlert(msg
, title
, flags
);
415 void CamuleRemoteGuiApp::AddRemoteLogLine(const wxString
& line
)
417 amuledlg
->AddLogLine(line
);
420 int CamuleRemoteGuiApp::InitGui(bool geometry_enabled
, wxString
&geom_string
)
422 CamuleGuiBase::InitGui(geometry_enabled
, geom_string
);
423 SetTopWindow(amuledlg
);
424 AddLogLineN(_("Ready")); // The first log line after the window is up triggers output of all the ones before
429 bool CamuleRemoteGuiApp::CopyTextToClipboard(wxString strText
)
431 return CamuleGuiBase::CopyTextToClipboard(strText
);
435 uint32
CamuleRemoteGuiApp::GetPublicIP()
441 wxString
CamuleRemoteGuiApp::GetLog(bool)
443 return wxEmptyString
;
447 wxString
CamuleRemoteGuiApp::GetServerLog(bool)
449 return wxEmptyString
;
453 wxString
CamuleRemoteGuiApp::CreateMagnetLink(const CAbstractFile
* f
)
455 // TODO: Remove duplicate code (also in amule.cpp) ...
458 uri
.AddField(wxT("dn"), f
->GetFileName().Cleanup(false).GetPrintable());
459 uri
.AddField(wxT("xt"), wxString(wxT("urn:ed2k:")) + f
->GetFileHash().Encode().Lower());
460 uri
.AddField(wxT("xt"), wxString(wxT("urn:ed2khash:")) + f
->GetFileHash().Encode().Lower());
461 uri
.AddField(wxT("xl"), wxString::Format(wxT("%") wxLongLongFmtSpec
wxT("u"), f
->GetFileSize()));
463 return uri
.GetLink();
466 wxString
CamuleRemoteGuiApp::CreateED2kLink(const CAbstractFile
* f
, bool add_source
, bool use_hostname
, bool addcryptoptions
)
468 // TODO: Avoid duplicate code (also in amule.cpp) ...
469 wxASSERT(!(!add_source
&& (use_hostname
|| addcryptoptions
)));
470 // Construct URL like this: ed2k://|file|<filename>|<size>|<hash>|/
471 wxString strURL
= CFormat(wxT("ed2k://|file|%s|%i|%s|/"))
472 % f
->GetFileName().Cleanup(false)
473 % f
->GetFileSize() % f
->GetFileHash().Encode();
475 if (add_source
&& IsConnected() && !IsFirewalled()) {
476 // Create the first part of the URL
477 strURL
<< wxT("|sources,");
480 strURL
<< thePrefs::GetYourHostname();
482 uint32 clientID
= GetID();
483 strURL
<< (uint8
) clientID
<< wxT(".") <<
484 (uint8
)(clientID
>> 8) << wxT(".") <<
485 (uint8
)(clientID
>> 16) << wxT(".") <<
486 (uint8
)(clientID
>> 24);
489 strURL
<< wxT(":") <<
492 if (addcryptoptions
) {
493 const uint8 uSupportsCryptLayer
= thePrefs::IsClientCryptLayerSupported() ? 1 : 0;
494 const uint8 uRequestsCryptLayer
= thePrefs::IsClientCryptLayerRequested() ? 1 : 0;
495 const uint8 uRequiresCryptLayer
= thePrefs::IsClientCryptLayerRequired() ? 1 : 0;
496 const uint8 byCryptOptions
= (uRequiresCryptLayer
<< 2) | (uRequestsCryptLayer
<< 1) | (uSupportsCryptLayer
<< 0) | (uSupportsCryptLayer
? 0x80 : 0x00);
498 strURL
<< wxT(":") << byCryptOptions
;
500 if (byCryptOptions
& 0x80) {
501 strURL
<< wxT(":") << thePrefs::GetUserHash().Encode();
506 } else if (add_source
) {
507 AddLogLineM(true, _("WARNING: You can't add yourself as a source for an eD2k link while having a lowid."));
510 // Result is "ed2k://|file|<filename>|<size>|<hash>|/|sources,[(<ip>|<hostname>):<port>[:cryptoptions[:hash]]]|/"
515 wxString
CamuleRemoteGuiApp::CreateED2kAICHLink(const CKnownFile
* f
)
517 // TODO: Avoid duplicate code (also in amule.cpp) ...
518 // Create the first part of the URL
519 wxString strURL
= CreateED2kLink(f
);
520 // Append the AICH info
521 if (f
->HasProperAICHHashSet()) {
522 strURL
.RemoveLast(); // remove trailing '/'
523 strURL
<< wxT("h=") << f
->GetAICHMasterHash() << wxT("|/");
526 // Result is "ed2k://|file|<filename>|<size>|<hash>|h=<AICH master hash>|/"
531 bool CamuleRemoteGuiApp::AddServer(CServer
*, bool)
533 // #warning TODO: Add remote command
538 bool CamuleRemoteGuiApp::IsFirewalled() const
540 if (IsConnectedED2K() && !serverconnect
->IsLowID()) {
544 return IsFirewalledKad();
548 bool CamuleRemoteGuiApp::IsConnectedED2K() const {
549 return serverconnect
&& serverconnect
->IsConnected();
553 void CamuleRemoteGuiApp::StartKad() {
554 m_connect
->StartKad();
558 void CamuleRemoteGuiApp::StopKad() {
559 m_connect
->StopKad();
563 void CamuleRemoteGuiApp::BootstrapKad(uint32 ip
, uint16 port
)
565 CECPacket
req(EC_OP_KAD_BOOTSTRAP_FROM_IP
);
566 req
.AddTag(CECTag(EC_TAG_BOOTSTRAP_IP
, ip
));
567 req
.AddTag(CECTag(EC_TAG_BOOTSTRAP_PORT
, port
));
569 m_connect
->SendPacket(&req
);
573 void CamuleRemoteGuiApp::UpdateNotesDat(const wxString
& url
)
575 CECPacket
req(EC_OP_KAD_UPDATE_FROM_URL
);
576 req
.AddTag(CECTag(EC_TAG_KADEMLIA_UPDATE_URL
, url
));
578 m_connect
->SendPacket(&req
);
582 void CamuleRemoteGuiApp::DisconnectED2K() {
583 if (IsConnectedED2K()) {
584 m_connect
->DisconnectED2K();
589 uint32
CamuleRemoteGuiApp::GetED2KID() const
591 return serverconnect
? serverconnect
->GetClientID() : 0;
595 uint32
CamuleRemoteGuiApp::GetID() const
601 void CamuleRemoteGuiApp::ShowUserCount() {
603 CFormat(_("Users: E: %s K: %s | Files E: %s K: %s")) % CastItoIShort(theStats::GetED2KUsers()) %
604 CastItoIShort(theStats::GetKadUsers()) % CastItoIShort(theStats::GetED2KFiles()) % CastItoIShort(theStats::GetKadFiles());
606 Notify_ShowUserCount(buffer
);
611 * Preferences: holds both local and remote settings.
613 * First, everything is loaded from local config file. Later, settings
614 * that are relevant on remote side only are loaded thru EC
616 CPreferencesRem::CPreferencesRem(CRemoteConnect
*conn
)
620 CPreferences::BuildItemList(theApp
->ConfigDir
);
621 CPreferences::LoadAllItems(wxConfigBase::Get());
624 // Settings queried from remote side
626 m_exchange_send_selected_prefs
=
628 EC_PREFS_CONNECTIONS
|
629 EC_PREFS_MESSAGEFILTER
|
635 EC_PREFS_CORETWEAKS
|
636 EC_PREFS_REMOTECONTROLS
|
638 m_exchange_recv_selected_prefs
=
639 m_exchange_send_selected_prefs
|
644 void CPreferencesRem::HandlePacket(const CECPacket
*packet
)
646 ((CEC_Prefs_Packet
*)packet
)->Apply();
648 if ( packet
->GetTagByName(EC_TAG_PREFS_CATEGORIES
) != 0 ) {
649 for (size_t i
= 0; i
< packet
->GetTagByName(EC_TAG_PREFS_CATEGORIES
)->GetTagCount(); i
++) {
650 const CECTag
*cat_tag
= packet
->GetTagByName(EC_TAG_PREFS_CATEGORIES
)->GetTagByIndex(i
);
651 Category_Struct
*cat
= new Category_Struct
;
652 cat
->title
= cat_tag
->GetTagByName(EC_TAG_CATEGORY_TITLE
)->GetStringData();
653 cat
->path
= CPath(cat_tag
->GetTagByName(EC_TAG_CATEGORY_PATH
)->GetStringData());
654 cat
->comment
= cat_tag
->GetTagByName(EC_TAG_CATEGORY_COMMENT
)->GetStringData();
655 cat
->color
= cat_tag
->GetTagByName(EC_TAG_CATEGORY_COLOR
)->GetInt();
656 cat
->prio
= cat_tag
->GetTagByName(EC_TAG_CATEGORY_PRIO
)->GetInt();
657 theApp
->glob_prefs
->AddCat(cat
);
660 Category_Struct
*cat
= new Category_Struct
;
661 cat
->title
= _("All");
663 cat
->prio
= PR_NORMAL
;
664 theApp
->glob_prefs
->AddCat(cat
);
666 wxECInitDoneEvent event
;
667 theApp
->AddPendingEvent(event
);
672 bool CPreferencesRem::LoadRemote()
675 // override local settings with remote
676 CECPacket
req(EC_OP_GET_PREFERENCES
, EC_DETAIL_UPDATE
);
678 // bring categories too
679 req
.AddTag(CECTag(EC_TAG_SELECT_PREFS
, m_exchange_recv_selected_prefs
));
681 m_conn
->SendRequest(this, &req
);
687 void CPreferencesRem::SendToRemote()
689 CEC_Prefs_Packet
pref_packet(m_exchange_send_selected_prefs
, EC_DETAIL_UPDATE
, EC_DETAIL_FULL
);
690 m_conn
->SendPacket(&pref_packet
);
694 Category_Struct
*CPreferencesRem::CreateCategory(
695 const wxString
& name
,
697 const wxString
& comment
,
701 CECPacket
req(EC_OP_CREATE_CATEGORY
);
702 CEC_Category_Tag
tag(0xffffffff, name
, path
.GetRaw(), comment
, color
, prio
);
704 m_conn
->SendPacket(&req
);
706 Category_Struct
*category
= new Category_Struct();
707 category
->path
= path
;
708 category
->title
= name
;
709 category
->comment
= comment
;
710 category
->color
= color
;
711 category
->prio
= prio
;
719 void CPreferencesRem::UpdateCategory(
721 const wxString
& name
,
723 const wxString
& comment
,
727 CECPacket
req(EC_OP_UPDATE_CATEGORY
);
728 CEC_Category_Tag
tag(cat
, name
, path
.GetRaw(), comment
, color
, prio
);
730 m_conn
->SendPacket(&req
);
732 Category_Struct
*category
= m_CatList
[cat
];
733 category
->path
= path
;
734 category
->title
= name
;
735 category
->comment
= comment
;
736 category
->color
= color
;
737 category
->prio
= prio
;
741 void CPreferencesRem::RemoveCat(uint8 cat
)
743 CECPacket
req(EC_OP_DELETE_CATEGORY
);
744 CEC_Category_Tag
tag(cat
, EC_DETAIL_CMD
);
746 m_conn
->SendPacket(&req
);
747 CPreferences::RemoveCat(cat
);
752 // Container implementation
754 CServerConnectRem::CServerConnectRem(CRemoteConnect
*conn
)
761 void CServerConnectRem::ConnectToAnyServer()
763 CECPacket
req(EC_OP_SERVER_CONNECT
);
764 m_Conn
->SendPacket(&req
);
768 void CServerConnectRem::StopConnectionTry()
770 // lfroen: isn't Disconnect the same ?
774 void CServerConnectRem::Disconnect()
776 CECPacket
req(EC_OP_SERVER_DISCONNECT
);
777 m_Conn
->SendPacket(&req
);
781 void CServerConnectRem::ConnectToServer(CServer
*server
)
783 m_Conn
->ConnectED2K(server
->GetIP(), server
->GetPort());
787 bool CServerConnectRem::ReQuery()
789 CECPacket
stat_req(EC_OP_GET_CONNSTATE
);
790 m_Conn
->SendRequest(this, &stat_req
);
796 void CServerConnectRem::HandlePacket(const CECPacket
*packet
)
798 CEC_ConnState_Tag
*tag
=
799 (CEC_ConnState_Tag
*)packet
->GetTagByName(EC_TAG_CONNSTATE
);
804 theApp
->m_ConnState
= 0;
806 m_ID
= tag
->GetEd2kId();
807 theApp
->m_clientID
= tag
->GetClientId();
809 if (tag
->IsConnectedED2K()) {
810 CECTag
*srvtag
= tag
->GetTagByName(EC_TAG_SERVER
);
814 server
= theApp
->serverlist
->GetByID(srvtag
->GetIPv4Data().IP());
815 if (m_CurrServer
&& (server
!= m_CurrServer
)) {
816 theApp
->amuledlg
->m_serverwnd
->serverlistctrl
->
817 HighlightServer(m_CurrServer
, false);
819 theApp
->amuledlg
->m_serverwnd
->serverlistctrl
->
820 HighlightServer(server
, true);
821 m_CurrServer
= server
;
822 theApp
->m_ConnState
|= CONNECTED_ED2K
;
824 if ( m_CurrServer
) {
825 theApp
->amuledlg
->m_serverwnd
->serverlistctrl
->
826 HighlightServer(m_CurrServer
, false);
831 if (tag
->IsConnectedKademlia()) {
832 if (tag
->IsKadFirewalled()) {
833 theApp
->m_ConnState
|= CONNECTED_KAD_FIREWALLED
;
835 theApp
->m_ConnState
|= CONNECTED_KAD_OK
;
838 if (tag
->IsKadRunning()) {
839 theApp
->m_ConnState
|= CONNECTED_KAD_NOT
;
843 theApp
->amuledlg
->ShowConnectionState();
848 * Server list: host list of ed2k servers.
850 CServerListRem::CServerListRem(CRemoteConnect
*conn
)
852 CRemoteContainer
<CServer
, uint32
, CEC_Server_Tag
>(conn
)
857 void CServerListRem::HandlePacket(const CECPacket
*packet
)
859 CRemoteContainer
<CServer
, uint32
, CEC_Server_Tag
>::HandlePacket(packet
);
864 void CServerListRem::UpdateServerMetFromURL(wxString url
)
866 CECPacket
req(EC_OP_SERVER_UPDATE_FROM_URL
);
867 req
.AddTag(CECTag(EC_TAG_SERVERS_UPDATE_URL
, url
));
869 m_conn
->SendPacket(&req
);
873 void CServerListRem::SaveServerMet()
875 // lfroen: stub, nothing to do
879 void CServerListRem::FilterServers()
886 void CServerListRem::RemoveServer(CServer
* server
)
888 m_conn
->RemoveServer(server
->GetIP(),server
->GetPort());
892 void CServerListRem::UpdateUserFileStatus(CServer
*server
)
895 m_TotalUser
= server
->GetUsers();
896 m_TotalFile
= server
->GetFiles();
899 CFormat(_("Total Users: %s | Total Files: %s")) % CastItoIShort(m_TotalUser
) % CastItoIShort(m_TotalFile
);
901 Notify_ShowUserCount(buffer
);
906 CServer
*CServerListRem::GetServerByAddress(const wxString
& WXUNUSED(address
), uint16
WXUNUSED(port
)) const
908 // It's ok to return 0 for context where this code is used in remote gui
912 CServer
*CServerListRem::GetServerByIPTCP(uint32
WXUNUSED(nIP
), uint16
WXUNUSED(nPort
)) const
914 // It's ok to return 0 for context where this code is used in remote gui
918 CServer
*CServerListRem::CreateItem(CEC_Server_Tag
*tag
)
920 return new CServer(tag
);
924 void CServerListRem::DeleteItem(CServer
*in_srv
)
926 CScopedPtr
<CServer
> srv(in_srv
);
927 theApp
->amuledlg
->m_serverwnd
->serverlistctrl
->RemoveServer(srv
.get());
931 uint32
CServerListRem::GetItemID(CServer
*server
)
933 return server
->GetIP();
937 void CServerListRem::ProcessItemUpdate(CEC_Server_Tag
*, CServer
*)
939 // server list is always realoaded from scratch
944 void CServerListRem::ReloadControl()
946 for(uint32 i
= 0;i
< GetCount(); i
++) {
947 CServer
*srv
= GetByIndex(i
);
948 theApp
->amuledlg
->m_serverwnd
->serverlistctrl
->RefreshServer(srv
);
953 CIPFilterRem::CIPFilterRem(CRemoteConnect
* conn
)
959 void CIPFilterRem::Reload()
961 CECPacket
req(EC_OP_IPFILTER_RELOAD
);
962 m_conn
->SendPacket(&req
);
966 void CIPFilterRem::Update(wxString
WXUNUSED(url
))
968 // FIXME: add command
976 CSharedFilesRem::CSharedFilesRem(CRemoteConnect
*conn
) : CRemoteContainer
<CKnownFile
, CMD4Hash
, CEC_SharedFile_Tag
>(conn
, true)
978 m_rename_file
= NULL
;
982 void CSharedFilesRem::Reload(bool, bool)
984 CECPacket
req(EC_OP_SHAREDFILES_RELOAD
);
986 m_conn
->SendPacket(&req
);
990 void CSharedFilesRem::AddFilesFromDirectory(const CPath
& path
)
992 CECPacket
req(EC_OP_SHAREDFILES_ADD_DIRECTORY
);
994 req
.AddTag(CECTag(EC_TAG_PREFS_DIRECTORIES
, path
.GetRaw()));
996 m_conn
->SendPacket(&req
);
1000 bool CSharedFilesRem::RenameFile(CKnownFile
* file
, const CPath
& newName
)
1002 // We use the printable name, as the filename originated from user input,
1003 // and the filesystem name might not be valid on the remote host.
1004 const wxString strNewName
= newName
.GetPrintable();
1006 CECPacket
request(EC_OP_RENAME_FILE
);
1007 request
.AddTag(CECTag(EC_TAG_KNOWNFILE
, file
->GetFileHash()));
1008 request
.AddTag(CECTag(EC_TAG_PARTFILE_NAME
, strNewName
));
1010 m_conn
->SendRequest(this, &request
);
1011 m_rename_file
= file
;
1012 m_new_name
= strNewName
;
1018 void CSharedFilesRem::HandlePacket(const CECPacket
*packet
)
1020 if (m_rename_file
&& (packet
->GetOpCode() == EC_OP_NOOP
)) {
1021 m_rename_file
->SetFileName(CPath(m_new_name
));
1022 m_rename_file
= NULL
;
1023 } else if (packet
->GetOpCode() != EC_OP_FAILED
) {
1024 CRemoteContainer
<CKnownFile
, CMD4Hash
, CEC_SharedFile_Tag
>::HandlePacket(packet
);
1029 CKnownFile
*CSharedFilesRem::CreateItem(CEC_SharedFile_Tag
*tag
)
1031 CKnownFile
*file
= new CKnownFile(tag
);
1033 m_enc_map
[file
->GetFileHash()] = RLE_Data(file
->GetPartCount(), true);
1035 ProcessItemUpdate(tag
, file
);
1037 theApp
->amuledlg
->m_sharedfileswnd
->sharedfilesctrl
->ShowFile(file
);
1043 void CSharedFilesRem::DeleteItem(CKnownFile
*in_file
)
1045 CScopedPtr
<CKnownFile
> file(in_file
);
1047 m_enc_map
.erase(file
->GetFileHash());
1049 theApp
->amuledlg
->m_sharedfileswnd
->sharedfilesctrl
->RemoveFile(file
.get());
1053 CMD4Hash
CSharedFilesRem::GetItemID(CKnownFile
*file
)
1055 return file
->GetFileHash();
1059 void CSharedFilesRem::ProcessItemUpdate(CEC_SharedFile_Tag
*tag
, CKnownFile
*file
)
1061 CECTag
*parttag
= tag
->GetTagByName(EC_TAG_PARTFILE_PART_STATUS
);
1062 const unsigned char *data
=
1063 m_enc_map
[file
->GetFileHash()].Decode(
1064 (unsigned char *)parttag
->GetTagData(),
1065 parttag
->GetTagDataLen());
1066 for(int i
= 0; i
< file
->GetPartCount(); ++i
) {
1067 file
->m_AvailPartFrequency
[i
] = data
[i
];
1070 tag
->SetRequests(file
->statistic
.requested
);
1071 tag
->SetAllRequests(file
->statistic
.alltimerequested
);
1072 tag
->SetAccepts(file
->statistic
.accepted
);
1073 tag
->SetAllAccepts(file
->statistic
.alltimeaccepted
);
1074 tag
->SetXferred(file
->statistic
.transferred
);
1075 tag
->SetAllXferred(file
->statistic
.alltimetransferred
);
1076 tag
->SetPrio(file
->m_iUpPriority
);
1078 file
->statistic
.requested
= tag
->GetRequests();
1079 file
->statistic
.alltimerequested
= tag
->GetAllRequests();
1080 file
->statistic
.accepted
= tag
->GetAccepts();
1081 file
->statistic
.alltimeaccepted
= tag
->GetAllAccepts();
1082 file
->statistic
.transferred
= tag
->GetXferred();
1083 file
->statistic
.alltimetransferred
= tag
->GetAllXferred();
1084 file
->m_iUpPriority
= tag
->Prio();
1086 if (file
->m_iUpPriority
>= 10) {
1087 file
->m_iUpPriority
-= 10;
1088 file
->m_bAutoUpPriority
= true;
1090 file
->m_bAutoUpPriority
= false;
1093 theApp
->knownfiles
->requested
+= file
->statistic
.requested
;
1094 theApp
->knownfiles
->transferred
+= file
->statistic
.transferred
;
1095 theApp
->knownfiles
->accepted
+= file
->statistic
.transferred
;
1097 theApp
->amuledlg
->m_sharedfileswnd
->sharedfilesctrl
->UpdateItem(file
);
1100 bool CSharedFilesRem::Phase1Done(const CECPacket
*)
1102 theApp
->knownfiles
->requested
= 0;
1103 theApp
->knownfiles
->transferred
= 0;
1104 theApp
->knownfiles
->accepted
= 0;
1109 void CSharedFilesRem::SetFilePrio(CKnownFile
*file
, uint8 prio
)
1111 CECPacket
req(EC_OP_SHARED_SET_PRIO
);
1113 CECTag
hashtag(EC_TAG_PARTFILE
, file
->GetFileHash());
1114 hashtag
.AddTag(CECTag(EC_TAG_PARTFILE_PRIO
, prio
));
1116 req
.AddTag(hashtag
);
1118 m_conn
->SendPacket(&req
);
1122 * List of uploading and waiting clients.
1124 CUpDownClientListRem::CUpDownClientListRem(CRemoteConnect
*conn
, int viewtype
)
1126 CRemoteContainer
<CUpDownClient
, uint32
, CEC_UpDownClient_Tag
>(conn
)
1128 m_viewtype
= viewtype
;
1132 CUpDownClient::CUpDownClient(CEC_UpDownClient_Tag
*tag
)
1134 m_bRemoteQueueFull
= false;
1135 m_nUserIDHybrid
= tag
->ID();
1136 m_Username
= tag
->ClientName();
1137 m_score
= tag
->Score();
1138 m_clientSoft
= tag
->ClientSoftware();
1139 m_clientVersionString
= GetSoftName(m_clientSoft
);
1140 m_clientSoftString
= m_clientVersionString
;
1142 // The functions to retrieve m_clientVerString information are
1143 // currently in BaseClient.cpp, which is not linked in remote-gui app.
1144 // So, in the meantime, we use a tag sent from core.
1145 m_clientVerString
= tag
->SoftVerStr();
1146 m_strModVersion
= wxEmptyString
;
1147 wxString clientModString
;
1148 if (!clientModString
.IsEmpty()) {
1149 m_clientVerString
+= wxT(" - ") + clientModString
;
1151 m_fullClientVerString
= m_clientSoftString
+ wxT(" ") + m_clientVerString
;
1154 m_UserHash
= tag
->UserID();
1157 m_nConnectIP
= m_dwUserIP
= tag
->UserIP();
1158 m_nUserPort
= tag
->UserPort();
1159 m_FullUserIP
= m_nConnectIP
;
1162 m_dwServerIP
= tag
->ServerIP();
1163 m_nServerPort
= tag
->ServerPort();
1164 m_ServerName
= tag
->ServerName();
1166 m_waitingPosition
= tag
->WaitingPosition();
1169 if (tag
->HaveFile()) {
1170 CMD4Hash filehash
= tag
->FileID();
1171 m_uploadingfile
= theApp
->sharedfiles
->GetByID(filehash
);
1172 if (!m_uploadingfile
) {
1173 m_uploadingfile
= theApp
->downloadqueue
->GetByID(filehash
);
1176 m_uploadingfile
= NULL
;
1179 m_nCurSessionUp
= 0;
1181 credits
= new CClientCredits(new CreditStruct());
1184 uint16
CUpQueueRem::GetWaitingPosition(const CUpDownClient
*client
) const
1186 return client
->GetWaitingPosition();
1189 /* Warning: do common base */
1192 bool CUpDownClient::IsIdentified() const
1194 return (credits
&& credits
->GetCurrentIdentState(GetIP()) == IS_IDENTIFIED
);
1198 bool CUpDownClient::IsBadGuy() const
1200 return (credits
&& credits
->GetCurrentIdentState(GetIP()) == IS_IDBADGUY
);
1204 bool CUpDownClient::SUIFailed() const
1206 return (credits
&& credits
->GetCurrentIdentState(GetIP()) == IS_IDFAILED
);
1210 bool CUpDownClient::SUINeeded() const
1212 return (credits
&& credits
->GetCurrentIdentState(GetIP()) == IS_IDNEEDED
);
1216 bool CUpDownClient::SUINotSupported() const
1218 return (credits
&& credits
->GetCurrentIdentState(GetIP()) == IS_NOTAVAILABLE
);
1222 uint64
CUpDownClient::GetDownloadedTotal() const
1224 return credits
? credits
->GetDownloadedTotal() : 0;
1228 uint64
CUpDownClient::GetUploadedTotal() const
1230 return credits
? credits
->GetUploadedTotal() : 0;
1234 double CUpDownClient::GetScoreRatio() const
1236 return credits
? credits
->GetScoreRatio(GetIP(), theApp
->CryptoAvailable()) : 0;
1242 CUpDownClient::~CUpDownClient()
1250 CUpDownClient
*CUpDownClientListRem::CreateItem(CEC_UpDownClient_Tag
*tag
)
1252 CUpDownClient
*client
= new CUpDownClient(tag
);
1253 ProcessItemUpdate(tag
, client
);
1255 theApp
->amuledlg
->m_transferwnd
->clientlistctrl
->InsertClient(client
, (ViewType
)m_viewtype
);
1261 void CUpDownClientListRem::DeleteItem(CUpDownClient
*client
)
1263 theApp
->amuledlg
->m_transferwnd
->clientlistctrl
->
1264 RemoveClient(client
, (ViewType
)m_viewtype
);
1269 uint32
CUpDownClientListRem::GetItemID(CUpDownClient
*client
)
1271 return client
->GetUserIDHybrid();
1275 void CUpDownClientListRem::ProcessItemUpdate(
1276 CEC_UpDownClient_Tag
*tag
,
1277 CUpDownClient
*client
)
1279 uint16 state
= tag
->ClientState();
1281 client
->m_nDownloadState
= state
& 0xff;
1282 client
->m_nUploadState
= (state
>> 8) & 0xff;
1284 client
->m_nUpDatarate
= tag
->SpeedUp();
1285 if ( client
->m_nDownloadState
== DS_DOWNLOADING
) {
1286 client
->kBpsDown
= tag
->SpeedDown() / 1024.0;
1288 client
->kBpsDown
= 0;
1291 client
->m_WaitTime
= tag
->WaitTime();
1292 client
->m_UpStartTimeDelay
= tag
->XferTime();
1293 client
->m_dwLastUpRequest
= tag
->LastReqTime();
1294 client
->m_WaitStartTime
= tag
->QueueTime();
1296 CreditStruct
*credit_struct
=
1297 (CreditStruct
*)client
->credits
->GetDataStruct();
1298 credit_struct
->uploaded
= tag
->XferUp();
1299 client
->m_nTransferredUp
= tag
->XferUpSession();
1301 credit_struct
->downloaded
= tag
->XferDown();
1305 CUpQueueRem::CUpQueueRem(CRemoteConnect
*conn
)
1307 m_up_list(conn
, vtUploading
), m_wait_list(conn
, vtQueued
)
1313 * Download queue container: hold PartFiles with progress status
1318 CDownQueueRem::CDownQueueRem(CRemoteConnect
*conn
)
1320 CRemoteContainer
<CPartFile
, CMD4Hash
, CEC_PartFile_Tag
>(conn
, true)
1325 bool CDownQueueRem::AddLink(const wxString
&link
, int)
1327 CECPacket
req(EC_OP_ADD_LINK
);
1328 req
.AddTag(CECTag(EC_TAG_STRING
, link
));
1330 m_conn
->SendPacket(&req
);
1335 void CDownQueueRem::StopUDPRequests()
1337 // have no idea what is it about
1341 void CDownQueueRem::ResetCatParts(int)
1343 // called when category being deleted. Command will be performed on remote side
1347 bool CDownQueueRem::IsPartFile(const CKnownFile
*) const
1349 // hope i understand it right
1354 void CDownQueueRem::OnConnectionState(bool)
1359 CPartFile
*CDownQueueRem::CreateItem(CEC_PartFile_Tag
*tag
)
1361 CPartFile
*file
= new CPartFile(tag
);
1362 m_enc_map
[file
->GetFileHash()] = PartFileEncoderData(file
->GetPartCount(), 10);
1363 ProcessItemUpdate(tag
, file
);
1365 theApp
->amuledlg
->m_transferwnd
->downloadlistctrl
->AddFile(file
);
1370 void CDownQueueRem::DeleteItem(CPartFile
*in_file
)
1372 CScopedPtr
<CPartFile
> file(in_file
);
1374 theApp
->amuledlg
->m_transferwnd
->downloadlistctrl
->RemoveFile(file
.get());
1376 m_enc_map
.erase(file
->GetFileHash());
1380 CMD4Hash
CDownQueueRem::GetItemID(CPartFile
*file
)
1382 return file
->GetFileHash();
1386 void CDownQueueRem::ProcessItemUpdate(CEC_PartFile_Tag
*tag
, CPartFile
*file
)
1392 uint32 tmpval
= (uint32
)(file
->kBpsDown
* 1024);
1393 tag
->SetSpeed(tmpval
);
1394 file
->kBpsDown
= tmpval
/ 1024.0;
1396 tag
->SetSizeXfer(file
->transferred
);
1397 tag
->SetSizeDone(file
->completedsize
);
1398 tag
->SetSourceXferCount(file
->transferingsrc
);
1399 tag
->SetSourceNotCurrCount(file
->m_notCurrentSources
);
1400 tag
->SetSourceCount(file
->m_source_count
);
1401 tag
->SetSourceCountA4AF(file
->m_a4af_source_count
);
1402 tag
->SetFileStatus(file
->status
);
1404 tag
->SetLastSeenComplete(file
->lastseencomplete
);
1406 tag
->SetFileCat(file
->m_category
);
1408 tag
->SetPrio(file
->m_iDownPriority
);
1410 file
->kBpsDown
= tag
->Speed() / 1024.0;
1412 if ( file
->kBpsDown
> 0 ) {
1413 file
->transferred
= tag
->SizeXfer();
1414 file
->SetCompletedSize(tag
->SizeDone());
1417 file
->transferingsrc
= tag
->SourceXferCount();
1418 file
->m_notCurrentSources
= tag
->SourceNotCurrCount();
1419 file
->m_source_count
= tag
->SourceCount();
1420 file
->m_a4af_source_count
= tag
->SourceCountA4AF();
1421 file
->status
= tag
->FileStatus();
1423 file
->lastseencomplete
= tag
->LastSeenComplete();
1425 file
->m_category
= tag
->FileCat();
1427 file
->m_iDownPriority
= tag
->Prio();
1428 if ( file
->m_iDownPriority
>= 10 ) {
1429 file
->m_iDownPriority
-= 10;
1430 file
->m_bAutoDownPriority
= true;
1432 file
->m_bAutoDownPriority
= false;
1435 file
->percentcompleted
= (100.0*file
->GetCompletedSize()) / file
->GetFileSize();
1436 if ( file
->m_iDownPriority
>= 10 ) {
1437 file
->m_iDownPriority
-= 10;
1438 file
->m_bAutoUpPriority
= true;
1440 file
->m_bAutoUpPriority
= false;
1444 // Copy part/gap status
1446 CECTag
*gaptag
= tag
->GetTagByName(EC_TAG_PARTFILE_GAP_STATUS
);
1447 CECTag
*parttag
= tag
->GetTagByName(EC_TAG_PARTFILE_PART_STATUS
);
1448 CECTag
*reqtag
= tag
->GetTagByName(EC_TAG_PARTFILE_REQ_STATUS
);
1449 if (gaptag
&& parttag
&& reqtag
) {
1450 wxASSERT(m_enc_map
.count(file
->GetFileHash()));
1452 PartFileEncoderData
&encoder
= m_enc_map
[file
->GetFileHash()];
1454 (unsigned char *)gaptag
->GetTagData(), gaptag
->GetTagDataLen(),
1455 (unsigned char *)parttag
->GetTagData(), parttag
->GetTagDataLen());
1457 const uint64
*reqparts
= (const uint64
*)reqtag
->GetTagData();
1458 unsigned reqcount
= reqtag
->GetTagDataLen() / (2 * sizeof(uint64
));
1460 unsigned gap_size
= encoder
.m_gap_status
.Size() / (2 * sizeof(uint64
));
1462 file
->m_gaplist
.Init(file
->GetFileSize(), false);
1465 const uint64
*gap_info
= (const uint64
*)encoder
.m_gap_status
.Buffer();
1466 for (unsigned j
= 0; j
< gap_size
;j
++) {
1467 file
->m_gaplist
.AddGap(ENDIAN_NTOHLL(gap_info
[2*j
]), ENDIAN_NTOHLL(gap_info
[2*j
+1]));
1470 // adjust size of requested block list
1471 while ( file
->m_requestedblocks_list
.size() > reqcount
) {
1472 delete file
->m_requestedblocks_list
.front();
1473 file
->m_requestedblocks_list
.pop_front();
1475 while ( file
->m_requestedblocks_list
.size() != reqcount
) {
1476 file
->m_requestedblocks_list
.push_front(new Requested_Block_Struct
);
1479 std::list
<Requested_Block_Struct
*>::iterator it2
= file
->m_requestedblocks_list
.begin();
1480 for (unsigned i
= 0; i
< reqcount
; ++i
) {
1481 Requested_Block_Struct
* block
= *it2
++;
1482 block
->StartOffset
= ENDIAN_NTOHLL(reqparts
[2*i
]);
1483 block
->EndOffset
= ENDIAN_NTOHLL(reqparts
[2*i
+1]);
1485 // copy parts frequency
1486 const unsigned char *part_info
= encoder
.m_part_status
.Buffer();
1487 for(int i
= 0; i
< file
->GetPartCount(); ++i
) {
1488 file
->m_SrcpartFrequency
[i
] = part_info
[i
];
1491 AddLogLineNS(CFormat(wxT("ERROR: %X %X %X")) % (size_t)gaptag
% (size_t)parttag
% (size_t)reqtag
);
1495 CECTag
*srcnametag
= tag
->GetTagByName(EC_TAG_PARTFILE_SOURCE_NAMES
);
1497 file
->ClearSourcenameItemList();
1498 int max
= srcnametag
->GetTagCount();
1499 for (int i
= 0; i
< max
- 1; ) {
1500 wxString name
= srcnametag
->GetTagByIndex(i
++)->GetStringData();
1501 long count
= srcnametag
->GetTagByIndex(i
++)->GetInt();
1502 file
->AddSourcenameItemList(name
, count
);
1507 CECTag
*commenttag
= tag
->GetTagByName(EC_TAG_PARTFILE_COMMENTS
);
1509 file
->ClearFileRatingList();
1510 int max
= commenttag
->GetTagCount();
1511 for (int i
= 0; i
< max
- 3; ) {
1512 wxString u
= commenttag
->GetTagByIndex(i
++)->GetStringData();
1513 wxString f
= commenttag
->GetTagByIndex(i
++)->GetStringData();
1514 int r
= commenttag
->GetTagByIndex(i
++)->GetInt();
1515 wxString c
= commenttag
->GetTagByIndex(i
++)->GetStringData();
1516 file
->AddFileRatingList(u
, f
, r
, c
);
1518 file
->UpdateFileRatingCommentAvail();
1521 theApp
->amuledlg
->m_transferwnd
->downloadlistctrl
->UpdateItem(file
);
1525 bool CDownQueueRem::Phase1Done(const CECPacket
*)
1531 void CDownQueueRem::SendFileCommand(CPartFile
*file
, ec_tagname_t cmd
)
1534 req
.AddTag(CECTag(EC_TAG_PARTFILE
, file
->GetFileHash()));
1536 m_conn
->SendPacket(&req
);
1540 void CDownQueueRem::Prio(CPartFile
*file
, uint8 prio
)
1542 CECPacket
req(EC_OP_PARTFILE_PRIO_SET
);
1544 CECTag
hashtag(EC_TAG_PARTFILE
, file
->GetFileHash());
1545 hashtag
.AddTag(CECTag(EC_TAG_PARTFILE_PRIO
, prio
));
1546 req
.AddTag(hashtag
);
1548 m_conn
->SendPacket(&req
);
1552 void CDownQueueRem::AutoPrio(CPartFile
*file
, bool flag
)
1554 CECPacket
req(EC_OP_PARTFILE_PRIO_SET
);
1556 CECTag
hashtag(EC_TAG_PARTFILE
, file
->GetFileHash());
1558 hashtag
.AddTag(CECTag(EC_TAG_PARTFILE_PRIO
,
1559 (uint8
)(flag
? PR_AUTO
: file
->GetDownPriority())));
1560 req
.AddTag(hashtag
);
1562 m_conn
->SendPacket(&req
);
1566 void CDownQueueRem::Category(CPartFile
*file
, uint8 cat
)
1568 CECPacket
req(EC_OP_PARTFILE_SET_CAT
);
1569 file
->m_category
= cat
;
1571 CECTag
hashtag(EC_TAG_PARTFILE
, file
->GetFileHash());
1572 hashtag
.AddTag(CECTag(EC_TAG_PARTFILE_CAT
, cat
));
1573 req
.AddTag(hashtag
);
1575 m_conn
->SendPacket(&req
);
1579 void CDownQueueRem::AddSearchToDownload(CSearchFile
* file
, uint8 category
)
1581 CECPacket
req(EC_OP_DOWNLOAD_SEARCH_RESULT
);
1582 CECTag
hashtag(EC_TAG_PARTFILE
, file
->GetFileHash());
1583 hashtag
.AddTag(CECTag(EC_TAG_PARTFILE_CAT
, category
));
1584 req
.AddTag(hashtag
);
1586 m_conn
->SendPacket(&req
);
1590 CClientListRem::CClientListRem(CRemoteConnect
*conn
)
1596 void CClientListRem::FilterQueues()
1603 CSearchListRem::CSearchListRem(CRemoteConnect
*conn
) : CRemoteContainer
<CSearchFile
, CMD4Hash
, CEC_SearchFile_Tag
>(conn
)
1609 wxString
CSearchListRem::StartNewSearch(
1610 uint32
* nSearchID
, SearchType search_type
,
1611 const CSearchList::CSearchParams
& params
)
1613 CECPacket
search_req(EC_OP_SEARCH_START
);
1614 EC_SEARCH_TYPE ec_search_type
= EC_SEARCH_LOCAL
;
1615 switch(search_type
) {
1616 case LocalSearch
: ec_search_type
= EC_SEARCH_LOCAL
; break;
1617 case GlobalSearch
: ec_search_type
= EC_SEARCH_GLOBAL
; break;
1618 case KadSearch
: ec_search_type
= EC_SEARCH_KAD
; break;
1621 CEC_Search_Tag(params
.searchString
, ec_search_type
,
1622 params
.typeText
, params
.extension
, params
.availability
,
1623 params
.minSize
, params
.maxSize
));
1625 m_conn
->SendPacket(&search_req
);
1626 m_curr_search
= *(nSearchID
); // No kad remote search yet.
1630 return wxEmptyString
; // EC reply will have the error mesg is needed.
1634 void CSearchListRem::StopGlobalSearch()
1636 if (m_curr_search
!= -1) {
1637 CECPacket
search_req(EC_OP_SEARCH_STOP
);
1638 m_conn
->SendPacket(&search_req
);
1643 void CSearchListRem::HandlePacket(const CECPacket
*packet
)
1645 if ( packet
->GetOpCode() == EC_OP_SEARCH_PROGRESS
) {
1646 CoreNotify_Search_Update_Progress(packet
->GetTagByIndex(0)->GetInt());
1648 CRemoteContainer
<CSearchFile
, CMD4Hash
, CEC_SearchFile_Tag
>::HandlePacket(packet
);
1653 CSearchFile::CSearchFile(CEC_SearchFile_Tag
*tag
)
1656 m_showChildren(false),
1658 m_completeSourceCount(0),
1663 SetFileName(CPath(tag
->FileName()));
1664 m_abyFileHash
= tag
->ID();
1665 SetFileSize(tag
->SizeFull());
1667 m_searchID
= theApp
->searchlist
->m_curr_search
;
1672 // dtor is virtual - must be implemented
1673 CSearchFile::~CSearchFile()
1678 CSearchFile
*CSearchListRem::CreateItem(CEC_SearchFile_Tag
*tag
)
1680 CSearchFile
*file
= new CSearchFile(tag
);
1681 ProcessItemUpdate(tag
, file
);
1683 theApp
->amuledlg
->m_searchwnd
->AddResult(file
);
1689 void CSearchListRem::DeleteItem(CSearchFile
*file
)
1695 CMD4Hash
CSearchListRem::GetItemID(CSearchFile
*file
)
1697 return file
->GetFileHash();
1701 void CSearchListRem::ProcessItemUpdate(CEC_SearchFile_Tag
*tag
, CSearchFile
*file
)
1703 file
->m_sourceCount
= tag
->SourceCount();
1704 file
->m_completeSourceCount
= tag
->CompleteSourceCount();
1708 bool CSearchListRem::Phase1Done(const CECPacket
*WXUNUSED(reply
))
1710 CECPacket
progress_req(EC_OP_SEARCH_PROGRESS
);
1711 m_conn
->SendRequest(this, &progress_req
);
1717 void CSearchListRem::RemoveResults(long nSearchID
)
1719 ResultMap::iterator it
= m_results
.find(nSearchID
);
1720 if (it
!= m_results
.end()) {
1721 CSearchResultList
& list
= it
->second
;
1722 for (unsigned int i
= 0; i
< list
.size(); ++i
) {
1725 m_results
.erase(it
);
1730 const CSearchResultList
& CSearchListRem::GetSearchResults(long nSearchID
)
1732 ResultMap::const_iterator it
= m_results
.find(nSearchID
);
1733 if (it
!= m_results
.end()) {
1737 // TODO: Should we assert in this case?
1738 static CSearchResultList list
;
1743 void CStatsUpdaterRem::HandlePacket(const CECPacket
*packet
)
1745 theStats::UpdateStats(packet
);
1746 theApp
->ShowUserCount(); // maybe there should be a check if a usercount changed ?
1750 bool CUpDownClient::IsBanned() const
1758 // Those functions have different implementation in remote gui
1760 void CUpDownClient::Ban()
1767 void CUpDownClient::UnBan()
1774 void CUpDownClient::RequestSharedFileList()
1781 void CKnownFile::SetFileComment(const wxString
&)
1788 void CKnownFile::SetFileRating(unsigned char)
1795 // I don't think it will be implemented - too match data transfer. But who knows ?
1796 wxString
CUpDownClient::ShowDownloadingParts() const
1798 return wxEmptyString
;
1802 bool CUpDownClient::SwapToAnotherFile(
1803 bool WXUNUSED(bIgnoreNoNeeded
),
1804 bool WXUNUSED(ignoreSuspensions
),
1805 bool WXUNUSED(bRemoveCompletely
),
1806 CPartFile
* WXUNUSED(toFile
))
1815 // Those functions are virtual. So even they don't get called they must
1816 // be defined so linker will be happy
1818 CPacket
* CKnownFile::CreateSrcInfoPacket(const CUpDownClient
*, uint8
/*byRequestedVersion*/, uint16
/*nRequestedOptions*/)
1825 bool CKnownFile::LoadFromFile(const class CFileDataIO
*)
1832 void CKnownFile::UpdatePartsInfo()
1838 CPacket
* CPartFile::CreateSrcInfoPacket(CUpDownClient
const *, uint8
/*byRequestedVersion*/, uint16
/*nRequestedOptions*/)
1845 void CPartFile::UpdatePartsInfo()
1851 void CPartFile::UpdateFileRatingCommentAvail()
1853 bool prevComment
= m_hasComment
;
1854 int prevRating
= m_iUserRating
;
1856 m_hasComment
= false;
1858 int ratingCount
= 0;
1860 FileRatingList::iterator it
= m_FileRatingList
.begin();
1861 for (; it
!= m_FileRatingList
.end(); ++it
) {
1862 SFileRating
& cur_rat
= *it
;
1864 if (!cur_rat
.Comment
.IsEmpty()) {
1865 m_hasComment
= true;
1868 uint8 rating
= cur_rat
.Rating
;
1870 wxASSERT(rating
<= 5);
1873 m_iUserRating
+= rating
;
1878 m_iUserRating
/= ratingCount
;
1879 wxASSERT(m_iUserRating
> 0 && m_iUserRating
<= 5);
1882 if ((prevComment
!= m_hasComment
) || (prevRating
!= m_iUserRating
)) {
1883 UpdateDisplayedInfo();
1887 bool CPartFile::SavePartFile(bool)
1895 // since gui is not linked with amule.cpp - define events here
1897 DEFINE_LOCAL_EVENT_TYPE(wxEVT_CORE_FINISHED_HTTP_DOWNLOAD
)
1898 DEFINE_LOCAL_EVENT_TYPE(wxEVT_CORE_SOURCE_DNS_DONE
)
1899 DEFINE_LOCAL_EVENT_TYPE(wxEVT_CORE_UDP_DNS_DONE
)
1900 DEFINE_LOCAL_EVENT_TYPE(wxEVT_CORE_SERVER_DNS_DONE
)
1901 // File_checked_for_headers