mirror of
https://github.com/lkddi/nexusphp.git
synced 2026-04-14 12:30:49 +08:00
announce handle dual
This commit is contained in:
@@ -34,6 +34,10 @@ class TrackerRepository extends BaseRepository
|
|||||||
const MUST_BE_CHEATER_SPEED = 1024 * 1024 * 1024; //1024 MB/s
|
const MUST_BE_CHEATER_SPEED = 1024 * 1024 * 1024; //1024 MB/s
|
||||||
const MAY_BE_CHEATER_SPEED = 1024 * 1024 * 100; //100 MB/s
|
const MAY_BE_CHEATER_SPEED = 1024 * 1024 * 100; //100 MB/s
|
||||||
|
|
||||||
|
const ANNOUNCE_FIRST = 0;
|
||||||
|
const ANNOUNCE_DUAL = 1;
|
||||||
|
const ANNOUNCE_DUPLICATE = 2;
|
||||||
|
|
||||||
// Port Blacklist
|
// Port Blacklist
|
||||||
protected const BLACK_PORTS = [
|
protected const BLACK_PORTS = [
|
||||||
22, // SSH Port
|
22, // SSH Port
|
||||||
@@ -63,8 +67,8 @@ class TrackerRepository extends BaseRepository
|
|||||||
$user = $this->checkUser($request);
|
$user = $this->checkUser($request);
|
||||||
$clientAllow = $this->checkClient($request);
|
$clientAllow = $this->checkClient($request);
|
||||||
$torrent = $this->checkTorrent($queries, $user);
|
$torrent = $this->checkTorrent($queries, $user);
|
||||||
if ($this->isReAnnounce($request, $queries['ip']) === false) {
|
$isReAnnounce = $this->isReAnnounce($request);
|
||||||
$withPeers = true;
|
if ($isReAnnounce < self::ANNOUNCE_DUPLICATE) {
|
||||||
/** @var Peer $peerSelf */
|
/** @var Peer $peerSelf */
|
||||||
$peerSelf = $this->checkMinInterval($torrent, $queries, $user);
|
$peerSelf = $this->checkMinInterval($torrent, $queries, $user);
|
||||||
$isPeerExists = true;
|
$isPeerExists = true;
|
||||||
@@ -91,32 +95,36 @@ class TrackerRepository extends BaseRepository
|
|||||||
$this->checkCheater($torrent, $dataTraffic, $user, $peerSelf);
|
$this->checkCheater($torrent, $dataTraffic, $user, $peerSelf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Note: Must update snatch first, otherwise peer `last_action` already change
|
|
||||||
*/
|
|
||||||
$snatch = $this->updateSnatch($peerSelf, $queries, $dataTraffic);
|
|
||||||
if ($queries['event'] == 'completed') {
|
|
||||||
$this->handleHitAndRun($user, $torrent, $snatch);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Note: Must update peer first, otherwise updateTorrent() count peer not correct
|
* Note: Must update peer first, otherwise updateTorrent() count peer not correct
|
||||||
|
* Update: Will not change $peerSelf any more
|
||||||
*/
|
*/
|
||||||
$this->updatePeer($peerSelf, $queries);
|
$this->updatePeer($peerSelf, $queries);
|
||||||
|
|
||||||
$this->updateTorrent($torrent, $queries, $isPeerExists);
|
if ($isReAnnounce === self::ANNOUNCE_FIRST) {
|
||||||
|
$withPeers = true;
|
||||||
|
/**
|
||||||
|
* Note: Must update snatch first, otherwise peer `last_action` already change
|
||||||
|
*/
|
||||||
|
$snatch = $this->updateSnatch($peerSelf, $queries, $dataTraffic);
|
||||||
|
if ($queries['event'] == 'completed') {
|
||||||
|
$this->handleHitAndRun($user, $torrent, $snatch);
|
||||||
|
}
|
||||||
|
|
||||||
if ($dataTraffic['uploaded_increment_for_user'] > 0) {
|
$this->updateTorrent($torrent, $queries, $isPeerExists);
|
||||||
$this->userUpdates['uploaded'] = DB::raw('uploaded + ' . $dataTraffic['uploaded_increment_for_user']);
|
|
||||||
}
|
if ($dataTraffic['uploaded_increment_for_user'] > 0) {
|
||||||
if ($dataTraffic['downloaded_increment_for_user'] > 0) {
|
$this->userUpdates['uploaded'] = DB::raw('uploaded + ' . $dataTraffic['uploaded_increment_for_user']);
|
||||||
$this->userUpdates['downloaded'] = DB::raw('downloaded + ' . $dataTraffic['downloaded_increment_for_user']);
|
}
|
||||||
}
|
if ($dataTraffic['downloaded_increment_for_user'] > 0) {
|
||||||
if ($user->clientselect != $clientAllow->id) {
|
$this->userUpdates['downloaded'] = DB::raw('downloaded + ' . $dataTraffic['downloaded_increment_for_user']);
|
||||||
$this->userUpdates['clientselect'] = $clientAllow->id;
|
}
|
||||||
}
|
if ($user->clientselect != $clientAllow->id) {
|
||||||
if ($user->showclienterror == 'yes') {
|
$this->userUpdates['clientselect'] = $clientAllow->id;
|
||||||
$this->userUpdates['showclienterror'] = 'no';
|
}
|
||||||
|
if ($user->showclienterror == 'yes') {
|
||||||
|
$this->userUpdates['showclienterror'] = 'no';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$repDict = $this->generateSuccessAnnounceResponse($torrent, $queries, $user, $withPeers);
|
$repDict = $this->generateSuccessAnnounceResponse($torrent, $queries, $user, $withPeers);
|
||||||
@@ -133,15 +141,8 @@ class TrackerRepository extends BaseRepository
|
|||||||
do_log("[" . get_class($exception) . "] " . $exception->getMessage() . "\n" . $exception->getTraceAsString(), 'error');
|
do_log("[" . get_class($exception) . "] " . $exception->getMessage() . "\n" . $exception->getTraceAsString(), 'error');
|
||||||
$repDict = $this->generateFailedAnnounceResponse("system error, report to sysop please, hint: " . nexus()->getRequestId());
|
$repDict = $this->generateFailedAnnounceResponse("system error, report to sysop please, hint: " . nexus()->getRequestId());
|
||||||
} finally {
|
} finally {
|
||||||
if (isset($user) && count($this->userUpdates)) {
|
if (isset($user)) {
|
||||||
$user->fill($this->userUpdates);
|
$this->updateUser($user);
|
||||||
$willBeUpdate = "[USER_ACTUAL_UPDATE] user: " . $user->id;
|
|
||||||
foreach ($user->getDirty() as $key => $value) {
|
|
||||||
$willBeUpdate .= ", $key = $value";
|
|
||||||
}
|
|
||||||
do_log($willBeUpdate);
|
|
||||||
$user->save();
|
|
||||||
do_log(last_query());
|
|
||||||
}
|
}
|
||||||
return $this->sendFinalAnnounceResponse($repDict);
|
return $this->sendFinalAnnounceResponse($repDict);
|
||||||
}
|
}
|
||||||
@@ -548,21 +549,29 @@ class TrackerRepository extends BaseRepository
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function isReAnnounce(Request $request, $ip): bool
|
protected function isReAnnounce(Request $request): int
|
||||||
{
|
{
|
||||||
$key = $request->query->get('key');
|
$key = $request->query->get('key');
|
||||||
$queryString = $request->getQueryString();
|
$queryString = $request->getQueryString();
|
||||||
$lockKeyOriginal = str_replace($key, '', $queryString);
|
$lockKeyOriginal = str_replace($key, '', $queryString);
|
||||||
$lockKeyOriginal .= "&__ip=" . $ip;
|
|
||||||
$lockKey = md5($lockKeyOriginal);
|
$lockKey = md5($lockKeyOriginal);
|
||||||
$startTimestamp = nexus()->getStartTimestamp();
|
$startTimestamp = nexus()->getStartTimestamp();
|
||||||
do_log("key: $key, queryString: $queryString, lockKeyOriginal: $lockKeyOriginal, startTimestamp: $startTimestamp");
|
do_log("key: $key, queryString: $queryString, lockKeyOriginal: $lockKeyOriginal, startTimestamp: $startTimestamp");
|
||||||
$redis = Redis::connection()->client();
|
$redis = Redis::connection()->client();
|
||||||
if (!$redis->set($lockKey, $startTimestamp, ['nx', 'ex' => 5])) {
|
$cache = $redis->get($lockKey);
|
||||||
do_log('[RE_ANNOUNCE]');
|
if ($cache === false) {
|
||||||
return true;
|
//new request
|
||||||
|
$redis->set($lockKey, $startTimestamp, ['ex' => self::MIN_ANNOUNCE_WAIT_SECOND]);
|
||||||
|
return self::ANNOUNCE_FIRST;
|
||||||
|
} else {
|
||||||
|
if (bcsub($startTimestamp, $cache, 3) < 0.5) {
|
||||||
|
do_log('[DUAL]');
|
||||||
|
return self::ANNOUNCE_DUAL;
|
||||||
|
} else {
|
||||||
|
do_log('[RE_ANNOUNCE]');
|
||||||
|
return self::ANNOUNCE_DUPLICATE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function generateSuccessAnnounceResponse($torrent, $queries, $user, $withPeers = true): array
|
private function generateSuccessAnnounceResponse($torrent, $queries, $user, $withPeers = true): array
|
||||||
@@ -728,6 +737,7 @@ class TrackerRepository extends BaseRepository
|
|||||||
*
|
*
|
||||||
* @param Torrent $torrent
|
* @param Torrent $torrent
|
||||||
* @param $queries
|
* @param $queries
|
||||||
|
* @param bool $isPeerExists
|
||||||
*/
|
*/
|
||||||
private function updateTorrent(Torrent $torrent, $queries, bool $isPeerExists)
|
private function updateTorrent(Torrent $torrent, $queries, bool $isPeerExists)
|
||||||
{
|
{
|
||||||
@@ -940,15 +950,8 @@ class TrackerRepository extends BaseRepository
|
|||||||
do_log("[" . get_class($exception) . "] " . $exception->getMessage() . "\n" . $exception->getTraceAsString(), 'error');
|
do_log("[" . get_class($exception) . "] " . $exception->getMessage() . "\n" . $exception->getTraceAsString(), 'error');
|
||||||
$repDict = $this->generateFailedAnnounceResponse("system error, report to sysop please, hint: " . nexus()->getRequestId());
|
$repDict = $this->generateFailedAnnounceResponse("system error, report to sysop please, hint: " . nexus()->getRequestId());
|
||||||
} finally {
|
} finally {
|
||||||
if (isset($user) && count($this->userUpdates)) {
|
if (isset($user)) {
|
||||||
$user->fill($this->userUpdates);
|
$this->updateUser($user);
|
||||||
$willBeUpdate = "[USER_ACTUAL_UPDATE] user: " . $user->id;
|
|
||||||
foreach ($user->getDirty() as $key => $value) {
|
|
||||||
$willBeUpdate .= ", $key = $value";
|
|
||||||
}
|
|
||||||
do_log($willBeUpdate);
|
|
||||||
$user->save();
|
|
||||||
do_log(last_query());
|
|
||||||
}
|
}
|
||||||
return $this->sendFinalAnnounceResponse($repDict);
|
return $this->sendFinalAnnounceResponse($repDict);
|
||||||
}
|
}
|
||||||
@@ -1030,4 +1033,13 @@ class TrackerRepository extends BaseRepository
|
|||||||
DB::insert($sql);
|
DB::insert($sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function updateUser(User $user)
|
||||||
|
{
|
||||||
|
if (count($this->userUpdates) === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$user->save($this->userUpdates);
|
||||||
|
do_log(last_query());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user