File 240-backports.diff of Package aMule-git

diff -Nur ./src/BaseClient.cpp ./src-backports/BaseClient.cpp
--- ./src/BaseClient.cpp	2011-10-06 04:02:32.000000000 +0900
+++ ./src-backports/BaseClient.cpp	2012-08-03 22:08:38.000000000 +0900
@@ -2857,7 +2857,7 @@
 		
 		// Build packet
 		CMemFile tempfile(80);
-		tempfile.WriteUInt32(foldersToSend.size());
+		tempfile.WriteUInt32(foldersToSend.size() + 1); // + 1 for the incomplete files
 
 		PathList::iterator it = foldersToSend.begin();
 		for (; it != foldersToSend.end(); ++it) {
diff -Nur ./src/ChatSelector.cpp ./src-backports/ChatSelector.cpp
--- ./src/ChatSelector.cpp	2011-06-13 17:50:25.000000000 +0900
+++ ./src-backports/ChatSelector.cpp	2012-08-03 22:08:38.000000000 +0900
@@ -352,11 +352,13 @@
 	
 	// Get the client that the session is open to
 	if (ci) {
-		clientref.Link(theApp->clientlist->FindClientByIP(IP_FROM_GUI_ID(ci->m_client_id), PORT_FROM_GUI_ID(ci->m_client_id)) CLIENT_DEBUGSTRING("CChatSelector::GetCurrentClient"));
-		return true;
-	} else {
-		return false;
+		CUpDownClient * client = theApp->clientlist->FindClientByIP(IP_FROM_GUI_ID(ci->m_client_id), PORT_FROM_GUI_ID(ci->m_client_id));
+		if (client) {
+			clientref.Link(client CLIENT_DEBUGSTRING("CChatSelector::GetCurrentClient"));
+			return true;
+		}  
 	}
+	return false;
 }
 #endif
 
diff -Nur ./src/DownloadListCtrl.cpp ./src-backports/DownloadListCtrl.cpp
--- ./src/DownloadListCtrl.cpp	2011-06-24 06:11:51.000000000 +0900
+++ ./src-backports/DownloadListCtrl.cpp	2012-08-03 22:08:38.000000000 +0900
@@ -976,7 +976,8 @@
 				
 				wxMemoryDC cdcStatus;
 				
-				if ( item->dwUpdated < dwTicks || !item->status || iWidth != item->status->GetWidth() ) {
+				if (item->dwUpdated < dwTicks || file->GetHashingProgress() > 0
+					|| !item->status || iWidth != item->status->GetWidth()) {
 					if ( item->status == NULL) {
 						item->status = new wxBitmap(iWidth, iHeight);
 					} else if ( item->status->GetWidth() != iWidth ) {
@@ -1007,10 +1008,13 @@
 				dc->Blit( rect.GetX(), rect.GetY() + 1, iWidth, iHeight, &cdcStatus, 0, 0);
 				
 				if (thePrefs::ShowPercent()) {
-					// Percentage of completing
-					// We strip anything below the first decimal point,
-					// to avoid Format doing roundings
-					float percent = floor( file->GetPercentCompleted() * 10.0f ) / 10.0f;
+					// Percentage of completing or hashing
+					uint16  hashingProgress = file->GetHashingProgress();
+					double  percent = hashingProgress == 0 ? file->GetPercentCompleted()
+										: 100.0 * hashingProgress * PARTSIZE / file->GetFileSize();
+					if (percent > 100.0) {
+						percent = 100.0;
+					}
 				
 					wxString buffer = CFormat(wxT("%.1f%%")) % percent;
 					int middlex = (2*rect.GetX() + rect.GetWidth()) >> 1;
@@ -1020,7 +1024,9 @@
 					
 					dc->GetTextExtent(buffer, &textwidth, &textheight);
 					wxColour AktColor = dc->GetTextForeground();
-					if (thePrefs::ShowProgBar()) {
+					// Ordinary progress bar: white percentage
+					// Hashing progressbar (green/yellow): black percentage
+					if (thePrefs::ShowProgBar() && hashingProgress == 0) {
 						dc->SetTextForeground(*wxWHITE);
 					} else {
 						dc->SetTextForeground(*wxBLACK);
@@ -1295,6 +1301,18 @@
 		s_ChunkBar.Fill( bFlat ? crFlatProgress : crProgress );
 		s_ChunkBar.Draw(dc, rect.x, rect.y, bFlat); 
 		return;
+	} else if (file->GetHashingProgress() > 0) {
+		uint64 left = file->GetHashingProgress() * PARTSIZE;
+		if (left < file->GetFileSize() - 1) {
+			// Fill the amount not yet hashed with yellow
+			s_ChunkBar.FillRange(left + 1, file->GetFileSize() - 1, bFlat ? crFlatPending : crPending);
+		} else {
+			left = file->GetFileSize() - 1;
+		}
+		// Fill the amount already hashed with green
+		s_ChunkBar.FillRange(0, left, bFlat ? crFlatProgress : crProgress);
+		s_ChunkBar.Draw(dc, rect.x, rect.y, bFlat);
+		return;
 	}
 	
 	// Part availability ( of missing parts )
diff -Nur ./src/ECSpecialCoreTags.cpp ./src-backports/ECSpecialCoreTags.cpp
--- ./src/ECSpecialCoreTags.cpp	2011-09-18 21:23:47.000000000 +0900
+++ ./src-backports/ECSpecialCoreTags.cpp	2012-08-03 22:08:38.000000000 +0900
@@ -177,6 +177,7 @@
 	AddTag(EC_TAG_PARTFILE_LAST_RECV, file->GetLastChangeDatetime(), valuemap);
 	AddTag(EC_TAG_PARTFILE_DOWNLOAD_ACTIVE, file->GetDlActiveTime(), valuemap);
 	AddTag(EC_TAG_PARTFILE_AVAILABLE_PARTS, file->GetAvailablePartCount(), valuemap);
+	AddTag(EC_TAG_PARTFILE_HASHED_PART_COUNT, file->GetHashingProgress(), valuemap);
 
 	AddTag(EC_TAG_PARTFILE_LOST_CORRUPTION, file->GetLostDueToCorruption(), valuemap);
 	AddTag(EC_TAG_PARTFILE_GAINED_COMPRESSION, file->GetGainDueToCompression(), valuemap);
diff -Nur ./src/ExternalConn.cpp ./src-backports/ExternalConn.cpp
--- ./src/ExternalConn.cpp	2011-11-05 04:59:23.000000000 +0900
+++ ./src-backports/ExternalConn.cpp	2012-08-03 22:16:02.000000000 +0900
@@ -55,6 +55,7 @@
 #include "RandomFunctions.h"
 #include "kademlia/kademlia/Kademlia.h"
 #include "kademlia/kademlia/UDPFirewallTester.h"
+#include "Statistics.h"
 
 
 //-------------------- File_Encoder --------------------
@@ -590,6 +591,7 @@
 				response->AddTag(CECTag(EC_TAG_STATS_KAD_USERS, Kademlia::CKademlia::GetKademliaUsers()));
 				response->AddTag(CECTag(EC_TAG_STATS_ED2K_FILES, totalfile));
 				response->AddTag(CECTag(EC_TAG_STATS_KAD_FILES, Kademlia::CKademlia::GetKademliaFiles()));
+				response->AddTag(CECTag(EC_TAG_STATS_KAD_NODES, CStatistics::GetKadNodes()));
 			}
 			// Kad stats
 			if (Kademlia::CKademlia::IsConnected()) {
diff -Nur ./src/GuiEvents.cpp ./src-backports/GuiEvents.cpp
--- ./src/GuiEvents.cpp	2011-06-13 17:50:25.000000000 +0900
+++ ./src-backports/GuiEvents.cpp	2012-08-03 22:08:38.000000000 +0900
@@ -647,6 +647,7 @@
 	void PartFile_Pause(CPartFile* file)
 	{
 		file->PauseFile();
+		file->SavePartFile();
 	}
 
 	void PartFile_Resume(CPartFile* file)
@@ -658,6 +659,7 @@
 	void PartFile_Stop(CPartFile* file)
 	{
 		file->StopFile();
+		file->SavePartFile();
 	}
 
 	void PartFile_PrioAuto(CPartFile* file, bool val)
diff -Nur ./src/IP2Country.cpp ./src-backports/IP2Country.cpp
--- ./src/IP2Country.cpp	2011-07-31 03:41:01.000000000 +0900
+++ ./src-backports/IP2Country.cpp	2012-08-03 22:08:38.000000000 +0900
@@ -163,7 +163,7 @@
 	// Load data from xpm files
 	for (int i = 0; i < flags::FLAGS_XPM_SIZE; ++i) {
 		CountryData countrydata;
-		countrydata.Name = char2unicode(flags::flagXPMCodeVector[i].code);
+		countrydata.Name = wxString(flags::flagXPMCodeVector[i].code, wxConvISO8859_1);
 		countrydata.Flag = wxImage(flags::flagXPMCodeVector[i].xpm);
 		
 		if (countrydata.Flag.IsOk()) {
@@ -193,7 +193,18 @@
 		return it->second;	
 	}
 	
-	const wxString CCode = wxString(char2unicode(GeoIP_country_code_by_addr(m_geoip, unicode2char(ip)))).MakeLower();
+	// wxString::MakeLower() fails miserably in Turkish localization with their dotted/non-dotted 'i's
+	// So fall back to some good ole C string processing.
+	std::string strCode;
+	const char * c = GeoIP_country_code_by_addr(m_geoip, unicode2char(ip));
+	if (!c) {
+		c = "unknown";
+	}
+	for ( ; *c; c++) {
+		strCode += ((*c >= 'A' && *c <= 'Z') ? *c + 'a' - 'A' : *c);
+	}
+
+	const wxString CCode(strCode.c_str(), wxConvISO8859_1);
 	
 	CountryDataMap::iterator it = m_CountryDataMap.find(CCode);
 	if (it == m_CountryDataMap.end()) { 
diff -Nur ./src/KadDlg.cpp ./src-backports/KadDlg.cpp
--- ./src/KadDlg.cpp	2011-06-13 17:50:25.000000000 +0900
+++ ./src-backports/KadDlg.cpp	2012-08-03 22:18:45.000000000 +0900
@@ -140,7 +140,11 @@
 
 		m_kad_scope->AppendPoints(update.timestamp, apfKad);
 	}
+}
 
+
+void CKadDlg::UpdateNodeCount(unsigned nodeCount)
+{
 	wxStaticText* label = CastChild( wxT("nodesListLabel"), wxStaticText );
 	wxCHECK_RET(label, wxT("Failed to find kad-nodes label"));
 
diff -Nur ./src/KadDlg.h ./src-backports/KadDlg.h
--- ./src/KadDlg.h	2011-06-13 17:50:25.000000000 +0900
+++ ./src-backports/KadDlg.h	2012-08-03 22:19:30.000000000 +0900
@@ -45,6 +45,7 @@
 	void SetUpdatePeriod(int step);
 	void SetGraphColors();
 	void UpdateGraph(const GraphUpdateInfo& update);
+	void UpdateNodeCount(unsigned nodes);
 		
 private:
 	COScopeCtrl* m_kad_scope;
diff -Nur ./src/KnownFile.cpp ./src-backports/KnownFile.cpp
--- ./src/KnownFile.cpp	2011-09-18 20:01:52.000000000 +0900
+++ ./src-backports/KnownFile.cpp	2012-08-03 22:08:38.000000000 +0900
@@ -321,6 +321,7 @@
 	m_lastDateChanged = 0;
 	m_bAutoUpPriority = thePrefs::GetNewAutoUp();
 	m_iUpPriority = ( m_bAutoUpPriority ) ? PR_HIGH : PR_NORMAL;
+	m_hashingProgress = 0;
 
 	statistic.fileParent = this;
 
diff -Nur ./src/KnownFile.h ./src-backports/KnownFile.h
--- ./src/KnownFile.h	2011-06-13 17:50:25.000000000 +0900
+++ ./src-backports/KnownFile.h	2012-08-03 22:08:38.000000000 +0900
@@ -301,6 +301,9 @@
 	bool	ShowSources() const			{ return m_showSources; }
 	void	SetShowPeers( bool val )	{ m_showPeers = val; }
 	bool	ShowPeers()	const			{ return m_showPeers; }
+	
+	virtual void SetHashingProgress(uint16) const {}        // does something for CPartFile only
+	uint16  GetHashingProgress() const      { return m_hashingProgress; }
 
 #ifdef CLIENT_GUI
 	CKnownFile(CEC_SharedFile_Tag *);
@@ -342,7 +345,11 @@
 	uint8	m_iUpPriority;
 	bool	m_bAutoUpPriority;
 	bool	m_PublishedED2K;
-
+	// Index of part being hashed, 0: no hashing in progress.
+	// The known file is const in the hashing thread, so rather drill this little hole by making it mutable
+	// than opening it all up.
+	mutable uint16 m_hashingProgress;
+	
 	/* Kad stuff */
 	Kademlia::WordList wordlist;
 	uint32	kadFileSearchID;
diff -Nur ./src/ListenSocket.cpp ./src-backports/ListenSocket.cpp
--- ./src/ListenSocket.cpp	2011-06-13 17:50:25.000000000 +0900
+++ ./src-backports/ListenSocket.cpp	2012-08-03 22:08:38.000000000 +0900
@@ -53,11 +53,11 @@
 	bListening = false;
 	shutdown = false;
 	m_OpenSocketsInterval = 0;
-	m_nPeningConnections = 0;
+	m_nPendingConnections = 0;
 	totalconnectionchecks = 0;
 	averageconnections = 0.0;
 	// Set the listen socket event handler -- The handler is written in amule.cpp
-	if (Ok()) {
+	if (IsOk()) {
  		SetEventHandler(*theApp, ID_LISTENSOCKET_EVENT);
  		SetNotify(wxSOCKET_CONNECTION_FLAG);
  		Notify(true);
@@ -98,8 +98,8 @@
 {
 	// 0.42e
 	bListening = true;
-	if (m_nPeningConnections) {
-		m_nPeningConnections--;
+	if (m_nPendingConnections) {
+		m_nPendingConnections--;
 		OnAccept(0);
 	}
 }
@@ -115,10 +115,10 @@
 {
 	// 0.42e
 	if (!nErrorCode) {
-		m_nPeningConnections++;
-		if (m_nPeningConnections < 1) {
+		m_nPendingConnections++;
+		if (m_nPendingConnections < 1) {
 			wxFAIL;
-			m_nPeningConnections = 1;
+			m_nPendingConnections = 1;
 		}
 		if (TooManySockets(true) && !theApp->serverconnect->IsConnecting()) {
 			StopListening();
@@ -131,8 +131,8 @@
 		}
 		// Deal with the pending connections, there might be more than one, due to
 		// the StopListening() call above.
-		while (m_nPeningConnections) {
-			m_nPeningConnections--;
+		while (m_nPendingConnections) {
+			m_nPendingConnections--;
 			// Create a new socket to deal with the connection
 			CClientTCPSocket* newclient = new CClientTCPSocket();
 			// Accept the connection and give it to the newly created socket
@@ -228,7 +228,8 @@
 
 bool CListenSocket::TooManySockets(bool bIgnoreInterval)
 {
-	if (GetOpenSockets() > thePrefs::GetMaxConnections() || (m_OpenSocketsInterval > (thePrefs::GetMaxConperFive()*GetMaxConperFiveModifier()) && !bIgnoreInterval)) {
+	if (GetOpenSockets() > thePrefs::GetMaxConnections() 
+		|| (!bIgnoreInterval && m_OpenSocketsInterval > (thePrefs::GetMaxConperFive() * GetMaxConperFiveModifier()))) {
 		return true;
 	} else {
 		return false;
diff -Nur ./src/ListenSocket.h ./src-backports/ListenSocket.h
--- ./src/ListenSocket.h	2011-06-13 17:50:25.000000000 +0900
+++ ./src-backports/ListenSocket.h	2012-08-03 22:08:38.000000000 +0900
@@ -73,7 +73,7 @@
 	
 	uint16	m_OpenSocketsInterval;
 	uint16	m_ConnectionStates[3];
-	uint16	m_nPeningConnections;
+	uint16  m_nPendingConnections;
 	uint32	totalconnectionchecks;
 	float	averageconnections;
 };
diff -Nur ./src/MuleUDPSocket.cpp ./src-backports/MuleUDPSocket.cpp
--- ./src/MuleUDPSocket.cpp	2011-06-13 17:50:25.000000000 +0900
+++ ./src-backports/MuleUDPSocket.cpp	2012-08-03 22:08:38.000000000 +0900
@@ -40,6 +40,7 @@
 #include "OtherFunctions.h"
 #include "kademlia/kademlia/Prefs.h"
 #include "ClientList.h"
+#include "Preferences.h"
 
 
 CMuleUDPSocket::CMuleUDPSocket(const wxString& name, int id, const amuleIPV4Address& address, const CProxyData* ProxyData)
@@ -232,7 +233,8 @@
 	newpending.port = port;
 	newpending.packet = packet;
 	newpending.time = GetTickCount();
- 	newpending.bEncrypt = bEncrypt && (pachTargetClientHashORKadID != NULL || (bKad && nReceiverVerifyKey != 0));
+	newpending.bEncrypt = bEncrypt && (pachTargetClientHashORKadID != NULL || (bKad && nReceiverVerifyKey != 0))
+										&& thePrefs::IsClientCryptLayerSupported();
 	newpending.bKad = bKad;
 	newpending.nReceiverVerifyKey = nReceiverVerifyKey;   
 	if (newpending.bEncrypt && pachTargetClientHashORKadID != NULL) {
diff -Nur ./src/PartFile.cpp ./src-backports/PartFile.cpp
--- ./src/PartFile.cpp	2011-10-16 00:43:21.000000000 +0900
+++ ./src-backports/PartFile.cpp	2012-08-03 22:08:38.000000000 +0900
@@ -3897,6 +3897,11 @@
 	return m_partmetfilename.RemoveAllExt().GetRaw().ToLong(&nr) ? nr : 0;
 }
 
+void CPartFile::SetHashingProgress(uint16 part) const
+{
+	m_hashingProgress = part;
+	Notify_DownloadCtrlUpdateItem(this);
+}
 
 #ifndef CLIENT_GUI
 
diff -Nur ./src/PartFile.h ./src-backports/PartFile.h
--- ./src/PartFile.h	2011-10-16 00:43:21.000000000 +0900
+++ ./src-backports/PartFile.h	2012-08-03 22:08:38.000000000 +0900
@@ -259,6 +259,13 @@
 	 * @param client The source to be recorded as dead for this file.
 	 */
 	void		AddDeadSource(const CUpDownClient* client);
+	
+        /**
+	 * Set the current progress of hashing and display it in the download list control.
+	 *
+	 * @param part Number of part currently being hashed. 0 for no hashing in progress.
+	 */
+	virtual void SetHashingProgress(uint16 part) const;
 
 	/**
 	 * Checks if a source is recorded as being dead for this file.
diff -Nur ./src/PrefsUnifiedDlg.cpp ./src-backports/PrefsUnifiedDlg.cpp
--- ./src/PrefsUnifiedDlg.cpp	2011-10-09 09:19:08.000000000 +0900
+++ ./src-backports/PrefsUnifiedDlg.cpp	2012-08-03 22:08:38.000000000 +0900
@@ -252,6 +252,7 @@
 				FindWindow(IDC_MINTRAY)->Show(false);
 			#else
 				FindWindow(IDC_MACHIDEONCLOSE)->Show(false);
+				thePrefs::SetHideOnClose(false);
 			#endif
 		} else if (pages[i].m_function == PreferencesEventsTab) {
 
@@ -438,7 +439,7 @@
 
 	FindWindow(IDC_MACHIDEONCLOSE)->Enable(true);
 	FindWindow(IDC_EXIT)->Enable(!thePrefs::HideOnClose());
-	if (!thePrefs::HideOnClose()) {
+	if (thePrefs::HideOnClose()) {
 		CastChild(IDC_EXIT, wxCheckBox)->SetValue(false);
 	}
 
@@ -613,7 +614,11 @@
 		restart_needed = true;
 		restart_needed_msg += _("- External connect interface changed.\n");
 	}
-
+	if (CfgChanged(IDC_SUPPORT_PO)) {
+		restart_needed = true;
+		restart_needed_msg += _("- Protocol obfuscation support changed.\n");
+	}
+	
 	// Force port checking
 	thePrefs::SetPort(thePrefs::GetPort());
 
diff -Nur ./src/ServerList.cpp ./src-backports/ServerList.cpp
--- ./src/ServerList.cpp	2011-10-09 06:07:50.000000000 +0900
+++ ./src-backports/ServerList.cpp	2012-08-03 22:08:38.000000000 +0900
@@ -455,7 +455,7 @@
 		wxString line = f.ReadLine();
 		
 		// Skip comments
-		if ( line.GetChar(0) == '#' || line.GetChar(0) == '/') {
+		if (line.IsEmpty() || line.GetChar(0) == '#' || line.GetChar(0) == '/') {
 			continue;
 		}
 
diff -Nur ./src/SharedFileList.cpp ./src-backports/SharedFileList.cpp
--- ./src/SharedFileList.cpp	2011-09-19 04:29:33.000000000 +0900
+++ ./src-backports/SharedFileList.cpp	2012-08-03 22:08:38.000000000 +0900
@@ -626,10 +626,8 @@
 		CKnownFile *cur_file = pos->second;
 
 		if (dir.IsSameDir(cur_file->GetFilePath())) {
-			continue;
+			list.push_back(cur_file);
 		}
-
-		list.push_back(cur_file);
 	}
 }
 
diff -Nur ./src/Statistics.cpp ./src-backports/Statistics.cpp
--- ./src/Statistics.cpp	2011-06-13 17:50:25.000000000 +0900
+++ ./src-backports/Statistics.cpp	2012-08-03 22:22:16.000000000 +0900
@@ -1050,6 +1050,7 @@
 	s_statData[sdKadIndexedNotes] = stats->GetTagByNameSafe(EC_TAG_STATS_KAD_INDEXED_NOTES)->GetInt();
 	s_statData[sdKadIndexedLoad] = stats->GetTagByNameSafe(EC_TAG_STATS_KAD_INDEXED_LOAD)->GetInt();
 	s_statData[sdKadIPAdress] = stats->GetTagByNameSafe(EC_TAG_STATS_KAD_IP_ADRESS)->GetInt();
+	s_statData[sdKadNodes] = stats->GetTagByNameSafe(EC_TAG_STATS_KAD_NODES)->GetInt();
 	s_statData[sdBuddyStatus] = stats->GetTagByNameSafe(EC_TAG_STATS_BUDDY_STATUS)->GetInt();
 	s_statData[sdBuddyIP] = stats->GetTagByNameSafe(EC_TAG_STATS_BUDDY_IP)->GetInt();
 	s_statData[sdBuddyPort] = stats->GetTagByNameSafe(EC_TAG_STATS_BUDDY_PORT)->GetInt();
diff -Nur ./src/Statistics.h ./src-backports/Statistics.h
--- ./src/Statistics.h	2011-06-13 17:50:25.000000000 +0900
+++ ./src-backports/Statistics.h	2012-08-03 22:27:09.000000000 +0900
@@ -319,6 +319,7 @@
 	// Kad nodes
 	static void	AddKadNode()				{ ++s_kadNodesCur; }
 	static void	RemoveKadNode()				{ --s_kadNodesCur; }
+	static uint16_t GetKadNodes()			{ return s_kadNodesCur; }
 
 
 	// Other
@@ -499,6 +500,7 @@
 	sdKadIndexedNotes,
 	sdKadIndexedLoad,
 	sdKadIPAdress,
+	sdKadNodes,
 	sdBuddyStatus,
 	sdBuddyIP,
 	sdBuddyPort,
@@ -555,6 +557,7 @@
 	static	uint32	GetBuddyIP()			{ return s_statData[sdBuddyIP]; }
 	static	uint32	GetBuddyPort()			{ return s_statData[sdBuddyPort]; }
 	static	bool	IsKadRunningInLanMode()	{ return s_statData[sdKadInLanMode] != 0; }
+	static uint32 GetKadNodes()			{ return s_statData[sdKadNodes]; }
 
 	static	void	UpdateStats(const CECPacket* stats);
 
diff -Nur ./src/ThreadTasks.cpp ./src-backports/ThreadTasks.cpp
--- ./src/ThreadTasks.cpp	2011-08-28 05:28:32.000000000 +0900
+++ ./src-backports/ThreadTasks.cpp	2012-08-03 22:08:38.000000000 +0900
@@ -148,18 +148,22 @@
 	// This loops creates the part-hashes, loop-de-loop.
 	try {
 		for (uint16 part = 0; part < knownfile->GetPartCount() && !TestDestroy(); part++) {
+			SetHashingProgress(part + 1);
 			if (CreateNextPartHash(file, part, knownfile.get(), m_toHash) == false) {
 				AddDebugLogLineC(logHasher,
 					CFormat(wxT("Error while hashing file, skipping: %s"))
 						% m_filename);
 			
+				SetHashingProgress(0);
 				return;
 			}
 		}
 	} catch (const CSafeIOException& e) {
 		AddDebugLogLineC(logHasher, wxT("IO exception while hashing file: ") + e.what());
+		SetHashingProgress(0);
 		return;
 	}
+	SetHashingProgress(0);
 
 	if ((m_toHash & EH_MD4) && !TestDestroy()) {
 		// If the file is < PARTSIZE, then the filehash is that one hash,
@@ -203,6 +207,12 @@
 	}
 }
 
+void CHashingTask::SetHashingProgress(uint16 part)
+{
+	if (m_owner) {
+		m_owner->SetHashingProgress(part);
+	}
+}
 
 bool CHashingTask::CreateNextPartHash(CFileAutoClose& file, uint16 part, CKnownFile* owner, EHashes toHash)
 {
diff -Nur ./src/ThreadTasks.h ./src-backports/ThreadTasks.h
--- ./src/ThreadTasks.h	2011-06-13 17:50:25.000000000 +0900
+++ ./src-backports/ThreadTasks.h	2012-08-03 22:08:38.000000000 +0900
@@ -110,6 +110,9 @@
 	EHashes m_toHash;
 	//! If a partfile or an AICH hashing, this pointer stores it for callbacks.
 	const CKnownFile* m_owner;
+
+private:
+	void SetHashingProgress(uint16 part);
 };
 
 
diff -Nur ./src/amule-remote-gui.cpp ./src-backports/amule-remote-gui.cpp
--- ./src/amule-remote-gui.cpp	2011-09-19 01:02:10.000000000 +0900
+++ ./src-backports/amule-remote-gui.cpp	2012-08-03 22:08:38.000000000 +0900
@@ -1562,6 +1562,7 @@
 	tag->AvailablePartCount(&file->m_availablePartsCount);
 	tag->Shared(&file->m_isShared);
 	tag->A4AFAuto(file->m_is_A4AF_auto);
+	tag->HashingProgress(file->m_hashingProgress);
 
 	tag->GetLostDueToCorruption(&file->m_iLostDueToCorruption);
 	tag->GetGainDueToCompression(&file->m_iGainDueToCompression);
diff -Nur ./src/amule.cpp ./src-backports/amule.cpp
--- ./src/amule.cpp	2011-09-18 20:01:52.000000000 +0900
+++ ./src-backports/amule.cpp	2012-08-03 22:08:38.000000000 +0900
@@ -760,7 +760,7 @@
 	// This command just sets a flag to control maximum number of connections.
 	// Notify(true) has already been called to the ListenSocket, so events may
 	// be already comming in.
-	if (listensocket->Ok()) {
+	if (listensocket->IsOk()) {
 		listensocket->StartListening();
 	} else {
 		// If we wern't able to start listening, we need to warn the user
diff -Nur ./src/amuleDlg.cpp ./src-backports/amuleDlg.cpp
--- ./src/amuleDlg.cpp	2011-10-09 09:19:08.000000000 +0900
+++ ./src-backports/amuleDlg.cpp	2012-08-03 22:30:02.000000000 +0900
@@ -1125,6 +1125,7 @@
 			m_transferwnd->clientlistctrl->SortList();
 			m_sharedfileswnd->peerslistctrl->SortList();
 		}
+		m_kademliawnd->UpdateNodeCount(CStatistics::GetKadNodes());
 	}
 
 	if (msCur-msPrev1 > 1000) {  // every second
diff -Nur ./src/libs/common/FileFunctions.cpp ./src-backports/libs/common/FileFunctions.cpp
--- ./src/libs/common/FileFunctions.cpp	2011-06-13 17:50:25.000000000 +0900
+++ ./src-backports/libs/common/FileFunctions.cpp	2012-08-03 22:08:38.000000000 +0900
@@ -133,39 +133,32 @@
  */
 bool UnpackZipFile(const wxString& file, const wxChar* files[])
 {
-	wxZipFSHandler archive; 
-	wxString filename = archive.FindFirst(
-		wxT("file:") + file + wxT("#zip:/*"), wxFILE);
-	
 	wxTempFile target(file);
-
-	while (!filename.IsEmpty() && !target.Length()) {
-		// Extract the filename part of the URI
-		filename = filename.AfterLast(wxT(':')).Lower();
-	
+	std::auto_ptr<wxZipEntry> entry;
+	wxFFileInputStream fileInputStream(file);
+	wxZipInputStream zip(fileInputStream);
+	bool run = true;
+	while (run) {
+		entry.reset(zip.GetNextEntry());
+		if (entry.get() == NULL) {
+			break;
+		}
+		// access meta-data
+		wxString name = entry->GetName();
 		// We only care about the files specified in the array
-		for (size_t i = 0; files[i] && !target.Length(); ++i) {
-			if (files[i] == filename) {
-				std::auto_ptr<wxZipEntry> entry;
-				wxFFileInputStream fileInputStream(file);
-				wxZipInputStream zip(fileInputStream);
-				while (entry.reset(zip.GetNextEntry()), entry.get() != NULL) {
-					// access meta-data
-					wxString name = entry->GetName();
-					// read 'zip' to access the entry's data
-					if (name == filename) {
-						char buffer[10240];
-						while (!zip.Eof()) {
-							zip.Read(buffer, sizeof(buffer));
-							target.Write(buffer, zip.LastRead());
-						}						
-						break;
-					}
+		// probably needed to weed out included nfos
+		for (int i = 0; run && files[i]; i++) {
+			if (name.CmpNoCase(files[i]) == 0) {
+				// we found the entry we want
+				// read 'zip' to access the entry's data
+				char buffer[10240];
+				while (!zip.Eof()) {
+					zip.Read(buffer, sizeof(buffer));
+					target.Write(buffer, zip.LastRead());
 				}
+				run = false;
 			}
 		}
-
-		filename = archive.FindNext();
 	}
 	
 	if (target.Length()) {
diff -Nur ./src/libs/ec/abstracts/ECCodes.abstract ./src-backports/libs/ec/abstracts/ECCodes.abstract
--- ./src/libs/ec/abstracts/ECCodes.abstract	2011-11-12 04:28:46.000000000 +0900
+++ ./src-backports/libs/ec/abstracts/ECCodes.abstract	2012-08-03 22:32:59.000000000 +0900
@@ -204,6 +204,7 @@
 	EC_TAG_STATS_TOTAL_SENT_BYTES             0x0218
 	EC_TAG_STATS_TOTAL_RECEIVED_BYTES         0x0219
 	EC_TAG_STATS_SHARED_FILE_COUNT            0x021A
+	EC_TAG_STATS_KAD_NODES                    0x021B
 
 EC_TAG_PARTFILE                           0x0300
 	EC_TAG_PARTFILE_NAME                      0x0301
diff -Nur ./src/libs/ec/cpp/ECCodes.h ./src-backports/libs/ec/cpp/ECCodes.h
--- ./src/libs/ec/cpp/ECCodes.h	2011-11-12 04:28:46.000000000 +0900
+++ ./src-backports/libs/ec/cpp/ECCodes.h	2012-08-03 22:36:31.000000000 +0900
@@ -175,6 +175,7 @@
 		EC_TAG_STATS_TOTAL_SENT_BYTES             = 0x0218,
 		EC_TAG_STATS_TOTAL_RECEIVED_BYTES         = 0x0219,
 		EC_TAG_STATS_SHARED_FILE_COUNT            = 0x021A,
+ 		EC_TAG_STATS_KAD_NODES                    = 0x021B,
 	EC_TAG_PARTFILE                           = 0x0300,
 		EC_TAG_PARTFILE_NAME                      = 0x0301,
 		EC_TAG_PARTFILE_PARTMETID                 = 0x0302,
@@ -621,6 +622,7 @@
 		case 0x0218: return wxT("EC_TAG_STATS_TOTAL_SENT_BYTES");
 		case 0x0219: return wxT("EC_TAG_STATS_TOTAL_RECEIVED_BYTES");
 		case 0x021A: return wxT("EC_TAG_STATS_SHARED_FILE_COUNT");
+		case 0x021B: return wxT("EC_TAG_STATS_KAD_NODES");
 		case 0x0300: return wxT("EC_TAG_PARTFILE");
 		case 0x0301: return wxT("EC_TAG_PARTFILE_NAME");
 		case 0x0302: return wxT("EC_TAG_PARTFILE_PARTMETID");
diff -Nur ./src/libs/ec/cpp/ECSpecialTags.h ./src-backports/libs/ec/cpp/ECSpecialTags.h
--- ./src/libs/ec/cpp/ECSpecialTags.h	2011-06-13 17:50:25.000000000 +0900
+++ ./src-backports/libs/ec/cpp/ECSpecialTags.h	2012-08-03 22:08:38.000000000 +0900
@@ -268,6 +268,7 @@
 		uint16		AvailablePartCount(uint16 *target = 0) const { return AssignIfExist(EC_TAG_PARTFILE_AVAILABLE_PARTS, target); }
  		bool		Shared(bool *target = 0)		const { return AssignIfExist(EC_TAG_PARTFILE_SHARED, target); }
  		bool		A4AFAuto(bool &target)			const { return AssignIfExist(EC_TAG_PARTFILE_A4AFAUTO, target); }
+ 		bool            HashingProgress(uint16 &target) const { return AssignIfExist(EC_TAG_PARTFILE_HASHED_PART_COUNT, target); }
 
 		uint64		GetLostDueToCorruption(uint64 *target = 0) const { return AssignIfExist(EC_TAG_PARTFILE_LOST_CORRUPTION, target); }
 		uint64		GetGainDueToCompression(uint64 *target = 0) const { return AssignIfExist(EC_TAG_PARTFILE_GAINED_COMPRESSION, target); }
diff -Nur ./src/libs/ec/java/ECCodes.java ./src-backports/libs/ec/java/ECCodes.java
--- ./src/libs/ec/java/ECCodes.java	2011-11-12 04:28:46.000000000 +0900
+++ ./src-backports/libs/ec/java/ECCodes.java	2012-08-03 22:38:20.000000000 +0900
@@ -163,6 +163,7 @@
 public final static short 	EC_TAG_STATS_TOTAL_SENT_BYTES             = 0x0218;
 public final static short 	EC_TAG_STATS_TOTAL_RECEIVED_BYTES         = 0x0219;
 public final static short 	EC_TAG_STATS_SHARED_FILE_COUNT            = 0x021A;
+public final static short	EC_TAG_STATS_KAD_NODES                    = 0x021B;
 public final static short EC_TAG_PARTFILE                           = 0x0300;
 public final static short 	EC_TAG_PARTFILE_NAME                      = 0x0301;
 public final static short 	EC_TAG_PARTFILE_PARTMETID                 = 0x0302;