Updated Hungarian translation.
[amule.git] / src / amule-remote-gui.cpp
blob1af561aa841f1ec79229e7c90c13a449bf28a31f
1 //
2 // This file is part of the aMule Project.
3 //
4 // Copyright (c) 2005-2011 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.
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 "SourceListCtrl.h"
44 #include "ChatWnd.h"
45 #include "DataToText.h" // Needed for GetSoftName()
46 #include "DownloadListCtrl.h" // Needed for CDownloadListCtrl
47 #include "Friend.h"
48 #include "GetTickCount.h" // Needed for GetTickCount
49 #include "GuiEvents.h"
50 #ifdef ENABLE_IP2COUNTRY
51 #include "IP2Country.h" // Needed for IP2Country
52 #endif
53 #include "InternalEvents.h" // Needed for wxEVT_CORE_FINISHED_HTTP_DOWNLOAD
54 #include "Logger.h"
55 #include "muuli_wdr.h" // Needed for IDs
56 #include "PartFile.h" // Needed for CPartFile
57 #include "SearchDlg.h" // Needed for CSearchDlg
58 #include "Server.h" // Needed for GetListName
59 #include "ServerWnd.h" // Needed for CServerWnd
60 #include "SharedFilesCtrl.h" // Needed for CSharedFilesCtrl
61 #include "SharedFilesWnd.h" // Needed for CSharedFilesWnd
62 #include "TransferWnd.h" // Needed for CTransferWnd
63 #include "UpDownClientEC.h" // Needed for CUpDownClient
64 #include "ServerListCtrl.h" // Needed for CServerListCtrl
65 #include "ScopedPtr.h"
66 #include "StatisticsDlg.h" // Needed for CStatisticsDlg
69 CEConnectDlg::CEConnectDlg()
71 wxDialog(theApp->amuledlg, -1, _("Connect to remote amule"), wxDefaultPosition)
73 CoreConnect(this, true);
75 wxString pref_host, pref_port;
76 wxConfig::Get()->Read(wxT("/EC/Host"), &pref_host, wxT("localhost"));
77 wxConfig::Get()->Read(wxT("/EC/Port"), &pref_port, wxT("4712"));
78 wxConfig::Get()->Read(wxT("/EC/Password"), &pwd_hash);
80 CastChild(ID_REMOTE_HOST, wxTextCtrl)->SetValue(pref_host);
81 CastChild(ID_REMOTE_PORT, wxTextCtrl)->SetValue(pref_port);
82 CastChild(ID_EC_PASSWD, wxTextCtrl)->SetValue(pwd_hash);
84 CentreOnParent();
88 wxString CEConnectDlg::PassHash()
90 return pwd_hash;
94 BEGIN_EVENT_TABLE(CEConnectDlg, wxDialog)
95 EVT_BUTTON(wxID_OK, CEConnectDlg::OnOK)
96 END_EVENT_TABLE()
99 void CEConnectDlg::OnOK(wxCommandEvent& evt)
101 wxString s_port = CastChild(ID_REMOTE_PORT, wxTextCtrl)->GetValue();
102 port = StrToLong(s_port);
104 host = CastChild(ID_REMOTE_HOST, wxTextCtrl)->GetValue();
105 passwd = CastChild(ID_EC_PASSWD, wxTextCtrl)->GetValue();
107 if (passwd != pwd_hash) {
108 pwd_hash = MD5Sum(passwd).GetHash();
110 m_save_user_pass = CastChild(ID_EC_SAVE, wxCheckBox)->IsChecked();
111 evt.Skip();
115 DEFINE_LOCAL_EVENT_TYPE(wxEVT_EC_INIT_DONE)
118 BEGIN_EVENT_TABLE(CamuleRemoteGuiApp, wxApp)
119 // Core timer
120 EVT_TIMER(ID_CORE_TIMER_EVENT, CamuleRemoteGuiApp::OnPollTimer)
122 EVT_CUSTOM(wxEVT_EC_CONNECTION, -1, CamuleRemoteGuiApp::OnECConnection)
123 EVT_CUSTOM(wxEVT_EC_INIT_DONE, -1, CamuleRemoteGuiApp::OnECInitDone)
125 EVT_MULE_NOTIFY(CamuleRemoteGuiApp::OnNotifyEvent)
127 #ifdef ENABLE_IP2COUNTRY
128 // HTTPDownload finished
129 EVT_MULE_INTERNAL(wxEVT_CORE_FINISHED_HTTP_DOWNLOAD, -1, CamuleRemoteGuiApp::OnFinishedHTTPDownload)
130 #endif
131 END_EVENT_TABLE()
134 IMPLEMENT_APP(CamuleRemoteGuiApp)
137 int CamuleRemoteGuiApp::OnExit()
139 StopTickTimer();
141 return wxApp::OnExit();
145 void CamuleRemoteGuiApp::OnPollTimer(wxTimerEvent&)
147 static int request_step = 0;
148 static uint32 msPrevStats = 0;
150 if (m_connect->RequestFifoFull()) {
151 return;
154 switch (request_step) {
155 case 0:
156 // We used to update the connection state here, but that's done with the stats in the next step now.
157 request_step++;
158 break;
159 case 1: {
160 CECPacket stats_req(EC_OP_STAT_REQ, EC_DETAIL_INC_UPDATE);
161 m_connect->SendRequest(&m_stats_updater, &stats_req);
162 request_step++;
163 break;
165 case 2:
166 if (amuledlg->m_sharedfileswnd->IsShown()
167 || amuledlg->m_chatwnd->IsShown()
168 || amuledlg->m_serverwnd->IsShown()) {
169 // update downloads, shared files and servers
170 knownfiles->DoRequery(EC_OP_GET_UPDATE, EC_TAG_KNOWNFILE);
171 } else if (amuledlg->m_transferwnd->IsShown()) {
172 // update both downloads and shared files
173 knownfiles->DoRequery(EC_OP_GET_UPDATE, EC_TAG_KNOWNFILE);
174 } else if (amuledlg->m_searchwnd->IsShown()) {
175 if (searchlist->m_curr_search != -1) {
176 searchlist->DoRequery(EC_OP_SEARCH_RESULTS, EC_TAG_SEARCHFILE);
178 } else if (amuledlg->m_statisticswnd->IsShown()) {
179 int sStatsUpdate = thePrefs::GetStatsInterval();
180 uint32 msCur = theStats::GetUptimeMillis();
181 if ((sStatsUpdate > 0) && ((int)(msCur - msPrevStats) > sStatsUpdate*1000)) {
182 msPrevStats = msCur;
183 stattree->DoRequery();
186 // Back to the roots
187 request_step = 0;
188 break;
189 default:
190 wxFAIL;
191 request_step = 0;
194 // Check for new links once per second.
195 static uint32 lastED2KLinkCheck = 0;
196 if (GetTickCount() - lastED2KLinkCheck >= 1000) {
197 AddLinksFromFile();
198 lastED2KLinkCheck = GetTickCount();
203 void CamuleRemoteGuiApp::OnFinishedHTTPDownload(CMuleInternalEvent& event)
205 if (event.GetInt() == HTTP_GeoIP) {
206 amuledlg->IP2CountryDownloadFinished(event.GetExtraLong());
207 // If we updated, the dialog is already up. Redraw it to show the flags.
208 amuledlg->Refresh();
213 void CamuleRemoteGuiApp::ShutDown(wxCloseEvent &WXUNUSED(evt))
215 // Stop the Core Timer
216 delete poll_timer;
217 poll_timer = NULL;
219 #ifdef ASIO_SOCKETS
220 m_AsioService->Stop();
221 delete m_AsioService;
222 m_AsioService = NULL;
223 #endif
225 // Destroy the EC socket
226 m_connect->Destroy();
227 m_connect = NULL;
230 if (amuledlg) {
231 amuledlg->DlgShutDown();
232 amuledlg->Destroy();
233 amuledlg = NULL;
235 delete m_allUploadingKnownFile;
236 delete stattree;
240 bool CamuleRemoteGuiApp::OnInit()
242 StartTickTimer();
243 amuledlg = NULL;
245 // Get theApp
246 theApp = &wxGetApp();
248 // Handle uncaught exceptions
249 InstallMuleExceptionHandler();
251 // Parse cmdline arguments.
252 if (!InitCommon(AMULE_APP_BASE::argc, AMULE_APP_BASE::argv)) {
253 return false;
256 // Create the polling timer
257 poll_timer = new wxTimer(this,ID_CORE_TIMER_EVENT);
258 if (!poll_timer) {
259 AddLogLineCS(_("Fatal Error: Failed to create Poll Timer"));
260 OnExit();
263 m_connect = new CRemoteConnect(this);
265 #ifdef ASIO_SOCKETS
266 m_AsioService = new CAsioService;
267 #endif
269 glob_prefs = new CPreferencesRem(m_connect);
270 long enableZLIB;
271 wxConfig::Get()->Read(wxT("/EC/ZLIB"), &enableZLIB, 1);
272 m_connect->SetCapabilities(enableZLIB != 0, true, false); // ZLIB, UTF8 numbers, notification
274 InitCustomLanguages();
275 InitLocale(m_locale, StrLang2wx(thePrefs::GetLanguageID()));
277 if (ShowConnectionDialog()) {
278 AddLogLineNS(_("Going to event loop..."));
279 return true;
282 return false;
286 bool CamuleRemoteGuiApp::CryptoAvailable() const
288 return thePrefs::IsSecureIdentEnabled(); // good enough
292 bool CamuleRemoteGuiApp::ShowConnectionDialog()
294 dialog = new CEConnectDlg;
296 if (m_skipConnectionDialog) {
297 wxCommandEvent evt;
298 dialog->OnOK(evt);
299 } else if (dialog->ShowModal() != wxID_OK) {
300 dialog->Destroy();
302 return false;
304 AddLogLineNS(_("Connecting..."));
305 if (!m_connect->ConnectToCore(dialog->Host(), dialog->Port(),
306 dialog->Login(), dialog->PassHash(),
307 wxT("amule-remote"), wxT("0x0001"))) {
308 wxMessageBox(_("Connection failed "),_("ERROR"),wxOK);
310 return false;
313 return true;
317 void CamuleRemoteGuiApp::OnECConnection(wxEvent& event) {
318 wxECSocketEvent& evt = *((wxECSocketEvent*)&event);
319 AddLogLineNS(_("Remote GUI EC event handler"));
320 wxString reply = evt.GetServerReply();
321 AddLogLineC(reply);
322 if (evt.GetResult() == true) {
323 // Connected - go to next init step
324 glob_prefs->LoadRemote();
325 } else {
326 AddLogLineNS(_("Going down"));
327 if (dialog) { // connect failed
328 wxMessageBox(
329 (CFormat(_("Connection Failed. Unable to connect to %s:%d\n")) % dialog->Host() % dialog->Port()) + reply,
330 _("ERROR"), wxOK);
331 } else { // server disconnected (probably terminated) later
332 wxMessageBox(_("Connection closed - aMule has terminated probably."), _("ERROR"), wxOK);
334 wxCloseEvent ev;
335 ShutDown(ev);
336 ExitMainLoop();
341 void CamuleRemoteGuiApp::OnECInitDone(wxEvent& )
343 Startup();
347 void CamuleRemoteGuiApp::OnNotifyEvent(CMuleGUIEvent& evt)
349 evt.Notify();
353 void CamuleRemoteGuiApp::Startup() {
355 if (dialog->SaveUserPass()) {
356 wxConfig::Get()->Write(wxT("/EC/Host"), dialog->Host());
357 wxConfig::Get()->Write(wxT("/EC/Port"), dialog->Port());
358 wxConfig::Get()->Write(wxT("/EC/Password"), dialog->PassHash());
360 dialog->Destroy();
361 dialog = NULL;
363 m_ConnState = 0;
364 m_clientID = 0;
366 serverconnect = new CServerConnectRem(m_connect);
367 m_statistics = new CStatistics(*m_connect);
368 stattree = new CStatTreeRem(m_connect);
370 clientlist = new CUpDownClientListRem(m_connect);
371 searchlist = new CSearchListRem(m_connect);
372 serverlist = new CServerListRem(m_connect);
373 friendlist = new CFriendListRem(m_connect);
376 sharedfiles = new CSharedFilesRem(m_connect);
377 knownfiles = new CKnownFilesRem(m_connect);
379 downloadqueue = new CDownQueueRem(m_connect);
380 ipfilter = new CIPFilterRem(m_connect);
382 m_allUploadingKnownFile = new CKnownFile;
384 // Create main dialog
385 InitGui(m_geometryEnabled, m_geometryString);
387 // Forward wxLog events to CLogger
388 wxLog::SetActiveTarget(new CLoggerTarget);
389 knownfiles->DoRequery(EC_OP_GET_UPDATE, EC_TAG_KNOWNFILE);
391 // Start the Poll Timer
392 poll_timer->Start(1000);
393 amuledlg->StartGuiTimer();
395 // Now activate GeoIP, so that the download dialog doesn't get destroyed immediately
396 #ifdef ENABLE_IP2COUNTRY
397 if (thePrefs::IsGeoIPEnabled()) {
398 amuledlg->m_IP2Country->Enable();
400 #endif
404 int CamuleRemoteGuiApp::ShowAlert(wxString msg, wxString title, int flags)
406 return CamuleGuiBase::ShowAlert(msg, title, flags);
410 void CamuleRemoteGuiApp::AddRemoteLogLine(const wxString& line)
412 amuledlg->AddLogLine(line);
415 int CamuleRemoteGuiApp::InitGui(bool geometry_enabled, wxString &geom_string)
417 CamuleGuiBase::InitGui(geometry_enabled, geom_string);
418 SetTopWindow(amuledlg);
419 AddLogLineN(_("Ready")); // The first log line after the window is up triggers output of all the ones before
420 return 0;
424 bool CamuleRemoteGuiApp::CopyTextToClipboard(wxString strText)
426 return CamuleGuiBase::CopyTextToClipboard(strText);
430 uint32 CamuleRemoteGuiApp::GetPublicIP()
432 return 0;
436 wxString CamuleRemoteGuiApp::GetLog(bool reset)
438 if (reset) {
439 amuledlg->ResetLog(ID_LOGVIEW);
440 CECPacket req(EC_OP_RESET_LOG);
441 m_connect->SendPacket(&req);
443 return wxEmptyString;
447 wxString CamuleRemoteGuiApp::GetServerLog(bool)
449 return wxEmptyString;
453 bool CamuleRemoteGuiApp::AddServer(CServer * server, bool)
455 CECPacket req(EC_OP_SERVER_ADD);
456 req.AddTag(CECTag(EC_TAG_SERVER_ADDRESS, CFormat(wxT("%s:%d")) % server->GetAddress() % server->GetPort()));
457 req.AddTag(CECTag(EC_TAG_SERVER_NAME, server->GetListName()));
458 m_connect->SendPacket(&req);
460 return true;
464 bool CamuleRemoteGuiApp::IsFirewalled() const
466 if (IsConnectedED2K() && !serverconnect->IsLowID()) {
467 return false;
470 return IsFirewalledKad();
474 bool CamuleRemoteGuiApp::IsConnectedED2K() const {
475 return serverconnect && serverconnect->IsConnected();
479 void CamuleRemoteGuiApp::StartKad() {
480 m_connect->StartKad();
484 void CamuleRemoteGuiApp::StopKad() {
485 m_connect->StopKad();
489 void CamuleRemoteGuiApp::BootstrapKad(uint32 ip, uint16 port)
491 CECPacket req(EC_OP_KAD_BOOTSTRAP_FROM_IP);
492 req.AddTag(CECTag(EC_TAG_BOOTSTRAP_IP, ip));
493 req.AddTag(CECTag(EC_TAG_BOOTSTRAP_PORT, port));
495 m_connect->SendPacket(&req);
499 void CamuleRemoteGuiApp::UpdateNotesDat(const wxString& url)
501 CECPacket req(EC_OP_KAD_UPDATE_FROM_URL);
502 req.AddTag(CECTag(EC_TAG_KADEMLIA_UPDATE_URL, url));
504 m_connect->SendPacket(&req);
508 void CamuleRemoteGuiApp::DisconnectED2K() {
509 if (IsConnectedED2K()) {
510 m_connect->DisconnectED2K();
515 uint32 CamuleRemoteGuiApp::GetED2KID() const
517 return serverconnect ? serverconnect->GetClientID() : 0;
521 uint32 CamuleRemoteGuiApp::GetID() const
523 return m_clientID;
527 void CamuleRemoteGuiApp::ShowUserCount() {
528 wxString buffer;
530 static const wxString s_singlenetstatusformat = _("Users: %s | Files: %s");
531 static const wxString s_bothnetstatusformat = _("Users: E: %s K: %s | Files: E: %s K: %s");
533 if (thePrefs::GetNetworkED2K() && thePrefs::GetNetworkKademlia()) {
534 buffer = CFormat(s_bothnetstatusformat) % CastItoIShort(theStats::GetED2KUsers()) % CastItoIShort(theStats::GetKadUsers()) % CastItoIShort(theStats::GetED2KFiles()) % CastItoIShort(theStats::GetKadFiles());
535 } else if (thePrefs::GetNetworkED2K()) {
536 buffer = CFormat(s_singlenetstatusformat) % CastItoIShort(theStats::GetED2KUsers()) % CastItoIShort(theStats::GetED2KFiles());
537 } else if (thePrefs::GetNetworkKademlia()) {
538 buffer = CFormat(s_singlenetstatusformat) % CastItoIShort(theStats::GetKadUsers()) % CastItoIShort(theStats::GetKadFiles());
539 } else {
540 buffer = _("No networks selected");
543 Notify_ShowUserCount(buffer);
548 * Preferences: holds both local and remote settings.
550 * First, everything is loaded from local config file. Later, settings
551 * that are relevant on remote side only are loaded thru EC
553 CPreferencesRem::CPreferencesRem(CRemoteConnect *conn)
555 m_conn = conn;
558 // Settings queried from remote side
560 m_exchange_send_selected_prefs =
561 EC_PREFS_GENERAL |
562 EC_PREFS_CONNECTIONS |
563 EC_PREFS_MESSAGEFILTER |
564 EC_PREFS_ONLINESIG |
565 EC_PREFS_SERVERS |
566 EC_PREFS_FILES |
567 EC_PREFS_DIRECTORIES |
568 EC_PREFS_SECURITY |
569 EC_PREFS_CORETWEAKS |
570 EC_PREFS_REMOTECONTROLS |
571 EC_PREFS_KADEMLIA;
572 m_exchange_recv_selected_prefs =
573 m_exchange_send_selected_prefs |
574 EC_PREFS_CATEGORIES;
578 void CPreferencesRem::HandlePacket(const CECPacket *packet)
580 static_cast<const CEC_Prefs_Packet *>(packet)->Apply();
582 const CECTag *cat_tags = packet->GetTagByName(EC_TAG_PREFS_CATEGORIES);
583 if (cat_tags) {
584 for (CECTag::const_iterator it = cat_tags->begin(); it != cat_tags->end(); ++it) {
585 const CECTag &cat_tag = *it;
586 Category_Struct *cat = new Category_Struct;
587 cat->title = cat_tag.GetTagByName(EC_TAG_CATEGORY_TITLE)->GetStringData();
588 cat->path = CPath(cat_tag.GetTagByName(EC_TAG_CATEGORY_PATH)->GetStringData());
589 cat->comment = cat_tag.GetTagByName(EC_TAG_CATEGORY_COMMENT)->GetStringData();
590 cat->color = cat_tag.GetTagByName(EC_TAG_CATEGORY_COLOR)->GetInt();
591 cat->prio = cat_tag.GetTagByName(EC_TAG_CATEGORY_PRIO)->GetInt();
592 theApp->glob_prefs->AddCat(cat);
594 } else {
595 Category_Struct *cat = new Category_Struct;
596 cat->title = _("All");
597 cat->color = 0;
598 cat->prio = PR_NORMAL;
599 theApp->glob_prefs->AddCat(cat);
601 wxECInitDoneEvent event;
602 theApp->AddPendingEvent(event);
607 bool CPreferencesRem::LoadRemote()
610 // override local settings with remote
611 CECPacket req(EC_OP_GET_PREFERENCES, EC_DETAIL_UPDATE);
613 // bring categories too
614 req.AddTag(CECTag(EC_TAG_SELECT_PREFS, m_exchange_recv_selected_prefs));
616 m_conn->SendRequest(this, &req);
618 return true;
622 void CPreferencesRem::SendToRemote()
624 CEC_Prefs_Packet pref_packet(m_exchange_send_selected_prefs, EC_DETAIL_UPDATE, EC_DETAIL_FULL);
625 m_conn->SendPacket(&pref_packet);
629 class CCatHandler : public CECPacketHandlerBase {
630 virtual void HandlePacket(const CECPacket *packet);
634 void CCatHandler::HandlePacket(const CECPacket *packet)
636 if (packet->GetOpCode() == EC_OP_FAILED) {
637 const CECTag * catTag = packet->GetTagByName(EC_TAG_CATEGORY);
638 const CECTag * pathTag = packet->GetTagByName(EC_TAG_CATEGORY_PATH);
639 if (catTag && pathTag && catTag->GetInt() < theApp->glob_prefs->GetCatCount()) {
640 int cat = catTag->GetInt();
641 Category_Struct* cs = theApp->glob_prefs->GetCategory(cat);
642 wxMessageBox(CFormat(_("Can't create directory '%s' for category '%s', keeping directory '%s'."))
643 % cs->path.GetPrintable() % cs->title % pathTag->GetStringData(),
644 _("ERROR"), wxOK);
645 cs->path = CPath(pathTag->GetStringData());
646 theApp->amuledlg->m_transferwnd->UpdateCategory(cat);
647 theApp->amuledlg->m_transferwnd->downloadlistctrl->Refresh();
650 delete this;
654 bool CPreferencesRem::CreateCategory(
655 Category_Struct *& category,
656 const wxString& name,
657 const CPath& path,
658 const wxString& comment,
659 uint32 color,
660 uint8 prio)
662 CECPacket req(EC_OP_CREATE_CATEGORY);
663 CEC_Category_Tag tag(0xffffffff, name, path.GetRaw(), comment, color, prio);
664 req.AddTag(tag);
665 m_conn->SendRequest(new CCatHandler, &req);
667 category = new Category_Struct();
668 category->path = path;
669 category->title = name;
670 category->comment = comment;
671 category->color = color;
672 category->prio = prio;
674 AddCat(category);
676 return true;
680 bool CPreferencesRem::UpdateCategory(
681 uint8 cat,
682 const wxString& name,
683 const CPath& path,
684 const wxString& comment,
685 uint32 color,
686 uint8 prio)
688 CECPacket req(EC_OP_UPDATE_CATEGORY);
689 CEC_Category_Tag tag(cat, name, path.GetRaw(), comment, color, prio);
690 req.AddTag(tag);
691 m_conn->SendRequest(new CCatHandler, &req);
693 Category_Struct *category = m_CatList[cat];
694 category->path = path;
695 category->title = name;
696 category->comment = comment;
697 category->color = color;
698 category->prio = prio;
700 return true;
704 void CPreferencesRem::RemoveCat(uint8 cat)
706 CECPacket req(EC_OP_DELETE_CATEGORY);
707 CEC_Category_Tag tag(cat, EC_DETAIL_CMD);
708 req.AddTag(tag);
709 m_conn->SendPacket(&req);
710 CPreferences::RemoveCat(cat);
715 // Container implementation
717 CServerConnectRem::CServerConnectRem(CRemoteConnect *conn)
719 m_CurrServer = 0;
720 m_Conn = conn;
724 void CServerConnectRem::ConnectToAnyServer()
726 CECPacket req(EC_OP_SERVER_CONNECT);
727 m_Conn->SendPacket(&req);
731 void CServerConnectRem::StopConnectionTry()
733 // lfroen: isn't Disconnect the same ?
737 void CServerConnectRem::Disconnect()
739 CECPacket req(EC_OP_SERVER_DISCONNECT);
740 m_Conn->SendPacket(&req);
744 void CServerConnectRem::ConnectToServer(CServer *server)
746 m_Conn->ConnectED2K(server->GetIP(), server->GetPort());
750 void CServerConnectRem::HandlePacket(const CECPacket *packet)
752 const CEC_ConnState_Tag *tag = static_cast<const CEC_ConnState_Tag *>(packet->GetTagByName(EC_TAG_CONNSTATE));
753 if (!tag) {
754 return;
757 theApp->m_ConnState = 0;
758 CServer *server;
759 m_ID = tag->GetEd2kId();
760 theApp->m_clientID = tag->GetClientId();
761 tag->GetKadID(theApp->m_kadID);
763 if (tag->IsConnectedED2K()) {
764 const CECTag *srvtag = tag->GetTagByName(EC_TAG_SERVER);
765 if (srvtag) {
766 server = theApp->serverlist->GetByID(srvtag->GetInt());
767 if (server != m_CurrServer) {
768 theApp->amuledlg->m_serverwnd->serverlistctrl->HighlightServer(server, true);
769 m_CurrServer = server;
772 theApp->m_ConnState |= CONNECTED_ED2K;
773 } else if ( m_CurrServer ) {
774 theApp->amuledlg->m_serverwnd->serverlistctrl->HighlightServer(m_CurrServer, false);
775 m_CurrServer = 0;
778 if (tag->IsConnectedKademlia()) {
779 if (tag->IsKadFirewalled()) {
780 theApp->m_ConnState |= CONNECTED_KAD_FIREWALLED;
781 } else {
782 theApp->m_ConnState |= CONNECTED_KAD_OK;
784 } else {
785 if (tag->IsKadRunning()) {
786 theApp->m_ConnState |= CONNECTED_KAD_NOT;
790 theApp->amuledlg->ShowConnectionState();
795 * Server list: host list of ed2k servers.
797 CServerListRem::CServerListRem(CRemoteConnect *conn)
799 CRemoteContainer<CServer, uint32, CEC_Server_Tag>(conn, true)
804 void CServerListRem::HandlePacket(const CECPacket *)
806 // There is no packet for the server list, it is part of the general update packet
807 wxFAIL;
808 // CRemoteContainer<CServer, uint32, CEC_Server_Tag>::HandlePacket(packet);
812 void CServerListRem::UpdateServerMetFromURL(wxString url)
814 CECPacket req(EC_OP_SERVER_UPDATE_FROM_URL);
815 req.AddTag(CECTag(EC_TAG_SERVERS_UPDATE_URL, url));
817 m_conn->SendPacket(&req);
821 void CServerListRem::SetStaticServer(CServer* server, bool isStatic)
823 // update display right away
824 server->SetIsStaticMember(isStatic);
825 Notify_ServerRefresh(server);
827 CECPacket req(EC_OP_SERVER_SET_STATIC_PRIO);
828 req.AddTag(CECTag(EC_TAG_SERVER, server->ECID()));
829 req.AddTag(CECTag(EC_TAG_SERVER_STATIC, isStatic));
831 m_conn->SendPacket(&req);
835 void CServerListRem::SetServerPrio(CServer* server, uint32 prio)
837 // update display right away
838 server->SetPreference(prio);
839 Notify_ServerRefresh(server);
841 CECPacket req(EC_OP_SERVER_SET_STATIC_PRIO);
842 req.AddTag(CECTag(EC_TAG_SERVER, server->ECID()));
843 req.AddTag(CECTag(EC_TAG_SERVER_PRIO, prio));
845 m_conn->SendPacket(&req);
849 void CServerListRem::RemoveServer(CServer* server)
851 m_conn->RemoveServer(server->GetIP(),server->GetPort());
855 void CServerListRem::UpdateUserFileStatus(CServer *server)
857 if (server) {
858 m_TotalUser = server->GetUsers();
859 m_TotalFile = server->GetFiles();
864 CServer *CServerListRem::GetServerByAddress(const wxString& WXUNUSED(address), uint16 WXUNUSED(port)) const
866 // It's ok to return 0 for context where this code is used in remote gui
867 return 0;
870 CServer *CServerListRem::GetServerByIPTCP(uint32 WXUNUSED(nIP), uint16 WXUNUSED(nPort)) const
872 // It's ok to return 0 for context where this code is used in remote gui
873 return 0;
876 CServer *CServerListRem::CreateItem(const CEC_Server_Tag *tag)
878 CServer * server = new CServer(tag);
879 ProcessItemUpdate(tag, server);
880 return server;
884 void CServerListRem::DeleteItem(CServer *in_srv)
886 CScopedPtr<CServer> srv(in_srv);
887 theApp->amuledlg->m_serverwnd->serverlistctrl->RemoveServer(srv.get());
891 uint32 CServerListRem::GetItemID(CServer *server)
893 return server->ECID();
897 void CServerListRem::ProcessItemUpdate(const CEC_Server_Tag * tag, CServer * server)
899 if (!tag->HasChildTags()) {
900 return;
902 tag->ServerName(& server->listname);
903 tag->ServerDesc(& server->description);
904 tag->ServerVersion(& server->m_strVersion);
905 tag->GetMaxUsers(& server->maxusers);
907 tag->GetFiles(& server->files);
908 tag->GetUsers(& server->users);
910 tag->GetPrio(& server->preferences); // SRV_PR_NORMAL = 0, so it's ok
911 tag->GetStatic(& server->staticservermember);
913 tag->GetPing(& server->ping);
914 tag->GetFailed(& server->failedcount);
916 theApp->amuledlg->m_serverwnd->serverlistctrl->RefreshServer(server);
920 CServer::CServer(const CEC_Server_Tag *tag) : CECID(tag->GetInt())
922 ip = tag->GetTagByNameSafe(EC_TAG_SERVER_IP)->GetInt();
923 port = tag->GetTagByNameSafe(EC_TAG_SERVER_PORT)->GetInt();
925 Init();
930 * IP filter
932 CIPFilterRem::CIPFilterRem(CRemoteConnect* conn)
934 m_conn = conn;
938 void CIPFilterRem::Reload()
940 CECPacket req(EC_OP_IPFILTER_RELOAD);
941 m_conn->SendPacket(&req);
945 void CIPFilterRem::Update(wxString url)
947 CECPacket req(EC_OP_IPFILTER_UPDATE);
948 req.AddTag(CECTag(EC_TAG_STRING, url));
950 m_conn->SendPacket(&req);
955 * Shared files list
957 CSharedFilesRem::CSharedFilesRem(CRemoteConnect *conn)
959 m_conn = conn;
963 void CSharedFilesRem::Reload(bool, bool)
965 CECPacket req(EC_OP_SHAREDFILES_RELOAD);
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->SendPacket(&request);
983 return true;
987 void CSharedFilesRem::SetFileCommentRating(CKnownFile* file, const wxString& newComment, int8 newRating)
989 CECPacket request(EC_OP_SHARED_FILE_SET_COMMENT);
990 request.AddTag(CECTag(EC_TAG_KNOWNFILE, file->GetFileHash()));
991 request.AddTag(CECTag(EC_TAG_KNOWNFILE_COMMENT, newComment));
992 request.AddTag(CECTag(EC_TAG_KNOWNFILE_RATING, newRating));
994 m_conn->SendPacket(&request);
998 void CSharedFilesRem::CopyFileList(std::vector<CKnownFile*>& out_list) const
1000 out_list.reserve(size());
1001 for (const_iterator it = begin(); it != end(); ++it) {
1002 out_list.push_back(it->second);
1007 void CKnownFilesRem::DeleteItem(CKnownFile * file)
1009 uint32 id = file->ECID();
1010 if (theApp->sharedfiles->count(id)) {
1011 theApp->amuledlg->m_sharedfileswnd->sharedfilesctrl->RemoveFile(file);
1012 theApp->sharedfiles->erase(id);
1014 if (theApp->downloadqueue->count(id)) {
1015 theApp->amuledlg->m_transferwnd->downloadlistctrl->RemoveFile(static_cast<CPartFile *>(file));
1016 theApp->downloadqueue->erase(id);
1018 delete file;
1022 uint32 CKnownFilesRem::GetItemID(CKnownFile *file)
1024 return file->ECID();
1028 void CKnownFilesRem::ProcessItemUpdate(const CEC_SharedFile_Tag *tag, CKnownFile *file)
1030 const CECTag *parttag = tag->GetTagByName(EC_TAG_PARTFILE_PART_STATUS);
1031 if (parttag) {
1032 const uint8 *data = file->m_partStatus.Decode(
1033 (uint8 *)parttag->GetTagData(),
1034 parttag->GetTagDataLen());
1035 for(int i = 0; i < file->GetPartCount(); ++i) {
1036 file->m_AvailPartFrequency[i] = data[i];
1039 wxString fileName;
1040 if (tag->FileName(fileName)) {
1041 file->SetFileName(CPath(fileName));
1043 if (tag->FilePath(fileName)) {
1044 file->m_filePath = CPath(fileName);
1046 tag->UpPrio(&file->m_iUpPriorityEC);
1047 tag->GetAICHHash(file->m_AICHMasterHash);
1048 // Bad thing - direct writing another class' members
1049 tag->GetRequests(&file->statistic.requested);
1050 tag->GetAllRequests(&file->statistic.alltimerequested);
1051 tag->GetAccepts(&file->statistic.accepted);
1052 tag->GetAllAccepts(&file->statistic.alltimeaccepted);
1053 tag->GetXferred(&file->statistic.transferred);
1054 tag->GetAllXferred(&file->statistic.alltimetransferred);
1055 tag->UpPrio(&file->m_iUpPriorityEC);
1056 if (file->m_iUpPriorityEC >= 10) {
1057 file->m_iUpPriority = file->m_iUpPriorityEC - 10;
1058 file->m_bAutoUpPriority = true;
1059 } else {
1060 file->m_iUpPriority = file->m_iUpPriorityEC;
1061 file->m_bAutoUpPriority = false;
1063 tag->GetCompleteSourcesLow(&file->m_nCompleteSourcesCountLo);
1064 tag->GetCompleteSourcesHigh(&file->m_nCompleteSourcesCountHi);
1065 tag->GetCompleteSources(&file->m_nCompleteSourcesCount);
1067 tag->GetOnQueue(&file->m_queuedCount);
1069 tag->GetComment(file->m_strComment);
1070 tag->GetRating(file->m_iRating);
1072 requested += file->statistic.requested;
1073 transferred += file->statistic.transferred;
1074 accepted += file->statistic.transferred;
1076 if (!m_initialUpdate) {
1077 theApp->amuledlg->m_sharedfileswnd->sharedfilesctrl->UpdateItem(file);
1080 if (file->IsPartFile()) {
1081 ProcessItemUpdatePartfile(static_cast<const CEC_PartFile_Tag *>(tag), static_cast<CPartFile *>(file));
1085 void CSharedFilesRem::SetFilePrio(CKnownFile *file, uint8 prio)
1087 CECPacket req(EC_OP_SHARED_SET_PRIO);
1089 CECTag hashtag(EC_TAG_PARTFILE, file->GetFileHash());
1090 hashtag.AddTag(CECTag(EC_TAG_PARTFILE_PRIO, prio));
1092 req.AddTag(hashtag);
1094 m_conn->SendPacket(&req);
1097 void CKnownFilesRem::ProcessUpdate(const CECTag *reply, CECPacket *, int)
1099 requested = 0;
1100 transferred = 0;
1101 accepted = 0;
1103 std::set<uint32> core_files;
1104 for (CECPacket::const_iterator it = reply->begin(); it != reply->end(); ++it) {
1105 const CECTag * curTag = &*it;
1106 ec_tagname_t tagname = curTag->GetTagName();
1107 if (tagname == EC_TAG_CLIENT) {
1108 theApp->clientlist->ProcessUpdate(curTag, NULL, EC_TAG_CLIENT);
1109 } else if (tagname == EC_TAG_SERVER) {
1110 theApp->serverlist->ProcessUpdate(curTag, NULL, EC_TAG_SERVER);
1111 } else if (tagname == EC_TAG_FRIEND) {
1112 theApp->friendlist->ProcessUpdate(curTag, NULL, EC_TAG_FRIEND);
1113 } else if (tagname == EC_TAG_KNOWNFILE || tagname == EC_TAG_PARTFILE) {
1114 const CEC_SharedFile_Tag *tag = static_cast<const CEC_SharedFile_Tag *>(curTag);
1115 uint32 id = tag->ID();
1116 bool isNew = true;
1117 if (!m_initialUpdate) {
1118 core_files.insert(id);
1119 std::map<uint32, CKnownFile*>::iterator it2 = m_items_hash.find(id);
1120 if (it2 != m_items_hash.end() ) {
1121 // Item already known: update it
1122 if (tag->HasChildTags()) {
1123 ProcessItemUpdate(tag, it2->second);
1125 isNew = false;
1128 if (isNew) {
1129 CKnownFile * newFile;
1130 if (tag->GetTagName() == EC_TAG_PARTFILE) {
1131 CPartFile *file = new CPartFile(static_cast<const CEC_PartFile_Tag *>(tag));
1132 ProcessItemUpdate(tag, file);
1133 (*theApp->downloadqueue)[id] = file;
1134 theApp->amuledlg->m_transferwnd->downloadlistctrl->AddFile(file);
1135 newFile = file;
1136 } else {
1137 newFile = new CKnownFile(tag);
1138 ProcessItemUpdate(tag, newFile);
1139 (*theApp->sharedfiles)[id] = newFile;
1140 if (!m_initialUpdate) {
1141 theApp->amuledlg->m_sharedfileswnd->sharedfilesctrl->ShowFile(newFile);
1144 AddItem(newFile);
1149 if (m_initialUpdate) {
1150 theApp->amuledlg->m_sharedfileswnd->sharedfilesctrl->ShowFileList();
1151 m_initialUpdate = false;
1152 } else {
1153 // remove items no longer present
1154 for(iterator it = begin(); it != end();) {
1155 iterator it2 = it++;
1156 if (!core_files.count(GetItemID(*it2))) {
1157 RemoveItem(it2); // This calls DeleteItem, where it is removed from lists and views.
1163 CKnownFilesRem::CKnownFilesRem(CRemoteConnect * conn) : CRemoteContainer<CKnownFile, uint32, CEC_SharedFile_Tag>(conn, true)
1165 requested = 0;
1166 transferred = 0;
1167 accepted = 0;
1168 m_initialUpdate = true;
1173 * List of uploading and waiting clients.
1175 CUpDownClientListRem::CUpDownClientListRem(CRemoteConnect *conn)
1177 CRemoteContainer<CClientRef, uint32, CEC_UpDownClient_Tag>(conn, true)
1182 CClientRef::CClientRef(const CEC_UpDownClient_Tag *tag)
1184 m_client = new CUpDownClient(tag);
1185 #ifdef DEBUG_ZOMBIE_CLIENTS
1186 m_client->Link(wxT("TAG"));
1187 #else
1188 m_client->Link();
1189 #endif
1193 CUpDownClient::CUpDownClient(const CEC_UpDownClient_Tag *tag) : CECID(tag->ID())
1195 m_linked = 0;
1196 #ifdef DEBUG_ZOMBIE_CLIENTS
1197 m_linkedDebug = false;
1198 #endif
1199 // Clients start up empty, then get asked for their data.
1200 // So all data here is processed in ProcessItemUpdate and thus updatable.
1201 m_bEmuleProtocol = false;
1202 m_AvailPartCount = 0;
1203 m_clientSoft = 0;
1204 m_nDownloadState = 0;
1205 m_Friend = NULL;
1206 m_bFriendSlot = false;
1207 m_nKadPort = 0;
1208 m_kBpsDown = 0;
1209 m_dwUserIP = 0;
1210 m_lastDownloadingPart = 0xffff;
1211 m_nextRequestedPart = 0xffff;
1212 m_obfuscationStatus = 0;
1213 m_nOldRemoteQueueRank = 0;
1214 m_nRemoteQueueRank = 0;
1215 m_reqfile = NULL;
1216 m_score = 0;
1217 m_dwServerIP = 0;
1218 m_nServerPort = 0;
1219 m_nSourceFrom = SF_NONE;
1220 m_nTransferredDown = 0;
1221 m_nTransferredUp = 0;
1222 m_nUpDatarate = 0;
1223 m_uploadingfile = NULL;
1224 m_waitingPosition = 0;
1225 m_nUploadState = 0;
1226 m_nUserIDHybrid = 0;
1227 m_nUserPort = 0;
1228 m_nClientVersion = 0;
1229 m_fNoViewSharedFiles = true;
1230 m_identState = IS_NOTAVAILABLE;
1231 m_bRemoteQueueFull = false;
1233 credits = new CClientCredits(new CreditStruct());
1236 #ifdef DEBUG_ZOMBIE_CLIENTS
1237 void CUpDownClient::Unlink(const wxString& from)
1239 std::multiset<wxString>::iterator it = m_linkedFrom.find(from);
1240 if (it != m_linkedFrom.end()) {
1241 m_linkedFrom.erase(it);
1243 m_linked--;
1244 if (!m_linked) {
1245 if (m_linkedDebug) {
1246 AddLogLineN(CFormat(wxT("Last reference to client %d %p unlinked, delete it.")) % ECID() % this);
1248 delete this;
1252 #else
1254 void CUpDownClient::Unlink()
1256 m_linked--;
1257 if (!m_linked) {
1258 delete this;
1261 #endif
1264 uint64 CUpDownClient::GetDownloadedTotal() const
1266 return credits->GetDownloadedTotal();
1270 uint64 CUpDownClient::GetUploadedTotal() const
1272 return credits->GetUploadedTotal();
1276 double CUpDownClient::GetScoreRatio() const
1278 return credits->GetScoreRatio(GetIP(), theApp->CryptoAvailable());
1281 /* End Warning */
1284 CUpDownClient::~CUpDownClient()
1286 delete credits;
1290 CClientRef *CUpDownClientListRem::CreateItem(const CEC_UpDownClient_Tag *tag)
1292 CClientRef *client = new CClientRef(tag);
1293 ProcessItemUpdate(tag, client);
1295 return client;
1299 void CUpDownClientListRem::DeleteItem(CClientRef *clientref)
1301 CUpDownClient* client = clientref->GetClient();
1302 if (client->m_reqfile) {
1303 client->m_reqfile->DelSource(client);
1304 client->m_reqfile = NULL;
1306 Notify_SourceCtrlRemoveSource(client->ECID(), (CPartFile*) NULL);
1308 if (client->m_uploadingfile) {
1309 client->m_uploadingfile->RemoveUploadingClient(client); // this notifies
1310 client->m_uploadingfile = NULL;
1312 theApp->m_allUploadingKnownFile->RemoveUploadingClient(client); // in case it vanished directly while uploading
1313 Notify_SharedCtrlRemoveClient(client->ECID(), (CKnownFile*) NULL);
1315 if (client->m_Friend) {
1316 client->m_Friend->UnLinkClient(); // this notifies
1317 client->m_Friend = NULL;
1320 #ifdef DEBUG_ZOMBIE_CLIENTS
1321 if (client->m_linked > 1) {
1322 AddLogLineC(CFormat(wxT("Client %d still linked in %d places: %s")) % client->ECID() % (client->m_linked - 1) % client->GetLinkedFrom());
1323 client->m_linkedDebug = true;
1325 #endif
1327 delete clientref;
1331 uint32 CUpDownClientListRem::GetItemID(CClientRef *client)
1333 return client->ECID();
1337 void CUpDownClientListRem::ProcessItemUpdate(
1338 const CEC_UpDownClient_Tag *tag,
1339 CClientRef *clientref)
1341 if (!tag->HasChildTags()) {
1342 return; // speed exit for clients without any change
1344 CUpDownClient *client = clientref->GetClient();
1346 tag->UserID(&client->m_nUserIDHybrid);
1347 tag->ClientName(&client->m_Username);
1348 // Client Software
1349 bool sw_updated = false;
1350 if (tag->ClientSoftware(client->m_clientSoft)) {
1351 client->m_clientSoftString = GetSoftName(client->m_clientSoft);
1352 sw_updated = true;
1354 if (tag->SoftVerStr(client->m_clientVerString) || sw_updated) {
1355 if (client->m_clientSoftString == _("Unknown")) {
1356 client->m_fullClientVerString = client->m_clientSoftString;
1357 } else {
1358 client->m_fullClientVerString = client->m_clientSoftString + wxT(" ") + client->m_clientVerString;
1361 // User hash
1362 tag->UserHash(&client->m_UserHash);
1364 // User IP:Port
1365 tag->UserIP(client->m_dwUserIP);
1366 tag->UserPort(&client->m_nUserPort);
1368 // Server IP:Port
1369 tag->ServerIP(&client->m_dwServerIP);
1370 tag->ServerPort(&client->m_nServerPort);
1371 tag->ServerName(&client->m_ServerName);
1373 tag->KadPort(client->m_nKadPort);
1374 tag->FriendSlot(client->m_bFriendSlot);
1376 tag->GetCurrentIdentState(&client->m_identState);
1377 tag->ObfuscationStatus(client->m_obfuscationStatus);
1378 tag->HasExtendedProtocol(&client->m_bEmuleProtocol);
1380 tag->WaitingPosition(&client->m_waitingPosition);
1381 tag->RemoteQueueRank(&client->m_nRemoteQueueRank);
1382 client->m_bRemoteQueueFull = client->m_nRemoteQueueRank == 0xffff;
1383 tag->OldRemoteQueueRank(&client->m_nOldRemoteQueueRank);
1385 tag->ClientDownloadState(client->m_nDownloadState);
1386 if (tag->ClientUploadState(client->m_nUploadState)) {
1387 if (client->m_nUploadState == US_UPLOADING) {
1388 theApp->m_allUploadingKnownFile->AddUploadingClient(client);
1389 } else {
1390 theApp->m_allUploadingKnownFile->RemoveUploadingClient(client);
1394 tag->SpeedUp(&client->m_nUpDatarate);
1395 if ( client->m_nDownloadState == DS_DOWNLOADING ) {
1396 tag->SpeedDown(&client->m_kBpsDown);
1397 } else {
1398 client->m_kBpsDown = 0;
1401 //tag->WaitTime(&client->m_WaitTime);
1402 //tag->XferTime(&client->m_UpStartTimeDelay);
1403 //tag->LastReqTime(&client->m_dwLastUpRequest);
1404 //tag->QueueTime(&client->m_WaitStartTime);
1406 CreditStruct *credit_struct = const_cast<CreditStruct *>(client->credits->GetDataStruct());
1407 tag->XferUp(&credit_struct->uploaded);
1408 tag->XferUpSession(&client->m_nTransferredUp);
1410 tag->XferDown(&credit_struct->downloaded);
1411 tag->XferDownSession(&client->m_nTransferredDown);
1413 tag->Score(&client->m_score);
1415 tag->NextRequestedPart(client->m_nextRequestedPart);
1416 tag->LastDownloadingPart(client->m_lastDownloadingPart);
1418 uint8 sourceFrom = 0;
1419 if (tag->GetSourceFrom(sourceFrom)) {
1420 client->m_nSourceFrom = (ESourceFrom)sourceFrom;
1423 tag->RemoteFilename(client->m_clientFilename);
1424 tag->DisableViewShared(client->m_fNoViewSharedFiles);
1425 tag->Version(client->m_nClientVersion);
1426 tag->ModVersion(client->m_strModVersion);
1427 tag->OSInfo(client->m_sClientOSInfo);
1428 tag->AvailableParts(client->m_AvailPartCount);
1430 // Download client
1431 uint32 fileID;
1432 bool notified = false;
1433 if (tag->RequestFile(fileID)) {
1434 if (client->m_reqfile) {
1435 Notify_SourceCtrlRemoveSource(client->ECID(), client->m_reqfile);
1436 client->m_reqfile->DelSource(client);
1437 client->m_reqfile = NULL;
1438 client->m_downPartStatus.clear();
1440 CKnownFile * kf = theApp->knownfiles->GetByID(fileID);
1441 if (kf && kf->IsCPartFile()) {
1442 client->m_reqfile = static_cast<CPartFile *>(kf);
1443 client->m_reqfile->AddSource(client);
1444 client->m_downPartStatus.setsize(kf->GetPartCount(), 0);
1445 Notify_SourceCtrlAddSource(client->m_reqfile, CCLIENTREF(client, wxT("AddSource")), A4AF_SOURCE);
1446 notified = true;
1450 // Part status
1451 const CECTag * partStatusTag = tag->GetTagByName(EC_TAG_CLIENT_PART_STATUS);
1452 if (partStatusTag) {
1453 if (partStatusTag->GetTagDataLen() == 0) {
1454 // empty tag means full source
1455 client->m_downPartStatus.SetAllTrue();
1456 } else if (partStatusTag->GetTagDataLen() == client->m_downPartStatus.SizeBuffer()) {
1457 client->m_downPartStatus.SetBuffer(partStatusTag->GetTagData());
1459 notified = false;
1462 if (!notified && client->m_reqfile && client->m_reqfile->ShowSources()) {
1463 SourceItemType type;
1464 switch (client->GetDownloadState()) {
1465 case DS_DOWNLOADING:
1466 case DS_ONQUEUE:
1467 // We will send A4AF, which will be checked.
1468 type = A4AF_SOURCE;
1469 break;
1470 default:
1471 type = UNAVAILABLE_SOURCE;
1472 break;
1475 Notify_SourceCtrlUpdateSource(client->ECID(), type);
1478 // Upload client
1479 notified = false;
1480 if (tag->UploadFile(fileID)) {
1481 if (client->m_uploadingfile) {
1482 client->m_uploadingfile->RemoveUploadingClient(client); // this notifies
1483 notified = true;
1484 client->m_uploadingfile = NULL;
1486 CKnownFile * kf = theApp->knownfiles->GetByID(fileID);
1487 if (kf) {
1488 client->m_uploadingfile = kf;
1489 client->m_upPartStatus.setsize(kf->GetPartCount(), 0);
1490 client->m_uploadingfile->AddUploadingClient(client); // this notifies
1491 notified = true;
1495 // Part status
1496 partStatusTag = tag->GetTagByName(EC_TAG_CLIENT_UPLOAD_PART_STATUS);
1497 if (partStatusTag) {
1498 if (partStatusTag->GetTagDataLen() == client->m_upPartStatus.SizeBuffer()) {
1499 client->m_upPartStatus.SetBuffer(partStatusTag->GetTagData());
1501 notified = false;
1504 if (!notified && client->m_uploadingfile
1505 && (client->m_uploadingfile->ShowPeers() || (client->m_nUploadState == US_UPLOADING))) {
1506 // notify if KnowFile is selected, or if it's uploading (in case clients are in show uploading mode)
1507 SourceItemType type;
1508 switch (client->GetUploadState()) {
1509 case US_UPLOADING:
1510 case US_ONUPLOADQUEUE:
1511 type = AVAILABLE_SOURCE;
1512 break;
1513 default:
1514 type = UNAVAILABLE_SOURCE;
1515 break;
1517 Notify_SharedCtrlRefreshClient(client->ECID(), type);
1523 * Download queue container: hold PartFiles with progress status
1528 bool CDownQueueRem::AddLink(const wxString &link, uint8 cat)
1530 CECPacket req(EC_OP_ADD_LINK);
1531 CECTag link_tag(EC_TAG_STRING, link);
1532 link_tag.AddTag(CECTag(EC_TAG_PARTFILE_CAT, cat));
1533 req.AddTag(link_tag);
1535 m_conn->SendPacket(&req);
1536 return true;
1540 void CDownQueueRem::ResetCatParts(int cat)
1542 // Called when category is deleted. Command will be performed on the remote side,
1543 // but files still should be updated here right away, or drawing errors (colour not available)
1544 // will happen.
1545 for (iterator it = begin(); it != end(); ++it) {
1546 CPartFile* file = it->second;
1547 file->RemoveCategory(cat);
1553 void CKnownFilesRem::ProcessItemUpdatePartfile(const CEC_PartFile_Tag *tag, CPartFile *file)
1556 // update status
1558 tag->Speed(&file->m_kbpsDown);
1559 file->kBpsDown = file->m_kbpsDown / 1024.0;
1561 tag->SizeXfer(&file->transferred);
1562 tag->SizeDone(&file->completedsize);
1563 tag->SourceXferCount(&file->transferingsrc);
1564 tag->SourceNotCurrCount(&file->m_notCurrentSources);
1565 tag->SourceCount(&file->m_source_count);
1566 tag->SourceCountA4AF(&file->m_a4af_source_count);
1567 tag->FileStatus(&file->status);
1568 tag->Stopped(&file->m_stopped);
1570 tag->LastSeenComplete(&file->lastseencomplete);
1571 tag->LastDateChanged(&file->m_lastDateChanged);
1572 tag->DownloadActiveTime(&file->m_nDlActiveTime);
1573 tag->AvailablePartCount(&file->m_availablePartsCount);
1574 tag->Shared(&file->m_isShared);
1575 tag->A4AFAuto(file->m_is_A4AF_auto);
1576 tag->HashingProgress(file->m_hashingProgress);
1578 tag->GetLostDueToCorruption(&file->m_iLostDueToCorruption);
1579 tag->GetGainDueToCompression(&file->m_iGainDueToCompression);
1580 tag->TotalPacketsSavedDueToICH(&file->m_iTotalPacketsSavedDueToICH);
1582 tag->FileCat(&file->m_category);
1584 tag->DownPrio(&file->m_iDownPriorityEC);
1585 if ( file->m_iDownPriorityEC >= 10 ) {
1586 file->m_iDownPriority = file->m_iDownPriorityEC - 10;
1587 file->m_bAutoDownPriority = true;
1588 } else {
1589 file->m_iDownPriority = file->m_iDownPriorityEC;
1590 file->m_bAutoDownPriority = false;
1593 file->percentcompleted = (100.0*file->GetCompletedSize()) / file->GetFileSize();
1596 // Copy part/gap status
1598 const CECTag *gaptag = tag->GetTagByName(EC_TAG_PARTFILE_GAP_STATUS);
1599 const CECTag *parttag = tag->GetTagByName(EC_TAG_PARTFILE_PART_STATUS);
1600 const CECTag *reqtag = tag->GetTagByName(EC_TAG_PARTFILE_REQ_STATUS);
1601 if (gaptag || parttag || reqtag) {
1602 PartFileEncoderData &encoder = file->m_PartFileEncoderData;
1604 if (gaptag) {
1605 ArrayOfUInts64 gaps;
1606 encoder.DecodeGaps(gaptag, gaps);
1607 int gap_size = gaps.size() / 2;
1608 // clear gaplist
1609 file->m_gaplist.Init(file->GetFileSize(), false);
1611 // and refill it
1612 for (int j = 0; j < gap_size; j++) {
1613 file->m_gaplist.AddGap(gaps[2*j], gaps[2*j+1]);
1616 if (parttag) {
1617 encoder.DecodeParts(parttag, file->m_SrcpartFrequency);
1618 // sanity check
1619 wxASSERT (file->m_SrcpartFrequency.size() == file->GetPartCount());
1621 if (reqtag) {
1622 ArrayOfUInts64 reqs;
1623 encoder.DecodeReqs(reqtag, reqs);
1624 int req_size = reqs.size() / 2;
1625 // clear reqlist
1626 DeleteContents(file->m_requestedblocks_list);
1628 // and refill it
1629 for (int j = 0; j < req_size; j++) {
1630 Requested_Block_Struct* block = new Requested_Block_Struct;
1631 block->StartOffset = reqs[2*j];
1632 block->EndOffset = reqs[2*j+1];
1633 file->m_requestedblocks_list.push_back(block);
1638 // Get source names and counts
1639 const CECTag *srcnametag = tag->GetTagByName(EC_TAG_PARTFILE_SOURCE_NAMES);
1640 if (srcnametag) {
1641 SourcenameItemMap &map = file->GetSourcenameItemMap();
1642 for (CECTag::const_iterator it = srcnametag->begin(); it != srcnametag->end(); ++it) {
1643 uint32 key = it->GetInt();
1644 int count = it->GetTagByNameSafe(EC_TAG_PARTFILE_SOURCE_NAMES_COUNTS)->GetInt();
1645 if (count == 0) {
1646 map.erase(key);
1647 } else {
1648 SourcenameItem &item = map[key];
1649 item.count = count;
1650 const CECTag *nametag = it->GetTagByName(EC_TAG_PARTFILE_SOURCE_NAMES);
1651 if (nametag) {
1652 item.name = nametag->GetStringData();
1658 // Get comments
1659 const CECTag *commenttag = tag->GetTagByName(EC_TAG_PARTFILE_COMMENTS);
1660 if (commenttag) {
1661 file->ClearFileRatingList();
1662 for (CECTag::const_iterator it = commenttag->begin(); it != commenttag->end(); ) {
1663 wxString u = (it++)->GetStringData();
1664 wxString f = (it++)->GetStringData();
1665 int r = (it++)->GetInt();
1666 wxString c = (it++)->GetStringData();
1667 file->AddFileRatingList(u, f, r, c);
1669 file->UpdateFileRatingCommentAvail();
1672 // Update A4AF sources
1673 ListOfUInts32 & clientIDs = file->GetA4AFClientIDs();
1674 const CECTag *a4aftag = tag->GetTagByName(EC_TAG_PARTFILE_A4AF_SOURCES);
1675 if (a4aftag) {
1676 file->ClearA4AFList();
1677 clientIDs.clear();
1678 for (CECTag::const_iterator it = a4aftag->begin(); it != a4aftag->end(); ++it) {
1679 if (it->GetTagName() != EC_TAG_ECID) { // should always be this
1680 continue;
1682 uint32 id = it->GetInt();
1683 CClientRef * src = theApp->clientlist->GetByID(id);
1684 if (src) {
1685 file->AddA4AFSource(src->GetClient());
1686 } else {
1687 // client wasn't transmitted yet, try it later
1688 clientIDs.push_back(id);
1691 } else if (!clientIDs.empty()) {
1692 // Process clients from the last pass whose ids were still unknown then
1693 for (ListOfUInts32::iterator it = clientIDs.begin(); it != clientIDs.end(); ) {
1694 ListOfUInts32::iterator it1 = it++;
1695 uint32 id = *it1;
1696 CClientRef * src = theApp->clientlist->GetByID(id);
1697 if (src) {
1698 file->AddA4AFSource(src->GetClient());
1699 clientIDs.erase(it1);
1704 theApp->amuledlg->m_transferwnd->downloadlistctrl->UpdateItem(file);
1706 // If file is shared check if it is already listed in shared files.
1707 // If not, add it and show it.
1708 if (file->IsShared() && !theApp->sharedfiles->count(file->ECID())) {
1709 (*theApp->sharedfiles)[file->ECID()] = file;
1710 theApp->amuledlg->m_sharedfileswnd->sharedfilesctrl->ShowFile(file);
1715 void CDownQueueRem::SendFileCommand(CPartFile *file, ec_tagname_t cmd)
1717 CECPacket req(cmd);
1718 req.AddTag(CECTag(EC_TAG_PARTFILE, file->GetFileHash()));
1720 m_conn->SendPacket(&req);
1724 void CDownQueueRem::Prio(CPartFile *file, uint8 prio)
1726 CECPacket req(EC_OP_PARTFILE_PRIO_SET);
1728 CECTag hashtag(EC_TAG_PARTFILE, file->GetFileHash());
1729 hashtag.AddTag(CECTag(EC_TAG_PARTFILE_PRIO, prio));
1730 req.AddTag(hashtag);
1732 m_conn->SendPacket(&req);
1736 void CDownQueueRem::AutoPrio(CPartFile *file, bool flag)
1738 CECPacket req(EC_OP_PARTFILE_PRIO_SET);
1740 CECTag hashtag(EC_TAG_PARTFILE, file->GetFileHash());
1742 hashtag.AddTag(CECTag(EC_TAG_PARTFILE_PRIO,
1743 (uint8)(flag ? PR_AUTO : file->GetDownPriority())));
1744 req.AddTag(hashtag);
1746 m_conn->SendPacket(&req);
1750 void CDownQueueRem::Category(CPartFile *file, uint8 cat)
1752 CECPacket req(EC_OP_PARTFILE_SET_CAT);
1753 file->SetCategory(cat);
1755 CECTag hashtag(EC_TAG_PARTFILE, file->GetFileHash());
1756 hashtag.AddTag(CECTag(EC_TAG_PARTFILE_CAT, cat));
1757 req.AddTag(hashtag);
1759 m_conn->SendPacket(&req);
1763 void CDownQueueRem::AddSearchToDownload(CSearchFile* file, uint8 category)
1765 CECPacket req(EC_OP_DOWNLOAD_SEARCH_RESULT);
1766 CECTag hashtag(EC_TAG_PARTFILE, file->GetFileHash());
1767 hashtag.AddTag(CECTag(EC_TAG_PARTFILE_CAT, category));
1768 req.AddTag(hashtag);
1770 m_conn->SendPacket(&req);
1774 void CDownQueueRem::ClearCompleted(const ListOfUInts32 & ecids)
1776 CECPacket req(EC_OP_CLEAR_COMPLETED);
1777 for (ListOfUInts32::const_iterator it = ecids.begin(); it != ecids.end(); ++it) {
1778 req.AddTag(CECTag(EC_TAG_ECID, *it));
1781 m_conn->SendPacket(&req);
1786 * List of friends.
1788 CFriendListRem::CFriendListRem(CRemoteConnect *conn)
1790 CRemoteContainer<CFriend, uint32, CEC_Friend_Tag>(conn, true)
1795 void CFriendListRem::HandlePacket(const CECPacket *)
1797 wxFAIL; // not needed
1801 CFriend * CFriendListRem::CreateItem(const CEC_Friend_Tag * tag)
1803 CFriend * Friend = new CFriend(tag->ID());
1804 ProcessItemUpdate(tag, Friend);
1805 return Friend;
1809 void CFriendListRem::DeleteItem(CFriend * Friend)
1811 Friend->UnLinkClient(false);
1812 Notify_ChatRemoveFriend(Friend);
1816 uint32 CFriendListRem::GetItemID(CFriend * Friend)
1818 return Friend->ECID();
1822 void CFriendListRem::ProcessItemUpdate(const CEC_Friend_Tag * tag, CFriend * Friend)
1824 if (!tag->HasChildTags()) {
1825 return;
1827 tag->Name(Friend->m_strName);
1828 tag->UserHash(Friend->m_UserHash);
1829 tag->IP(Friend->m_dwLastUsedIP);
1830 tag->Port(Friend->m_nLastUsedPort);
1831 uint32 clientID;
1832 bool notified = false;
1833 if (tag->Client(clientID)) {
1834 if (clientID) {
1835 CClientRef * client = theApp->clientlist->GetByID(clientID);
1836 if (client) {
1837 Friend->LinkClient(*client); // this notifies
1838 notified = true;
1840 } else {
1841 // Unlink
1842 Friend->UnLinkClient(false);
1845 if (!notified) {
1846 Notify_ChatUpdateFriend(Friend);
1851 void CFriendListRem::AddFriend(const CClientRef& toadd)
1853 CECPacket req(EC_OP_FRIEND);
1855 CECEmptyTag addtag(EC_TAG_FRIEND_ADD);
1856 addtag.AddTag(CECTag(EC_TAG_CLIENT, toadd.ECID()));
1857 req.AddTag(addtag);
1859 m_conn->SendPacket(&req);
1863 void CFriendListRem::AddFriend(const CMD4Hash& userhash, uint32 lastUsedIP, uint32 lastUsedPort, const wxString& name)
1865 CECPacket req(EC_OP_FRIEND);
1867 CECEmptyTag addtag(EC_TAG_FRIEND_ADD);
1868 addtag.AddTag(CECTag(EC_TAG_FRIEND_HASH, userhash));
1869 addtag.AddTag(CECTag(EC_TAG_FRIEND_IP, lastUsedIP));
1870 addtag.AddTag(CECTag(EC_TAG_FRIEND_PORT, lastUsedPort));
1871 addtag.AddTag(CECTag(EC_TAG_FRIEND_NAME, name));
1872 req.AddTag(addtag);
1874 m_conn->SendPacket(&req);
1878 void CFriendListRem::RemoveFriend(CFriend* toremove)
1880 CECPacket req(EC_OP_FRIEND);
1882 CECEmptyTag removetag(EC_TAG_FRIEND_REMOVE);
1883 removetag.AddTag(CECTag(EC_TAG_FRIEND, toremove->ECID()));
1884 req.AddTag(removetag);
1886 m_conn->SendPacket(&req);
1890 void CFriendListRem::SetFriendSlot(CFriend* Friend, bool new_state)
1892 CECPacket req(EC_OP_FRIEND);
1894 CECTag slottag(EC_TAG_FRIEND_FRIENDSLOT, new_state);
1895 slottag.AddTag(CECTag(EC_TAG_FRIEND, Friend->ECID()));
1896 req.AddTag(slottag);
1898 m_conn->SendPacket(&req);
1902 void CFriendListRem::RequestSharedFileList(CFriend* Friend)
1904 CECPacket req(EC_OP_FRIEND);
1906 CECEmptyTag sharedtag(EC_TAG_FRIEND_SHARED);
1907 sharedtag.AddTag(CECTag(EC_TAG_FRIEND, Friend->ECID()));
1908 req.AddTag(sharedtag);
1910 m_conn->SendPacket(&req);
1914 void CFriendListRem::RequestSharedFileList(CClientRef& client)
1916 CECPacket req(EC_OP_FRIEND);
1918 CECEmptyTag sharedtag(EC_TAG_FRIEND_SHARED);
1919 sharedtag.AddTag(CECTag(EC_TAG_CLIENT, client.ECID()));
1920 req.AddTag(sharedtag);
1922 m_conn->SendPacket(&req);
1928 * Search results
1930 CSearchListRem::CSearchListRem(CRemoteConnect *conn) : CRemoteContainer<CSearchFile, uint32, CEC_SearchFile_Tag>(conn, true)
1932 m_curr_search = -1;
1936 wxString CSearchListRem::StartNewSearch(
1937 uint32* nSearchID, SearchType search_type,
1938 const CSearchList::CSearchParams& params)
1940 CECPacket search_req(EC_OP_SEARCH_START);
1941 EC_SEARCH_TYPE ec_search_type = EC_SEARCH_LOCAL;
1942 switch(search_type) {
1943 case LocalSearch: ec_search_type = EC_SEARCH_LOCAL; break;
1944 case GlobalSearch: ec_search_type = EC_SEARCH_GLOBAL; break;
1945 case KadSearch: ec_search_type = EC_SEARCH_KAD; break;
1947 search_req.AddTag(
1948 CEC_Search_Tag(params.searchString, ec_search_type,
1949 params.typeText, params.extension, params.availability,
1950 params.minSize, params.maxSize));
1952 m_conn->SendPacket(&search_req);
1953 m_curr_search = *(nSearchID); // No kad remote search yet.
1955 Flush();
1957 return wxEmptyString; // EC reply will have the error mesg is needed.
1961 void CSearchListRem::StopSearch(bool)
1963 if (m_curr_search != -1) {
1964 CECPacket search_req(EC_OP_SEARCH_STOP);
1965 m_conn->SendPacket(&search_req);
1970 void CSearchListRem::HandlePacket(const CECPacket *packet)
1972 if ( packet->GetOpCode() == EC_OP_SEARCH_PROGRESS ) {
1973 CoreNotify_Search_Update_Progress(packet->GetFirstTagSafe()->GetInt());
1974 } else {
1975 CRemoteContainer<CSearchFile, uint32, CEC_SearchFile_Tag>::HandlePacket(packet);
1980 CSearchFile::CSearchFile(const CEC_SearchFile_Tag *tag)
1982 CECID(tag->ID()),
1983 m_parent(NULL),
1984 m_showChildren(false),
1985 m_sourceCount(0),
1986 m_completeSourceCount(0),
1987 m_kademlia(false),
1988 m_downloadStatus(NEW),
1989 m_clientID(0),
1990 m_clientPort(0),
1991 m_kadPublishInfo(0)
1993 SetFileName(CPath(tag->FileName()));
1994 m_abyFileHash = tag->FileHash();
1995 SetFileSize(tag->SizeFull());
1997 m_searchID = theApp->searchlist->m_curr_search;
1998 uint32 parentID = tag->ParentID();
1999 if (parentID) {
2000 CSearchFile * parent = theApp->searchlist->GetByID(parentID);
2001 if (parent) {
2002 parent->AddChild(this);
2008 void CSearchFile::AddChild(CSearchFile* file)
2010 m_children.push_back(file);
2011 file->m_parent = this;
2015 // dtor is virtual - must be implemented
2016 CSearchFile::~CSearchFile()
2021 CSearchFile *CSearchListRem::CreateItem(const CEC_SearchFile_Tag *tag)
2023 CSearchFile *file = new CSearchFile(tag);
2024 ProcessItemUpdate(tag, file);
2026 theApp->amuledlg->m_searchwnd->AddResult(file);
2028 return file;
2032 void CSearchListRem::DeleteItem(CSearchFile *file)
2034 delete file;
2038 uint32 CSearchListRem::GetItemID(CSearchFile *file)
2040 return file->ECID();
2044 void CSearchListRem::ProcessItemUpdate(const CEC_SearchFile_Tag *tag, CSearchFile *file)
2046 uint32 sourceCount = file->m_sourceCount;
2047 uint32 completeSourceCount = file->m_completeSourceCount;
2048 CSearchFile::DownloadStatus status = file->m_downloadStatus;
2049 tag->SourceCount(&file->m_sourceCount);
2050 tag->CompleteSourceCount(&file->m_completeSourceCount);
2051 tag->DownloadStatus((uint32 *) &file->m_downloadStatus);
2053 if (file->m_sourceCount != sourceCount
2054 || file->m_completeSourceCount != completeSourceCount
2055 || file->m_downloadStatus != status) {
2056 if (theApp->amuledlg && theApp->amuledlg->m_searchwnd) {
2057 theApp->amuledlg->m_searchwnd->UpdateResult(file);
2063 bool CSearchListRem::Phase1Done(const CECPacket *WXUNUSED(reply))
2065 CECPacket progress_req(EC_OP_SEARCH_PROGRESS);
2066 m_conn->SendRequest(this, &progress_req);
2068 return true;
2072 void CSearchListRem::RemoveResults(long nSearchID)
2074 ResultMap::iterator it = m_results.find(nSearchID);
2075 if (it != m_results.end()) {
2076 CSearchResultList& list = it->second;
2077 for (unsigned int i = 0; i < list.size(); ++i) {
2078 delete list[i];
2080 m_results.erase(it);
2085 const CSearchResultList& CSearchListRem::GetSearchResults(long nSearchID)
2087 ResultMap::const_iterator it = m_results.find(nSearchID);
2088 if (it != m_results.end()) {
2089 return it->second;
2092 // TODO: Should we assert in this case?
2093 static CSearchResultList list;
2094 return list;
2098 void CStatsUpdaterRem::HandlePacket(const CECPacket *packet)
2100 theStats::UpdateStats(packet);
2101 theApp->amuledlg->ShowTransferRate();
2102 theApp->ShowUserCount(); // maybe there should be a check if a usercount changed ?
2103 // handle the connstate tag which is included in the stats packet
2104 theApp->serverconnect->HandlePacket(packet);
2108 void CUpDownClient::RequestSharedFileList()
2110 CClientRef ref = CCLIENTREF(this, wxEmptyString);
2111 theApp->friendlist->RequestSharedFileList(ref);
2115 bool CUpDownClient::SwapToAnotherFile(
2116 bool WXUNUSED(bIgnoreNoNeeded),
2117 bool WXUNUSED(ignoreSuspensions),
2118 bool WXUNUSED(bRemoveCompletely),
2119 CPartFile* toFile)
2121 CECPacket req(EC_OP_CLIENT_SWAP_TO_ANOTHER_FILE);
2122 req.AddTag(CECTag(EC_TAG_CLIENT, ECID()));
2123 req.AddTag(CECTag(EC_TAG_PARTFILE, toFile->GetFileHash()));
2124 theApp->m_connect->SendPacket(&req);
2126 return true;
2130 wxString CAICHHash::GetString() const
2132 return EncodeBase32(m_abyBuffer, HASHSIZE);
2137 // Those functions are virtual. So even they don't get called they must
2138 // be defined so linker will be happy
2140 CPacket* CKnownFile::CreateSrcInfoPacket(const CUpDownClient *, uint8 /*byRequestedVersion*/, uint16 /*nRequestedOptions*/)
2142 wxFAIL;
2143 return 0;
2147 bool CKnownFile::LoadFromFile(const class CFileDataIO*)
2149 wxFAIL;
2150 return false;
2154 void CKnownFile::UpdatePartsInfo()
2156 wxFAIL;
2160 CPacket* CPartFile::CreateSrcInfoPacket(CUpDownClient const *, uint8 /*byRequestedVersion*/, uint16 /*nRequestedOptions*/)
2162 wxFAIL;
2163 return 0;
2167 void CPartFile::UpdatePartsInfo()
2169 wxFAIL;
2174 void CPartFile::UpdateFileRatingCommentAvail()
2176 bool prevComment = m_hasComment;
2177 int prevRating = m_iUserRating;
2179 m_hasComment = false;
2180 m_iUserRating = 0;
2181 int ratingCount = 0;
2183 FileRatingList::iterator it = m_FileRatingList.begin();
2184 for (; it != m_FileRatingList.end(); ++it) {
2185 SFileRating& cur_rat = *it;
2187 if (!cur_rat.Comment.IsEmpty()) {
2188 m_hasComment = true;
2191 uint8 rating = cur_rat.Rating;
2192 if (rating) {
2193 wxASSERT(rating <= 5);
2195 ratingCount++;
2196 m_iUserRating += rating;
2200 if (ratingCount) {
2201 m_iUserRating /= ratingCount;
2202 wxASSERT(m_iUserRating > 0 && m_iUserRating <= 5);
2205 if ((prevComment != m_hasComment) || (prevRating != m_iUserRating)) {
2206 UpdateDisplayedInfo();
2211 void CStatTreeRem::DoRequery()
2213 CECPacket request(EC_OP_GET_STATSTREE);
2214 if (thePrefs::GetMaxClientVersions() != 0) {
2215 request.AddTag(CECTag(EC_TAG_STATTREE_CAPPING, (uint8)thePrefs::GetMaxClientVersions()));
2217 m_conn->SendRequest(this, &request);
2220 void CStatTreeRem::HandlePacket(const CECPacket * p)
2222 const CECTag* treeRoot = p->GetTagByName(EC_TAG_STATTREE_NODE);
2223 if (treeRoot) {
2224 theApp->amuledlg->m_statisticswnd->RebuildStatTreeRemote(treeRoot);
2225 theApp->amuledlg->m_statisticswnd->ShowStatistics();
2229 CamuleRemoteGuiApp *theApp;
2232 // since gui is not linked with amule.cpp - define events here
2234 DEFINE_LOCAL_EVENT_TYPE(wxEVT_CORE_FINISHED_HTTP_DOWNLOAD)
2235 DEFINE_LOCAL_EVENT_TYPE(wxEVT_CORE_SOURCE_DNS_DONE)
2236 DEFINE_LOCAL_EVENT_TYPE(wxEVT_CORE_UDP_DNS_DONE)
2237 DEFINE_LOCAL_EVENT_TYPE(wxEVT_CORE_SERVER_DNS_DONE)
2238 // File_checked_for_headers