Upstream tarball 20080902
[amule.git] / src / amule-remote-gui.cpp
blob8376af19bee20a225991b19ca09cad8dd3fbaf1a
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 <memory> // Needed for auto_ptr
30 using std::auto_ptr;
33 #include <wx/ipc.h>
34 #include <wx/cmdline.h> // Needed for wxCmdLineParser
35 #include <wx/config.h> // Do_not_auto_remove (win32)
36 #include <wx/fileconf.h> // Needed for wxFileConfig
39 #include <common/Format.h>
40 #include <common/StringFunctions.h>
41 #include <common/MD5Sum.h>
44 #include <include/common/EventIDs.h>
47 #include "amule.h" // Interface declarations.
48 #include "amuleDlg.h" // Needed for CamuleDlg
49 #include "ClientCredits.h"
50 #include "ClientListCtrl.h"
51 #include "DataToText.h" // Needed for GetSoftName()
52 #include "DownloadListCtrl.h" // Needed for CDownloadListCtrl
53 #include "GuiEvents.h"
54 #ifdef ENABLE_IP2COUNTRY
55 #include "IP2Country.h" // Needed for IP2Country
56 #endif
57 #include "Logger.h"
58 #include "muuli_wdr.h" // Needed for IDs
59 #include "PartFile.h" // Needed for CPartFile
60 #include "SearchDlg.h" // Needed for CSearchDlg
61 #include "Server.h" // Needed for GetListName
62 #include "ServerWnd.h" // Needed for CServerWnd
63 #include "SharedFilesCtrl.h" // Needed for CSharedFilesCtrl
64 #include "SharedFilesWnd.h" // Needed for CSharedFilesWnd
65 #include "TransferWnd.h" // Needed for CTransferWnd
66 #include "updownclient.h"
67 #include "ServerListCtrl.h" // Needed for CServerListCtrl
68 #include "MagnetURI.h" // Needed for CMagnetURI
71 CEConnectDlg::CEConnectDlg()
73 wxDialog(theApp->amuledlg, -1, _("Connect to remote amule"), wxDefaultPosition)
75 CoreConnect(this, true);
77 wxString pref_host, pref_port;
78 wxConfig::Get()->Read(wxT("/EC/Host"), &pref_host, wxT("localhost"));
79 wxConfig::Get()->Read(wxT("/EC/Port"), &pref_port, wxT("4712"));
80 wxConfig::Get()->Read(wxT("/EC/Password"), &pwd_hash);
82 CastChild(ID_REMOTE_HOST, wxTextCtrl)->SetValue(pref_host);
83 CastChild(ID_REMOTE_PORT, wxTextCtrl)->SetValue(pref_port);
84 CastChild(ID_EC_PASSWD, wxTextCtrl)->SetValue(pwd_hash);
86 CentreOnParent();
90 wxString CEConnectDlg::PassHash()
92 return pwd_hash;
96 BEGIN_EVENT_TABLE(CEConnectDlg, wxDialog)
97 EVT_BUTTON(wxID_OK, CEConnectDlg::OnOK)
98 END_EVENT_TABLE()
101 void CEConnectDlg::OnOK(wxCommandEvent& evt)
103 wxString s_port = CastChild(ID_REMOTE_PORT, wxTextCtrl)->GetValue();
104 port = StrToLong(s_port);
106 host = CastChild(ID_REMOTE_HOST, wxTextCtrl)->GetValue();
107 passwd = CastChild(ID_EC_PASSWD, wxTextCtrl)->GetValue();
109 if (passwd != pwd_hash) {
110 pwd_hash = MD5Sum(passwd).GetHash();
112 m_save_user_pass = CastChild(ID_EC_SAVE, wxCheckBox)->IsChecked();
113 evt.Skip();
117 DEFINE_LOCAL_EVENT_TYPE(wxEVT_EC_INIT_DONE)
120 BEGIN_EVENT_TABLE(CamuleRemoteGuiApp, wxApp)
121 // Core timer
122 EVT_TIMER(ID_CORE_TIMER_EVENT, CamuleRemoteGuiApp::OnPollTimer)
124 EVT_CUSTOM(wxEVT_EC_CONNECTION, -1, CamuleRemoteGuiApp::OnECConnection)
125 EVT_CUSTOM(wxEVT_EC_INIT_DONE, -1, CamuleRemoteGuiApp::OnECInitDone)
127 EVT_MULE_NOTIFY(CamuleRemoteGuiApp::OnNotifyEvent)
128 EVT_MULE_LOGGING(CamuleRemoteGuiApp::OnLoggingEvent)
129 END_EVENT_TABLE()
132 IMPLEMENT_APP(CamuleRemoteGuiApp)
135 int CamuleRemoteGuiApp::OnExit()
137 StopTickTimer();
139 return wxApp::OnExit();
143 void CamuleRemoteGuiApp::OnPollTimer(wxTimerEvent&)
145 static int request_step = 0;
147 if (m_connect->RequestFifoFull()) {
148 return;
151 switch (request_step) {
152 case 0:
153 serverconnect->ReQuery();
154 serverlist->UpdateUserFileStatus(serverconnect->GetCurrentServer());
155 request_step++;
156 break;
157 case 1: {
158 CECPacket stats_req(EC_OP_STAT_REQ);
159 m_connect->SendRequest(&m_stats_updater, &stats_req);
160 amuledlg->ShowTransferRate();
161 request_step++;
162 break;
164 case 2:
165 if (amuledlg->m_sharedfileswnd->IsShown()) {
166 sharedfiles->DoRequery(EC_OP_GET_SHARED_FILES, EC_TAG_KNOWNFILE);
167 } else if (amuledlg->m_serverwnd->IsShown()) {
168 //serverlist->FullReload(EC_OP_GET_SERVER_LIST);
169 } else if (amuledlg->m_transferwnd->IsShown()) {
170 static bool firstcall = true;
171 downloadqueue->DoRequery(
172 theApp->m_FileDetailDialogActive || firstcall ?
173 EC_OP_GET_DLOAD_QUEUE_DETAIL : EC_OP_GET_DLOAD_QUEUE,
174 EC_TAG_PARTFILE);
175 firstcall = false;
176 switch(amuledlg->m_transferwnd->clientlistctrl->GetListView()) {
177 case vtUploading:
178 uploadqueue->ReQueryUp();
179 break;
180 case vtQueued:
181 uploadqueue->ReQueryWait();
182 break;
183 case vtClients:
184 break;
185 case vtNone:
186 break;
188 amuledlg->m_transferwnd->ShowQueueCount(theStats::GetWaitingUserCount());
189 } else if (amuledlg->m_searchwnd->IsShown()) {
190 if (searchlist->m_curr_search != -1) {
191 searchlist->DoRequery(EC_OP_SEARCH_RESULTS, EC_TAG_SEARCHFILE);
194 // Back to the roots
195 request_step = 0;
196 break;
197 default:
198 printf("WTF?\n");
199 request_step = 0;
204 void CamuleRemoteGuiApp::ShutDown(wxCloseEvent &WXUNUSED(evt))
206 // Stop the Core Timer
207 delete poll_timer;
208 poll_timer = NULL;
210 // Destroy the EC socket
211 m_connect->Destroy();
212 m_connect = NULL;
215 if (amuledlg) {
216 amuledlg->DlgShutDown();
217 amuledlg->Destroy();
218 amuledlg = NULL;
223 bool CamuleRemoteGuiApp::OnInit()
225 StartTickTimer();
226 amuledlg = NULL;
227 if ( !wxApp::OnInit() ) {
228 return false;
231 // Get theApp
232 theApp = &wxGetApp();
234 // Handle uncaught exceptions
235 InstallMuleExceptionHandler();
237 // Create the polling timer
238 poll_timer = new wxTimer(this,ID_CORE_TIMER_EVENT);
239 if (!poll_timer) {
240 printf("Fatal Error: Failed to create Poll Timer");
241 OnExit();
244 m_connect = new CRemoteConnect(this);
245 SetAppName(wxT("aMule"));
247 // Load Preferences
248 // This creates the CFG file we shall use
249 ConfigDir = GetConfigDir();
250 if (!wxDirExists(ConfigDir)) {
251 wxMkdir(ConfigDir);
254 wxConfig::Set(new wxFileConfig(wxEmptyString, wxEmptyString,
255 ConfigDir + wxT("remote.conf")));
257 glob_prefs = new CPreferencesRem(m_connect);
259 InitCustomLanguages();
260 InitLocale(m_locale, StrLang2wx(thePrefs::GetLanguageID()));
262 bool result = ShowConnectionDialog();
264 printf("Going to event loop...\n");
266 return result;
270 bool CamuleRemoteGuiApp::CryptoAvailable() const
272 return clientcredits && clientcredits->CryptoAvailable();
276 bool CamuleRemoteGuiApp::ShowConnectionDialog() {
278 dialog = new CEConnectDlg;
280 if (dialog->ShowModal() != wxID_OK) {
281 dialog->Destroy();
283 return false;
285 printf("Connecting...\n");
286 if (!m_connect->ConnectToCore(dialog->Host(), dialog->Port(),
287 dialog->Login(), dialog->PassHash(),
288 wxT("amule-remote"), wxT("0x0001"))) {
289 wxMessageBox(_("Connection failed "),_("ERROR"),wxOK);
291 return false;
294 return true;
298 void CamuleRemoteGuiApp::OnECConnection(wxEvent& event) {
299 wxECSocketEvent& evt = *((wxECSocketEvent*)&event);
300 printf("Remote GUI EC event handler\n");
301 AddLogLineM(true,evt.GetServerReply());
302 if (evt.GetResult() == true) {
303 // Connected - go to next init step
304 glob_prefs->LoadRemote();
305 } else {
306 printf("Going down\n");
307 ExitMainLoop();
312 void CamuleRemoteGuiApp::OnECInitDone(wxEvent& )
314 Startup();
318 void CamuleRemoteGuiApp::OnLoggingEvent(CLoggingEvent& evt)
320 printf("LOG: %s\n", unicode2char(evt.Message()).data());
324 void CamuleRemoteGuiApp::OnNotifyEvent(CMuleGUIEvent& evt)
326 evt.Notify();
330 void CamuleRemoteGuiApp::Startup() {
332 if (dialog->SaveUserPass()) {
333 wxConfig::Get()->Write(wxT("/EC/Host"), dialog->Host());
334 wxConfig::Get()->Write(wxT("/EC/Port"), dialog->Port());
335 wxConfig::Get()->Write(wxT("/EC/Password"), dialog->PassHash());
337 dialog->Destroy();
339 m_ConnState = 0;
340 m_clientID = 0;
342 serverconnect = new CServerConnectRem(m_connect);
343 m_statistics = new CStatistics(*m_connect);
345 clientlist = new CClientListRem(m_connect);
346 searchlist = new CSearchListRem(m_connect);
347 serverlist = new CServerListRem(m_connect);
349 sharedfiles = new CSharedFilesRem(m_connect);
350 knownfiles = new CKnownFilesRem(sharedfiles);
352 clientcredits = new CClientCreditsRem();
354 // bugfix - do this before creating the uploadqueue
355 downloadqueue = new CDownQueueRem(m_connect);
356 uploadqueue = new CUpQueueRem(m_connect);
357 ipfilter = new CIPFilterRem(m_connect);
359 // Parse cmdline arguments.
360 wxCmdLineParser cmdline(wxApp::argc, wxApp::argv);
361 cmdline.AddSwitch(wxT("v"), wxT("version"),
362 wxT("Displays the current version number."));
363 cmdline.AddSwitch(wxT("h"), wxT("help"),
364 wxT("Displays this information."));
365 cmdline.AddOption(wxT("geometry"), wxEmptyString, wxT("Sets the geometry of the app.\n\t\t\t<str> uses the same format as standard X11 apps:\n\t\t\t[=][<width>{xX}<height>][{+-}<xoffset>{+-}<yoffset>]"));
366 cmdline.Parse();
368 bool geometry_enabled = false;
369 wxString geom_string;
370 if (cmdline.Found(wxT("geometry"), &geom_string)) {
371 geometry_enabled = true;
374 // Create main dialog
375 InitGui(0, geom_string);
377 // Forward wxLog events to CLogger
378 wxLog::SetActiveTarget(new CLoggerTarget);
379 serverlist->FullReload(EC_OP_GET_SERVER_LIST);
380 sharedfiles->DoRequery(EC_OP_GET_SHARED_FILES, EC_TAG_KNOWNFILE);
382 // Start the Poll Timer
383 poll_timer->Start(1000);
384 amuledlg->StartGuiTimer();
388 void CamuleRemoteGuiApp::ShowAlert(wxString msg, wxString title, int flags)
390 CamuleGuiBase::ShowAlert(msg, title, flags);
394 int CamuleRemoteGuiApp::InitGui(bool geometry_enabled, wxString &geom_string)
396 CamuleGuiBase::InitGui(geometry_enabled, geom_string);
397 SetTopWindow(amuledlg);
398 return 0;
402 bool CamuleRemoteGuiApp::CopyTextToClipboard(wxString strText)
404 return CamuleGuiBase::CopyTextToClipboard(strText);
408 uint32 CamuleRemoteGuiApp::GetPublicIP()
410 return 0;
414 wxString CamuleRemoteGuiApp::GetLog(bool)
416 return wxEmptyString;
420 wxString CamuleRemoteGuiApp::GetServerLog(bool)
422 return wxEmptyString;
426 wxString CamuleRemoteGuiApp::CreateMagnetLink(const CAbstractFile* f)
428 // TODO: Remove duplicate code (also in amule.cpp) ...
429 CMagnetURI uri;
431 uri.AddField(wxT("dn"), f->GetFileName().Cleanup(false).GetPrintable());
432 uri.AddField(wxT("xt"), wxString(wxT("urn:ed2k:")) + f->GetFileHash().Encode().Lower());
433 uri.AddField(wxT("xl"), wxString::Format(wxT("%") wxLongLongFmtSpec wxT("u"), f->GetFileSize()));
435 return uri.GetLink();
438 wxString CamuleRemoteGuiApp::CreateED2kLink(const CAbstractFile* f, bool add_source, bool use_hostname, bool addcryptoptions)
440 // TODO: Avoid duplicate code (also in amule.cpp) ...
441 wxASSERT(!(!add_source && (use_hostname || addcryptoptions)));
442 // Construct URL like this: ed2k://|file|<filename>|<size>|<hash>|/
443 wxString strURL = CFormat(wxT("ed2k://|file|%s|%i|%s|/"))
444 % f->GetFileName().Cleanup(false)
445 % f->GetFileSize() % f->GetFileHash().Encode();
447 if (add_source && IsConnected() && !IsFirewalled()) {
448 // Create the first part of the URL
449 strURL << wxT("|sources,");
451 if (use_hostname) {
452 strURL << thePrefs::GetYourHostname();
453 } else {
454 uint32 clientID = GetID();
455 strURL << (uint8) clientID << wxT(".") <<
456 (uint8)(clientID >> 8) << wxT(".") <<
457 (uint8)(clientID >> 16) << wxT(".") <<
458 (uint8)(clientID >> 24);
461 strURL << wxT(":") <<
462 thePrefs::GetPort();
464 if (addcryptoptions) {
465 const uint8 uSupportsCryptLayer = thePrefs::IsClientCryptLayerSupported() ? 1 : 0;
466 const uint8 uRequestsCryptLayer = thePrefs::IsClientCryptLayerRequested() ? 1 : 0;
467 const uint8 uRequiresCryptLayer = thePrefs::IsClientCryptLayerRequired() ? 1 : 0;
468 const uint8 byCryptOptions = (uRequiresCryptLayer << 2) | (uRequestsCryptLayer << 1) | (uSupportsCryptLayer << 0) | (uSupportsCryptLayer ? 0x80 : 0x00);
470 strURL << wxT(":") << byCryptOptions;
472 if (byCryptOptions & 0x80) {
473 strURL << wxT(":") << thePrefs::GetUserHash().Encode();
477 strURL << wxT("|/");
478 } else if (add_source) {
479 AddLogLineM(true, _("WARNING: You can't add yourself as a source for an eD2k link while having a lowid."));
482 // Result is "ed2k://|file|<filename>|<size>|<hash>|/|sources,[(<ip>|<hostname>):<port>[:cryptoptions[:hash]]]|/"
483 return strURL;
487 wxString CamuleRemoteGuiApp::CreateED2kAICHLink(const CKnownFile* f)
489 // TODO: Avoid duplicate code (also in amule.cpp) ...
490 // Create the first part of the URL
491 wxString strURL = CreateED2kLink(f);
492 // Append the AICH info
493 if (f->HasProperAICHHashSet()) {
494 strURL << wxT("|h=") << f->GetAICHMasterHash() << wxT("|/");
497 // Result is "ed2k://|file|<filename>|<size>|<hash>|/|h=<AICH master hash>|/"
498 return strURL;
502 bool CamuleRemoteGuiApp::AddServer(CServer *, bool)
504 // #warning TODO: Add remote command
505 return true;
509 bool CamuleRemoteGuiApp::IsFirewalled() const
511 if (IsConnectedED2K() && !serverconnect->IsLowID()) {
512 return false;
515 return IsFirewalledKad();
519 bool CamuleRemoteGuiApp::IsConnectedED2K() const {
520 return serverconnect && serverconnect->IsConnected();
524 void CamuleRemoteGuiApp::StartKad() {
525 m_connect->StartKad();
529 void CamuleRemoteGuiApp::StopKad() {
530 m_connect->StopKad();
534 void CamuleRemoteGuiApp::BootstrapKad(uint32 ip, uint16 port)
536 CECPacket req(EC_OP_KAD_BOOTSTRAP_FROM_IP);
537 req.AddTag(CECTag(EC_TAG_BOOTSTRAP_IP, ip));
538 req.AddTag(CECTag(EC_TAG_BOOTSTRAP_PORT, port));
540 m_connect->SendPacket(&req);
544 void CamuleRemoteGuiApp::UpdateNotesDat(const wxString& url)
546 CECPacket req(EC_OP_KAD_UPDATE_FROM_URL);
547 req.AddTag(CECTag(EC_TAG_KADEMLIA_UPDATE_URL, url));
549 m_connect->SendPacket(&req);
553 void CamuleRemoteGuiApp::DisconnectED2K() {
554 if (IsConnectedED2K()) {
555 m_connect->DisconnectED2K();
560 uint32 CamuleRemoteGuiApp::GetED2KID() const
562 return serverconnect ? serverconnect->GetClientID() : 0;
566 uint32 CamuleRemoteGuiApp::GetID() const
568 return m_clientID;
572 void CamuleRemoteGuiApp::ShowUserCount() {
573 wxString buffer =
574 CFormat(_("Users: E: %s K: %s | Files E: %s K: %s")) % CastItoIShort(theStats::GetED2KUsers()) %
575 CastItoIShort(theStats::GetKadUsers()) % CastItoIShort(theStats::GetED2KFiles()) % CastItoIShort(theStats::GetKadFiles());
577 Notify_ShowUserCount(buffer);
582 * Preferences: holds both local and remote settings.
584 * First, everything is loaded from local config file. Later, settings
585 * that are relevant on remote side only are loaded thru EC
587 CPreferencesRem::CPreferencesRem(CRemoteConnect *conn)
589 m_conn = conn;
591 CPreferences::BuildItemList(theApp->ConfigDir);
592 CPreferences::LoadAllItems(wxConfigBase::Get());
595 // Settings queried from remote side
597 m_exchange_send_selected_prefs =
598 EC_PREFS_GENERAL |
599 EC_PREFS_CONNECTIONS |
600 EC_PREFS_MESSAGEFILTER |
601 EC_PREFS_ONLINESIG |
602 EC_PREFS_SERVERS |
603 EC_PREFS_FILES |
604 EC_PREFS_SRCDROP |
605 EC_PREFS_SECURITY |
606 EC_PREFS_CORETWEAKS |
607 EC_PREFS_REMOTECONTROLS |
608 EC_PREFS_KADEMLIA;
609 m_exchange_recv_selected_prefs =
610 m_exchange_send_selected_prefs |
611 EC_PREFS_CATEGORIES;
615 void CPreferencesRem::HandlePacket(const CECPacket *packet)
617 ((CEC_Prefs_Packet *)packet)->Apply();
619 if ( packet->GetTagByName(EC_TAG_PREFS_CATEGORIES) != 0 ) {
620 for (int i = 0; i < packet->GetTagByName(EC_TAG_PREFS_CATEGORIES)->GetTagCount(); i++) {
621 const CECTag *cat_tag = packet->GetTagByName(EC_TAG_PREFS_CATEGORIES)->GetTagByIndex(i);
622 Category_Struct *cat = new Category_Struct;
623 cat->title = cat_tag->GetTagByName(EC_TAG_CATEGORY_TITLE)->GetStringData();
624 cat->path = CPath(cat_tag->GetTagByName(EC_TAG_CATEGORY_PATH)->GetStringData());
625 cat->comment = cat_tag->GetTagByName(EC_TAG_CATEGORY_COMMENT)->GetStringData();
626 cat->color = cat_tag->GetTagByName(EC_TAG_CATEGORY_COLOR)->GetInt();
627 cat->prio = cat_tag->GetTagByName(EC_TAG_CATEGORY_PRIO)->GetInt();
628 theApp->glob_prefs->AddCat(cat);
630 } else {
631 Category_Struct *cat = new Category_Struct;
632 cat->title = _("All");
633 cat->color = 0;
634 cat->prio = PR_NORMAL;
635 theApp->glob_prefs->AddCat(cat);
637 wxECInitDoneEvent event;
638 theApp->AddPendingEvent(event);
643 bool CPreferencesRem::LoadRemote()
646 // override local settings with remote
647 CECPacket req(EC_OP_GET_PREFERENCES, EC_DETAIL_UPDATE);
649 // bring categories too
650 req.AddTag(CECTag(EC_TAG_SELECT_PREFS, m_exchange_recv_selected_prefs));
652 m_conn->SendRequest(this, &req);
654 return true;
658 void CPreferencesRem::SendToRemote()
660 CEC_Prefs_Packet pref_packet(m_exchange_send_selected_prefs, EC_DETAIL_UPDATE, EC_DETAIL_FULL);
661 m_conn->SendPacket(&pref_packet);
665 Category_Struct *CPreferencesRem::CreateCategory(
666 const wxString& name,
667 const CPath& path,
668 const wxString& comment,
669 uint32 color,
670 uint8 prio)
672 CECPacket req(EC_OP_CREATE_CATEGORY);
673 CEC_Category_Tag tag(0xffffffff, name, path.GetRaw(), comment, color, prio);
674 req.AddTag(tag);
675 m_conn->SendPacket(&req);
677 Category_Struct *category = new Category_Struct();
678 category->path = path;
679 category->title = name;
680 category->comment = comment;
681 category->color = color;
682 category->prio = prio;
684 AddCat(category);
686 return category;
690 void CPreferencesRem::UpdateCategory(
691 uint8 cat,
692 const wxString& name,
693 const CPath& path,
694 const wxString& comment,
695 uint32 color,
696 uint8 prio)
698 CECPacket req(EC_OP_UPDATE_CATEGORY);
699 CEC_Category_Tag tag(cat, name, path.GetRaw(), comment, color, prio);
700 req.AddTag(tag);
701 m_conn->SendPacket(&req);
703 Category_Struct *category = m_CatList[cat];
704 category->path = path;
705 category->title = name;
706 category->comment = comment;
707 category->color = color;
708 category->prio = prio;
712 void CPreferencesRem::RemoveCat(uint8 cat)
714 CECPacket req(EC_OP_DELETE_CATEGORY);
715 CEC_Category_Tag tag(cat, EC_DETAIL_CMD);
716 req.AddTag(tag);
717 m_conn->SendPacket(&req);
718 CPreferences::RemoveCat(cat);
723 // Container implementation
725 CServerConnectRem::CServerConnectRem(CRemoteConnect *conn)
727 m_CurrServer = 0;
728 m_Conn = conn;
732 void CServerConnectRem::ConnectToAnyServer()
734 CECPacket req(EC_OP_SERVER_CONNECT);
735 m_Conn->SendPacket(&req);
739 void CServerConnectRem::StopConnectionTry()
741 // lfroen: isn't Disconnect the same ?
745 void CServerConnectRem::Disconnect()
747 CECPacket req(EC_OP_SERVER_DISCONNECT);
748 m_Conn->SendPacket(&req);
752 void CServerConnectRem::ConnectToServer(CServer *server)
754 m_Conn->ConnectED2K(server->GetIP(), server->GetPort());
758 bool CServerConnectRem::ReQuery()
760 CECPacket stat_req(EC_OP_STAT_REQ);
761 m_Conn->SendRequest(this, &stat_req);
763 return true;
767 void CServerConnectRem::HandlePacket(const CECPacket *packet)
769 CEC_ConnState_Tag *tag =
770 (CEC_ConnState_Tag *)packet->GetTagByName(EC_TAG_CONNSTATE);
771 if (!tag) {
772 return;
775 theApp->m_ConnState = 0;
776 CServer *server;
777 m_ID = tag->GetEd2kId();
778 theApp->m_clientID = tag->GetClientId();
780 if (tag->IsConnectedED2K()) {
781 CECTag *srvtag = tag->GetTagByName(EC_TAG_SERVER);
782 if (!srvtag) {
783 return;
785 server = theApp->serverlist->GetByID(srvtag->GetIPv4Data().IP());
786 if (m_CurrServer && (server != m_CurrServer)) {
787 theApp->amuledlg->m_serverwnd->serverlistctrl->
788 HighlightServer(m_CurrServer, false);
790 theApp->amuledlg->m_serverwnd->serverlistctrl->
791 HighlightServer(server, true);
792 m_CurrServer = server;
793 theApp->m_ConnState |= CONNECTED_ED2K;
794 } else {
795 if ( m_CurrServer ) {
796 theApp->amuledlg->m_serverwnd->serverlistctrl->
797 HighlightServer(m_CurrServer, false);
798 m_CurrServer = 0;
802 if (tag->IsConnectedKademlia()) {
803 if (tag->IsKadFirewalled()) {
804 theApp->m_ConnState |= CONNECTED_KAD_FIREWALLED;
805 } else {
806 theApp->m_ConnState |= CONNECTED_KAD_OK;
808 } else {
809 if (tag->IsKadRunning()) {
810 theApp->m_ConnState |= CONNECTED_KAD_NOT;
814 theApp->amuledlg->ShowConnectionState();
819 * Server list: host list of ed2k servers.
821 CServerListRem::CServerListRem(CRemoteConnect *conn)
823 CRemoteContainer<CServer, uint32, CEC_Server_Tag>(conn)
828 void CServerListRem::HandlePacket(const CECPacket *packet)
830 CRemoteContainer<CServer, uint32, CEC_Server_Tag>::HandlePacket(packet);
831 ReloadControl();
835 void CServerListRem::UpdateServerMetFromURL(wxString url)
837 CECPacket req(EC_OP_SERVER_UPDATE_FROM_URL);
838 req.AddTag(CECTag(EC_TAG_SERVERS_UPDATE_URL, url));
840 m_conn->SendPacket(&req);
844 void CServerListRem::SaveServerMet()
846 // lfroen: stub, nothing to do
850 void CServerListRem::FilterServers()
852 // FIXME: add code
853 //wxASSERT(0);
857 void CServerListRem::RemoveServer(CServer* server)
859 m_conn->RemoveServer(server->GetIP(),server->GetPort());
863 void CServerListRem::UpdateUserFileStatus(CServer *server)
865 if (server) {
866 m_TotalUser = server->GetUsers();
867 m_TotalFile = server->GetFiles();
869 wxString buffer =
870 CFormat(_("Total Users: %s | Total Files: %s")) % CastItoIShort(m_TotalUser) % CastItoIShort(m_TotalFile);
872 Notify_ShowUserCount(buffer);
877 CServer *CServerListRem::GetServerByAddress(const wxString& WXUNUSED(address), uint16 WXUNUSED(port)) const
879 // It's ok to return 0 for context where this code is used in remote gui
880 return 0;
883 CServer *CServerListRem::GetServerByIPTCP(uint32 WXUNUSED(nIP), uint16 WXUNUSED(nPort)) const
885 // It's ok to return 0 for context where this code is used in remote gui
886 return 0;
889 CServer *CServerListRem::CreateItem(CEC_Server_Tag *tag)
891 return new CServer(tag);
895 void CServerListRem::DeleteItem(CServer *in_srv)
897 auto_ptr<CServer> srv(in_srv);
898 theApp->amuledlg->m_serverwnd->serverlistctrl->RemoveServer(srv.get());
902 uint32 CServerListRem::GetItemID(CServer *server)
904 return server->GetIP();
908 void CServerListRem::ProcessItemUpdate(CEC_Server_Tag *, CServer *)
910 // server list is always realoaded from scratch
911 wxASSERT(0);
915 void CServerListRem::ReloadControl()
917 for(uint32 i = 0;i < GetCount(); i++) {
918 CServer *srv = GetByIndex(i);
919 theApp->amuledlg->m_serverwnd->serverlistctrl->RefreshServer(srv);
924 CIPFilterRem::CIPFilterRem(CRemoteConnect* conn)
926 m_conn = conn;
930 void CIPFilterRem::Reload()
932 CECPacket req(EC_OP_IPFILTER_RELOAD);
933 m_conn->SendPacket(&req);
937 void CIPFilterRem::Update(wxString WXUNUSED(url))
939 // FIXME: add command
940 //wxASSERT(0);
945 * Shared files list
947 CSharedFilesRem::CSharedFilesRem(CRemoteConnect *conn) : CRemoteContainer<CKnownFile, CMD4Hash, CEC_SharedFile_Tag>(conn, true)
949 m_rename_file = NULL;
953 void CSharedFilesRem::Reload(bool, bool)
955 CECPacket req(EC_OP_SHAREDFILES_RELOAD);
957 m_conn->SendPacket(&req);
961 void CSharedFilesRem::AddFilesFromDirectory(const CPath& path)
963 CECPacket req(EC_OP_SHAREDFILES_ADD_DIRECTORY);
965 req.AddTag(CECTag(EC_TAG_PREFS_DIRECTORIES, path.GetRaw()));
967 m_conn->SendPacket(&req);
971 bool CSharedFilesRem::RenameFile(CKnownFile* file, const CPath& newName)
973 // We use the printable name, as the filename originated from user input,
974 // and the filesystem name might not be valid on the remote host.
975 const wxString strNewName = newName.GetPrintable();
977 CECPacket request(EC_OP_RENAME_FILE);
978 request.AddTag(CECTag(EC_TAG_KNOWNFILE, file->GetFileHash()));
979 request.AddTag(CECTag(EC_TAG_PARTFILE_NAME, strNewName));
981 m_conn->SendRequest(this, &request);
982 m_rename_file = file;
983 m_new_name = strNewName;
985 return true;
989 void CSharedFilesRem::HandlePacket(const CECPacket *packet)
991 if (m_rename_file && (packet->GetOpCode() == EC_OP_NOOP)) {
992 m_rename_file->SetFileName(CPath(m_new_name));
993 m_rename_file = NULL;
994 } else if (packet->GetOpCode() != EC_OP_FAILED) {
995 CRemoteContainer<CKnownFile, CMD4Hash, CEC_SharedFile_Tag>::HandlePacket(packet);
1000 CKnownFile *CSharedFilesRem::CreateItem(CEC_SharedFile_Tag *tag)
1002 CKnownFile *file = new CKnownFile(tag);
1004 m_enc_map[file->GetFileHash()] = RLE_Data(file->GetPartCount(), true);
1006 ProcessItemUpdate(tag, file);
1008 theApp->amuledlg->m_sharedfileswnd->sharedfilesctrl->ShowFile(file);
1010 return file;
1014 void CSharedFilesRem::DeleteItem(CKnownFile *in_file)
1016 auto_ptr<CKnownFile> file(in_file);
1018 m_enc_map.erase(file->GetFileHash());
1020 theApp->amuledlg->m_sharedfileswnd->sharedfilesctrl->RemoveFile(file.get());
1024 CMD4Hash CSharedFilesRem::GetItemID(CKnownFile *file)
1026 return file->GetFileHash();
1030 void CSharedFilesRem::ProcessItemUpdate(CEC_SharedFile_Tag *tag, CKnownFile *file)
1032 CECTag *parttag = tag->GetTagByName(EC_TAG_PARTFILE_PART_STATUS);
1033 const unsigned char *data =
1034 m_enc_map[file->GetFileHash()].Decode(
1035 (unsigned char *)parttag->GetTagData(),
1036 parttag->GetTagDataLen());
1037 for(int i = 0; i < file->GetPartCount(); ++i) {
1038 file->m_AvailPartFrequency[i] = data[i];
1040 if (m_inc_tags) {
1041 tag->SetRequests(file->statistic.requested);
1042 tag->SetAllRequests(file->statistic.alltimerequested);
1043 tag->SetAccepts(file->statistic.accepted);
1044 tag->SetAllAccepts(file->statistic.alltimeaccepted);
1045 tag->SetXferred(file->statistic.transferred );
1046 tag->SetAllXferred(file->statistic.alltimetransferred);
1047 tag->SetPrio(file->m_iUpPriority);
1048 } else {
1049 file->statistic.requested = tag->GetRequests();
1050 file->statistic.alltimerequested = tag->GetAllRequests();
1051 file->statistic.accepted = tag->GetAccepts();
1052 file->statistic.alltimeaccepted = tag->GetAllAccepts();
1053 file->statistic.transferred = tag->GetXferred();
1054 file->statistic.alltimetransferred = tag->GetAllXferred();
1055 file->m_iUpPriority = tag->Prio();
1057 if (file->m_iUpPriority >= 10) {
1058 file->m_iUpPriority -= 10;
1059 file->m_bAutoUpPriority = true;
1060 } else {
1061 file->m_bAutoUpPriority = false;
1064 theApp->knownfiles->requested += file->statistic.requested;
1065 theApp->knownfiles->transferred += file->statistic.transferred;
1066 theApp->knownfiles->accepted += file->statistic.transferred;
1068 theApp->amuledlg->m_sharedfileswnd->sharedfilesctrl->UpdateItem(file);
1071 bool CSharedFilesRem::Phase1Done(const CECPacket *)
1073 theApp->knownfiles->requested = 0;
1074 theApp->knownfiles->transferred = 0;
1075 theApp->knownfiles->accepted = 0;
1077 return true;
1080 void CSharedFilesRem::SetFilePrio(CKnownFile *file, uint8 prio)
1082 CECPacket req(EC_OP_SHARED_SET_PRIO);
1084 CECTag hashtag(EC_TAG_PARTFILE, file->GetFileHash());
1085 hashtag.AddTag(CECTag(EC_TAG_PARTFILE_PRIO, prio));
1087 req.AddTag(hashtag);
1089 m_conn->SendPacket(&req);
1093 * List of uploading and waiting clients.
1095 CUpDownClientListRem::CUpDownClientListRem(CRemoteConnect *conn, int viewtype)
1097 CRemoteContainer<CUpDownClient, uint32, CEC_UpDownClient_Tag>(conn)
1099 m_viewtype = viewtype;
1103 CUpDownClient::CUpDownClient(CEC_UpDownClient_Tag *tag)
1105 m_bRemoteQueueFull = false;
1106 m_nUserIDHybrid = tag->ID();
1107 m_Username = tag->ClientName();
1108 m_score = tag->Score();
1109 m_clientSoft = tag->ClientSoftware();
1110 m_clientVersionString = GetSoftName(m_clientSoft);
1111 m_clientSoftString = m_clientVersionString;
1113 // The functions to retrieve m_clientVerString information are
1114 // currently in BaseClient.cpp, which is not linked in remote-gui app.
1115 // So, in the meantime, we use a tag sent from core.
1116 m_clientVerString = tag->SoftVerStr();
1117 m_strModVersion = wxEmptyString;
1118 wxString clientModString;
1119 if (!clientModString.IsEmpty()) {
1120 m_clientVerString += wxT(" - ") + clientModString;
1122 m_fullClientVerString = m_clientSoftString + wxT(" ") + m_clientVerString;
1124 // User hash
1125 m_UserHash = tag->UserID();
1127 // User IP:Port
1128 m_nConnectIP = m_dwUserIP = tag->UserIP();
1129 m_nUserPort = tag->UserPort();
1130 m_FullUserIP = Uint32toStringIP(m_nConnectIP);
1132 // Server IP:Port
1133 m_dwServerIP = tag->ServerIP();
1134 m_nServerPort = tag->ServerPort();
1135 m_ServerName = tag->ServerName();
1137 m_waitingPosition = tag->WaitingPosition();
1139 m_Friend = 0;
1140 if (tag->HaveFile()) {
1141 CMD4Hash filehash = tag->FileID();
1142 m_uploadingfile = theApp->sharedfiles->GetByID(filehash);
1143 if (!m_uploadingfile) {
1144 m_uploadingfile = theApp->downloadqueue->GetByID(filehash);
1146 } else {
1147 m_uploadingfile = NULL;
1150 m_nCurSessionUp = 0;
1152 credits = new CClientCredits(new CreditStruct());
1155 uint16 CUpQueueRem::GetWaitingPosition(const CUpDownClient *client) const
1157 return client->GetWaitingPosition();
1160 /* Warning: do common base */
1163 bool CUpDownClient::IsIdentified() const
1165 return (credits && credits->GetCurrentIdentState(GetIP()) == IS_IDENTIFIED);
1169 bool CUpDownClient::IsBadGuy() const
1171 return (credits && credits->GetCurrentIdentState(GetIP()) == IS_IDBADGUY);
1175 bool CUpDownClient::SUIFailed() const
1177 return (credits && credits->GetCurrentIdentState(GetIP()) == IS_IDFAILED);
1181 bool CUpDownClient::SUINeeded() const
1183 return (credits && credits->GetCurrentIdentState(GetIP()) == IS_IDNEEDED);
1187 bool CUpDownClient::SUINotSupported() const
1189 return (credits && credits->GetCurrentIdentState(GetIP()) == IS_NOTAVAILABLE);
1193 uint64 CUpDownClient::GetDownloadedTotal() const
1195 return credits ? credits->GetDownloadedTotal() : 0;
1199 uint64 CUpDownClient::GetUploadedTotal() const
1201 return credits ? credits->GetUploadedTotal() : 0;
1205 double CUpDownClient::GetScoreRatio() const
1207 return credits ? credits->GetScoreRatio(GetIP(), theApp->CryptoAvailable()) : 0;
1210 /* End Warning */
1213 CUpDownClient::~CUpDownClient()
1215 if (credits) {
1216 delete credits;
1221 CUpDownClient *CUpDownClientListRem::CreateItem(CEC_UpDownClient_Tag *tag)
1223 CUpDownClient *client = new CUpDownClient(tag);
1224 ProcessItemUpdate(tag, client);
1226 theApp->amuledlg->m_transferwnd->clientlistctrl->InsertClient(client, (ViewType)m_viewtype);
1228 return client;
1232 void CUpDownClientListRem::DeleteItem(CUpDownClient *client)
1234 theApp->amuledlg->m_transferwnd->clientlistctrl->
1235 RemoveClient(client, (ViewType)m_viewtype);
1236 delete client;
1240 uint32 CUpDownClientListRem::GetItemID(CUpDownClient *client)
1242 return client->GetUserIDHybrid();
1246 void CUpDownClientListRem::ProcessItemUpdate(
1247 CEC_UpDownClient_Tag *tag,
1248 CUpDownClient *client)
1250 uint16 state = tag->ClientState();
1252 client->m_nDownloadState = state & 0xff;
1253 client->m_nUploadState = (state >> 8) & 0xff;
1255 client->m_nUpDatarate = tag->SpeedUp();
1256 if ( client->m_nDownloadState == DS_DOWNLOADING ) {
1257 client->kBpsDown = tag->SpeedDown() / 1024.0;
1258 } else {
1259 client->kBpsDown = 0;
1262 client->m_WaitTime = tag->WaitTime();
1263 client->m_UpStartTimeDelay = tag->XferTime();
1264 client->m_dwLastUpRequest = tag->LastReqTime();
1265 client->m_WaitStartTime = tag->QueueTime();
1267 CreditStruct *credit_struct =
1268 (CreditStruct *)client->credits->GetDataStruct();
1269 credit_struct->uploaded = tag->XferUp();
1270 client->m_nTransferredUp = tag->XferUpSession();
1272 credit_struct->downloaded = tag->XferDown();
1276 CUpQueueRem::CUpQueueRem(CRemoteConnect *conn)
1278 m_up_list(conn, vtUploading), m_wait_list(conn, vtQueued)
1284 * Download queue container: hold PartFiles with progress status
1289 CDownQueueRem::CDownQueueRem(CRemoteConnect *conn)
1291 CRemoteContainer<CPartFile, CMD4Hash, CEC_PartFile_Tag>(conn, true)
1296 bool CDownQueueRem::AddLink(const wxString &link, int)
1298 CECPacket req(EC_OP_ADD_LINK);
1299 req.AddTag(CECTag(EC_TAG_STRING, link));
1301 m_conn->SendPacket(&req);
1302 return true;
1306 void CDownQueueRem::StopUDPRequests()
1308 // have no idea what is it about
1312 void CDownQueueRem::ResetCatParts(int)
1314 // called when category being deleted. Command will be performed on remote side
1318 bool CDownQueueRem::IsPartFile(const CKnownFile *) const
1320 // hope i understand it right
1321 return true;
1325 void CDownQueueRem::OnConnectionState(bool)
1330 CPartFile *CDownQueueRem::CreateItem(CEC_PartFile_Tag *tag)
1332 CPartFile *file = new CPartFile(tag);
1333 m_enc_map[file->GetFileHash()] = PartFileEncoderData(file->GetPartCount(), 10);
1334 ProcessItemUpdate(tag, file);
1336 theApp->amuledlg->m_transferwnd->downloadlistctrl->AddFile(file);
1337 return file;
1341 void CDownQueueRem::DeleteItem(CPartFile *in_file)
1343 auto_ptr<CPartFile> file(in_file);
1345 theApp->amuledlg->m_transferwnd->downloadlistctrl->RemoveFile(file.get());
1347 m_enc_map.erase(file->GetFileHash());
1351 CMD4Hash CDownQueueRem::GetItemID(CPartFile *file)
1353 return file->GetFileHash();
1357 void CDownQueueRem::ProcessItemUpdate(CEC_PartFile_Tag *tag, CPartFile *file)
1360 // update status
1362 if (m_inc_tags) {
1363 uint32 tmpval = (uint32)(file->kBpsDown * 1024);
1364 tag->SetSpeed(tmpval);
1365 file->kBpsDown = tmpval / 1024.0;
1367 tag->SetSizeXfer(file->transferred);
1368 tag->SetSizeDone(file->completedsize);
1369 tag->SetSourceXferCount(file->transferingsrc);
1370 tag->SetSourceNotCurrCount(file->m_notCurrentSources);
1371 tag->SetSourceCount(file->m_source_count);
1372 tag->SetSourceCountA4AF(file->m_a4af_source_count);
1373 tag->SetFileStatus(file->status);
1375 tag->SetLastSeenComplete(file->lastseencomplete);
1377 tag->SetFileCat(file->m_category);
1379 tag->SetPrio(file->m_iDownPriority);
1380 } else {
1381 file->kBpsDown = tag->Speed() / 1024.0;
1383 if ( file->kBpsDown > 0 ) {
1384 file->transferred = tag->SizeXfer();
1385 file->SetCompletedSize(tag->SizeDone());
1388 file->transferingsrc = tag->SourceXferCount();
1389 file->m_notCurrentSources = tag->SourceNotCurrCount();
1390 file->m_source_count = tag->SourceCount();
1391 file->m_a4af_source_count = tag->SourceCountA4AF();
1392 file->status = tag->FileStatus();
1394 file->lastseencomplete = tag->LastSeenComplete();
1396 file->m_category = tag->FileCat();
1398 file->m_iDownPriority = tag->Prio();
1399 if ( file->m_iDownPriority >= 10 ) {
1400 file->m_iDownPriority-= 10;
1401 file->m_bAutoDownPriority = true;
1402 } else {
1403 file->m_bAutoDownPriority = false;
1406 file->percentcompleted = (100.0*file->GetCompletedSize()) / file->GetFileSize();
1407 if ( file->m_iDownPriority >= 10 ) {
1408 file->m_iDownPriority -= 10;
1409 file->m_bAutoUpPriority = true;
1410 } else {
1411 file->m_bAutoUpPriority = false;
1415 // Copy part/gap status
1417 CECTag *gaptag = tag->GetTagByName(EC_TAG_PARTFILE_GAP_STATUS);
1418 CECTag *parttag = tag->GetTagByName(EC_TAG_PARTFILE_PART_STATUS);
1419 CECTag *reqtag = tag->GetTagByName(EC_TAG_PARTFILE_REQ_STATUS);
1420 if (gaptag && parttag && reqtag) {
1421 wxASSERT(m_enc_map.count(file->GetFileHash()));
1423 PartFileEncoderData &encoder = m_enc_map[file->GetFileHash()];
1424 encoder.Decode(
1425 (unsigned char *)gaptag->GetTagData(), gaptag->GetTagDataLen(),
1426 (unsigned char *)parttag->GetTagData(), parttag->GetTagDataLen());
1428 const Gap_Struct *reqparts = (const Gap_Struct *)reqtag->GetTagData();
1429 unsigned reqcount = reqtag->GetTagDataLen() / sizeof(Gap_Struct);
1431 // adjust size of gaplist to reqcount
1432 unsigned gap_size = encoder.m_gap_status.Size() / (2 * sizeof(uint64));
1433 while ( file->m_gaplist.size() > gap_size ) {
1434 file->m_gaplist.pop_front();
1436 while ( file->m_gaplist.size() != gap_size ) {
1437 file->m_gaplist.push_front(new Gap_Struct);
1439 const uint64 *gap_info = (const uint64 *)encoder.m_gap_status.Buffer();
1442 std::list<Gap_Struct*>::iterator it = file->m_gaplist.begin();
1443 for (unsigned j = 0; j < gap_size;j++) {
1444 Gap_Struct* gap = *it++;
1445 gap->start = ENDIAN_NTOHLL(gap_info[2*j]);
1446 gap->end = ENDIAN_NTOHLL(gap_info[2*j+1]);
1449 // adjust size of requested block list
1450 while ( file->m_requestedblocks_list.size() > reqcount ) {
1451 file->m_requestedblocks_list.pop_front();
1453 while ( file->m_requestedblocks_list.size() != reqcount ) {
1454 file->m_requestedblocks_list.push_front(new Requested_Block_Struct);
1457 std::list<Requested_Block_Struct*>::iterator it2 = file->m_requestedblocks_list.begin();
1458 for (unsigned i = 0; i < reqcount; ++i) {
1459 Requested_Block_Struct* block = *it2++;
1460 block->StartOffset = ENDIAN_NTOHLL(reqparts[i].start);
1461 block->EndOffset = ENDIAN_NTOHLL(reqparts[i].end);
1463 // copy parts frequency
1464 const unsigned char *part_info = encoder.m_part_status.Buffer();
1465 for(int i = 0; i < file->GetPartCount(); ++i) {
1466 file->m_SrcpartFrequency[i] = part_info[i];
1468 } else {
1469 printf("ERROR: %p %p %p\n", (void*)gaptag, (void*)parttag, (void*)reqtag);
1472 // Get source names
1473 CECTag *srcnametag = tag->GetTagByName(EC_TAG_PARTFILE_SOURCE_NAMES);
1474 if (srcnametag) {
1475 file->ClearSourcenameItemList();
1476 int max = srcnametag->GetTagCount();
1477 for (int i = 0; i < max - 1; ) {
1478 wxString name = srcnametag->GetTagByIndex(i++)->GetStringData();
1479 long count = srcnametag->GetTagByIndex(i++)->GetInt();
1480 file->AddSourcenameItemList(name, count);
1484 // Get comments
1485 CECTag *commenttag = tag->GetTagByName(EC_TAG_PARTFILE_COMMENTS);
1486 if (commenttag) {
1487 file->ClearFileRatingList();
1488 int max = commenttag->GetTagCount();
1489 for (int i = 0; i < max - 3; ) {
1490 wxString u = commenttag->GetTagByIndex(i++)->GetStringData();
1491 wxString f = commenttag->GetTagByIndex(i++)->GetStringData();
1492 int r = commenttag->GetTagByIndex(i++)->GetInt();
1493 wxString c = commenttag->GetTagByIndex(i++)->GetStringData();
1494 file->AddFileRatingList(u, f, r, c);
1496 file->UpdateFileRatingCommentAvail();
1499 theApp->amuledlg->m_transferwnd->downloadlistctrl->UpdateItem(file);
1503 bool CDownQueueRem::Phase1Done(const CECPacket *)
1505 return true;
1509 void CDownQueueRem::SendFileCommand(CPartFile *file, ec_tagname_t cmd)
1511 CECPacket req(cmd);
1512 req.AddTag(CECTag(EC_TAG_PARTFILE, file->GetFileHash()));
1514 m_conn->SendPacket(&req);
1518 void CDownQueueRem::Prio(CPartFile *file, uint8 prio)
1520 CECPacket req(EC_OP_PARTFILE_PRIO_SET);
1522 CECTag hashtag(EC_TAG_PARTFILE, file->GetFileHash());
1523 hashtag.AddTag(CECTag(EC_TAG_PARTFILE_PRIO, prio));
1524 req.AddTag(hashtag);
1526 m_conn->SendPacket(&req);
1530 void CDownQueueRem::AutoPrio(CPartFile *file, bool flag)
1532 CECPacket req(EC_OP_PARTFILE_PRIO_SET);
1534 CECTag hashtag(EC_TAG_PARTFILE, file->GetFileHash());
1536 hashtag.AddTag(CECTag(EC_TAG_PARTFILE_PRIO,
1537 (uint8)(flag ? PR_AUTO : file->GetDownPriority())));
1538 req.AddTag(hashtag);
1540 m_conn->SendPacket(&req);
1544 void CDownQueueRem::Category(CPartFile *file, uint8 cat)
1546 CECPacket req(EC_OP_PARTFILE_SET_CAT);
1547 file->m_category = cat;
1549 CECTag hashtag(EC_TAG_PARTFILE, file->GetFileHash());
1550 hashtag.AddTag(CECTag(EC_TAG_PARTFILE_CAT, cat));
1551 req.AddTag(hashtag);
1553 m_conn->SendPacket(&req);
1557 void CDownQueueRem::AddSearchToDownload(CSearchFile* file, uint8 category)
1559 CECPacket req(EC_OP_DOWNLOAD_SEARCH_RESULT);
1560 CECTag hashtag(EC_TAG_PARTFILE, file->GetFileHash());
1561 hashtag.AddTag(CECTag(EC_TAG_PARTFILE_CAT, category));
1562 req.AddTag(hashtag);
1564 m_conn->SendPacket(&req);
1568 CClientListRem::CClientListRem(CRemoteConnect *conn)
1570 m_conn = conn;
1574 void CClientListRem::FilterQueues()
1576 // FIXME: add code
1577 //wxASSERT(0);
1581 CSearchListRem::CSearchListRem(CRemoteConnect *conn) : CRemoteContainer<CSearchFile, CMD4Hash, CEC_SearchFile_Tag>(conn)
1583 m_curr_search = -1;
1587 wxString CSearchListRem::StartNewSearch(
1588 uint32* nSearchID, SearchType search_type,
1589 const CSearchList::CSearchParams& params)
1591 CECPacket search_req(EC_OP_SEARCH_START);
1592 EC_SEARCH_TYPE ec_search_type = EC_SEARCH_LOCAL;
1593 switch(search_type) {
1594 case LocalSearch: ec_search_type = EC_SEARCH_LOCAL; break;
1595 case GlobalSearch: ec_search_type = EC_SEARCH_GLOBAL; break;
1596 case KadSearch: ec_search_type = EC_SEARCH_KAD; break;
1598 search_req.AddTag(
1599 CEC_Search_Tag(params.searchString, ec_search_type,
1600 params.typeText, params.extension, params.availability,
1601 params.minSize, params.maxSize));
1603 m_conn->SendPacket(&search_req);
1604 m_curr_search = *(nSearchID); // No kad remote search yet.
1606 Flush();
1608 return wxEmptyString; // EC reply will have the error mesg is needed.
1612 void CSearchListRem::StopGlobalSearch()
1614 if (m_curr_search != -1) {
1615 CECPacket search_req(EC_OP_SEARCH_STOP);
1616 m_conn->SendPacket(&search_req);
1621 void CSearchListRem::HandlePacket(const CECPacket *packet)
1623 if ( packet->GetOpCode() == EC_OP_SEARCH_PROGRESS ) {
1624 CoreNotify_Search_Update_Progress(packet->GetTagByIndex(0)->GetInt());
1625 } else {
1626 CRemoteContainer<CSearchFile, CMD4Hash, CEC_SearchFile_Tag>::HandlePacket(packet);
1631 CSearchFile::CSearchFile(CEC_SearchFile_Tag *tag)
1633 m_parent(NULL),
1634 m_showChildren(false),
1635 m_sourceCount(0),
1636 m_completeSourceCount(0),
1637 m_kademlia(false),
1638 m_clientID(0),
1639 m_clientPort(0)
1641 SetFileName(CPath(tag->FileName()));
1642 m_abyFileHash = tag->ID();
1643 SetFileSize(tag->SizeFull());
1645 m_searchID = theApp->searchlist->m_curr_search;
1650 // dtor is virtual - must be implemented
1651 CSearchFile::~CSearchFile()
1656 CSearchFile *CSearchListRem::CreateItem(CEC_SearchFile_Tag *tag)
1658 CSearchFile *file = new CSearchFile(tag);
1659 ProcessItemUpdate(tag, file);
1661 theApp->amuledlg->m_searchwnd->AddResult(file);
1663 return file;
1667 void CSearchListRem::DeleteItem(CSearchFile *file)
1669 delete file;
1673 CMD4Hash CSearchListRem::GetItemID(CSearchFile *file)
1675 return file->GetFileHash();
1679 void CSearchListRem::ProcessItemUpdate(CEC_SearchFile_Tag *tag, CSearchFile *file)
1681 file->m_sourceCount = tag->SourceCount();
1682 file->m_completeSourceCount = tag->CompleteSourceCount();
1686 bool CSearchListRem::Phase1Done(const CECPacket *WXUNUSED(reply))
1688 CECPacket progress_req(EC_OP_SEARCH_PROGRESS);
1689 m_conn->SendRequest(this, &progress_req);
1691 return true;
1695 void CSearchListRem::RemoveResults(long nSearchID)
1697 ResultMap::iterator it = m_results.find(nSearchID);
1698 if (it != m_results.end()) {
1699 CSearchResultList& list = it->second;
1700 for (unsigned int i = 0; i < list.size(); ++i) {
1701 delete list[i];
1703 m_results.erase(it);
1708 const CSearchResultList& CSearchListRem::GetSearchResults(long nSearchID)
1710 ResultMap::const_iterator it = m_results.find(nSearchID);
1711 if (it != m_results.end()) {
1712 return it->second;
1715 // TODO: Should we assert in this case?
1716 static CSearchResultList list;
1717 return list;
1721 void CStatsUpdaterRem::HandlePacket(const CECPacket *packet)
1723 theStats::UpdateStats(packet);
1724 theApp->ShowUserCount(); // maybe there should be a check if a usercount changed ?
1728 bool CUpDownClient::IsBanned() const
1730 // FIXME: add code
1731 return false;
1736 // Those functions have different implementation in remote gui
1738 void CUpDownClient::Ban()
1740 // FIXME: add code
1741 wxASSERT(0);
1745 void CUpDownClient::UnBan()
1747 // FIXME: add code
1748 wxASSERT(0);
1752 void CUpDownClient::RequestSharedFileList()
1754 // FIXME: add code
1755 wxASSERT(0);
1759 void CKnownFile::SetFileComment(const wxString &)
1761 // FIXME: add code
1762 wxASSERT(0);
1766 void CKnownFile::SetFileRating(unsigned char)
1768 // FIXME: add code
1769 wxASSERT(0);
1773 // I don't think it will be implemented - too match data transfer. But who knows ?
1774 wxString CUpDownClient::ShowDownloadingParts() const
1776 return wxEmptyString;
1780 bool CUpDownClient::SwapToAnotherFile(
1781 bool WXUNUSED(bIgnoreNoNeeded),
1782 bool WXUNUSED(ignoreSuspensions),
1783 bool WXUNUSED(bRemoveCompletely),
1784 CPartFile* WXUNUSED(toFile))
1786 // FIXME: add code
1787 wxASSERT(0);
1788 return false;
1793 // Those functions are virtual. So even they don't get called they must
1794 // be defined so linker will be happy
1796 CPacket* CKnownFile::CreateSrcInfoPacket(const CUpDownClient *, uint8 /*byRequestedVersion*/, uint16 /*nRequestedOptions*/)
1798 wxASSERT(0);
1799 return 0;
1803 bool CKnownFile::LoadFromFile(const class CFileDataIO*)
1805 wxASSERT(0);
1806 return false;
1810 void CKnownFile::UpdatePartsInfo()
1812 wxASSERT(0);
1816 void CKnownFile::SetFileSize(uint64 nFileSize)
1818 CAbstractFile::SetFileSize(nFileSize);
1822 CPacket* CPartFile::CreateSrcInfoPacket(CUpDownClient const *, uint8 /*byRequestedVersion*/, uint16 /*nRequestedOptions*/)
1824 wxASSERT(0);
1825 return 0;
1829 void CPartFile::UpdatePartsInfo()
1831 wxASSERT(0);
1835 void CPartFile::UpdateFileRatingCommentAvail()
1837 bool prevComment = m_hasComment;
1838 int prevRating = m_iUserRating;
1840 m_hasComment = false;
1841 m_iUserRating = 0;
1842 int ratingCount = 0;
1844 FileRatingList::iterator it = m_FileRatingList.begin();
1845 for (; it != m_FileRatingList.end(); ++it) {
1846 SFileRating& cur_rat = *it;
1848 if (!cur_rat.Comment.IsEmpty()) {
1849 m_hasComment = true;
1852 uint8 rating = cur_rat.Rating;
1853 if (rating) {
1854 wxASSERT(rating <= 5);
1856 ratingCount++;
1857 m_iUserRating += rating;
1861 if (ratingCount) {
1862 m_iUserRating /= ratingCount;
1863 wxASSERT(m_iUserRating > 0 && m_iUserRating <= 5);
1866 if ((prevComment != m_hasComment) || (prevRating != m_iUserRating)) {
1867 UpdateDisplayedInfo();
1871 bool CPartFile::SavePartFile(bool)
1873 wxASSERT(0);
1874 return false;
1879 // since gui is not linked with amule.cpp - define events here
1881 DEFINE_LOCAL_EVENT_TYPE(wxEVT_CORE_FINISHED_HTTP_DOWNLOAD)
1882 DEFINE_LOCAL_EVENT_TYPE(wxEVT_CORE_SOURCE_DNS_DONE)
1883 DEFINE_LOCAL_EVENT_TYPE(wxEVT_CORE_UDP_DNS_DONE)
1884 DEFINE_LOCAL_EVENT_TYPE(wxEVT_CORE_SERVER_DNS_DONE)
1885 // File_checked_for_headers