Upstream tarball 9894
[amule.git] / src / amule-remote-gui.cpp
blobff31d1dd366f3936a570147f1290d7fbef2da8db
1 //
2 // This file is part of the aMule Project.
3 //
4 // Copyright (c) 2005-2008 aMule Team ( admin@amule.org / http://www.amule.org )
5 //
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
8 // respective authors.
9 //
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.
19 //
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
29 #include <wx/ipc.h>
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
52 #endif
53 #include "InternalEvents.h" // Needed for wxEVT_CORE_FINISHED_HTTP_DOWNLOAD
54 #include "Logger.h"
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 "ScopedPtr.h"
68 CEConnectDlg::CEConnectDlg()
70 wxDialog(theApp->amuledlg, -1, _("Connect to remote amule"), wxDefaultPosition)
72 CoreConnect(this, true);
74 wxString pref_host, pref_port;
75 wxConfig::Get()->Read(wxT("/EC/Host"), &pref_host, wxT("localhost"));
76 wxConfig::Get()->Read(wxT("/EC/Port"), &pref_port, wxT("4712"));
77 wxConfig::Get()->Read(wxT("/EC/Password"), &pwd_hash);
79 CastChild(ID_REMOTE_HOST, wxTextCtrl)->SetValue(pref_host);
80 CastChild(ID_REMOTE_PORT, wxTextCtrl)->SetValue(pref_port);
81 CastChild(ID_EC_PASSWD, wxTextCtrl)->SetValue(pwd_hash);
83 CentreOnParent();
87 wxString CEConnectDlg::PassHash()
89 return pwd_hash;
93 BEGIN_EVENT_TABLE(CEConnectDlg, wxDialog)
94 EVT_BUTTON(wxID_OK, CEConnectDlg::OnOK)
95 END_EVENT_TABLE()
98 void CEConnectDlg::OnOK(wxCommandEvent& evt)
100 wxString s_port = CastChild(ID_REMOTE_PORT, wxTextCtrl)->GetValue();
101 port = StrToLong(s_port);
103 host = CastChild(ID_REMOTE_HOST, wxTextCtrl)->GetValue();
104 passwd = CastChild(ID_EC_PASSWD, wxTextCtrl)->GetValue();
106 if (passwd != pwd_hash) {
107 pwd_hash = MD5Sum(passwd).GetHash();
109 m_save_user_pass = CastChild(ID_EC_SAVE, wxCheckBox)->IsChecked();
110 evt.Skip();
114 DEFINE_LOCAL_EVENT_TYPE(wxEVT_EC_INIT_DONE)
117 BEGIN_EVENT_TABLE(CamuleRemoteGuiApp, wxApp)
118 // Core timer
119 EVT_TIMER(ID_CORE_TIMER_EVENT, CamuleRemoteGuiApp::OnPollTimer)
121 EVT_CUSTOM(wxEVT_EC_CONNECTION, -1, CamuleRemoteGuiApp::OnECConnection)
122 EVT_CUSTOM(wxEVT_EC_INIT_DONE, -1, CamuleRemoteGuiApp::OnECInitDone)
124 EVT_MULE_NOTIFY(CamuleRemoteGuiApp::OnNotifyEvent)
126 #ifdef ENABLE_IP2COUNTRY
127 // HTTPDownload finished
128 EVT_MULE_INTERNAL(wxEVT_CORE_FINISHED_HTTP_DOWNLOAD, -1, CamuleRemoteGuiApp::OnFinishedHTTPDownload)
129 #endif
130 END_EVENT_TABLE()
133 IMPLEMENT_APP(CamuleRemoteGuiApp)
136 int CamuleRemoteGuiApp::OnExit()
138 StopTickTimer();
140 return wxApp::OnExit();
144 void CamuleRemoteGuiApp::OnPollTimer(wxTimerEvent&)
146 static int request_step = 0;
148 if (m_connect->RequestFifoFull()) {
149 return;
152 switch (request_step) {
153 case 0:
154 serverconnect->ReQuery();
155 serverlist->UpdateUserFileStatus(serverconnect->GetCurrentServer());
156 request_step++;
157 break;
158 case 1: {
159 CECPacket stats_req(EC_OP_STAT_REQ);
160 m_connect->SendRequest(&m_stats_updater, &stats_req);
161 amuledlg->ShowTransferRate();
162 request_step++;
163 break;
165 case 2:
166 if (amuledlg->m_sharedfileswnd->IsShown()) {
167 sharedfiles->DoRequery(EC_OP_GET_SHARED_FILES, EC_TAG_KNOWNFILE);
168 } else if (amuledlg->m_serverwnd->IsShown()) {
169 //serverlist->FullReload(EC_OP_GET_SERVER_LIST);
170 } else if (amuledlg->m_transferwnd->IsShown()) {
171 downloadqueue->DoRequery(EC_OP_GET_DLOAD_QUEUE, EC_TAG_PARTFILE);
172 switch(amuledlg->m_transferwnd->clientlistctrl->GetListView()) {
173 case vtUploading:
174 uploadqueue->ReQueryUp();
175 break;
176 case vtQueued:
177 uploadqueue->ReQueryWait();
178 break;
179 case vtClients:
180 break;
181 case vtNone:
182 break;
184 amuledlg->m_transferwnd->ShowQueueCount(theStats::GetWaitingUserCount());
185 } else if (amuledlg->m_searchwnd->IsShown()) {
186 if (searchlist->m_curr_search != -1) {
187 searchlist->DoRequery(EC_OP_SEARCH_RESULTS, EC_TAG_SEARCHFILE);
190 // Back to the roots
191 request_step = 0;
192 break;
193 default:
194 AddLogLineCS(wxT("WTF?")); // should not happen. :-)
195 request_step = 0;
198 // Check for new links once per second.
199 static uint32 lastED2KLinkCheck = 0;
200 if (GetTickCount() - lastED2KLinkCheck >= 1000) {
201 AddLinksFromFile();
202 lastED2KLinkCheck = GetTickCount();
207 void CamuleRemoteGuiApp::OnFinishedHTTPDownload(CMuleInternalEvent& event)
209 #ifdef ENABLE_IP2COUNTRY
210 if (event.GetInt() == HTTP_GeoIP) {
211 amuledlg->IP2CountryDownloadFinished(event.GetExtraLong());
212 // If we updated, the dialog is already up. Redraw it to show the flags.
213 amuledlg->Refresh();
215 #endif
219 void CamuleRemoteGuiApp::ShutDown(wxCloseEvent &WXUNUSED(evt))
221 // Stop the Core Timer
222 delete poll_timer;
223 poll_timer = NULL;
225 // Destroy the EC socket
226 m_connect->Destroy();
227 m_connect = NULL;
230 if (amuledlg) {
231 amuledlg->DlgShutDown();
232 amuledlg->Destroy();
233 amuledlg = NULL;
238 bool CamuleRemoteGuiApp::OnInit()
240 StartTickTimer();
241 amuledlg = NULL;
243 // Get theApp
244 theApp = &wxGetApp();
246 // Handle uncaught exceptions
247 InstallMuleExceptionHandler();
249 // Parse cmdline arguments.
250 if (!InitCommon(AMULE_APP_BASE::argc, AMULE_APP_BASE::argv)) {
251 return false;
254 // Create the polling timer
255 poll_timer = new wxTimer(this,ID_CORE_TIMER_EVENT);
256 if (!poll_timer) {
257 AddLogLineCS(_("Fatal Error: Failed to create Poll Timer"));
258 OnExit();
261 m_connect = new CRemoteConnect(this);
263 glob_prefs = new CPreferencesRem(m_connect);
265 InitCustomLanguages();
266 InitLocale(m_locale, StrLang2wx(thePrefs::GetLanguageID()));
268 if (ShowConnectionDialog()) {
269 AddLogLineNS(_("Going to event loop..."));
270 return true;
273 return false;
277 bool CamuleRemoteGuiApp::CryptoAvailable() const
279 return thePrefs::IsSecureIdentEnabled(); // good enough
283 bool CamuleRemoteGuiApp::ShowConnectionDialog()
285 dialog = new CEConnectDlg;
287 if (m_skipConnectionDialog) {
288 wxCommandEvent evt;
289 dialog->OnOK(evt);
290 } else if (dialog->ShowModal() != wxID_OK) {
291 dialog->Destroy();
293 return false;
295 AddLogLineNS(_("Connecting..."));
296 if (!m_connect->ConnectToCore(dialog->Host(), dialog->Port(),
297 dialog->Login(), dialog->PassHash(),
298 wxT("amule-remote"), wxT("0x0001"))) {
299 wxMessageBox(_("Connection failed "),_("ERROR"),wxOK);
301 return false;
304 return true;
308 void CamuleRemoteGuiApp::OnECConnection(wxEvent& event) {
309 wxECSocketEvent& evt = *((wxECSocketEvent*)&event);
310 AddLogLineNS(_("Remote GUI EC event handler"));
311 wxString reply = evt.GetServerReply();
312 AddLogLineM(true, reply);
313 if (evt.GetResult() == true) {
314 // Connected - go to next init step
315 glob_prefs->LoadRemote();
316 } else {
317 AddLogLineNS(_("Going down"));
318 if (dialog) { // connect failed
319 wxMessageBox(
320 (CFormat(_("Connection Failed. Unable to connect to %s:%d\n")) % dialog->Host() % dialog->Port()) + reply,
321 _("ERROR"), wxOK);
322 } else { // server disconnected (probably terminated) later
323 wxMessageBox(_("Connection closed - aMule has terminated probably."), _("ERROR"), wxOK);
325 ExitMainLoop();
330 void CamuleRemoteGuiApp::OnECInitDone(wxEvent& )
332 Startup();
336 void CamuleRemoteGuiApp::OnNotifyEvent(CMuleGUIEvent& evt)
338 evt.Notify();
342 void CamuleRemoteGuiApp::Startup() {
344 if (dialog->SaveUserPass()) {
345 wxConfig::Get()->Write(wxT("/EC/Host"), dialog->Host());
346 wxConfig::Get()->Write(wxT("/EC/Port"), dialog->Port());
347 wxConfig::Get()->Write(wxT("/EC/Password"), dialog->PassHash());
349 dialog->Destroy();
350 dialog = NULL;
352 m_ConnState = 0;
353 m_clientID = 0;
355 serverconnect = new CServerConnectRem(m_connect);
356 m_statistics = new CStatistics(*m_connect);
358 clientlist = new CClientListRem(m_connect);
359 searchlist = new CSearchListRem(m_connect);
360 serverlist = new CServerListRem(m_connect);
362 sharedfiles = new CSharedFilesRem(m_connect);
363 knownfiles = new CKnownFilesRem(sharedfiles);
365 // bugfix - do this before creating the uploadqueue
366 downloadqueue = new CDownQueueRem(m_connect);
367 uploadqueue = new CUpQueueRem(m_connect);
368 ipfilter = new CIPFilterRem(m_connect);
370 // Create main dialog
371 InitGui(m_geometryEnabled, m_geometryString);
373 // Forward wxLog events to CLogger
374 wxLog::SetActiveTarget(new CLoggerTarget);
375 serverlist->FullReload(EC_OP_GET_SERVER_LIST);
376 sharedfiles->DoRequery(EC_OP_GET_SHARED_FILES, EC_TAG_KNOWNFILE);
378 // Start the Poll Timer
379 poll_timer->Start(1000);
380 amuledlg->StartGuiTimer();
382 // Now activate GeoIP, so that the download dialog doesn't get destroyed immediately
383 #ifdef ENABLE_IP2COUNTRY
384 if (thePrefs::IsGeoIPEnabled()) {
385 amuledlg->m_IP2Country->Enable();
387 #endif
391 int CamuleRemoteGuiApp::ShowAlert(wxString msg, wxString title, int flags)
393 return CamuleGuiBase::ShowAlert(msg, title, flags);
397 void CamuleRemoteGuiApp::AddRemoteLogLine(const wxString& line)
399 amuledlg->AddLogLine(line);
402 int CamuleRemoteGuiApp::InitGui(bool geometry_enabled, wxString &geom_string)
404 CamuleGuiBase::InitGui(geometry_enabled, geom_string);
405 SetTopWindow(amuledlg);
406 AddLogLineN(_("Ready")); // The first log line after the window is up triggers output of all the ones before
407 return 0;
411 bool CamuleRemoteGuiApp::CopyTextToClipboard(wxString strText)
413 return CamuleGuiBase::CopyTextToClipboard(strText);
417 uint32 CamuleRemoteGuiApp::GetPublicIP()
419 return 0;
423 wxString CamuleRemoteGuiApp::GetLog(bool)
425 return wxEmptyString;
429 wxString CamuleRemoteGuiApp::GetServerLog(bool)
431 return wxEmptyString;
435 bool CamuleRemoteGuiApp::AddServer(CServer *, bool)
437 // #warning TODO: Add remote command
438 return true;
442 bool CamuleRemoteGuiApp::IsFirewalled() const
444 if (IsConnectedED2K() && !serverconnect->IsLowID()) {
445 return false;
448 return IsFirewalledKad();
452 bool CamuleRemoteGuiApp::IsConnectedED2K() const {
453 return serverconnect && serverconnect->IsConnected();
457 void CamuleRemoteGuiApp::StartKad() {
458 m_connect->StartKad();
462 void CamuleRemoteGuiApp::StopKad() {
463 m_connect->StopKad();
467 void CamuleRemoteGuiApp::BootstrapKad(uint32 ip, uint16 port)
469 CECPacket req(EC_OP_KAD_BOOTSTRAP_FROM_IP);
470 req.AddTag(CECTag(EC_TAG_BOOTSTRAP_IP, ip));
471 req.AddTag(CECTag(EC_TAG_BOOTSTRAP_PORT, port));
473 m_connect->SendPacket(&req);
477 void CamuleRemoteGuiApp::UpdateNotesDat(const wxString& url)
479 CECPacket req(EC_OP_KAD_UPDATE_FROM_URL);
480 req.AddTag(CECTag(EC_TAG_KADEMLIA_UPDATE_URL, url));
482 m_connect->SendPacket(&req);
486 void CamuleRemoteGuiApp::DisconnectED2K() {
487 if (IsConnectedED2K()) {
488 m_connect->DisconnectED2K();
493 uint32 CamuleRemoteGuiApp::GetED2KID() const
495 return serverconnect ? serverconnect->GetClientID() : 0;
499 uint32 CamuleRemoteGuiApp::GetID() const
501 return m_clientID;
505 void CamuleRemoteGuiApp::ShowUserCount() {
506 wxString buffer;
508 static const wxString s_singlenetstatusformat = _("Users: %s | Files: %s");
509 static const wxString s_bothnetstatusformat = _("Users: E: %s K: %s | Files: E: %s K: %s");
511 if (thePrefs::GetNetworkED2K() && thePrefs::GetNetworkKademlia()) {
512 buffer = CFormat(s_bothnetstatusformat) % CastItoIShort(theStats::GetED2KUsers()) % CastItoIShort(theStats::GetKadUsers()) % CastItoIShort(theStats::GetED2KFiles()) % CastItoIShort(theStats::GetKadFiles());
513 } else if (thePrefs::GetNetworkED2K()) {
514 buffer = CFormat(s_singlenetstatusformat) % CastItoIShort(theStats::GetED2KUsers()) % CastItoIShort(theStats::GetED2KFiles());
515 } else if (thePrefs::GetNetworkKademlia()) {
516 buffer = CFormat(s_singlenetstatusformat) % CastItoIShort(theStats::GetKadUsers()) % CastItoIShort(theStats::GetKadFiles());
517 } else {
518 buffer = _("No networks selected");
521 Notify_ShowUserCount(buffer);
526 * Preferences: holds both local and remote settings.
528 * First, everything is loaded from local config file. Later, settings
529 * that are relevant on remote side only are loaded thru EC
531 CPreferencesRem::CPreferencesRem(CRemoteConnect *conn)
533 m_conn = conn;
536 // Settings queried from remote side
538 m_exchange_send_selected_prefs =
539 EC_PREFS_GENERAL |
540 EC_PREFS_CONNECTIONS |
541 EC_PREFS_MESSAGEFILTER |
542 EC_PREFS_ONLINESIG |
543 EC_PREFS_SERVERS |
544 EC_PREFS_FILES |
545 EC_PREFS_SRCDROP |
546 EC_PREFS_DIRECTORIES |
547 EC_PREFS_SECURITY |
548 EC_PREFS_CORETWEAKS |
549 EC_PREFS_REMOTECONTROLS |
550 EC_PREFS_KADEMLIA;
551 m_exchange_recv_selected_prefs =
552 m_exchange_send_selected_prefs |
553 EC_PREFS_CATEGORIES;
557 void CPreferencesRem::HandlePacket(const CECPacket *packet)
559 ((CEC_Prefs_Packet *)packet)->Apply();
561 if ( packet->GetTagByName(EC_TAG_PREFS_CATEGORIES) != 0 ) {
562 for (size_t i = 0; i < packet->GetTagByName(EC_TAG_PREFS_CATEGORIES)->GetTagCount(); i++) {
563 const CECTag *cat_tag = packet->GetTagByName(EC_TAG_PREFS_CATEGORIES)->GetTagByIndex(i);
564 Category_Struct *cat = new Category_Struct;
565 cat->title = cat_tag->GetTagByName(EC_TAG_CATEGORY_TITLE)->GetStringData();
566 cat->path = CPath(cat_tag->GetTagByName(EC_TAG_CATEGORY_PATH)->GetStringData());
567 cat->comment = cat_tag->GetTagByName(EC_TAG_CATEGORY_COMMENT)->GetStringData();
568 cat->color = cat_tag->GetTagByName(EC_TAG_CATEGORY_COLOR)->GetInt();
569 cat->prio = cat_tag->GetTagByName(EC_TAG_CATEGORY_PRIO)->GetInt();
570 theApp->glob_prefs->AddCat(cat);
572 } else {
573 Category_Struct *cat = new Category_Struct;
574 cat->title = _("All");
575 cat->color = 0;
576 cat->prio = PR_NORMAL;
577 theApp->glob_prefs->AddCat(cat);
579 wxECInitDoneEvent event;
580 theApp->AddPendingEvent(event);
585 bool CPreferencesRem::LoadRemote()
588 // override local settings with remote
589 CECPacket req(EC_OP_GET_PREFERENCES, EC_DETAIL_UPDATE);
591 // bring categories too
592 req.AddTag(CECTag(EC_TAG_SELECT_PREFS, m_exchange_recv_selected_prefs));
594 m_conn->SendRequest(this, &req);
596 return true;
600 void CPreferencesRem::SendToRemote()
602 CEC_Prefs_Packet pref_packet(m_exchange_send_selected_prefs, EC_DETAIL_UPDATE, EC_DETAIL_FULL);
603 m_conn->SendPacket(&pref_packet);
607 class CCatHandler : public CECPacketHandlerBase {
608 virtual void HandlePacket(const CECPacket *packet);
612 void CCatHandler::HandlePacket(const CECPacket *packet)
614 if (packet->GetOpCode() == EC_OP_FAILED) {
615 const CECTag * catTag = packet->GetTagByName(EC_TAG_CATEGORY);
616 const CECTag * pathTag = packet->GetTagByName(EC_TAG_CATEGORY_PATH);
617 if (catTag && pathTag && catTag->GetInt() < theApp->glob_prefs->GetCatCount()) {
618 int cat = catTag->GetInt();
619 Category_Struct* cs = theApp->glob_prefs->GetCategory(cat);
620 wxMessageBox(CFormat(_("Can't create directory '%s' for category '%s', keeping directory '%s'."))
621 % cs->path.GetPrintable() % cs->title % pathTag->GetStringData(),
622 _("ERROR"), wxOK);
623 cs->path = CPath(pathTag->GetStringData());
624 theApp->amuledlg->m_transferwnd->UpdateCategory(cat);
625 theApp->amuledlg->m_transferwnd->downloadlistctrl->Refresh();
628 delete this;
632 bool CPreferencesRem::CreateCategory(
633 Category_Struct *& category,
634 const wxString& name,
635 const CPath& path,
636 const wxString& comment,
637 uint32 color,
638 uint8 prio)
640 CECPacket req(EC_OP_CREATE_CATEGORY);
641 CEC_Category_Tag tag(0xffffffff, name, path.GetRaw(), comment, color, prio);
642 req.AddTag(tag);
643 m_conn->SendRequest(new CCatHandler, &req);
645 category = new Category_Struct();
646 category->path = path;
647 category->title = name;
648 category->comment = comment;
649 category->color = color;
650 category->prio = prio;
652 AddCat(category);
654 return true;
658 bool CPreferencesRem::UpdateCategory(
659 uint8 cat,
660 const wxString& name,
661 const CPath& path,
662 const wxString& comment,
663 uint32 color,
664 uint8 prio)
666 CECPacket req(EC_OP_UPDATE_CATEGORY);
667 CEC_Category_Tag tag(cat, name, path.GetRaw(), comment, color, prio);
668 req.AddTag(tag);
669 m_conn->SendRequest(new CCatHandler, &req);
671 Category_Struct *category = m_CatList[cat];
672 category->path = path;
673 category->title = name;
674 category->comment = comment;
675 category->color = color;
676 category->prio = prio;
678 return true;
682 void CPreferencesRem::RemoveCat(uint8 cat)
684 CECPacket req(EC_OP_DELETE_CATEGORY);
685 CEC_Category_Tag tag(cat, EC_DETAIL_CMD);
686 req.AddTag(tag);
687 m_conn->SendPacket(&req);
688 CPreferences::RemoveCat(cat);
693 // Container implementation
695 CServerConnectRem::CServerConnectRem(CRemoteConnect *conn)
697 m_CurrServer = 0;
698 m_Conn = conn;
702 void CServerConnectRem::ConnectToAnyServer()
704 CECPacket req(EC_OP_SERVER_CONNECT);
705 m_Conn->SendPacket(&req);
709 void CServerConnectRem::StopConnectionTry()
711 // lfroen: isn't Disconnect the same ?
715 void CServerConnectRem::Disconnect()
717 CECPacket req(EC_OP_SERVER_DISCONNECT);
718 m_Conn->SendPacket(&req);
722 void CServerConnectRem::ConnectToServer(CServer *server)
724 m_Conn->ConnectED2K(server->GetIP(), server->GetPort());
728 bool CServerConnectRem::ReQuery()
730 CECPacket stat_req(EC_OP_GET_CONNSTATE);
731 m_Conn->SendRequest(this, &stat_req);
733 return true;
737 void CServerConnectRem::HandlePacket(const CECPacket *packet)
739 CEC_ConnState_Tag *tag =
740 (CEC_ConnState_Tag *)packet->GetTagByName(EC_TAG_CONNSTATE);
741 if (!tag) {
742 return;
745 theApp->m_ConnState = 0;
746 CServer *server;
747 m_ID = tag->GetEd2kId();
748 theApp->m_clientID = tag->GetClientId();
750 if (tag->IsConnectedED2K()) {
751 CECTag *srvtag = tag->GetTagByName(EC_TAG_SERVER);
752 if (!srvtag) {
753 return;
755 server = theApp->serverlist->GetByID(srvtag->GetIPv4Data().IP());
756 if (m_CurrServer && (server != m_CurrServer)) {
757 theApp->amuledlg->m_serverwnd->serverlistctrl->
758 HighlightServer(m_CurrServer, false);
760 theApp->amuledlg->m_serverwnd->serverlistctrl->
761 HighlightServer(server, true);
762 m_CurrServer = server;
763 theApp->m_ConnState |= CONNECTED_ED2K;
764 } else {
765 if ( m_CurrServer ) {
766 theApp->amuledlg->m_serverwnd->serverlistctrl->
767 HighlightServer(m_CurrServer, false);
768 m_CurrServer = 0;
772 if (tag->IsConnectedKademlia()) {
773 if (tag->IsKadFirewalled()) {
774 theApp->m_ConnState |= CONNECTED_KAD_FIREWALLED;
775 } else {
776 theApp->m_ConnState |= CONNECTED_KAD_OK;
778 } else {
779 if (tag->IsKadRunning()) {
780 theApp->m_ConnState |= CONNECTED_KAD_NOT;
784 theApp->amuledlg->ShowConnectionState();
789 * Server list: host list of ed2k servers.
791 CServerListRem::CServerListRem(CRemoteConnect *conn)
793 CRemoteContainer<CServer, uint32, CEC_Server_Tag>(conn)
798 void CServerListRem::HandlePacket(const CECPacket *packet)
800 CRemoteContainer<CServer, uint32, CEC_Server_Tag>::HandlePacket(packet);
801 ReloadControl();
805 void CServerListRem::UpdateServerMetFromURL(wxString url)
807 CECPacket req(EC_OP_SERVER_UPDATE_FROM_URL);
808 req.AddTag(CECTag(EC_TAG_SERVERS_UPDATE_URL, url));
810 m_conn->SendPacket(&req);
814 void CServerListRem::SaveServerMet()
816 // lfroen: stub, nothing to do
820 void CServerListRem::FilterServers()
822 // FIXME: add code
823 //wxFAIL;
827 void CServerListRem::RemoveServer(CServer* server)
829 m_conn->RemoveServer(server->GetIP(),server->GetPort());
833 void CServerListRem::UpdateUserFileStatus(CServer *server)
835 if (server) {
836 m_TotalUser = server->GetUsers();
837 m_TotalFile = server->GetFiles();
839 wxString buffer =
840 CFormat(_("Total Users: %s | Total Files: %s")) % CastItoIShort(m_TotalUser) % CastItoIShort(m_TotalFile);
842 Notify_ShowUserCount(buffer);
847 CServer *CServerListRem::GetServerByAddress(const wxString& WXUNUSED(address), uint16 WXUNUSED(port)) const
849 // It's ok to return 0 for context where this code is used in remote gui
850 return 0;
853 CServer *CServerListRem::GetServerByIPTCP(uint32 WXUNUSED(nIP), uint16 WXUNUSED(nPort)) const
855 // It's ok to return 0 for context where this code is used in remote gui
856 return 0;
859 CServer *CServerListRem::CreateItem(CEC_Server_Tag *tag)
861 return new CServer(tag);
865 void CServerListRem::DeleteItem(CServer *in_srv)
867 CScopedPtr<CServer> srv(in_srv);
868 theApp->amuledlg->m_serverwnd->serverlistctrl->RemoveServer(srv.get());
872 uint32 CServerListRem::GetItemID(CServer *server)
874 return server->GetIP();
878 void CServerListRem::ProcessItemUpdate(CEC_Server_Tag *, CServer *)
880 // server list is always realoaded from scratch
881 wxFAIL;
885 void CServerListRem::ReloadControl()
887 for(uint32 i = 0;i < GetCount(); i++) {
888 CServer *srv = GetByIndex(i);
889 theApp->amuledlg->m_serverwnd->serverlistctrl->RefreshServer(srv);
894 CIPFilterRem::CIPFilterRem(CRemoteConnect* conn)
896 m_conn = conn;
900 void CIPFilterRem::Reload()
902 CECPacket req(EC_OP_IPFILTER_RELOAD);
903 m_conn->SendPacket(&req);
907 void CIPFilterRem::Update(wxString WXUNUSED(url))
909 // FIXME: add command
910 //wxFAIL;
915 * Shared files list
917 CSharedFilesRem::CSharedFilesRem(CRemoteConnect *conn) : CRemoteContainer<CKnownFile, CMD4Hash, CEC_SharedFile_Tag>(conn, true)
919 m_rename_file = NULL;
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->SendRequest(this, &request);
952 m_rename_file = file;
953 m_new_name = strNewName;
955 return true;
959 void CSharedFilesRem::HandlePacket(const CECPacket *packet)
961 if (m_rename_file && (packet->GetOpCode() == EC_OP_NOOP)) {
962 m_rename_file->SetFileName(CPath(m_new_name));
963 m_rename_file = NULL;
964 } else if (packet->GetOpCode() != EC_OP_FAILED) {
965 CRemoteContainer<CKnownFile, CMD4Hash, CEC_SharedFile_Tag>::HandlePacket(packet);
970 CKnownFile *CSharedFilesRem::CreateItem(CEC_SharedFile_Tag *tag)
972 CKnownFile *file = new CKnownFile(tag);
974 m_enc_map[file->GetFileHash()] = RLE_Data(file->GetPartCount(), true);
976 ProcessItemUpdate(tag, file);
978 theApp->amuledlg->m_sharedfileswnd->sharedfilesctrl->ShowFile(file);
980 return file;
984 void CSharedFilesRem::DeleteItem(CKnownFile *in_file)
986 CScopedPtr<CKnownFile> file(in_file);
988 m_enc_map.erase(file->GetFileHash());
990 theApp->amuledlg->m_sharedfileswnd->sharedfilesctrl->RemoveFile(file.get());
994 CMD4Hash CSharedFilesRem::GetItemID(CKnownFile *file)
996 return file->GetFileHash();
1000 void CSharedFilesRem::ProcessItemUpdate(CEC_SharedFile_Tag *tag, CKnownFile *file)
1002 CECTag *parttag = tag->GetTagByName(EC_TAG_PARTFILE_PART_STATUS);
1003 const unsigned char *data =
1004 m_enc_map[file->GetFileHash()].Decode(
1005 (unsigned char *)parttag->GetTagData(),
1006 parttag->GetTagDataLen());
1007 for(int i = 0; i < file->GetPartCount(); ++i) {
1008 file->m_AvailPartFrequency[i] = data[i];
1010 tag->GetRequests(&file->statistic.requested);
1011 tag->GetAllRequests(&file->statistic.alltimerequested);
1012 tag->GetAccepts(&file->statistic.accepted);
1013 tag->GetAllAccepts(&file->statistic.alltimeaccepted);
1014 tag->GetXferred(&file->statistic.transferred);
1015 tag->GetAllXferred(&file->statistic.alltimetransferred);
1016 tag->Prio(&file->m_iUpPriorityEC);
1017 if (file->m_iUpPriorityEC >= 10) {
1018 file->m_iUpPriority = file->m_iUpPriorityEC - 10;
1019 file->m_bAutoUpPriority = true;
1020 } else {
1021 file->m_iUpPriority = file->m_iUpPriorityEC;
1022 file->m_bAutoUpPriority = false;
1025 theApp->knownfiles->requested += file->statistic.requested;
1026 theApp->knownfiles->transferred += file->statistic.transferred;
1027 theApp->knownfiles->accepted += file->statistic.transferred;
1029 theApp->amuledlg->m_sharedfileswnd->sharedfilesctrl->UpdateItem(file);
1032 bool CSharedFilesRem::Phase1Done(const CECPacket *)
1034 theApp->knownfiles->requested = 0;
1035 theApp->knownfiles->transferred = 0;
1036 theApp->knownfiles->accepted = 0;
1038 return true;
1041 void CSharedFilesRem::SetFilePrio(CKnownFile *file, uint8 prio)
1043 CECPacket req(EC_OP_SHARED_SET_PRIO);
1045 CECTag hashtag(EC_TAG_PARTFILE, file->GetFileHash());
1046 hashtag.AddTag(CECTag(EC_TAG_PARTFILE_PRIO, prio));
1048 req.AddTag(hashtag);
1050 m_conn->SendPacket(&req);
1054 * List of uploading and waiting clients.
1056 CUpDownClientListRem::CUpDownClientListRem(CRemoteConnect *conn, int viewtype)
1058 CRemoteContainer<CUpDownClient, uint32, CEC_UpDownClient_Tag>(conn)
1060 m_viewtype = viewtype;
1064 CUpDownClient::CUpDownClient(CEC_UpDownClient_Tag *tag)
1066 m_bRemoteQueueFull = false;
1067 m_nUserIDHybrid = tag->ID();
1068 m_Username = tag->ClientName();
1069 m_score = tag->Score();
1070 m_clientSoft = tag->ClientSoftware();
1071 m_clientVersionString = GetSoftName(m_clientSoft);
1072 m_clientSoftString = m_clientVersionString;
1073 m_identState = tag->GetCurrentIdentState();
1074 m_hasbeenobfuscatinglately = tag->HasObfuscatedConnection();
1076 // The functions to retrieve m_clientVerString information are
1077 // currently in BaseClient.cpp, which is not linked in remote-gui app.
1078 // So, in the meantime, we use a tag sent from core.
1079 m_clientVerString = tag->SoftVerStr();
1080 m_strModVersion = wxEmptyString;
1081 wxString clientModString;
1082 if (!clientModString.IsEmpty()) {
1083 m_clientVerString += wxT(" - ") + clientModString;
1085 m_fullClientVerString = m_clientSoftString + wxT(" ") + m_clientVerString;
1087 // User hash
1088 m_UserHash = tag->UserID();
1090 // User IP:Port
1091 m_nConnectIP = m_dwUserIP = tag->UserIP();
1092 m_nUserPort = tag->UserPort();
1093 m_FullUserIP = m_nConnectIP;
1095 // Server IP:Port
1096 m_dwServerIP = tag->ServerIP();
1097 m_nServerPort = tag->ServerPort();
1098 m_ServerName = tag->ServerName();
1100 m_waitingPosition = tag->WaitingPosition();
1101 m_nRemoteQueueRank = tag->RemoteQueueRank();
1102 m_bRemoteQueueFull = m_nRemoteQueueRank == 0xffff;
1103 m_cAsked = tag->AskedCount();
1105 m_Friend = 0;
1106 if (tag->HaveFile()) {
1107 CMD4Hash filehash = tag->FileID();
1108 m_uploadingfile = theApp->sharedfiles->GetByID(filehash);
1109 if (!m_uploadingfile) {
1110 m_uploadingfile = theApp->downloadqueue->GetByID(filehash);
1112 } else {
1113 m_uploadingfile = NULL;
1116 m_nCurSessionUp = 0;
1118 credits = new CClientCredits(new CreditStruct());
1121 uint16 CUpQueueRem::GetWaitingPosition(const CUpDownClient *client) const
1123 return client->GetWaitingPosition();
1126 /* Warning: do common base */
1129 bool CUpDownClient::IsIdentified() const
1131 return m_identState == IS_IDENTIFIED;
1135 bool CUpDownClient::IsBadGuy() const
1137 return m_identState == IS_IDBADGUY;
1141 bool CUpDownClient::SUIFailed() const
1143 return m_identState == IS_IDFAILED;
1147 bool CUpDownClient::SUINeeded() const
1149 return m_identState == IS_IDNEEDED;
1153 bool CUpDownClient::SUINotSupported() const
1155 return m_identState == IS_NOTAVAILABLE;
1159 uint64 CUpDownClient::GetDownloadedTotal() const
1161 return credits->GetDownloadedTotal();
1165 uint64 CUpDownClient::GetUploadedTotal() const
1167 return credits->GetUploadedTotal();
1171 double CUpDownClient::GetScoreRatio() const
1173 return credits->GetScoreRatio(GetIP(), theApp->CryptoAvailable());
1176 /* End Warning */
1179 CUpDownClient::~CUpDownClient()
1181 delete credits;
1185 CUpDownClient *CUpDownClientListRem::CreateItem(CEC_UpDownClient_Tag *tag)
1187 CUpDownClient *client = new CUpDownClient(tag);
1188 ProcessItemUpdate(tag, client);
1190 theApp->amuledlg->m_transferwnd->clientlistctrl->InsertClient(client, (ViewType)m_viewtype);
1192 return client;
1196 void CUpDownClientListRem::DeleteItem(CUpDownClient *client)
1198 theApp->amuledlg->m_transferwnd->clientlistctrl->
1199 RemoveClient(client, (ViewType)m_viewtype);
1200 delete client;
1204 uint32 CUpDownClientListRem::GetItemID(CUpDownClient *client)
1206 return client->GetUserIDHybrid();
1210 void CUpDownClientListRem::ProcessItemUpdate(
1211 CEC_UpDownClient_Tag *tag,
1212 CUpDownClient *client)
1214 uint16 state = tag->ClientState();
1216 client->m_nDownloadState = state & 0xff;
1217 client->m_nUploadState = (state >> 8) & 0xff;
1219 client->m_nUpDatarate = tag->SpeedUp();
1220 if ( client->m_nDownloadState == DS_DOWNLOADING ) {
1221 client->kBpsDown = tag->SpeedDown() / 1024.0;
1222 } else {
1223 client->kBpsDown = 0;
1226 client->m_WaitTime = tag->WaitTime();
1227 client->m_UpStartTimeDelay = tag->XferTime();
1228 client->m_dwLastUpRequest = tag->LastReqTime();
1229 client->m_WaitStartTime = tag->QueueTime();
1231 CreditStruct *credit_struct =
1232 (CreditStruct *)client->credits->GetDataStruct();
1233 credit_struct->uploaded = tag->XferUp();
1234 client->m_nTransferredUp = tag->XferUpSession();
1236 credit_struct->downloaded = tag->XferDown();
1237 client->m_nTransferredDown = tag->XferDownSession();
1239 client->m_score = tag->Score();
1240 client->m_rating = tag->Rating();
1244 CUpQueueRem::CUpQueueRem(CRemoteConnect *conn)
1246 m_up_list(conn, vtUploading), m_wait_list(conn, vtQueued)
1252 * Download queue container: hold PartFiles with progress status
1257 CDownQueueRem::CDownQueueRem(CRemoteConnect *conn)
1259 CRemoteContainer<CPartFile, CMD4Hash, CEC_PartFile_Tag>(conn, true)
1264 bool CDownQueueRem::AddLink(const wxString &link, uint8 cat)
1266 CECPacket req(EC_OP_ADD_LINK);
1267 CECTag link_tag(EC_TAG_STRING, link);
1268 link_tag.AddTag(CECTag(EC_TAG_PARTFILE_CAT, cat));
1269 req.AddTag(link_tag);
1271 m_conn->SendPacket(&req);
1272 return true;
1276 void CDownQueueRem::StopUDPRequests()
1278 // have no idea what is it about
1282 void CDownQueueRem::ResetCatParts(int)
1284 // called when category being deleted. Command will be performed on remote side
1288 bool CDownQueueRem::IsPartFile(const CKnownFile *) const
1290 // hope i understand it right
1291 return true;
1295 void CDownQueueRem::OnConnectionState(bool)
1300 CPartFile *CDownQueueRem::CreateItem(CEC_PartFile_Tag *tag)
1302 CPartFile *file = new CPartFile(tag);
1303 m_enc_map[file->GetFileHash()] = PartFileEncoderData(file->GetPartCount(), 10);
1304 ProcessItemUpdate(tag, file);
1306 theApp->amuledlg->m_transferwnd->downloadlistctrl->AddFile(file);
1307 return file;
1311 void CDownQueueRem::DeleteItem(CPartFile *in_file)
1313 CScopedPtr<CPartFile> file(in_file);
1315 theApp->amuledlg->m_transferwnd->downloadlistctrl->RemoveFile(file.get());
1317 m_enc_map.erase(file->GetFileHash());
1321 CMD4Hash CDownQueueRem::GetItemID(CPartFile *file)
1323 return file->GetFileHash();
1327 void CDownQueueRem::ProcessItemUpdate(CEC_PartFile_Tag *tag, CPartFile *file)
1330 // update status
1332 tag->Speed(&file->m_kbpsDown);
1333 file->kBpsDown = file->m_kbpsDown / 1024.0;
1335 tag->SizeXfer(&file->transferred);
1336 tag->SizeDone(&file->completedsize);
1337 tag->SourceXferCount(&file->transferingsrc);
1338 tag->SourceNotCurrCount(&file->m_notCurrentSources);
1339 tag->SourceCount(&file->m_source_count);
1340 tag->SourceCountA4AF(&file->m_a4af_source_count);
1341 tag->FileStatus(&file->status);
1342 tag->Stopped(&file->m_stopped);
1344 tag->LastSeenComplete(&file->lastseencomplete);
1345 tag->LastDateChanged(&file->m_lastDateChanged);
1346 tag->DownloadActiveTime(&file->m_nDlActiveTime);
1348 tag->GetLostDueToCorruption(&file->m_iLostDueToCorruption);
1349 tag->GetGainDueToCompression(&file->m_iGainDueToCompression);
1350 tag->TotalPacketsSavedDueToICH(&file->m_iTotalPacketsSavedDueToICH);
1352 tag->FileCat(&file->m_category);
1354 tag->Prio(&file->m_iDownPriorityEC);
1355 if ( file->m_iDownPriorityEC >= 10 ) {
1356 file->m_iDownPriority = file->m_iDownPriorityEC - 10;
1357 file->m_bAutoDownPriority = true;
1358 } else {
1359 file->m_iDownPriority = file->m_iDownPriorityEC;
1360 file->m_bAutoDownPriority = false;
1363 file->percentcompleted = (100.0*file->GetCompletedSize()) / file->GetFileSize();
1366 // Copy part/gap status
1368 CECTag *gaptag = tag->GetTagByName(EC_TAG_PARTFILE_GAP_STATUS);
1369 CECTag *parttag = tag->GetTagByName(EC_TAG_PARTFILE_PART_STATUS);
1370 CECTag *reqtag = tag->GetTagByName(EC_TAG_PARTFILE_REQ_STATUS);
1371 if (gaptag && parttag && reqtag) {
1372 wxASSERT(m_enc_map.count(file->GetFileHash()));
1374 PartFileEncoderData &encoder = m_enc_map[file->GetFileHash()];
1375 encoder.Decode(
1376 (unsigned char *)gaptag->GetTagData(), gaptag->GetTagDataLen(),
1377 (unsigned char *)parttag->GetTagData(), parttag->GetTagDataLen());
1379 const uint64 *reqparts = (const uint64 *)reqtag->GetTagData();
1380 unsigned reqcount = reqtag->GetTagDataLen() / (2 * sizeof(uint64));
1382 unsigned gap_size = encoder.m_gap_status.Size() / (2 * sizeof(uint64));
1383 // clear gaplist
1384 file->m_gaplist.Init(file->GetFileSize(), false);
1386 // and refill it
1387 const uint64 *gap_info = (const uint64 *)encoder.m_gap_status.Buffer();
1388 for (unsigned j = 0; j < gap_size;j++) {
1389 file->m_gaplist.AddGap(ENDIAN_NTOHLL(gap_info[2*j]), ENDIAN_NTOHLL(gap_info[2*j+1]));
1392 // adjust size of requested block list
1393 while ( file->m_requestedblocks_list.size() > reqcount ) {
1394 delete file->m_requestedblocks_list.front();
1395 file->m_requestedblocks_list.pop_front();
1397 while ( file->m_requestedblocks_list.size() != reqcount ) {
1398 file->m_requestedblocks_list.push_front(new Requested_Block_Struct);
1401 std::list<Requested_Block_Struct*>::iterator it2 = file->m_requestedblocks_list.begin();
1402 for (unsigned i = 0; i < reqcount; ++i) {
1403 Requested_Block_Struct* block = *it2++;
1404 block->StartOffset = ENDIAN_NTOHLL(reqparts[2*i]);
1405 block->EndOffset = ENDIAN_NTOHLL(reqparts[2*i+1]);
1407 // copy parts frequency
1408 const unsigned char *part_info = encoder.m_part_status.Buffer();
1409 for(int i = 0; i < file->GetPartCount(); ++i) {
1410 file->m_SrcpartFrequency[i] = part_info[i];
1412 } else {
1413 AddLogLineNS(CFormat(wxT("ERROR: %X %X %X")) % (size_t)gaptag % (size_t)parttag % (size_t)reqtag);
1416 // Get source names
1417 CECTag *srcnametag = tag->GetTagByName(EC_TAG_PARTFILE_SOURCE_NAMES);
1418 if (srcnametag) {
1419 file->ClearSourcenameItemList();
1420 int max = srcnametag->GetTagCount();
1421 for (int i = 0; i < max - 1; ) {
1422 wxString name = srcnametag->GetTagByIndex(i++)->GetStringData();
1423 long count = srcnametag->GetTagByIndex(i++)->GetInt();
1424 file->AddSourcenameItemList(name, count);
1428 // Get comments
1429 CECTag *commenttag = tag->GetTagByName(EC_TAG_PARTFILE_COMMENTS);
1430 if (commenttag) {
1431 file->ClearFileRatingList();
1432 int max = commenttag->GetTagCount();
1433 for (int i = 0; i < max - 3; ) {
1434 wxString u = commenttag->GetTagByIndex(i++)->GetStringData();
1435 wxString f = commenttag->GetTagByIndex(i++)->GetStringData();
1436 int r = commenttag->GetTagByIndex(i++)->GetInt();
1437 wxString c = commenttag->GetTagByIndex(i++)->GetStringData();
1438 file->AddFileRatingList(u, f, r, c);
1440 file->UpdateFileRatingCommentAvail();
1443 theApp->amuledlg->m_transferwnd->downloadlistctrl->UpdateItem(file);
1447 bool CDownQueueRem::Phase1Done(const CECPacket *)
1449 return true;
1453 void CDownQueueRem::SendFileCommand(CPartFile *file, ec_tagname_t cmd)
1455 CECPacket req(cmd);
1456 req.AddTag(CECTag(EC_TAG_PARTFILE, file->GetFileHash()));
1458 m_conn->SendPacket(&req);
1462 void CDownQueueRem::Prio(CPartFile *file, uint8 prio)
1464 CECPacket req(EC_OP_PARTFILE_PRIO_SET);
1466 CECTag hashtag(EC_TAG_PARTFILE, file->GetFileHash());
1467 hashtag.AddTag(CECTag(EC_TAG_PARTFILE_PRIO, prio));
1468 req.AddTag(hashtag);
1470 m_conn->SendPacket(&req);
1474 void CDownQueueRem::AutoPrio(CPartFile *file, bool flag)
1476 CECPacket req(EC_OP_PARTFILE_PRIO_SET);
1478 CECTag hashtag(EC_TAG_PARTFILE, file->GetFileHash());
1480 hashtag.AddTag(CECTag(EC_TAG_PARTFILE_PRIO,
1481 (uint8)(flag ? PR_AUTO : file->GetDownPriority())));
1482 req.AddTag(hashtag);
1484 m_conn->SendPacket(&req);
1488 void CDownQueueRem::Category(CPartFile *file, uint8 cat)
1490 CECPacket req(EC_OP_PARTFILE_SET_CAT);
1491 file->m_category = cat;
1493 CECTag hashtag(EC_TAG_PARTFILE, file->GetFileHash());
1494 hashtag.AddTag(CECTag(EC_TAG_PARTFILE_CAT, cat));
1495 req.AddTag(hashtag);
1497 m_conn->SendPacket(&req);
1501 void CDownQueueRem::AddSearchToDownload(CSearchFile* file, uint8 category)
1503 CECPacket req(EC_OP_DOWNLOAD_SEARCH_RESULT);
1504 CECTag hashtag(EC_TAG_PARTFILE, file->GetFileHash());
1505 hashtag.AddTag(CECTag(EC_TAG_PARTFILE_CAT, category));
1506 req.AddTag(hashtag);
1508 m_conn->SendPacket(&req);
1512 CClientListRem::CClientListRem(CRemoteConnect *conn)
1514 m_conn = conn;
1518 void CClientListRem::FilterQueues()
1520 // FIXME: add code
1521 //wxFAIL;
1525 CSearchListRem::CSearchListRem(CRemoteConnect *conn) : CRemoteContainer<CSearchFile, CMD4Hash, CEC_SearchFile_Tag>(conn)
1527 m_curr_search = -1;
1531 wxString CSearchListRem::StartNewSearch(
1532 uint32* nSearchID, SearchType search_type,
1533 const CSearchList::CSearchParams& params)
1535 CECPacket search_req(EC_OP_SEARCH_START);
1536 EC_SEARCH_TYPE ec_search_type = EC_SEARCH_LOCAL;
1537 switch(search_type) {
1538 case LocalSearch: ec_search_type = EC_SEARCH_LOCAL; break;
1539 case GlobalSearch: ec_search_type = EC_SEARCH_GLOBAL; break;
1540 case KadSearch: ec_search_type = EC_SEARCH_KAD; break;
1542 search_req.AddTag(
1543 CEC_Search_Tag(params.searchString, ec_search_type,
1544 params.typeText, params.extension, params.availability,
1545 params.minSize, params.maxSize));
1547 m_conn->SendPacket(&search_req);
1548 m_curr_search = *(nSearchID); // No kad remote search yet.
1550 Flush();
1552 return wxEmptyString; // EC reply will have the error mesg is needed.
1556 void CSearchListRem::StopGlobalSearch()
1558 if (m_curr_search != -1) {
1559 CECPacket search_req(EC_OP_SEARCH_STOP);
1560 m_conn->SendPacket(&search_req);
1565 void CSearchListRem::StopKadSearch()
1567 // FIXME implementation needed
1571 void CSearchListRem::HandlePacket(const CECPacket *packet)
1573 if ( packet->GetOpCode() == EC_OP_SEARCH_PROGRESS ) {
1574 CoreNotify_Search_Update_Progress(packet->GetTagByIndex(0)->GetInt());
1575 } else {
1576 CRemoteContainer<CSearchFile, CMD4Hash, CEC_SearchFile_Tag>::HandlePacket(packet);
1581 CSearchFile::CSearchFile(CEC_SearchFile_Tag *tag)
1583 m_parent(NULL),
1584 m_showChildren(false),
1585 m_sourceCount(0),
1586 m_completeSourceCount(0),
1587 m_kademlia(false),
1588 m_clientID(0),
1589 m_clientPort(0)
1591 SetFileName(CPath(tag->FileName()));
1592 m_abyFileHash = tag->ID();
1593 SetFileSize(tag->SizeFull());
1595 m_searchID = theApp->searchlist->m_curr_search;
1600 // dtor is virtual - must be implemented
1601 CSearchFile::~CSearchFile()
1606 CSearchFile *CSearchListRem::CreateItem(CEC_SearchFile_Tag *tag)
1608 CSearchFile *file = new CSearchFile(tag);
1609 ProcessItemUpdate(tag, file);
1611 theApp->amuledlg->m_searchwnd->AddResult(file);
1613 return file;
1617 void CSearchListRem::DeleteItem(CSearchFile *file)
1619 delete file;
1623 CMD4Hash CSearchListRem::GetItemID(CSearchFile *file)
1625 return file->GetFileHash();
1629 void CSearchListRem::ProcessItemUpdate(CEC_SearchFile_Tag *tag, CSearchFile *file)
1631 file->m_sourceCount = tag->SourceCount();
1632 file->m_completeSourceCount = tag->CompleteSourceCount();
1636 bool CSearchListRem::Phase1Done(const CECPacket *WXUNUSED(reply))
1638 CECPacket progress_req(EC_OP_SEARCH_PROGRESS);
1639 m_conn->SendRequest(this, &progress_req);
1641 return true;
1645 void CSearchListRem::RemoveResults(long nSearchID)
1647 ResultMap::iterator it = m_results.find(nSearchID);
1648 if (it != m_results.end()) {
1649 CSearchResultList& list = it->second;
1650 for (unsigned int i = 0; i < list.size(); ++i) {
1651 delete list[i];
1653 m_results.erase(it);
1658 const CSearchResultList& CSearchListRem::GetSearchResults(long nSearchID)
1660 ResultMap::const_iterator it = m_results.find(nSearchID);
1661 if (it != m_results.end()) {
1662 return it->second;
1665 // TODO: Should we assert in this case?
1666 static CSearchResultList list;
1667 return list;
1671 void CStatsUpdaterRem::HandlePacket(const CECPacket *packet)
1673 theStats::UpdateStats(packet);
1674 theApp->ShowUserCount(); // maybe there should be a check if a usercount changed ?
1678 bool CUpDownClient::IsBanned() const
1680 // FIXME: add code
1681 return false;
1686 // Those functions have different implementation in remote gui
1688 void CUpDownClient::Ban()
1690 // FIXME: add code
1691 wxFAIL;
1695 void CUpDownClient::UnBan()
1697 // FIXME: add code
1698 wxFAIL;
1702 void CUpDownClient::RequestSharedFileList()
1704 // FIXME: add code
1705 wxFAIL;
1709 void CKnownFile::SetFileComment(const wxString &)
1711 // FIXME: add code
1712 wxMessageBox(_("Comments and ratings are not supported on remote gui yet"), _("Information"), wxOK | wxICON_INFORMATION);
1716 void CKnownFile::SetFileRating(unsigned char)
1718 // FIXME: add code
1722 // I don't think it will be implemented - too match data transfer. But who knows ?
1723 wxString CUpDownClient::ShowDownloadingParts() const
1725 return wxEmptyString;
1729 bool CUpDownClient::SwapToAnotherFile(
1730 bool WXUNUSED(bIgnoreNoNeeded),
1731 bool WXUNUSED(ignoreSuspensions),
1732 bool WXUNUSED(bRemoveCompletely),
1733 CPartFile* WXUNUSED(toFile))
1735 // FIXME: add code
1736 wxFAIL;
1737 return false;
1742 // Those functions are virtual. So even they don't get called they must
1743 // be defined so linker will be happy
1745 CPacket* CKnownFile::CreateSrcInfoPacket(const CUpDownClient *, uint8 /*byRequestedVersion*/, uint16 /*nRequestedOptions*/)
1747 wxFAIL;
1748 return 0;
1752 bool CKnownFile::LoadFromFile(const class CFileDataIO*)
1754 wxFAIL;
1755 return false;
1759 void CKnownFile::UpdatePartsInfo()
1761 wxFAIL;
1765 CPacket* CPartFile::CreateSrcInfoPacket(CUpDownClient const *, uint8 /*byRequestedVersion*/, uint16 /*nRequestedOptions*/)
1767 wxFAIL;
1768 return 0;
1772 void CPartFile::UpdatePartsInfo()
1774 wxFAIL;
1778 void CPartFile::UpdateFileRatingCommentAvail()
1780 bool prevComment = m_hasComment;
1781 int prevRating = m_iUserRating;
1783 m_hasComment = false;
1784 m_iUserRating = 0;
1785 int ratingCount = 0;
1787 FileRatingList::iterator it = m_FileRatingList.begin();
1788 for (; it != m_FileRatingList.end(); ++it) {
1789 SFileRating& cur_rat = *it;
1791 if (!cur_rat.Comment.IsEmpty()) {
1792 m_hasComment = true;
1795 uint8 rating = cur_rat.Rating;
1796 if (rating) {
1797 wxASSERT(rating <= 5);
1799 ratingCount++;
1800 m_iUserRating += rating;
1804 if (ratingCount) {
1805 m_iUserRating /= ratingCount;
1806 wxASSERT(m_iUserRating > 0 && m_iUserRating <= 5);
1809 if ((prevComment != m_hasComment) || (prevRating != m_iUserRating)) {
1810 UpdateDisplayedInfo();
1814 bool CPartFile::SavePartFile(bool)
1816 wxFAIL;
1817 return false;
1822 // since gui is not linked with amule.cpp - define events here
1824 DEFINE_LOCAL_EVENT_TYPE(wxEVT_CORE_FINISHED_HTTP_DOWNLOAD)
1825 DEFINE_LOCAL_EVENT_TYPE(wxEVT_CORE_SOURCE_DNS_DONE)
1826 DEFINE_LOCAL_EVENT_TYPE(wxEVT_CORE_UDP_DNS_DONE)
1827 DEFINE_LOCAL_EVENT_TYPE(wxEVT_CORE_SERVER_DNS_DONE)
1828 // File_checked_for_headers