EnableExplicit ; Вызывается когда пир сообщает что он заинтерисован в нас ; и если мы его разблокируем, то он будет качать от нас. Procedure Peer_Upload_New(*Local_TorrentList.Core_Torrent) Protected CountInterestedPeer, ListPos ListPos = ListIndex(*Local_TorrentList\TorrentList()\Network\PeerList()) If ListPos>=0 CountInterestedPeer=0 ForEach *Local_TorrentList\TorrentList()\Network\PeerList() If *Local_TorrentList\TorrentList()\Network\PeerList()\Peer_Status\Interested = #True CountInterestedPeer + 1 EndIf Next If CountInterestedPeer < G_ProgramSetting\Lan\SlotTorrent ; Не превышено число слотов раздачи на торрент. SelectElement(*Local_TorrentList\TorrentList()\Network\PeerList(), ListPos) If Peer_SendMessage(*Local_TorrentList, #Peer_Message_UnChoke) *Local_TorrentList\TorrentList()\Network\PeerList()\MyStatus\Choke = #False ; Наш клиент не блокирует того клиента. EndIf EndIf SelectElement(*Local_TorrentList\TorrentList()\Network\PeerList(), ListPos) EndIf EndProcedure Structure Peer_Upload_Refresh_Info Total_InBytes.q ; Общее число байт, полученое от этого пира. ConnectID.i ; Идентификатор связит с пиром. Number.l ; Норем пира в списке. EndStructure Procedure Peer_Upload_Refresh_SetPeer(*Local_TorrentList.Core_Torrent, List PeerList.Peer_Upload_Refresh_Info(), MaxCount) ; Сообщаем пирам что они могут качать или не могут это делать. Protected Temp Temp=0 ForEach PeerList() SelectElement(*Local_TorrentList\TorrentList()\Network\PeerList(), PeerList()\Number) If Temp < MaxCount If *Local_TorrentList\TorrentList()\Network\PeerList()\MyStatus\Choke=#True If Peer_SendMessage(*Local_TorrentList, #Peer_Message_UnChoke) *Local_TorrentList\TorrentList()\Network\PeerList()\MyStatus\Choke=#False EndIf EndIf Else If *Local_TorrentList\TorrentList()\Network\PeerList()\MyStatus\Choke=#False If Peer_SendMessage(*Local_TorrentList, #Peer_Message_Choke) *Local_TorrentList\TorrentList()\Network\PeerList()\MyStatus\Choke=#True EndIf EndIf EndIf Temp+1 Next EndProcedure Procedure Peer_Upload_Refresh(*Local_TorrentList.Core_Torrent) ; Вызывается раз в 10 секунд и определяет какие пиры будут качать от нашего клиента. Protected CurrentCount, MaxCount, Temp, rd Protected NewList PeerList.Peer_Upload_Refresh_Info(), Struct.Peer_Upload_Refresh_Info Protected i Static State.a CurrentCount=0 : Temp=0 MaxCount = G_ProgramSetting\Lan\SlotTorrent ForEach *Local_TorrentList\TorrentList()\Network\PeerList() If *Local_TorrentList\TorrentList()\Network\PeerList()\ConnectID If *Local_TorrentList\TorrentList()\Network\PeerList()\Peer_Status\Interested=#True If AddElement(PeerList()) PeerList()\Total_InBytes = *Local_TorrentList\TorrentList()\Network\PeerList()\Total_InBytes PeerList()\ConnectID = *Local_TorrentList\TorrentList()\Network\PeerList()\ConnectID PeerList()\Number = Temp CurrentCount+1 ; Этоn пир в нас заинтерисован. EndIf EndIf EndIf Temp+1 Next If ListSize(PeerList())>0 If CurrentCount > MaxCount ; Пиров, хотящих скачать, больше чем слотов раздачи. If *Local_TorrentList\TorrentList()\TorrentStatus = #TorrentStatus_Load If State<=2 ; Будем отдавать только тем, кто больше всего нам отдал. CompilerIf #PB_Compiler_Version<520 SortStructuredList(PeerList(), #PB_Sort_Descending, OffsetOf(Peer_Upload_Refresh_Info\Total_InBytes), #PB_Sort_Quad) CompilerElse SortStructuredList(PeerList(), #PB_Sort_Descending, OffsetOf(Peer_Upload_Refresh_Info\Total_InBytes), #PB_Quad) CompilerEndIf SelectElement(PeerList(), 0) If PeerList()\Total_InBytes>0 Peer_Upload_Refresh_SetPeer(*Local_TorrentList, PeerList(), MaxCount) ; Сообщаем пирам что они могут качать или не могут это делать. Else ; Ни один пир не прислал нам данные. Goto Peer_Upload_Refresh_M1 EndIf State+1 Else State=0 Goto Peer_Upload_Refresh_M1 EndIf Else Peer_Upload_Refresh_M1: rd = Random(100) For i=0 To rd Temp=Random(CurrentCount-1) SelectElement(PeerList(), Temp) Struct\Total_InBytes = PeerList()\Total_InBytes Struct\ConnectID = PeerList()\ConnectID Struct\Number = PeerList()\Number DeleteElement(PeerList()) Temp=Random(CurrentCount-2) SelectElement(PeerList(), Temp) If InsertElement(PeerList()) PeerList()\Total_InBytes = Struct\Total_InBytes PeerList()\ConnectID = Struct\ConnectID PeerList()\Number = Struct\Number Else Break EndIf Next i Peer_Upload_Refresh_SetPeer(*Local_TorrentList, PeerList(), MaxCount) ; Сообщаем пирам что они могут качать или не могут это делать. EndIf Else Peer_Upload_Refresh_SetPeer(*Local_TorrentList, PeerList(), MaxCount) EndIf EndIf EndProcedure Procedure Peer_Upload_RandomConnect(*Local_TorrentList.Core_Torrent) ; Выбор проихвольного пира для конекта с ним чтобы раздать ему торрент. Protected SizeList, x, ListPos, Pos Protected CountInterestedPeer, CountPiece If *Local_TorrentList\TorrentList()\TorrentStatus = #TorrentStatus_Seed SizeList=ListSize(*Local_TorrentList\TorrentList()\Network\PeerList()) If SizeList>0 ListPos = ListIndex(*Local_TorrentList\TorrentList()\Network\PeerList()) CountInterestedPeer=0 ForEach *Local_TorrentList\TorrentList()\Network\PeerList() If *Local_TorrentList\TorrentList()\Network\PeerList()\Peer_Status\Interested = #True CountInterestedPeer + 1 EndIf Next If *Local_TorrentList\TorrentList()\Network\CountActivePeer < G_ProgramSetting\Lan\MaxConnect / 2 And *Local_TorrentList\TorrentList()\Network\CountActivePeer < G_ProgramSetting\Lan\MaxPeer / 2 And CountInterestedPeer < G_ProgramSetting\Lan\SlotTorrent CountPiece = *Local_TorrentList\TorrentList()\Torrent\CountPiece x=0 Repeat Pos = Random(SizeList-1) SelectElement(*Local_TorrentList\TorrentList()\Network\PeerList(), Pos) If *Local_TorrentList\TorrentList()\Network\PeerList()\ConnectID = 0 If *Local_TorrentList\TorrentList()\Network\PeerList()\Err_ConnectCount < #Peer_MaxErrConnect ; Пир вообще доступен? Предыдущие конекты были успешны! If Peer_ConnectTime(*Local_TorrentList) If *Local_TorrentList\TorrentList()\Network\PeerList()\Peer_ConnectStatus = #True ; Раньше этот пир уже был подключен и проходил процедуру "рукопожатия". ; Раз он раньше был подключен, то скорее всего прислал данные об имеющихся у него частях. If Torrent_CountPiece(*Local_TorrentList\TorrentList()\Network\PeerList()\MapPiece(), CountPiece)>=CountPiece Goto Peer_Upload_RandomConnect_M1 ; У клиента есть весь торрент и нет смысла с ним устанавливать соединение. EndIf EndIf If *Local_TorrentList\TorrentList()\Network\PeerList()\Time_UploadNoConnect>0 If *Local_TorrentList\Info\Current_Time - *Local_TorrentList\TorrentList()\Network\PeerList()\Time_UploadNoConnect < 0 Goto Peer_Upload_RandomConnect_M1 EndIf EndIf ; Устанавливаем подключение к пиру. Peer_AddConnectPeer(*Local_TorrentList, 0) Break EndIf EndIf EndIf Peer_Upload_RandomConnect_M1: x+1 Until x>=10 EndIf If ListPos>=0 SelectElement(*Local_TorrentList\TorrentList()\Network\PeerList(), ListPos) EndIf EndIf EndIf EndProcedure DisableExplicit ; IDE Options = PureBasic 5.11 (Windows - x86) ; Folding = - ; EnableXP