Improve the code by static code analysis [2/3]: Performance
[amule.git] / src / FriendList.cpp
blobcf2bae029899675e6c052c55c9bd4585151c84e8
1 //
2 // This file is part of the aMule Project.
3 //
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 )
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.
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(const CClientRef& 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 CClientRef client = toremove->GetLinkedClient();
87 if (client.IsLinked()) {
88 client.SetFriendSlot(false);
89 client.SetFriend(NULL);
90 toremove->UnLinkClient();
93 m_FriendList.remove(toremove);
95 SaveList();
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()) {
106 return;
109 CFile file;
110 try {
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);
121 } else {
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()
135 CFile file;
136 if (file.Create(theApp->ConfigDir + wxT("emfriends.met"), true)) {
137 try {
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());
147 } else {
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) {
164 return cur_friend;
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)
169 // -> save the hash
170 cur_friend->SetUserHash(userhash);
171 SaveList();
173 return cur_friend;
177 return NULL;
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) {
186 return cur_friend;
190 return NULL;
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)
213 if (cur_friend) {
214 CUpDownClient* client = cur_friend->GetLinkedClient().GetClient();
215 if (!client) {
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)
238 if (Friend) {
239 CUpDownClient* client = Friend->GetLinkedClient().GetClient();
240 if (!client) {
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")));
247 } else {
248 AddLogLineC(_("CRITICAL - no client on StartChatSession"));
253 // File_checked_for_headers