Upstream tarball 10015
[amule.git] / src / amule-remote-gui.cpp
blobde3c0c1d354ffcd35ef10ccbb7fcc11e25e87673
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 #include <wx/ipc.h>
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 "ClientListCtrl.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
49 #endif
50 #include "InternalEvents.h" // Needed for wxEVT_CORE_FINISHED_HTTP_DOWNLOAD
51 #include "Logger.h"
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);
80 CentreOnParent();
84 wxString CEConnectDlg::PassHash()
86 return pwd_hash;
90 BEGIN_EVENT_TABLE(CEConnectDlg, wxDialog)
91 EVT_BUTTON(wxID_OK, CEConnectDlg::OnOK)
92 END_EVENT_TABLE()
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();
107 evt.Skip();
111 DEFINE_LOCAL_EVENT_TYPE(wxEVT_EC_INIT_DONE)
114 BEGIN_EVENT_TABLE(CamuleRemoteGuiApp, wxApp)
115 // Core timer
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)
126 #endif
127 END_EVENT_TABLE()
130 IMPLEMENT_APP(CamuleRemoteGuiApp)
133 int CamuleRemoteGuiApp::OnExit()
135 StopTickTimer();
137 return wxApp::OnExit();
141 void CamuleRemoteGuiApp::OnPollTimer(wxTimerEvent&)
143 static int request_step = 0;
145 if (m_connect->RequestFifoFull()) {
146 return;
149 switch (request_step) {
150 case 0:
151 serverconnect->ReQuery();
152 serverlist->UpdateUserFileStatus(serverconnect->GetCurrentServer());
153 request_step++;
154 break;
155 case 1: {
156 CECPacket stats_req(EC_OP_STAT_REQ);
157 m_connect->SendRequest(&m_stats_updater, &stats_req);
158 amuledlg->ShowTransferRate();
159 request_step++;
160 break;
162 case 2:
163 if (amuledlg->m_sharedfileswnd->IsShown()) {
164 sharedfiles->DoRequery(EC_OP_GET_SHARED_FILES, EC_TAG_KNOWNFILE);
165 } else if (amuledlg->m_serverwnd->IsShown()) {
166 //serverlist->FullReload(EC_OP_GET_SERVER_LIST);
167 } else if (amuledlg->m_transferwnd->IsShown()) {
168 downloadqueue->DoRequery(EC_OP_GET_DLOAD_QUEUE, EC_TAG_PARTFILE);
169 switch(amuledlg->m_transferwnd->clientlistctrl->GetListView()) {
170 case vtUploading:
171 uploadqueue->ReQueryUp();
172 break;
173 case vtQueued:
174 uploadqueue->ReQueryWait();
175 break;
176 case vtClients:
177 break;
178 case vtNone:
179 break;
181 amuledlg->m_transferwnd->ShowQueueCount(theStats::GetWaitingUserCount());
182 } else if (amuledlg->m_searchwnd->IsShown()) {
183 if (searchlist->m_curr_search != -1) {
184 searchlist->DoRequery(EC_OP_SEARCH_RESULTS, EC_TAG_SEARCHFILE);
187 // Back to the roots
188 request_step = 0;
189 break;
190 default:
191 AddLogLineCS(wxT("WTF?")); // should not happen. :-)
192 request_step = 0;
195 // Check for new links once per second.
196 static uint32 lastED2KLinkCheck = 0;
197 if (GetTickCount() - lastED2KLinkCheck >= 1000) {
198 AddLinksFromFile();
199 lastED2KLinkCheck = GetTickCount();
204 void CamuleRemoteGuiApp::OnFinishedHTTPDownload(CMuleInternalEvent& event)
206 #ifdef ENABLE_IP2COUNTRY
207 if (event.GetInt() == HTTP_GeoIP) {
208 amuledlg->IP2CountryDownloadFinished(event.GetExtraLong());
209 // If we updated, the dialog is already up. Redraw it to show the flags.
210 amuledlg->Refresh();
212 #endif
216 void CamuleRemoteGuiApp::ShutDown(wxCloseEvent &WXUNUSED(evt))
218 // Stop the Core Timer
219 delete poll_timer;
220 poll_timer = NULL;
222 // Destroy the EC socket
223 m_connect->Destroy();
224 m_connect = NULL;
227 if (amuledlg) {
228 amuledlg->DlgShutDown();
229 amuledlg->Destroy();
230 amuledlg = NULL;
235 bool CamuleRemoteGuiApp::OnInit()
237 StartTickTimer();
238 amuledlg = NULL;
240 // Get theApp
241 theApp = &wxGetApp();
243 // Handle uncaught exceptions
244 InstallMuleExceptionHandler();
246 // Parse cmdline arguments.
247 if (!InitCommon(AMULE_APP_BASE::argc, AMULE_APP_BASE::argv)) {
248 return false;
251 // Create the polling timer
252 poll_timer = new wxTimer(this,ID_CORE_TIMER_EVENT);
253 if (!poll_timer) {
254 AddLogLineCS(_("Fatal Error: Failed to create Poll Timer"));
255 OnExit();
258 m_connect = new CRemoteConnect(this);
260 glob_prefs = new CPreferencesRem(m_connect);
262 InitCustomLanguages();
263 InitLocale(m_locale, StrLang2wx(thePrefs::GetLanguageID()));
265 if (ShowConnectionDialog()) {
266 AddLogLineNS(_("Going to event loop..."));
267 return true;
270 return false;
274 bool CamuleRemoteGuiApp::CryptoAvailable() const
276 return thePrefs::IsSecureIdentEnabled(); // good enough
280 bool CamuleRemoteGuiApp::ShowConnectionDialog()
282 dialog = new CEConnectDlg;
284 if (m_skipConnectionDialog) {
285 wxCommandEvent evt;
286 dialog->OnOK(evt);
287 } else if (dialog->ShowModal() != wxID_OK) {
288 dialog->Destroy();
290 return false;
292 AddLogLineNS(_("Connecting..."));
293 if (!m_connect->ConnectToCore(dialog->Host(), dialog->Port(),
294 dialog->Login(), dialog->PassHash(),
295 wxT("amule-remote"), wxT("0x0001"))) {
296 wxMessageBox(_("Connection failed "),_("ERROR"),wxOK);
298 return false;
301 return true;
305 void CamuleRemoteGuiApp::OnECConnection(wxEvent& event) {
306 wxECSocketEvent& evt = *((wxECSocketEvent*)&event);
307 AddLogLineNS(_("Remote GUI EC event handler"));
308 wxString reply = evt.GetServerReply();
309 AddLogLineM(true, reply);
310 if (evt.GetResult() == true) {
311 // Connected - go to next init step
312 glob_prefs->LoadRemote();
313 } else {
314 AddLogLineNS(_("Going down"));
315 if (dialog) { // connect failed
316 wxMessageBox(
317 (CFormat(_("Connection Failed. Unable to connect to %s:%d\n")) % dialog->Host() % dialog->Port()) + reply,
318 _("ERROR"), wxOK);
319 } else { // server disconnected (probably terminated) later
320 wxMessageBox(_("Connection closed - aMule has terminated probably."), _("ERROR"), wxOK);
322 ExitMainLoop();
327 void CamuleRemoteGuiApp::OnECInitDone(wxEvent& )
329 Startup();
333 void CamuleRemoteGuiApp::OnNotifyEvent(CMuleGUIEvent& evt)
335 evt.Notify();
339 void CamuleRemoteGuiApp::Startup() {
341 if (dialog->SaveUserPass()) {
342 wxConfig::Get()->Write(wxT("/EC/Host"), dialog->Host());
343 wxConfig::Get()->Write(wxT("/EC/Port"), dialog->Port());
344 wxConfig::Get()->Write(wxT("/EC/Password"), dialog->PassHash());
346 dialog->Destroy();
347 dialog = NULL;
349 m_ConnState = 0;
350 m_clientID = 0;
352 serverconnect = new CServerConnectRem(m_connect);
353 m_statistics = new CStatistics(*m_connect);
355 clientlist = new CClientListRem(m_connect);
356 searchlist = new CSearchListRem(m_connect);
357 serverlist = new CServerListRem(m_connect);
359 sharedfiles = new CSharedFilesRem(m_connect);
360 knownfiles = new CKnownFilesRem(sharedfiles);
362 // bugfix - do this before creating the uploadqueue
363 downloadqueue = new CDownQueueRem(m_connect);
364 uploadqueue = new CUpQueueRem(m_connect);
365 ipfilter = new CIPFilterRem(m_connect);
367 // Create main dialog
368 InitGui(m_geometryEnabled, m_geometryString);
370 // Forward wxLog events to CLogger
371 wxLog::SetActiveTarget(new CLoggerTarget);
372 serverlist->FullReload(EC_OP_GET_SERVER_LIST);
373 sharedfiles->DoRequery(EC_OP_GET_SHARED_FILES, EC_TAG_KNOWNFILE);
375 // Start the Poll Timer
376 poll_timer->Start(1000);
377 amuledlg->StartGuiTimer();
379 // Now activate GeoIP, so that the download dialog doesn't get destroyed immediately
380 #ifdef ENABLE_IP2COUNTRY
381 if (thePrefs::IsGeoIPEnabled()) {
382 amuledlg->m_IP2Country->Enable();
384 #endif
388 int CamuleRemoteGuiApp::ShowAlert(wxString msg, wxString title, int flags)
390 return CamuleGuiBase::ShowAlert(msg, title, flags);
394 void CamuleRemoteGuiApp::AddRemoteLogLine(const wxString& line)
396 amuledlg->AddLogLine(line);
399 int CamuleRemoteGuiApp::InitGui(bool geometry_enabled, wxString &geom_string)
401 CamuleGuiBase::InitGui(geometry_enabled, geom_string);
402 SetTopWindow(amuledlg);
403 AddLogLineN(_("Ready")); // The first log line after the window is up triggers output of all the ones before
404 return 0;
408 bool CamuleRemoteGuiApp::CopyTextToClipboard(wxString strText)
410 return CamuleGuiBase::CopyTextToClipboard(strText);
414 uint32 CamuleRemoteGuiApp::GetPublicIP()
416 return 0;
420 wxString CamuleRemoteGuiApp::GetLog(bool)
422 return wxEmptyString;
426 wxString CamuleRemoteGuiApp::GetServerLog(bool)
428 return wxEmptyString;
432 bool CamuleRemoteGuiApp::AddServer(CServer *, bool)
434 // #warning TODO: Add remote command
435 return true;
439 bool CamuleRemoteGuiApp::IsFirewalled() const
441 if (IsConnectedED2K() && !serverconnect->IsLowID()) {
442 return false;
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
498 return m_clientID;
502 void CamuleRemoteGuiApp::ShowUserCount() {
503 wxString buffer;
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());
514 } else {
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)
530 m_conn = conn;
533 // Settings queried from remote side
535 m_exchange_send_selected_prefs =
536 EC_PREFS_GENERAL |
537 EC_PREFS_CONNECTIONS |
538 EC_PREFS_MESSAGEFILTER |
539 EC_PREFS_ONLINESIG |
540 EC_PREFS_SERVERS |
541 EC_PREFS_FILES |
542 EC_PREFS_SRCDROP |
543 EC_PREFS_DIRECTORIES |
544 EC_PREFS_SECURITY |
545 EC_PREFS_CORETWEAKS |
546 EC_PREFS_REMOTECONTROLS |
547 EC_PREFS_KADEMLIA;
548 m_exchange_recv_selected_prefs =
549 m_exchange_send_selected_prefs |
550 EC_PREFS_CATEGORIES;
554 void CPreferencesRem::HandlePacket(const CECPacket *packet)
556 ((CEC_Prefs_Packet *)packet)->Apply();
558 if ( packet->GetTagByName(EC_TAG_PREFS_CATEGORIES) != 0 ) {
559 for (size_t i = 0; i < packet->GetTagByName(EC_TAG_PREFS_CATEGORIES)->GetTagCount(); i++) {
560 const CECTag *cat_tag = packet->GetTagByName(EC_TAG_PREFS_CATEGORIES)->GetTagByIndex(i);
561 Category_Struct *cat = new Category_Struct;
562 cat->title = cat_tag->GetTagByName(EC_TAG_CATEGORY_TITLE)->GetStringData();
563 cat->path = CPath(cat_tag->GetTagByName(EC_TAG_CATEGORY_PATH)->GetStringData());
564 cat->comment = cat_tag->GetTagByName(EC_TAG_CATEGORY_COMMENT)->GetStringData();
565 cat->color = cat_tag->GetTagByName(EC_TAG_CATEGORY_COLOR)->GetInt();
566 cat->prio = cat_tag->GetTagByName(EC_TAG_CATEGORY_PRIO)->GetInt();
567 theApp->glob_prefs->AddCat(cat);
569 } else {
570 Category_Struct *cat = new Category_Struct;
571 cat->title = _("All");
572 cat->color = 0;
573 cat->prio = PR_NORMAL;
574 theApp->glob_prefs->AddCat(cat);
576 wxECInitDoneEvent event;
577 theApp->AddPendingEvent(event);
582 bool CPreferencesRem::LoadRemote()
585 // override local settings with remote
586 CECPacket req(EC_OP_GET_PREFERENCES, EC_DETAIL_UPDATE);
588 // bring categories too
589 req.AddTag(CECTag(EC_TAG_SELECT_PREFS, m_exchange_recv_selected_prefs));
591 m_conn->SendRequest(this, &req);
593 return true;
597 void CPreferencesRem::SendToRemote()
599 CEC_Prefs_Packet pref_packet(m_exchange_send_selected_prefs, EC_DETAIL_UPDATE, EC_DETAIL_FULL);
600 m_conn->SendPacket(&pref_packet);
604 class CCatHandler : public CECPacketHandlerBase {
605 virtual void HandlePacket(const CECPacket *packet);
609 void CCatHandler::HandlePacket(const CECPacket *packet)
611 if (packet->GetOpCode() == EC_OP_FAILED) {
612 const CECTag * catTag = packet->GetTagByName(EC_TAG_CATEGORY);
613 const CECTag * pathTag = packet->GetTagByName(EC_TAG_CATEGORY_PATH);
614 if (catTag && pathTag && catTag->GetInt() < theApp->glob_prefs->GetCatCount()) {
615 int cat = catTag->GetInt();
616 Category_Struct* cs = theApp->glob_prefs->GetCategory(cat);
617 wxMessageBox(CFormat(_("Can't create directory '%s' for category '%s', keeping directory '%s'."))
618 % cs->path.GetPrintable() % cs->title % pathTag->GetStringData(),
619 _("ERROR"), wxOK);
620 cs->path = CPath(pathTag->GetStringData());
621 theApp->amuledlg->m_transferwnd->UpdateCategory(cat);
622 theApp->amuledlg->m_transferwnd->downloadlistctrl->Refresh();
625 delete this;
629 bool CPreferencesRem::CreateCategory(
630 Category_Struct *& category,
631 const wxString& name,
632 const CPath& path,
633 const wxString& comment,
634 uint32 color,
635 uint8 prio)
637 CECPacket req(EC_OP_CREATE_CATEGORY);
638 CEC_Category_Tag tag(0xffffffff, name, path.GetRaw(), comment, color, prio);
639 req.AddTag(tag);
640 m_conn->SendRequest(new CCatHandler, &req);
642 category = new Category_Struct();
643 category->path = path;
644 category->title = name;
645 category->comment = comment;
646 category->color = color;
647 category->prio = prio;
649 AddCat(category);
651 return true;
655 bool CPreferencesRem::UpdateCategory(
656 uint8 cat,
657 const wxString& name,
658 const CPath& path,
659 const wxString& comment,
660 uint32 color,
661 uint8 prio)
663 CECPacket req(EC_OP_UPDATE_CATEGORY);
664 CEC_Category_Tag tag(cat, name, path.GetRaw(), comment, color, prio);
665 req.AddTag(tag);
666 m_conn->SendRequest(new CCatHandler, &req);
668 Category_Struct *category = m_CatList[cat];
669 category->path = path;
670 category->title = name;
671 category->comment = comment;
672 category->color = color;
673 category->prio = prio;
675 return true;
679 void CPreferencesRem::RemoveCat(uint8 cat)
681 CECPacket req(EC_OP_DELETE_CATEGORY);
682 CEC_Category_Tag tag(cat, EC_DETAIL_CMD);
683 req.AddTag(tag);
684 m_conn->SendPacket(&req);
685 CPreferences::RemoveCat(cat);
690 // Container implementation
692 CServerConnectRem::CServerConnectRem(CRemoteConnect *conn)
694 m_CurrServer = 0;
695 m_Conn = conn;
699 void CServerConnectRem::ConnectToAnyServer()
701 CECPacket req(EC_OP_SERVER_CONNECT);
702 m_Conn->SendPacket(&req);
706 void CServerConnectRem::StopConnectionTry()
708 // lfroen: isn't Disconnect the same ?
712 void CServerConnectRem::Disconnect()
714 CECPacket req(EC_OP_SERVER_DISCONNECT);
715 m_Conn->SendPacket(&req);
719 void CServerConnectRem::ConnectToServer(CServer *server)
721 m_Conn->ConnectED2K(server->GetIP(), server->GetPort());
725 bool CServerConnectRem::ReQuery()
727 CECPacket stat_req(EC_OP_GET_CONNSTATE);
728 m_Conn->SendRequest(this, &stat_req);
730 return true;
734 void CServerConnectRem::HandlePacket(const CECPacket *packet)
736 CEC_ConnState_Tag *tag =
737 (CEC_ConnState_Tag *)packet->GetTagByName(EC_TAG_CONNSTATE);
738 if (!tag) {
739 return;
742 theApp->m_ConnState = 0;
743 CServer *server;
744 m_ID = tag->GetEd2kId();
745 theApp->m_clientID = tag->GetClientId();
747 if (tag->IsConnectedED2K()) {
748 CECTag *srvtag = tag->GetTagByName(EC_TAG_SERVER);
749 if (!srvtag) {
750 return;
752 server = theApp->serverlist->GetByID(srvtag->GetIPv4Data().IP());
753 if (m_CurrServer && (server != m_CurrServer)) {
754 theApp->amuledlg->m_serverwnd->serverlistctrl->
755 HighlightServer(m_CurrServer, false);
757 theApp->amuledlg->m_serverwnd->serverlistctrl->
758 HighlightServer(server, true);
759 m_CurrServer = server;
760 theApp->m_ConnState |= CONNECTED_ED2K;
761 } else {
762 if ( m_CurrServer ) {
763 theApp->amuledlg->m_serverwnd->serverlistctrl->
764 HighlightServer(m_CurrServer, false);
765 m_CurrServer = 0;
769 if (tag->IsConnectedKademlia()) {
770 if (tag->IsKadFirewalled()) {
771 theApp->m_ConnState |= CONNECTED_KAD_FIREWALLED;
772 } else {
773 theApp->m_ConnState |= CONNECTED_KAD_OK;
775 } else {
776 if (tag->IsKadRunning()) {
777 theApp->m_ConnState |= CONNECTED_KAD_NOT;
781 theApp->amuledlg->ShowConnectionState();
786 * Server list: host list of ed2k servers.
788 CServerListRem::CServerListRem(CRemoteConnect *conn)
790 CRemoteContainer<CServer, uint32, CEC_Server_Tag>(conn, false)
795 void CServerListRem::HandlePacket(const CECPacket *packet)
797 CRemoteContainer<CServer, uint32, CEC_Server_Tag>::HandlePacket(packet);
798 ReloadControl();
802 void CServerListRem::UpdateServerMetFromURL(wxString url)
804 CECPacket req(EC_OP_SERVER_UPDATE_FROM_URL);
805 req.AddTag(CECTag(EC_TAG_SERVERS_UPDATE_URL, url));
807 m_conn->SendPacket(&req);
811 void CServerListRem::SaveServerMet()
813 // lfroen: stub, nothing to do
817 void CServerListRem::FilterServers()
819 // FIXME: add code
820 //wxFAIL;
824 void CServerListRem::RemoveServer(CServer* server)
826 m_conn->RemoveServer(server->GetIP(),server->GetPort());
830 void CServerListRem::UpdateUserFileStatus(CServer *server)
832 if (server) {
833 m_TotalUser = server->GetUsers();
834 m_TotalFile = server->GetFiles();
836 wxString buffer =
837 CFormat(_("Total Users: %s | Total Files: %s")) % CastItoIShort(m_TotalUser) % CastItoIShort(m_TotalFile);
839 Notify_ShowUserCount(buffer);
844 CServer *CServerListRem::GetServerByAddress(const wxString& WXUNUSED(address), uint16 WXUNUSED(port)) const
846 // It's ok to return 0 for context where this code is used in remote gui
847 return 0;
850 CServer *CServerListRem::GetServerByIPTCP(uint32 WXUNUSED(nIP), uint16 WXUNUSED(nPort)) const
852 // It's ok to return 0 for context where this code is used in remote gui
853 return 0;
856 CServer *CServerListRem::CreateItem(CEC_Server_Tag *tag)
858 return new CServer(tag);
862 void CServerListRem::DeleteItem(CServer *in_srv)
864 CScopedPtr<CServer> srv(in_srv);
865 theApp->amuledlg->m_serverwnd->serverlistctrl->RemoveServer(srv.get());
869 uint32 CServerListRem::GetItemID(CServer *server)
871 return server->GetIP();
875 void CServerListRem::ProcessItemUpdate(CEC_Server_Tag *, CServer *)
877 // server list is always realoaded from scratch
878 wxFAIL;
882 void CServerListRem::ReloadControl()
884 for(uint32 i = 0;i < GetCount(); i++) {
885 CServer *srv = GetByIndex(i);
886 theApp->amuledlg->m_serverwnd->serverlistctrl->RefreshServer(srv);
891 CIPFilterRem::CIPFilterRem(CRemoteConnect* conn)
893 m_conn = conn;
897 void CIPFilterRem::Reload()
899 CECPacket req(EC_OP_IPFILTER_RELOAD);
900 m_conn->SendPacket(&req);
904 void CIPFilterRem::Update(wxString url)
906 CECPacket req(EC_OP_IPFILTER_UPDATE);
907 req.AddTag(CECTag(EC_TAG_STRING, url));
909 m_conn->SendPacket(&req);
914 * Shared files list
916 CSharedFilesRem::CSharedFilesRem(CRemoteConnect *conn) : CRemoteContainer<CKnownFile, CMD4Hash, CEC_SharedFile_Tag>(conn, true)
918 m_rename_file = NULL;
922 void CSharedFilesRem::Reload(bool, bool)
924 CECPacket req(EC_OP_SHAREDFILES_RELOAD);
926 m_conn->SendPacket(&req);
930 void CSharedFilesRem::AddFilesFromDirectory(const CPath& path)
932 CECPacket req(EC_OP_SHAREDFILES_ADD_DIRECTORY);
934 req.AddTag(CECTag(EC_TAG_PREFS_DIRECTORIES, path.GetRaw()));
936 m_conn->SendPacket(&req);
940 bool CSharedFilesRem::RenameFile(CKnownFile* file, const CPath& newName)
942 // We use the printable name, as the filename originated from user input,
943 // and the filesystem name might not be valid on the remote host.
944 const wxString strNewName = newName.GetPrintable();
946 CECPacket request(EC_OP_RENAME_FILE);
947 request.AddTag(CECTag(EC_TAG_KNOWNFILE, file->GetFileHash()));
948 request.AddTag(CECTag(EC_TAG_PARTFILE_NAME, strNewName));
950 m_conn->SendRequest(this, &request);
951 m_rename_file = file;
952 m_new_name = strNewName;
954 return true;
958 void CSharedFilesRem::HandlePacket(const CECPacket *packet)
960 if (m_rename_file && (packet->GetOpCode() == EC_OP_NOOP)) {
961 m_rename_file->SetFileName(CPath(m_new_name));
962 m_rename_file = NULL;
963 } else if (packet->GetOpCode() != EC_OP_FAILED) {
964 CRemoteContainer<CKnownFile, CMD4Hash, CEC_SharedFile_Tag>::HandlePacket(packet);
969 CKnownFile *CSharedFilesRem::CreateItem(CEC_SharedFile_Tag *tag)
971 CKnownFile *file = new CKnownFile(tag);
973 m_enc_map[file->GetFileHash()] = RLE_Data(file->GetPartCount(), true);
975 ProcessItemUpdate(tag, file);
977 theApp->amuledlg->m_sharedfileswnd->sharedfilesctrl->ShowFile(file);
979 return file;
983 void CSharedFilesRem::DeleteItem(CKnownFile *in_file)
985 CScopedPtr<CKnownFile> file(in_file);
987 m_enc_map.erase(file->GetFileHash());
989 theApp->amuledlg->m_sharedfileswnd->sharedfilesctrl->RemoveFile(file.get());
993 CMD4Hash CSharedFilesRem::GetItemID(CKnownFile *file)
995 return file->GetFileHash();
999 void CSharedFilesRem::ProcessItemUpdate(CEC_SharedFile_Tag *tag, CKnownFile *file)
1001 CECTag *parttag = tag->GetTagByName(EC_TAG_PARTFILE_PART_STATUS);
1002 if (parttag) {
1003 const uint8 *data = m_enc_map[file->GetFileHash()].Decode(
1004 (uint8 *)parttag->GetTagData(),
1005 parttag->GetTagDataLen());
1006 for(int i = 0; i < file->GetPartCount(); ++i) {
1007 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, true)
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_clientSoft = tag->ClientSoftware();
1070 m_clientVersionString = GetSoftName(m_clientSoft);
1071 m_clientSoftString = m_clientVersionString;
1072 m_bEmuleProtocol = false;
1074 // The functions to retrieve m_clientVerString information are
1075 // currently in BaseClient.cpp, which is not linked in remote-gui app.
1076 // So, in the meantime, we use a tag sent from core.
1077 m_clientVerString = tag->SoftVerStr();
1078 m_strModVersion = wxEmptyString;
1079 wxString clientModString;
1080 if (!clientModString.IsEmpty()) {
1081 m_clientVerString += wxT(" - ") + clientModString;
1083 m_fullClientVerString = m_clientSoftString + wxT(" ") + m_clientVerString;
1085 // User hash
1086 m_UserHash = tag->UserID();
1088 // User IP:Port
1089 m_nConnectIP = m_dwUserIP = tag->UserIP();
1090 m_nUserPort = tag->UserPort();
1091 m_FullUserIP = m_nConnectIP;
1093 // Server IP:Port
1094 m_dwServerIP = tag->ServerIP();
1095 m_nServerPort = tag->ServerPort();
1096 m_ServerName = tag->ServerName();
1098 m_Friend = 0;
1099 if (tag->HaveFile()) {
1100 CMD4Hash filehash = tag->FileID();
1101 m_uploadingfile = theApp->sharedfiles->GetByID(filehash);
1102 if (!m_uploadingfile) {
1103 m_uploadingfile = theApp->downloadqueue->GetByID(filehash);
1105 } else {
1106 m_uploadingfile = NULL;
1109 m_nCurSessionUp = 0;
1111 credits = new CClientCredits(new CreditStruct());
1114 uint16 CUpQueueRem::GetWaitingPosition(const CUpDownClient *client) const
1116 return client->GetWaitingPosition();
1119 /* Warning: do common base */
1122 bool CUpDownClient::IsIdentified() const
1124 return m_identState == IS_IDENTIFIED;
1128 bool CUpDownClient::IsBadGuy() const
1130 return m_identState == IS_IDBADGUY;
1134 bool CUpDownClient::SUIFailed() const
1136 return m_identState == IS_IDFAILED;
1140 bool CUpDownClient::SUINeeded() const
1142 return m_identState == IS_IDNEEDED;
1146 bool CUpDownClient::SUINotSupported() const
1148 return m_identState == IS_NOTAVAILABLE;
1152 uint64 CUpDownClient::GetDownloadedTotal() const
1154 return credits->GetDownloadedTotal();
1158 uint64 CUpDownClient::GetUploadedTotal() const
1160 return credits->GetUploadedTotal();
1164 double CUpDownClient::GetScoreRatio() const
1166 return credits->GetScoreRatio(GetIP(), theApp->CryptoAvailable());
1169 /* End Warning */
1172 CUpDownClient::~CUpDownClient()
1174 delete credits;
1178 CUpDownClient *CUpDownClientListRem::CreateItem(CEC_UpDownClient_Tag *tag)
1180 CUpDownClient *client = new CUpDownClient(tag);
1181 ProcessItemUpdate(tag, client);
1183 theApp->amuledlg->m_transferwnd->clientlistctrl->InsertClient(client, (ViewType)m_viewtype);
1185 return client;
1189 void CUpDownClientListRem::DeleteItem(CUpDownClient *client)
1191 theApp->amuledlg->m_transferwnd->clientlistctrl->
1192 RemoveClient(client, (ViewType)m_viewtype);
1193 delete client;
1197 uint32 CUpDownClientListRem::GetItemID(CUpDownClient *client)
1199 return client->GetUserIDHybrid();
1203 void CUpDownClientListRem::ProcessItemUpdate(
1204 CEC_UpDownClient_Tag *tag,
1205 CUpDownClient *client)
1207 tag->GetCurrentIdentState(&client->m_identState);
1208 tag->HasObfuscatedConnection(&client->m_hasbeenobfuscatinglately);
1209 tag->HasExtendedProtocol(&client->m_bEmuleProtocol);
1211 tag->WaitingPosition(&client->m_waitingPosition);
1212 tag->RemoteQueueRank(&client->m_nRemoteQueueRank);
1213 client->m_bRemoteQueueFull = client->m_nRemoteQueueRank == 0xffff;
1214 tag->AskedCount(&client->m_cAsked);
1216 tag->ClientDownloadState(&client->m_nDownloadState);
1217 tag->ClientUploadState(&client->m_nUploadState);
1219 tag->SpeedUp(&client->m_nUpDatarate);
1220 if ( client->m_nDownloadState == DS_DOWNLOADING ) {
1221 tag->SpeedDown(&client->kBpsDown);
1222 } else {
1223 client->kBpsDown = 0;
1226 tag->WaitTime(&client->m_WaitTime);
1227 tag->XferTime(&client->m_UpStartTimeDelay);
1228 tag->LastReqTime(&client->m_dwLastUpRequest);
1229 tag->QueueTime(&client->m_WaitStartTime);
1231 CreditStruct *credit_struct =
1232 (CreditStruct *)client->credits->GetDataStruct();
1233 tag->XferUp(&credit_struct->uploaded);
1234 tag->XferUpSession(&client->m_nTransferredUp);
1236 tag->XferDown(&credit_struct->downloaded);
1237 tag->XferDownSession(&client->m_nTransferredDown);
1239 tag->Score(&client->m_score);
1240 tag->Rating(&client->m_rating);
1242 theApp->amuledlg->m_transferwnd->clientlistctrl->UpdateClient(client,
1243 theApp->amuledlg->m_transferwnd->clientlistctrl->GetListView()); // Fixme, Listview shouldn't be required as parameter
1247 CUpQueueRem::CUpQueueRem(CRemoteConnect *conn)
1249 m_up_list(conn, vtUploading), m_wait_list(conn, vtQueued)
1255 * Download queue container: hold PartFiles with progress status
1260 CDownQueueRem::CDownQueueRem(CRemoteConnect *conn)
1262 CRemoteContainer<CPartFile, CMD4Hash, CEC_PartFile_Tag>(conn, true)
1267 bool CDownQueueRem::AddLink(const wxString &link, uint8 cat)
1269 CECPacket req(EC_OP_ADD_LINK);
1270 CECTag link_tag(EC_TAG_STRING, link);
1271 link_tag.AddTag(CECTag(EC_TAG_PARTFILE_CAT, cat));
1272 req.AddTag(link_tag);
1274 m_conn->SendPacket(&req);
1275 return true;
1279 void CDownQueueRem::StopUDPRequests()
1281 // have no idea what is it about
1285 void CDownQueueRem::ResetCatParts(int cat)
1287 // Called when category is deleted. Command will be performed on the remote side,
1288 // but files still should be updated here right away, or drawing errors (colour not available)
1289 // will happen.
1290 for ( uint16 i = 0; i < GetFileCount(); i++ ) {
1291 CPartFile* file = GetFileByIndex( i );
1293 if ( file->GetCategory() == cat ) {
1294 // Reset the category
1295 file->SetCategory( 0 );
1296 } else if ( file->GetCategory() > cat ) {
1297 // Set to the new position of the original category
1298 file->SetCategory( file->GetCategory() - 1 );
1304 bool CDownQueueRem::IsPartFile(const CKnownFile *) const
1306 // hope i understand it right
1307 return true;
1311 void CDownQueueRem::OnConnectionState(bool)
1316 CPartFile *CDownQueueRem::CreateItem(CEC_PartFile_Tag *tag)
1318 CPartFile *file = new CPartFile(tag);
1319 m_enc_map[file->GetFileHash()] = PartFileEncoderData();
1320 ProcessItemUpdate(tag, file);
1322 theApp->amuledlg->m_transferwnd->downloadlistctrl->AddFile(file);
1323 return file;
1327 void CDownQueueRem::DeleteItem(CPartFile *in_file)
1329 CScopedPtr<CPartFile> file(in_file);
1331 theApp->amuledlg->m_transferwnd->downloadlistctrl->RemoveFile(file.get());
1333 m_enc_map.erase(file->GetFileHash());
1337 CMD4Hash CDownQueueRem::GetItemID(CPartFile *file)
1339 return file->GetFileHash();
1343 void CDownQueueRem::ProcessItemUpdate(CEC_PartFile_Tag *tag, CPartFile *file)
1346 // update status
1348 tag->Speed(&file->m_kbpsDown);
1349 file->kBpsDown = file->m_kbpsDown / 1024.0;
1351 tag->SizeXfer(&file->transferred);
1352 tag->SizeDone(&file->completedsize);
1353 tag->SourceXferCount(&file->transferingsrc);
1354 tag->SourceNotCurrCount(&file->m_notCurrentSources);
1355 tag->SourceCount(&file->m_source_count);
1356 tag->SourceCountA4AF(&file->m_a4af_source_count);
1357 tag->FileStatus(&file->status);
1358 tag->Stopped(&file->m_stopped);
1360 tag->LastSeenComplete(&file->lastseencomplete);
1361 tag->LastDateChanged(&file->m_lastDateChanged);
1362 tag->DownloadActiveTime(&file->m_nDlActiveTime);
1363 tag->AvailablePartCount(&file->m_availablePartsCount);
1365 tag->GetLostDueToCorruption(&file->m_iLostDueToCorruption);
1366 tag->GetGainDueToCompression(&file->m_iGainDueToCompression);
1367 tag->TotalPacketsSavedDueToICH(&file->m_iTotalPacketsSavedDueToICH);
1369 tag->FileCat(&file->m_category);
1371 tag->Prio(&file->m_iDownPriorityEC);
1372 if ( file->m_iDownPriorityEC >= 10 ) {
1373 file->m_iDownPriority = file->m_iDownPriorityEC - 10;
1374 file->m_bAutoDownPriority = true;
1375 } else {
1376 file->m_iDownPriority = file->m_iDownPriorityEC;
1377 file->m_bAutoDownPriority = false;
1380 file->percentcompleted = (100.0*file->GetCompletedSize()) / file->GetFileSize();
1383 // Copy part/gap status
1385 CECTag *gaptag = tag->GetTagByName(EC_TAG_PARTFILE_GAP_STATUS);
1386 CECTag *parttag = tag->GetTagByName(EC_TAG_PARTFILE_PART_STATUS);
1387 CECTag *reqtag = tag->GetTagByName(EC_TAG_PARTFILE_REQ_STATUS);
1388 if (gaptag || parttag || reqtag) {
1389 wxASSERT(m_enc_map.count(file->GetFileHash()));
1391 PartFileEncoderData &encoder = m_enc_map[file->GetFileHash()];
1393 if (gaptag) {
1394 ArrayOfUInts64 gaps;
1395 encoder.DecodeGaps(gaptag, gaps);
1396 int gap_size = gaps.size() / 2;
1397 // clear gaplist
1398 file->m_gaplist.Init(file->GetFileSize(), false);
1400 // and refill it
1401 for (int j = 0; j < gap_size; j++) {
1402 file->m_gaplist.AddGap(gaps[2*j], gaps[2*j+1]);
1405 if (parttag) {
1406 encoder.DecodeParts(parttag, file->m_SrcpartFrequency);
1407 // sanity check
1408 wxASSERT (file->m_SrcpartFrequency.size() == file->GetPartCount());
1410 if (reqtag) {
1411 ArrayOfUInts64 reqs;
1412 encoder.DecodeReqs(reqtag, reqs);
1413 int req_size = reqs.size() / 2;
1414 // clear reqlist
1415 DeleteContents(file->m_requestedblocks_list);
1417 // and refill it
1418 for (int j = 0; j < req_size; j++) {
1419 Requested_Block_Struct* block = new Requested_Block_Struct;
1420 block->StartOffset = reqs[2*j];
1421 block->EndOffset = reqs[2*j+1];
1422 file->m_requestedblocks_list.push_back(block);
1427 // Get source names and counts
1428 CECTag *srcnametag = tag->GetTagByName(EC_TAG_PARTFILE_SOURCE_NAMES);
1429 CECTag *srccounttag = tag->GetTagByName(EC_TAG_PARTFILE_SOURCE_NAMES_COUNTS);
1430 // Full update (names and counts)
1431 if (srcnametag) {
1432 size_t max = srcnametag->GetTagCount();
1433 // Some sanity checks (this shouldn't go wrong)
1434 if (!srccounttag) {
1435 AddLogLineN(wxT("Source names missing counts - too old core ?"));
1436 } else if (srccounttag->GetTagCount() != max) {
1437 AddLogLineN(CFormat(wxT("%d source names and %d source counts - should not happen."))
1438 % max % srccounttag->GetTagCount());
1439 } else {
1440 file->ClearSourcenameItemList();
1441 for (size_t i = 0; i < max; i++) {
1442 wxString name = srcnametag->GetTagByIndex(i)->GetStringData();
1443 long count = srccounttag->GetTagByIndex(i)->GetInt();
1444 file->AddSourcenameItemList(name, count);
1447 // Only counts updated
1448 } else if (srccounttag) {
1449 size_t max = srccounttag->GetTagCount();
1450 SourcenameItemList &list = file->GetSourcenameItemList();
1451 if (list.size() != max) {
1452 AddLogLineN(CFormat(wxT("%d source items and %d source counts - should not happen."))
1453 % list.size() % max);
1454 } else {
1455 SourcenameItemList::iterator it = list.begin();
1456 for (size_t i = 0; i < max; i++, it++) {
1457 it->count = srccounttag->GetTagByIndex(i)->GetInt();
1462 // Get comments
1463 CECTag *commenttag = tag->GetTagByName(EC_TAG_PARTFILE_COMMENTS);
1464 if (commenttag) {
1465 file->ClearFileRatingList();
1466 int max = commenttag->GetTagCount();
1467 for (int i = 0; i < max - 3; ) {
1468 wxString u = commenttag->GetTagByIndex(i++)->GetStringData();
1469 wxString f = commenttag->GetTagByIndex(i++)->GetStringData();
1470 int r = commenttag->GetTagByIndex(i++)->GetInt();
1471 wxString c = commenttag->GetTagByIndex(i++)->GetStringData();
1472 file->AddFileRatingList(u, f, r, c);
1474 file->UpdateFileRatingCommentAvail();
1477 theApp->amuledlg->m_transferwnd->downloadlistctrl->UpdateItem(file);
1481 bool CDownQueueRem::Phase1Done(const CECPacket *)
1483 return true;
1487 void CDownQueueRem::SendFileCommand(CPartFile *file, ec_tagname_t cmd)
1489 CECPacket req(cmd);
1490 req.AddTag(CECTag(EC_TAG_PARTFILE, file->GetFileHash()));
1492 m_conn->SendPacket(&req);
1496 void CDownQueueRem::Prio(CPartFile *file, uint8 prio)
1498 CECPacket req(EC_OP_PARTFILE_PRIO_SET);
1500 CECTag hashtag(EC_TAG_PARTFILE, file->GetFileHash());
1501 hashtag.AddTag(CECTag(EC_TAG_PARTFILE_PRIO, prio));
1502 req.AddTag(hashtag);
1504 m_conn->SendPacket(&req);
1508 void CDownQueueRem::AutoPrio(CPartFile *file, bool flag)
1510 CECPacket req(EC_OP_PARTFILE_PRIO_SET);
1512 CECTag hashtag(EC_TAG_PARTFILE, file->GetFileHash());
1514 hashtag.AddTag(CECTag(EC_TAG_PARTFILE_PRIO,
1515 (uint8)(flag ? PR_AUTO : file->GetDownPriority())));
1516 req.AddTag(hashtag);
1518 m_conn->SendPacket(&req);
1522 void CDownQueueRem::Category(CPartFile *file, uint8 cat)
1524 CECPacket req(EC_OP_PARTFILE_SET_CAT);
1525 file->m_category = cat;
1527 CECTag hashtag(EC_TAG_PARTFILE, file->GetFileHash());
1528 hashtag.AddTag(CECTag(EC_TAG_PARTFILE_CAT, cat));
1529 req.AddTag(hashtag);
1531 m_conn->SendPacket(&req);
1535 void CDownQueueRem::AddSearchToDownload(CSearchFile* file, uint8 category)
1537 CECPacket req(EC_OP_DOWNLOAD_SEARCH_RESULT);
1538 CECTag hashtag(EC_TAG_PARTFILE, file->GetFileHash());
1539 hashtag.AddTag(CECTag(EC_TAG_PARTFILE_CAT, category));
1540 req.AddTag(hashtag);
1542 m_conn->SendPacket(&req);
1546 CClientListRem::CClientListRem(CRemoteConnect *conn)
1548 m_conn = conn;
1552 void CClientListRem::FilterQueues()
1554 // FIXME: add code
1555 //wxFAIL;
1559 CSearchListRem::CSearchListRem(CRemoteConnect *conn) : CRemoteContainer<CSearchFile, CMD4Hash, CEC_SearchFile_Tag>(conn, true)
1561 m_curr_search = -1;
1565 wxString CSearchListRem::StartNewSearch(
1566 uint32* nSearchID, SearchType search_type,
1567 const CSearchList::CSearchParams& params)
1569 CECPacket search_req(EC_OP_SEARCH_START);
1570 EC_SEARCH_TYPE ec_search_type = EC_SEARCH_LOCAL;
1571 switch(search_type) {
1572 case LocalSearch: ec_search_type = EC_SEARCH_LOCAL; break;
1573 case GlobalSearch: ec_search_type = EC_SEARCH_GLOBAL; break;
1574 case KadSearch: ec_search_type = EC_SEARCH_KAD; break;
1576 search_req.AddTag(
1577 CEC_Search_Tag(params.searchString, ec_search_type,
1578 params.typeText, params.extension, params.availability,
1579 params.minSize, params.maxSize));
1581 m_conn->SendPacket(&search_req);
1582 m_curr_search = *(nSearchID); // No kad remote search yet.
1584 Flush();
1586 return wxEmptyString; // EC reply will have the error mesg is needed.
1590 void CSearchListRem::StopGlobalSearch()
1592 if (m_curr_search != -1) {
1593 CECPacket search_req(EC_OP_SEARCH_STOP);
1594 m_conn->SendPacket(&search_req);
1599 void CSearchListRem::StopKadSearch()
1601 // FIXME implementation needed
1605 void CSearchListRem::HandlePacket(const CECPacket *packet)
1607 if ( packet->GetOpCode() == EC_OP_SEARCH_PROGRESS ) {
1608 CoreNotify_Search_Update_Progress(packet->GetTagByIndex(0)->GetInt());
1609 } else {
1610 CRemoteContainer<CSearchFile, CMD4Hash, CEC_SearchFile_Tag>::HandlePacket(packet);
1615 CSearchFile::CSearchFile(CEC_SearchFile_Tag *tag)
1617 m_parent(NULL),
1618 m_showChildren(false),
1619 m_sourceCount(0),
1620 m_completeSourceCount(0),
1621 m_kademlia(false),
1622 m_downloadStatus(NEW),
1623 m_clientID(0),
1624 m_clientPort(0)
1626 SetFileName(CPath(tag->FileName()));
1627 m_abyFileHash = tag->ID();
1628 SetFileSize(tag->SizeFull());
1630 m_searchID = theApp->searchlist->m_curr_search;
1635 // dtor is virtual - must be implemented
1636 CSearchFile::~CSearchFile()
1641 CSearchFile *CSearchListRem::CreateItem(CEC_SearchFile_Tag *tag)
1643 CSearchFile *file = new CSearchFile(tag);
1644 ProcessItemUpdate(tag, file);
1646 theApp->amuledlg->m_searchwnd->AddResult(file);
1648 return file;
1652 void CSearchListRem::DeleteItem(CSearchFile *file)
1654 delete file;
1658 CMD4Hash CSearchListRem::GetItemID(CSearchFile *file)
1660 return file->GetFileHash();
1664 void CSearchListRem::ProcessItemUpdate(CEC_SearchFile_Tag *tag, CSearchFile *file)
1666 uint32 sourceCount = file->m_sourceCount;
1667 uint32 completeSourceCount = file->m_completeSourceCount;
1668 CSearchFile::DownloadStatus status = file->m_downloadStatus;
1669 tag->SourceCount(&file->m_sourceCount);
1670 tag->CompleteSourceCount(&file->m_completeSourceCount);
1671 tag->DownloadStatus((uint32 *) &file->m_downloadStatus);
1673 if (file->m_sourceCount != sourceCount
1674 || file->m_completeSourceCount != completeSourceCount
1675 || file->m_downloadStatus != status) {
1676 if (theApp->amuledlg && theApp->amuledlg->m_searchwnd) {
1677 theApp->amuledlg->m_searchwnd->UpdateResult(file);
1683 bool CSearchListRem::Phase1Done(const CECPacket *WXUNUSED(reply))
1685 CECPacket progress_req(EC_OP_SEARCH_PROGRESS);
1686 m_conn->SendRequest(this, &progress_req);
1688 return true;
1692 void CSearchListRem::RemoveResults(long nSearchID)
1694 ResultMap::iterator it = m_results.find(nSearchID);
1695 if (it != m_results.end()) {
1696 CSearchResultList& list = it->second;
1697 for (unsigned int i = 0; i < list.size(); ++i) {
1698 delete list[i];
1700 m_results.erase(it);
1705 const CSearchResultList& CSearchListRem::GetSearchResults(long nSearchID)
1707 ResultMap::const_iterator it = m_results.find(nSearchID);
1708 if (it != m_results.end()) {
1709 return it->second;
1712 // TODO: Should we assert in this case?
1713 static CSearchResultList list;
1714 return list;
1718 void CStatsUpdaterRem::HandlePacket(const CECPacket *packet)
1720 theStats::UpdateStats(packet);
1721 theApp->ShowUserCount(); // maybe there should be a check if a usercount changed ?
1725 bool CUpDownClient::IsBanned() const
1727 // FIXME: add code
1728 return false;
1733 // Those functions have different implementation in remote gui
1735 void CUpDownClient::Ban()
1737 // FIXME: add code
1738 wxFAIL;
1742 void CUpDownClient::UnBan()
1744 // FIXME: add code
1745 wxFAIL;
1749 void CUpDownClient::RequestSharedFileList()
1751 // FIXME: add code
1752 wxFAIL;
1756 void CKnownFile::SetFileComment(const wxString &)
1758 // FIXME: add code
1759 wxMessageBox(_("Comments and ratings are not supported on remote gui yet"), _("Information"), wxOK | wxICON_INFORMATION);
1763 void CKnownFile::SetFileRating(unsigned char)
1765 // FIXME: add code
1769 // I don't think it will be implemented - too match data transfer. But who knows ?
1770 wxString CUpDownClient::ShowDownloadingParts() const
1772 return wxEmptyString;
1776 bool CUpDownClient::SwapToAnotherFile(
1777 bool WXUNUSED(bIgnoreNoNeeded),
1778 bool WXUNUSED(ignoreSuspensions),
1779 bool WXUNUSED(bRemoveCompletely),
1780 CPartFile* WXUNUSED(toFile))
1782 // FIXME: add code
1783 wxFAIL;
1784 return false;
1789 // Those functions are virtual. So even they don't get called they must
1790 // be defined so linker will be happy
1792 CPacket* CKnownFile::CreateSrcInfoPacket(const CUpDownClient *, uint8 /*byRequestedVersion*/, uint16 /*nRequestedOptions*/)
1794 wxFAIL;
1795 return 0;
1799 bool CKnownFile::LoadFromFile(const class CFileDataIO*)
1801 wxFAIL;
1802 return false;
1806 void CKnownFile::UpdatePartsInfo()
1808 wxFAIL;
1812 CPacket* CPartFile::CreateSrcInfoPacket(CUpDownClient const *, uint8 /*byRequestedVersion*/, uint16 /*nRequestedOptions*/)
1814 wxFAIL;
1815 return 0;
1819 void CPartFile::UpdatePartsInfo()
1821 wxFAIL;
1825 void CPartFile::UpdateFileRatingCommentAvail()
1827 bool prevComment = m_hasComment;
1828 int prevRating = m_iUserRating;
1830 m_hasComment = false;
1831 m_iUserRating = 0;
1832 int ratingCount = 0;
1834 FileRatingList::iterator it = m_FileRatingList.begin();
1835 for (; it != m_FileRatingList.end(); ++it) {
1836 SFileRating& cur_rat = *it;
1838 if (!cur_rat.Comment.IsEmpty()) {
1839 m_hasComment = true;
1842 uint8 rating = cur_rat.Rating;
1843 if (rating) {
1844 wxASSERT(rating <= 5);
1846 ratingCount++;
1847 m_iUserRating += rating;
1851 if (ratingCount) {
1852 m_iUserRating /= ratingCount;
1853 wxASSERT(m_iUserRating > 0 && m_iUserRating <= 5);
1856 if ((prevComment != m_hasComment) || (prevRating != m_iUserRating)) {
1857 UpdateDisplayedInfo();
1861 bool CPartFile::SavePartFile(bool)
1863 wxFAIL;
1864 return false;
1867 CamuleRemoteGuiApp *theApp;
1870 // since gui is not linked with amule.cpp - define events here
1872 DEFINE_LOCAL_EVENT_TYPE(wxEVT_CORE_FINISHED_HTTP_DOWNLOAD)
1873 DEFINE_LOCAL_EVENT_TYPE(wxEVT_CORE_SOURCE_DNS_DONE)
1874 DEFINE_LOCAL_EVENT_TYPE(wxEVT_CORE_UDP_DNS_DONE)
1875 DEFINE_LOCAL_EVENT_TYPE(wxEVT_CORE_SERVER_DNS_DONE)
1876 // File_checked_for_headers