2 // This file is part of the aMule Project.
4 // Copyright (c) 2003-2008 aMule Team ( admin@amule.org / http://www.amule.org )
5 // Copyright (c) 2002-2008 Merkur ( devs@emule-project.net / http://www.emule-project.net )
7 // Any parts of this program derived from the xMule, lMule or eMule project,
8 // or contributed by third-party developers are copyrighted by their
11 // This program is free software; you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation; either version 2 of the License, or
14 // (at your option) any later version.
16 // This program is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU General Public License for more details.
21 // You should have received a copy of the GNU General Public License
22 // along with this program; if not, write to the Free Software
23 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #include "FriendList.h" // Interface
29 #include <common/DataFileVersion.h>
31 #include "amule.h" // Needed for theApp: let it first or fail under win32
32 #include "ClientList.h" // Needed for CClientList
33 #include "updownclient.h" // Needed for CUpDownClient
34 #include "Friend.h" // Needed for CFriend
37 #include "GuiEvents.h"
39 CFriendList::CFriendList()
43 CFriendList::~CFriendList()
47 DeleteContents(m_FriendList
);
51 void CFriendList::AddFriend(CFriend
* toadd
, bool notify
)
53 m_FriendList
.push_back(toadd
);
56 Notify_ChatUpdateFriend(toadd
);
61 void CFriendList::AddFriend(const CMD4Hash
& userhash
, uint32 lastUsedIP
, uint32 lastUsedPort
, const wxString
& name
, uint32 lastSeen
, uint32 lastChatted
)
63 CFriend
* NewFriend
= new CFriend( userhash
, lastSeen
, lastUsedIP
, lastUsedPort
, lastChatted
, name
);
65 AddFriend( NewFriend
);
70 void CFriendList::AddFriend(CUpDownClient
* toadd
)
72 if ( toadd
->IsFriend() ) {
76 CFriend
* NewFriend
= new CFriend( toadd
);
77 toadd
->SetFriend(NewFriend
);
79 AddFriend(NewFriend
, false); // has already notified
83 void CFriendList::RemoveFriend(CFriend
* toremove
)
86 if ( toremove
->GetLinkedClient() ){
87 toremove
->GetLinkedClient()->SetFriendSlot(false);
88 toremove
->GetLinkedClient()->SetFriend(NULL
);
89 toremove
->UnLinkClient();
92 m_FriendList
.remove(toremove
);
96 Notify_ChatRemoveFriend(toremove
); // this deletes the friend
100 void CFriendList::LoadList()
102 CPath metfile
= CPath(theApp
->ConfigDir
+ wxT("emfriends.met"));
104 if (!metfile
.FileExists()) {
110 if ( file
.Open(metfile
) ) {
111 if ( file
.ReadUInt8() /*header*/ == MET_HEADER
) {
112 uint32 nRecordsNumber
= file
.ReadUInt32();
113 for (uint32 i
= 0; i
< nRecordsNumber
; i
++) {
114 CFriend
* Record
= new CFriend();
115 Record
->LoadFromFile(&file
);
116 m_FriendList
.push_back(Record
);
117 Notify_ChatUpdateFriend(Record
);
121 AddLogLineN(_("Failed to open friend list file 'emfriends.met' for reading!"));
123 } catch (const CInvalidPacket
& e
) {
124 AddDebugLogLineC(logGeneral
, wxT("Invalid entry in friend list, file may be corrupt: ") + e
.what());
125 } catch (const CSafeIOException
& e
) {
126 AddDebugLogLineC(logGeneral
, wxT("IO error while reading 'emfriends.met': ") + e
.what());
132 void CFriendList::SaveList()
135 if (file
.Create(theApp
->ConfigDir
+ wxT("emfriends.met"), true)) {
137 file
.WriteUInt8(MET_HEADER
);
138 file
.WriteUInt32(m_FriendList
.size());
140 for (FriendList::iterator it
= m_FriendList
.begin(); it
!= m_FriendList
.end(); ++it
) {
141 (*it
)->WriteToFile(&file
);
143 } catch (const CIOFailureException
& e
) {
144 AddDebugLogLineC(logGeneral
, wxT("IO failure while saving 'emfriends.met': ") + e
.what());
147 AddLogLineN(_("Failed to open friend list file 'emfriends.met' for writing!"));
152 CFriend
* CFriendList::FindFriend(const CMD4Hash
& userhash
, uint32 dwIP
, uint16 nPort
)
155 for(FriendList::iterator it
= m_FriendList
.begin(); it
!= m_FriendList
.end(); ++it
) {
157 CFriend
* cur_friend
= *it
;
158 // to avoid that unwanted clients become a friend, we have to distinguish between friends with
159 // a userhash and of friends which are identified by IP+port only.
160 if ( !userhash
.IsEmpty() && cur_friend
->HasHash() ) {
161 // check for a friend which has the same userhash as the specified one
162 if (cur_friend
->GetUserHash() == userhash
) {
165 } else if (cur_friend
->GetIP() == dwIP
&& cur_friend
->GetPort() == nPort
) {
166 if (!userhash
.IsEmpty() && !cur_friend
->HasHash() ) {
167 // Friend without hash (probably IP entered through dialog)
169 cur_friend
->SetUserHash(userhash
);
180 CFriend
* CFriendList::FindFriend(uint32 ecid
)
182 for (FriendList::iterator it
= m_FriendList
.begin(); it
!= m_FriendList
.end(); ++it
) {
183 CFriend
* cur_friend
= *it
;
184 if (cur_friend
->ECID() == ecid
) {
193 bool CFriendList::IsAlreadyFriend( uint32 dwLastUsedIP
, uint32 nLastUsedPort
)
195 return (FindFriend( CMD4Hash(), dwLastUsedIP
, nLastUsedPort
) != NULL
);
199 void CFriendList::RemoveAllFriendSlots()
201 for(FriendList::iterator it
= m_FriendList
.begin(); it
!= m_FriendList
.end(); ++it
) {
202 CFriend
* cur_friend
= *it
;
203 if ( cur_friend
->GetLinkedClient() ) {
204 cur_friend
->GetLinkedClient()->SetFriendSlot(false);
210 void CFriendList::RequestSharedFileList(CFriend
* cur_friend
)
213 CUpDownClient
* client
= cur_friend
->GetLinkedClient();
215 client
= new CUpDownClient(cur_friend
->GetPort(), cur_friend
->GetIP(), 0, 0, 0, true, true);
216 client
->SetUserName(cur_friend
->GetName());
217 theApp
->clientlist
->AddClient(client
);
219 client
->RequestSharedFileList();
224 void CFriendList::SetFriendSlot(CFriend
* Friend
, bool new_state
)
226 if (Friend
&& Friend
->GetLinkedClient()) {
227 RemoveAllFriendSlots();
228 Friend
->GetLinkedClient()->SetFriendSlot(new_state
);
229 CoreNotify_Upload_Resort_Queue();
234 void CFriendList::StartChatSession(CFriend
* Friend
)
237 CUpDownClient
* client
= Friend
->GetLinkedClient();
239 client
= new CUpDownClient(Friend
->GetPort(), Friend
->GetIP(), 0, 0, 0, true, true);
240 client
->SetIP(Friend
->GetIP());
241 client
->SetUserName(Friend
->GetName());
242 theApp
->clientlist
->AddClient(client
);
243 Friend
->LinkClient(client
);
246 AddLogLineC(_("CRITICAL - no client on StartChatSession"));
251 // File_checked_for_headers