2 // This file is part of the aMule Project.
4 // Copyright (c) 2003-2011 aMule Team ( admin@amule.org / http://www.amule.org )
5 // Copyright (c) 2002-2011 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(const CClientRef
& 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 CClientRef client
= toremove
->GetLinkedClient();
87 if (client
.IsLinked()) {
88 client
.SetFriendSlot(false);
89 client
.SetFriend(NULL
);
90 toremove
->UnLinkClient();
93 m_FriendList
.remove(toremove
);
97 Notify_ChatRemoveFriend(toremove
); // this deletes the friend
101 void CFriendList::LoadList()
103 CPath metfile
= CPath(theApp
->ConfigDir
+ wxT("emfriends.met"));
105 if (!metfile
.FileExists()) {
111 if ( file
.Open(metfile
) ) {
112 if ( file
.ReadUInt8() /*header*/ == MET_HEADER
) {
113 uint32 nRecordsNumber
= file
.ReadUInt32();
114 for (uint32 i
= 0; i
< nRecordsNumber
; i
++) {
115 CFriend
* Record
= new CFriend();
116 Record
->LoadFromFile(&file
);
117 m_FriendList
.push_back(Record
);
118 Notify_ChatUpdateFriend(Record
);
122 AddLogLineN(_("Failed to open friend list file 'emfriends.met' for reading!"));
124 } catch (const CInvalidPacket
& e
) {
125 AddDebugLogLineC(logGeneral
, wxT("Invalid entry in friend list, file may be corrupt: ") + e
.what());
126 } catch (const CSafeIOException
& e
) {
127 AddDebugLogLineC(logGeneral
, wxT("IO error while reading 'emfriends.met': ") + e
.what());
133 void CFriendList::SaveList()
136 if (file
.Create(theApp
->ConfigDir
+ wxT("emfriends.met"), true)) {
138 file
.WriteUInt8(MET_HEADER
);
139 file
.WriteUInt32(m_FriendList
.size());
141 for (FriendList::iterator it
= m_FriendList
.begin(); it
!= m_FriendList
.end(); ++it
) {
142 (*it
)->WriteToFile(&file
);
144 } catch (const CIOFailureException
& e
) {
145 AddDebugLogLineC(logGeneral
, wxT("IO failure while saving 'emfriends.met': ") + e
.what());
148 AddLogLineN(_("Failed to open friend list file 'emfriends.met' for writing!"));
153 CFriend
* CFriendList::FindFriend(const CMD4Hash
& userhash
, uint32 dwIP
, uint16 nPort
)
156 for(FriendList::iterator it
= m_FriendList
.begin(); it
!= m_FriendList
.end(); ++it
) {
158 CFriend
* cur_friend
= *it
;
159 // to avoid that unwanted clients become a friend, we have to distinguish between friends with
160 // a userhash and of friends which are identified by IP+port only.
161 if ( !userhash
.IsEmpty() && cur_friend
->HasHash() ) {
162 // check for a friend which has the same userhash as the specified one
163 if (cur_friend
->GetUserHash() == userhash
) {
166 } else if (cur_friend
->GetIP() == dwIP
&& cur_friend
->GetPort() == nPort
) {
167 if (!userhash
.IsEmpty() && !cur_friend
->HasHash() ) {
168 // Friend without hash (probably IP entered through dialog)
170 cur_friend
->SetUserHash(userhash
);
181 CFriend
* CFriendList::FindFriend(uint32 ecid
)
183 for (FriendList::iterator it
= m_FriendList
.begin(); it
!= m_FriendList
.end(); ++it
) {
184 CFriend
* cur_friend
= *it
;
185 if (cur_friend
->ECID() == ecid
) {
194 bool CFriendList::IsAlreadyFriend( uint32 dwLastUsedIP
, uint32 nLastUsedPort
)
196 return (FindFriend( CMD4Hash(), dwLastUsedIP
, nLastUsedPort
) != NULL
);
200 void CFriendList::RemoveAllFriendSlots()
202 for(FriendList::iterator it
= m_FriendList
.begin(); it
!= m_FriendList
.end(); ++it
) {
203 CFriend
* cur_friend
= *it
;
204 if (cur_friend
->GetLinkedClient().IsLinked()) {
205 cur_friend
->GetLinkedClient().SetFriendSlot(false);
211 void CFriendList::RequestSharedFileList(CFriend
* cur_friend
)
214 CUpDownClient
* client
= cur_friend
->GetLinkedClient().GetClient();
216 client
= new CUpDownClient(cur_friend
->GetPort(), cur_friend
->GetIP(), 0, 0, 0, true, true);
217 client
->SetUserName(cur_friend
->GetName());
218 theApp
->clientlist
->AddClient(client
);
219 cur_friend
->LinkClient(CCLIENTREF(client
, wxT("CFriendList::RequestSharedFileList")));
221 client
->RequestSharedFileList();
226 void CFriendList::SetFriendSlot(CFriend
* Friend
, bool new_state
)
228 if (Friend
&& Friend
->GetLinkedClient().IsLinked()) {
229 RemoveAllFriendSlots();
230 Friend
->GetLinkedClient().SetFriendSlot(new_state
);
231 CoreNotify_Upload_Resort_Queue();
236 void CFriendList::StartChatSession(CFriend
* Friend
)
239 CUpDownClient
* client
= Friend
->GetLinkedClient().GetClient();
241 client
= new CUpDownClient(Friend
->GetPort(), Friend
->GetIP(), 0, 0, 0, true, true);
242 client
->SetIP(Friend
->GetIP());
243 client
->SetUserName(Friend
->GetName());
244 theApp
->clientlist
->AddClient(client
);
245 Friend
->LinkClient(CCLIENTREF(client
, wxT("CFriendList::StartChatSession")));
248 AddLogLineC(_("CRITICAL - no client on StartChatSession"));
253 // File_checked_for_headers