📄 pepeercontrolimpl.java
字号:
throws Exception
{
if (data_offset % 16384L != 0L)
throw new Exception("data must start at a block offset");
int piece_length = disk_mgr.getPieceLength();
int data_length = 0;
DirectByteBuffer arr$[] = data;
int len$ = arr$.length;
for (int i$ = 0; i$ < len$; i$++)
{
DirectByteBuffer buffer = arr$[i$];
data_length += buffer.remaining((byte)8);
}
long written = 0L;
int buffer_number = 0;
int i = 0;
do
{
if (i >= data_length)
break;
int rem = data_length - i;
if (rem > 16384)
rem = 16384;
int piece_number = (int)(data_offset / (long)piece_length);
DiskManagerPiece dm_piece = dm_pieces[piece_number];
int block_number = (int)(data_offset - (long)(piece_number * piece_length)) / 16384;
int block_size = dm_piece.getBlockSize(block_number);
if (rem < block_size)
break;
DirectByteBuffer chunk = DirectByteBufferPool.getBuffer((byte)9, block_size);
writeBlock(piece_number, block_number * 16384, chunk, null, true);
written += rem;
data_offset += rem;
i += 16384;
} while (true);
List unwritten = new ArrayList();
for (int i = buffer_number; i < data.length; i++)
if (data[i].hasRemaining((byte)8))
unwritten.add(data[i]);
else
data[i].returnToPool();
return (DirectByteBuffer[])unwritten.toArray(new DirectByteBuffer[unwritten.size()]);
}
public void writeBlock(int pieceNumber, int offset, DirectByteBuffer data, PEPeer sender, boolean cancel)
{
int blockNumber = offset / 16384;
DiskManagerPiece dmPiece = dm_pieces[pieceNumber];
if (dmPiece.isWritten(blockNumber))
{
data.returnToPool();
return;
}
PEPiece pe_piece = pePieces[pieceNumber];
if (pe_piece != null)
pe_piece.setDownloaded(offset);
DiskManagerWriteRequest request = disk_mgr.createWriteRequest(pieceNumber, offset, data, sender);
disk_mgr.enqueueWriteRequest(request, this);
if (piecePicker.isInEndGameMode())
piecePicker.removeFromEndGameModeChunks(pieceNumber, offset);
if (cancel || piecePicker.isInEndGameMode())
{
ArrayList peer_transports = peer_transports_cow;
for (int i = 0; i < peer_transports.size(); i++)
{
PEPeerTransport connection = (PEPeerTransport)peer_transports.get(i);
DiskManagerReadRequest dmr = disk_mgr.createReadRequest(pieceNumber, offset, dmPiece.getBlockSize(blockNumber));
connection.sendCancel(dmr);
}
}
}
public boolean isWritten(int piece_number, int offset)
{
return dm_pieces[piece_number].isWritten(offset / 16384);
}
public boolean validateReadRequest(PEPeerTransport originator, int pieceNumber, int offset, int length)
{
if (disk_mgr.checkBlockConsistencyForRead(originator.getIp(), pieceNumber, offset, length))
{
if (enable_seeding_piece_rechecks && isSeeding())
{
DiskManagerPiece dm_piece = dm_pieces[pieceNumber];
int read_count = dm_piece.getReadCount() & 0xffff;
if (read_count < 65525)
{
read_count++;
dm_piece.setReadCount((short)read_count);
}
}
return true;
} else
{
return false;
}
}
public boolean validateHintRequest(PEPeerTransport originator, int pieceNumber, int offset, int length)
{
return disk_mgr.checkBlockConsistencyForHint(originator.getIp(), pieceNumber, offset, length);
}
public boolean validatePieceReply(PEPeerTransport originator, int pieceNumber, int offset, DirectByteBuffer data)
{
return disk_mgr.checkBlockConsistencyForWrite(originator.getIp(), pieceNumber, offset, data);
}
public int getAvailability(int pieceNumber)
{
return piecePicker.getAvailability(pieceNumber);
}
public void havePiece(int pieceNumber, int pieceLength, PEPeer pcOrigin)
{
piecePicker.addHavePiece(pcOrigin, pieceNumber);
_stats.haveNewPiece(pieceLength);
if (superSeedMode)
{
superSeedPieces[pieceNumber].peerHasPiece(pcOrigin);
if (pieceNumber == pcOrigin.getUniqueAnnounce())
{
pcOrigin.setUniqueAnnounce(-1);
superSeedModeNumberOfAnnounces--;
}
}
int availability = piecePicker.getAvailability(pieceNumber) - 1;
if (availability < 4)
{
if (dm_pieces[pieceNumber].isDone())
availability--;
if (availability <= 0)
return;
ArrayList peer_transports = peer_transports_cow;
for (int i = peer_transports.size() - 1; i >= 0; i--)
{
PEPeerTransport pc = (PEPeerTransport)peer_transports.get(i);
if (pc != pcOrigin && pc.getPeerState() == 30 && pc.isPieceAvailable(pieceNumber))
((PEPeerStatsImpl)pc.getStats()).statisticalSentPiece(pieceLength / availability);
}
}
}
public int getPieceLength(int pieceNumber)
{
return disk_mgr.getPieceLength(pieceNumber);
}
public int getNbPeers()
{
return _peers;
}
public int getNbSeeds()
{
return _seeds;
}
public int getNbRemoteConnectionsExcludingUDP()
{
return _remotesNoUdpNoLan;
}
public long getLastRemoteConnectionTime()
{
return last_remote_time;
}
public PEPeerManagerStats getStats()
{
return _stats;
}
public int getNbPeersStalledPendingLoad()
{
int res = 0;
Iterator it = peer_transports_cow.iterator();
do
{
if (!it.hasNext())
break;
PEPeerTransport transport = (PEPeerTransport)it.next();
if (transport.isStalledPendingLoad())
res++;
} while (true);
return res;
}
public long getETA()
{
long now = SystemTime.getCurrentTime();
if (now < last_eta_calculation || now - last_eta_calculation > 900L)
{
long dataRemaining = disk_mgr.getRemainingExcludingDND();
if (dataRemaining > 0L)
{
int writtenNotChecked = 0;
for (int i = 0; i < _nbPieces; i++)
if (dm_pieces[i].isInteresting())
writtenNotChecked += dm_pieces[i].getNbWritten() * 16384;
dataRemaining -= writtenNotChecked;
if (dataRemaining < 0L)
dataRemaining = 0L;
}
long result;
if (dataRemaining == 0L)
{
long timeElapsed = (_timeFinished - _timeStarted) / 1000L;
if (timeElapsed > 1L)
result = timeElapsed * -1L;
else
result = 0L;
} else
{
long averageSpeed = _averageReceptionSpeed.getAverage();
long lETA = averageSpeed != 0L ? dataRemaining / averageSpeed : 0x6cebb800L;
if (lETA == 0L)
lETA = 1L;
result = lETA;
}
last_eta = result;
last_eta_calculation = now;
}
return last_eta;
}
public boolean isRTA()
{
return piecePicker.getRTAProviders().size() > 0;
}
private void addToPeerTransports(PEPeerTransport peer)
{
boolean added = false;
peer_transports_mon.enter();
if (peer.getPeerState() == 50)
{
peer_transports_mon.exit();
return;
}
if (!peer_transports_cow.contains(peer))
break MISSING_BLOCK_LABEL_53;
Debug.out("Transport added twice");
peer_transports_mon.exit();
return;
List limiters;
if (is_running)
{
ArrayList new_peer_transports = new ArrayList(peer_transports_cow.size() + 1);
new_peer_transports.addAll(peer_transports_cow);
new_peer_transports.add(peer);
peer_transports_cow = new_peer_transports;
added = true;
}
limiters = external_rate_limiters_cow;
peer_transports_mon.exit();
break MISSING_BLOCK_LABEL_130;
Exception exception;
exception;
peer_transports_mon.exit();
throw exception;
if (added)
{
if (peer.isIncoming())
{
long connect_time = SystemTime.getCurrentTime();
if (connect_time > last_remote_time)
last_remote_time = connect_time;
}
if (limiters != null)
{
for (int i = 0; i < limiters.size(); i++)
{
Object entry[] = (Object[])(Object[])limiters.get(i);
peer.addRateLimiter((LimitedRateGroup)entry[0], ((Boolean)entry[1]).booleanValue());
}
}
peerAdded(peer);
} else
{
peer.closeConnection("PeerTransport added when manager not running");
}
return;
}
public void addRateLimiter(LimitedRateGroup group, boolean upload)
{
List transports;
peer_transports_mon.enter();
ArrayList new_limiters = new ArrayList(external_rate_limiters_cow != null ? external_rate_limiters_cow.size() + 1 : 1);
if (external_rate_limiters_cow != null)
new_limiters.addAll(external_rate_limiters_cow);
new_limiters.add(((Object) (new Object[] {
group, new Boolean(upload)
})));
external_rate_limiters_cow = new_limiters;
transports = peer_transports_cow;
peer_transports_mon.exit();
break MISSING_BLOCK_LABEL_113;
Exception exception;
exception;
peer_transports_mon.exit();
throw exception;
for (int i = 0; i < transports.size(); i++)
((PEPeer)transports.get(i)).addRateLimiter(group, upload);
return;
}
public void removeRateLimiter(LimitedRateGroup group, boolean upload)
{
List transports;
peer_transports_mon.enter();
if (external_rate_limiters_cow != null)
{
ArrayList new_limiters = new ArrayList(external_rate_limiters_cow.size() - 1);
for (int i = 0; i < external_rate_limiters_cow.size(); i++)
{
Object entry[] = (Object[])(Object[])external_rate_limiters_cow.get(i);
if (entry[0] != group)
new_limiters.add(((Object) (entry)));
}
if (new_limiters.size() == 0)
external_rate_limiters_cow = null;
else
external_rate_limiters_cow = new_limiters;
}
transports = peer_transports_cow;
peer_transports_mon.exit();
break MISSING_BLOCK_LABEL_141;
Exception exception;
exception;
peer_transports_mon.exit();
throw exception;
for (int i = 0; i < transports.size(); i++)
((PEPeerTransport)transports.get(i)).removeRateLimiter(group, upload);
return;
}
public int getUploadRateLimitBytesPerSecond()
{
return adapter.getUploadRateLimitBytesPerSecond();
}
public int getDownloadRateLimitBytesPerSecond()
{
return adapter.getDownloadRateLimitBytesPerSecond();
}
public void peerConnectionClosed(PEPeerTransport peer, boolean connect_failed, boolean network_failed)
{
boolean connection_found;
boolean tcpReconnect;
connection_found = false;
tcpReconnect = false;
peer_transports_mon.enter();
int udpPort = peer.getUDPListenPort();
boolean canTryUDP = UDPNetworkManager.UDP_OUTGOING_ENABLED && peer.getUDPListenPort() > 0;
if (is_running)
{
PeerItem peer_item = peer.getPeerItemIdentity();
PeerItem self_item = peer_database.getSelfPeer();
if (self_item == null || !self_item.equals(peer_item))
{
String ip = peer.getIp();
String key = (new StringBuilder()).append(ip).append(":").append(udpPort).toString();
if (peer.isTCP())
{
if (connect_failed)
{
if (canTryUDP && udp_fallback_for_failed_connection)
pending_nat_traversals.put(key, peer);
} else
if (canTryUDP && udp_fallback_for_dropped_connection && network_failed && seeding_mode && peer.isInterested() && !peer.isSeed() && !peer.isRelativeSeed() && peer.getStats().getEstimatedSecondsToCompletion() > 60L && FeatureAvailability.isUDPPeerReconnectEnabled())
{
if (Logger.isEnabled())
Logger.log(new LogEvent(peer, LOGID, 1, "Unexpected stream closure detected, attempting recovery"));
udp_reconnects.put(key, peer);
} else
if (network_failed && peer.isSafeForReconnect() && (!seeding_mode || !peer.isSeed() && !peer.isRelativeSeed() && peer.getStats().getEstimatedSecondsToCompletion() >= 60L) && getMaxConnections() > 0 && getMaxNewConnectionsAllowed() > getMaxConnections() / 3 && FeatureAvailability.isGeneralPeerReconnectEnabled())
tcpReconnect = true;
} else
if (connect_failed && udp_fallback_for_failed_connection && peer.getData(PEER_NAT_TRAVERSE_DONE_KEY) == null)
pending_nat_traversals.put(key, peer);
}
}
if (peer_transports_cow.contains(peer))
{
ArrayList new_peer_transports = new ArrayList(peer_transports_cow);
new_peer_transports.remove(peer);
peer_transports_cow = new_peer_transports;
connection_found = true;
}
peer_transports_mon.exit();
break MISSING_BLOCK_LABEL_455;
Exception exception;
exception;
peer_transports_mon.exit();
throw exception;
if (connection_found)
{
if (peer.getPeerState() != 50)
System.out.println((new StringBuilder()).append("peer.getPeerState() != PEPeer.DISCONNECTED: ").append(peer.getPeerState()).toString());
peerRemoved(peer);
}
if (tcpReconnect)
peer.reconnect(false);
return;
}
public void peerAdded(PEPeer pc)
{
adapter.addPeer(pc);
ArrayList peer_manager_listeners = peer_manager_listeners_cow;
for (int i = 0; i < peer_manager_listeners.size(); i++)
((PEPeerManagerListener)peer_manager_listeners.get(i)).peerAdded(this, pc);
}
public void peerRemoved(PEPeer pc)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -