Rework friends for EC
[amule.git] / src / FriendList.cpp
blobd848db648ef346f5502c1a6ea06dc66eedb8637c
1 //
2 // This file is part of the aMule Project.
3 //
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 )
6 //
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
9 // respective authors.
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.
20 //
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
35 #include "CFile.h"
36 #include "Logger.h"
37 #include "GuiEvents.h"
39 CFriendList::CFriendList()
43 CFriendList::~CFriendList()
45 SaveList();
47 DeleteContents(m_FriendList);
51 void CFriendList::AddFriend(CFriend* toadd, bool notify)
53 m_FriendList.push_back(toadd);
54 SaveList();
55 if (notify) {
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() ) {
73 return;
76 CFriend* NewFriend = new CFriend( toadd );
77 toadd->SetFriend(NewFriend);
79 AddFriend(NewFriend, false); // has already notified
83 void CFriendList::RemoveFriend(CFriend* toremove)
85 if (toremove) {
86 if ( toremove->GetLinkedClient() ){
87 toremove->GetLinkedClient()->SetFriendSlot(false);
88 toremove->GetLinkedClient()->SetFriend(NULL);
89 toremove->UnLinkClient();
92 m_FriendList.remove(toremove);
94 SaveList();
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()) {
105 return;
108 CFile file;
109 try {
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);
120 } else {
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()
134 CFile file;
135 if (file.Create(theApp->ConfigDir + wxT("emfriends.met"), true)) {
136 try {
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());
146 } else {
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) {
163 return cur_friend;
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)
168 // -> save the hash
169 cur_friend->SetUserHash(userhash);
170 SaveList();
172 return cur_friend;
176 return NULL;
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) {
185 return cur_friend;
189 return NULL;
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)
212 if (cur_friend) {
213 CUpDownClient* client = cur_friend->GetLinkedClient();
214 if (!client) {
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)
236 if (Friend) {
237 CUpDownClient* client = Friend->GetLinkedClient();
238 if (!client) {
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);
245 } else {
246 AddLogLineC(_("CRITICAL - no client on StartChatSession"));
251 // File_checked_for_headers