2 // This file is part of the aMule Project.
4 // Copyright (c) 2005-2008 aMule Team ( admin@amule.org / http://www.amule.org )
6 // Any parts of this program derived from the xMule, lMule or eMule project,
7 // or contributed by third-party developers are copyrighted by their
10 // This program is free software; you can redistribute it and/or modify
11 // it under the terms of the GNU General Public License as published by
12 // the Free Software Foundation; either version 2 of the License, or
13 // (at your option) any later version.
15 // This program is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
20 // You should have received a copy of the GNU General Public License
21 // along with this program; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #ifndef AMULE_REMOTE_GUI_H
26 #define AMULE_REMOTE_GUI_H
29 #include <ec/cpp/RemoteConnect.h> // Needed for CRemoteConnect
32 #include "Statistics.h"
33 #include "Preferences.h"
34 #include "Statistics.h"
36 #include "SearchList.h" // Needed for CSearchFile
52 #include <wx/dialog.h>
54 class CEConnectDlg
: public wxDialog
{
59 wxString login
, passwd
;
60 bool m_save_user_pass
;
66 void OnOK(wxCommandEvent
& event
);
68 wxString
Host() { return host
; }
69 int Port() { return port
; }
71 wxString
Login() { return login
; }
73 bool SaveUserPass() { return m_save_user_pass
; }
76 DECLARE_LOCAL_EVENT_TYPE(wxEVT_EC_INIT_DONE
, wxEVT_USER_FIRST
+ 1001)
78 class wxECInitDoneEvent
: public wxEvent
{
80 wxECInitDoneEvent() : wxEvent(-1, wxEVT_EC_INIT_DONE
)
84 wxEvent
*Clone(void) const
86 return new wxECInitDoneEvent(*this);
90 class CPreferencesRem
: public CPreferences
, public CECPacketHandlerBase
{
91 CRemoteConnect
*m_conn
;
92 uint32 m_exchange_send_selected_prefs
;
93 uint32 m_exchange_recv_selected_prefs
;
95 virtual void HandlePacket(const CECPacket
*packet
);
97 CPreferencesRem(CRemoteConnect
*);
99 bool CreateCategory(Category_Struct
*& category
, const wxString
& name
, const CPath
& path
,
100 const wxString
& comment
, uint32 color
, uint8 prio
);
101 bool UpdateCategory(uint8 cat
, const wxString
& name
, const CPath
& path
,
102 const wxString
& comment
, uint32 color
, uint8 prio
);
104 void RemoveCat(uint8 cat
);
111 // T - type if item in container
112 // I - type of id of item
113 // G - type of tag used to create/update items
115 template <class T
, class I
, class G
= CECTag
>
116 class CRemoteContainer
: public CECPacketHandlerBase
{
119 IDLE
, // no request in the air
120 STATUS_REQ_SENT
, // sent request for item status
121 FULL_REQ_SENT
// sent request for full info
124 CRemoteConnect
*m_conn
;
126 std::list
<T
*> m_items
;
127 std::map
<I
, T
*> m_items_hash
;
129 // .size() is O(N) operation in stl
132 // use incremental tags algorithm
135 // command that will be used in full request
136 int m_full_req_cmd
, m_full_req_tag
;
138 virtual void HandlePacket(const CECPacket
*packet
)
140 switch(this->m_state
) {
141 case IDLE
: wxFAIL
; // not expecting anything
142 case STATUS_REQ_SENT
:
143 // if derived class choose not to proceed, return - but with good status
144 this->m_state
= IDLE
;
145 if ( this->Phase1Done(packet
) ) {
146 if (this->m_inc_tags
) {
147 // Incremental tags: new items always carry full info.
148 ProcessUpdate(packet
, NULL
, m_full_req_tag
);
150 // Non-incremental tags: we might get partial info on new items.
151 // Collect all this items in a tag, and then request full info about them.
152 CECPacket
req_full(this->m_full_req_cmd
);
154 ProcessUpdate(packet
, &req_full
, m_full_req_tag
);
156 // Phase 3: request full info about files we don't have yet
157 if ( req_full
.HasChildTags() ) {
158 m_conn
->SendRequest(this, &req_full
);
159 this->m_state
= FULL_REQ_SENT
;
171 CRemoteContainer(CRemoteConnect
*conn
, bool inc_tags
)
177 m_inc_tags
= inc_tags
;
180 virtual ~CRemoteContainer()
184 typedef typename
std::list
<T
*>::iterator iterator
;
185 iterator
begin() { return m_items
.begin(); }
186 iterator
end() { return m_items
.end(); }
193 void AddItem(T
*item
)
195 m_items
.push_back(item
);
196 m_items_hash
[GetItemID(item
)] = item
;
202 // avoid creating nodes
203 return m_items_hash
.count(id
) ? m_items_hash
[id
] : NULL
;
209 m_items_hash
.clear();
217 We usually don't keep outdated code as comments, but this blocking implementation
218 shows the overall procedure well. It had to be scattered for the event driven implementation.
220 bool FullReload(int cmd)
223 CScopedPtr<const CECPacket> reply(this->m_conn->SendRecvPacket(&req));
224 if ( !reply.get() ) {
227 for(typename std::list<T *>::iterator j = this->m_items.begin(); j != this->m_items.end(); j++) {
228 this->DeleteItem(*j);
233 ProcessFull(reply.get());
238 void FullReload(int cmd
)
240 if ( this->m_state
!= IDLE
) {
244 for(typename
std::list
<T
*>::iterator j
= this->m_items
.begin(); j
!= this->m_items
.end(); j
++) {
245 this->DeleteItem(*j
);
251 this->m_conn
->SendRequest(this, &req
);
252 this->m_state
= FULL_REQ_SENT
;
253 this->m_full_req_cmd
= cmd
;
257 // Following are like basicly same code as in webserver. Eventually it must
260 void DoRequery(int cmd
, int tag
)
262 if ( this->m_state
!= IDLE
) {
265 CECPacket
req_sts(cmd
, m_inc_tags
? EC_DETAIL_INC_UPDATE
: EC_DETAIL_UPDATE
);
266 this->m_conn
->SendRequest(this, &req_sts
);
267 this->m_state
= STATUS_REQ_SENT
;
268 this->m_full_req_cmd
= cmd
;
269 this->m_full_req_tag
= tag
;
272 We usually don't keep outdated code as comments, but this blocking implementation
273 shows the overall procedure well. It had to be scattered for the event driven implementation.
275 bool DoRequery(int cmd, int tag)
277 CECPacket req_sts(cmd, m_inc_tags ? EC_DETAIL_INC_UPDATE : EC_DETAIL_UPDATE);
280 // Phase 1: request status
281 CScopedPtr<const CECPacket> reply(this->m_conn->SendRecvPacket(&req_sts));
282 if ( !reply.get() ) {
286 if ( !this->Phase1Done(reply.get()) ) {
287 // if derived class choose not to proceed, return - but with good status
291 // Phase 2: update status, mark new files for subsequent query
292 CECPacket req_full(cmd);
294 ProcessUpdate(reply.get(), &req_full, tag);
299 // Phase 3: request full info about files we don't have yet
300 if ( req_full.GetTagCount() ) {
301 reply.reset(this->m_conn->SendRecvPacket(&req_full));
302 if ( !reply.get() ) {
305 ProcessFull(reply.get());
312 void ProcessFull(const CECPacket
*reply
)
314 for (CECPacket::const_iterator it
= reply
->begin(); it
!= reply
->end(); it
++) {
315 G
*tag
= (G
*) & *it
;
316 // initialize item data from EC tag
317 AddItem(CreateItem(tag
));
321 void RemoveItem(iterator
& it
)
323 I item_id
= GetItemID(*it
);
327 m_items_hash
.erase(item_id
);
328 // item may contain data that need to be freed externally, before
329 // dtor is called and memory freed
335 virtual void ProcessUpdate(const CECTag
*reply
, CECPacket
*full_req
, int req_type
)
337 std::set
<I
> core_files
;
338 for (CECPacket::const_iterator it
= reply
->begin(); it
!= reply
->end(); it
++) {
339 G
*tag
= (G
*) & *it
;
340 if ( tag
->GetTagName() != req_type
) {
344 core_files
.insert(tag
->ID());
345 if ( m_items_hash
.count(tag
->ID()) ) {
346 // Item already known: update it
347 T
*item
= m_items_hash
[tag
->ID()];
348 ProcessItemUpdate(tag
, item
);
352 // Non-incremental mode: we have only partial info
353 // so we need to request full info before we can use the item
354 full_req
->AddTag(CECTag(req_type
, tag
->ID()));
356 // Incremental mode: new items always carry full info,
357 // so we can add it right away
358 AddItem(CreateItem(tag
));
362 for(iterator it
= begin(); it
!= end();) {
364 if ( core_files
.count(GetItemID(*it2
)) == 0 ) {
370 virtual T
*CreateItem(G
*)
374 virtual void DeleteItem(T
*)
377 virtual I
GetItemID(T
*)
381 virtual void ProcessItemUpdate(G
*, T
*)
385 virtual bool Phase1Done(const CECPacket
*)
391 class CServerConnectRem
: public CECPacketHandlerBase
{
392 CRemoteConnect
*m_Conn
;
395 CServer
*m_CurrServer
;
397 virtual void HandlePacket(const CECPacket
*packet
);
400 CServerConnectRem(CRemoteConnect
*);
403 bool IsConnected() { return (m_ID
!= 0) && (m_ID
!= 0xffffffff); }
404 bool IsConnecting() { return m_ID
== 0xffffffff; }
405 bool IsLowID() { return m_ID
< 16777216; }
406 uint32
GetClientID() { return m_ID
; }
407 CServer
*GetCurrentServer() { return m_CurrServer
; }
412 void ConnectToServer(CServer
* server
);
413 void ConnectToAnyServer();
414 void StopConnectionTry();
418 class CServerListRem
: public CRemoteContainer
<CServer
, uint32
, CEC_Server_Tag
> {
419 uint32 m_TotalUser
, m_TotalFile
;
421 virtual void HandlePacket(const CECPacket
*packet
);
423 CServerListRem(CRemoteConnect
*);
424 void GetUserFileStatus(uint32
&total_user
, uint32
&total_file
)
426 total_user
= m_TotalUser
;
427 total_file
= m_TotalFile
;
430 void UpdateUserFileStatus(CServer
*server
);
432 CServer
* GetServerByAddress(const wxString
& address
, uint16 port
) const;
433 CServer
* GetServerByIPTCP(uint32 nIP
, uint16 nPort
) const;
438 void RemoveServer(CServer
* server
);
439 void UpdateServerMetFromURL(wxString url
);
440 void SetStaticServer(CServer
* server
, bool isStatic
);
441 void SetServerPrio(CServer
* server
, uint32 prio
);
442 void SaveServerMet() {} // not needed here
443 void FilterServers() {} // not needed here
448 CServer
*CreateItem(CEC_Server_Tag
*);
449 void DeleteItem(CServer
*);
450 uint32
GetItemID(CServer
*);
451 void ProcessItemUpdate(CEC_Server_Tag
*, CServer
*);
454 class CUpDownClientListRem
: public CRemoteContainer
<CUpDownClient
, uint32
, CEC_UpDownClient_Tag
> {
456 CUpDownClientListRem(CRemoteConnect
*);
458 const CClientPtrList
& GetList() const { return m_items
; };
460 void FilterQueues() {} // not needed here
464 CUpDownClient
*CreateItem(CEC_UpDownClient_Tag
*);
465 void DeleteItem(CUpDownClient
*);
466 uint32
GetItemID(CUpDownClient
*);
467 void ProcessItemUpdate(CEC_UpDownClient_Tag
*, CUpDownClient
*);
470 class CDownQueueRem
: public std::map
<uint32
, CPartFile
*> {
471 CRemoteConnect
*m_conn
;
473 CDownQueueRem(CRemoteConnect
* conn
) { m_conn
= conn
; }
475 CPartFile
* GetFileByID(uint32 id
);
480 void Prio(CPartFile
*file
, uint8 prio
);
481 void AutoPrio(CPartFile
*file
, bool flag
);
482 void Category(CPartFile
*file
, uint8 cat
);
484 void SendFileCommand(CPartFile
*file
, ec_tagname_t cmd
);
488 void StopUDPRequests() {}
489 void AddFileLinkToDownload(CED2KFileLink
*, uint8
);
490 bool AddLink(const wxString
&link
, uint8 category
= 0);
491 void UnsetCompletedFilesExist();
492 void ResetCatParts(int cat
);
493 void AddSearchToDownload(CSearchFile
* toadd
, uint8 category
);
494 void ClearCompleted(const ListOfUInts32
& ecids
);
497 class CSharedFilesRem
: public std::map
<uint32
, CKnownFile
*> {
498 CRemoteConnect
*m_conn
;
500 CSharedFilesRem(CRemoteConnect
* conn
);
502 CKnownFile
*GetFileByID(uint32 id
);
504 void SetFilePrio(CKnownFile
*file
, uint8 prio
);
509 void AddFilesFromDirectory(const CPath
&);
510 void Reload(bool sendtoserver
= true, bool firstload
= false);
511 bool RenameFile(CKnownFile
* file
, const CPath
& newName
);
512 void SetFileCommentRating(CKnownFile
* file
, const wxString
& newComment
, int8 newRating
);
515 class CKnownFilesRem
: public CRemoteContainer
<CKnownFile
, uint32
, CEC_SharedFile_Tag
> {
516 CKnownFile
* CreateKnownFile(CEC_SharedFile_Tag
*tag
, CKnownFile
*file
= NULL
);
517 CPartFile
* CreatePartFile(CEC_PartFile_Tag
*tag
);
520 CKnownFilesRem(CRemoteConnect
* conn
);
522 CKnownFile
*FindKnownFileByID(uint32 id
) { return GetByID(id
); }
531 CKnownFile
*CreateItem(CEC_SharedFile_Tag
*) { wxFAIL
; return NULL
; } // unused, required by template
532 void DeleteItem(CKnownFile
*);
533 uint32
GetItemID(CKnownFile
*);
534 void ProcessItemUpdate(CEC_SharedFile_Tag
*, CKnownFile
*);
535 bool Phase1Done(const CECPacket
*) { return true; }
536 void ProcessUpdate(const CECTag
*reply
, CECPacket
*full_req
, int req_type
);
538 void ProcessItemUpdatePartfile(CEC_PartFile_Tag
*, CPartFile
*);
542 CRemoteConnect
*m_conn
;
544 CIPFilterRem(CRemoteConnect
*conn
);
550 void Update(wxString strURL
= wxEmptyString
);
551 bool IsReady() const { return true; }
554 class CSearchListRem
: public CRemoteContainer
<CSearchFile
, uint32
, CEC_SearchFile_Tag
> {
555 virtual void HandlePacket(const CECPacket
*);
557 CSearchListRem(CRemoteConnect
*);
560 typedef std::map
<long, CSearchResultList
> ResultMap
;
563 const CSearchResultList
& GetSearchResults(long nSearchID
);
564 void RemoveResults(long nSearchID
);
565 const CSearchResultList
& GetSearchResults(long nSearchID
) const;
570 wxString
StartNewSearch(uint32
* nSearchID
, SearchType search_type
,
571 const CSearchList::CSearchParams
& params
);
573 void StopSearch(bool globalOnly
= false);
578 CSearchFile
*CreateItem(CEC_SearchFile_Tag
*);
579 void DeleteItem(CSearchFile
*);
580 uint32
GetItemID(CSearchFile
*);
581 void ProcessItemUpdate(CEC_SearchFile_Tag
*, CSearchFile
*);
582 bool Phase1Done(const CECPacket
*);
585 class CFriendListRem
: public CRemoteContainer
<CFriend
, uint32
, CEC_Friend_Tag
> {
586 virtual void HandlePacket(const CECPacket
*);
588 CFriendListRem(CRemoteConnect
*);
590 void AddFriend(CUpDownClient
* toadd
);
591 void AddFriend(const CMD4Hash
& userhash
, uint32 lastUsedIP
, uint32 lastUsedPort
, const wxString
& name
);
592 void RemoveFriend(CFriend
* toremove
);
593 void RequestSharedFileList(CFriend
* Friend
);
594 void RequestSharedFileList(CUpDownClient
* client
);
595 void SetFriendSlot(CFriend
* Friend
, bool new_state
);
600 CFriend
*CreateItem(CEC_Friend_Tag
*);
601 void DeleteItem(CFriend
*);
602 uint32
GetItemID(CFriend
*);
603 void ProcessItemUpdate(CEC_Friend_Tag
*, CFriend
*);
606 class CStatsUpdaterRem
: public CECPacketHandlerBase
{
607 virtual void HandlePacket(const CECPacket
*);
609 CStatsUpdaterRem() {}
612 class CStatTreeRem
: public CECPacketHandlerBase
{
613 virtual void HandlePacket(const CECPacket
*);
614 CRemoteConnect
*m_conn
;
616 CStatTreeRem(CRemoteConnect
* conn
) { m_conn
= conn
; }
620 class CListenSocketRem
{
621 uint32 m_peak_connections
;
623 uint32
GetPeakConnections() { return m_peak_connections
; }
626 class CamuleRemoteGuiApp
: public wxApp
, public CamuleGuiBase
, public CamuleAppCommon
{
629 virtual int InitGui(bool geometry_enable
, wxString
&geometry_string
);
635 void OnPollTimer(wxTimerEvent
& evt
);
637 void OnECConnection(wxEvent
& event
);
638 void OnECInitDone(wxEvent
& event
);
639 void OnNotifyEvent(CMuleGUIEvent
& evt
);
640 void OnFinishedHTTPDownload(CMuleInternalEvent
& event
);
642 CStatsUpdaterRem m_stats_updater
;
647 bool ShowConnectionDialog();
649 class CRemoteConnect
*m_connect
;
651 CEConnectDlg
*dialog
;
653 bool CopyTextToClipboard(wxString strText
);
655 virtual int ShowAlert(wxString msg
, wxString title
, int flags
);
657 void ShutDown(wxCloseEvent
&evt
);
659 CPreferencesRem
*glob_prefs
;
662 // Provide access to core data thru EC
663 CServerConnectRem
*serverconnect
;
664 CServerListRem
*serverlist
;
665 CDownQueueRem
*downloadqueue
;
666 CSharedFilesRem
*sharedfiles
;
667 CKnownFilesRem
*knownfiles
;
668 CUpDownClientListRem
*clientlist
;
669 CIPFilterRem
*ipfilter
;
670 CSearchListRem
*searchlist
;
671 CFriendListRem
*friendlist
;
672 CListenSocketRem
*listensocket
;
673 CStatTreeRem
* stattree
;
675 CStatistics
*m_statistics
;
677 bool AddServer(CServer
*srv
, bool fromUser
= false);
679 uint32
GetPublicIP();
681 wxString
GetLog(bool reset
= false);
682 wxString
GetServerLog(bool reset
= false);
684 void AddServerMessageLine(wxString
&msg
);
685 void AddRemoteLogLine(const wxString
& line
);
687 void SetOSFiles(wxString
) { /* onlinesig is created on remote side */ }
689 bool IsConnected() const { return IsConnectedED2K() || IsConnectedKad(); }
690 bool IsFirewalled() const;
691 bool IsConnectedED2K() const;
692 bool IsConnectedKad() const
694 return ((m_ConnState
& CONNECTED_KAD_OK
)
695 || (m_ConnState
& CONNECTED_KAD_FIREWALLED
));
697 bool IsFirewalledKad() const { return (m_ConnState
& CONNECTED_KAD_FIREWALLED
) != 0; }
699 bool IsKadRunning() const { return ((m_ConnState
& CONNECTED_KAD_OK
)
700 || (m_ConnState
& CONNECTED_KAD_FIREWALLED
)
701 || (m_ConnState
& CONNECTED_KAD_NOT
)); }
703 // Check Kad state (UDP)
704 bool IsFirewalledKadUDP() const { return theStats::IsFirewalledKadUDP(); }
705 bool IsKadRunningInLanMode() const { return theStats::IsKadRunningInLanMode(); }
707 uint32
GetKadUsers() const { return theStats::GetKadUsers(); }
708 uint32
GetKadFiles() const { return theStats::GetKadFiles(); }
709 uint32
GetKadIndexedSources() const { return theStats::GetKadIndexedSources(); }
710 uint32
GetKadIndexedKeywords() const{ return theStats::GetKadIndexedKeywords(); }
711 uint32
GetKadIndexedNotes() const { return theStats::GetKadIndexedNotes(); }
712 uint32
GetKadIndexedLoad() const { return theStats::GetKadIndexedLoad(); }
713 // True IP of machine
714 uint32
GetKadIPAdress() const { return theStats::GetKadIPAdress(); }
716 uint8
GetBuddyStatus() const { return theStats::GetBuddyStatus(); }
717 uint32
GetBuddyIP() const { return theStats::GetBuddyIP(); }
718 uint32
GetBuddyPort() const { return theStats::GetBuddyPort(); }
723 /** Bootstraps kad from the specified IP (must be in hostorder). */
724 void BootstrapKad(uint32 ip
, uint16 port
);
725 /** Updates the nodes.dat file from the specified url. */
726 void UpdateNotesDat(const wxString
& str
);
728 void DisconnectED2K();
730 bool CryptoAvailable() const;
732 uint32
GetED2KID() const;
733 uint32
GetID() const;
734 void ShowUserCount();
740 // This KnownFile collects all currently uploading clients for display in the upload list control
741 CKnownFile
* m_allUploadingKnownFile
;
743 DECLARE_EVENT_TABLE()
746 DECLARE_APP(CamuleRemoteGuiApp
)
748 extern CamuleRemoteGuiApp
*theApp
;
750 #endif /* AMULE_REMOTE_GUI_H */
752 // File_checked_for_headers