finish seed box basic

This commit is contained in:
xiaomlove
2022-07-23 15:05:32 +08:00
parent b507c41bf0
commit 42bf8f0467
32 changed files with 644 additions and 249 deletions
+89 -7
View File
@@ -1,12 +1,16 @@
<?php
namespace App\Repositories;
use App\Exceptions\InsufficientPermissionException;
use App\Models\Message;
use App\Models\Poll;
use App\Models\SeedBoxRecord;
use App\Models\Torrent;
use App\Models\User;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Nexus\Database\NexusDB;
use PhpIP\IP;
use PhpIP\IPBlock;
@@ -20,35 +24,66 @@ class SeedBoxRepository extends BaseRepository
return $query->paginate();
}
/**
* @param array $params
* @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model
*/
public function store(array $params)
{
$params = $this->formatParams($params);
$seedBoxRecord = SeedBoxRecord::query()->create($params);
$this->clearCache();
return $seedBoxRecord;
}
private function formatParams(array $params): array
{
if (!empty($params['ip']) && empty($params['ip_begin']) && empty($params['ip_end'])) {
if (str_contains($params['ip'], '/')) {
try {
$ipBlock = IPBlock::create($params['ip']);
$params['ip_begin_numeric'] = $ipBlock->getFirstIp()->numeric();
$params['ip_end_numeric'] = $ipBlock->getLastIp()->numeric();
} else {
$ip = IP::create($params['ip']);
$params['ip_begin_numeric'] = $ip->numeric();
$params['ip_end_numeric'] = $ip->numeric();
$params['version'] = $ipBlock->getVersion();
} catch (\Exception $exception) {
do_log("[NOT_IP_BLOCK], {$params['ip']}" . $exception->getMessage());
}
if (empty($params['version'])) {
try {
$ip = IP::create($params['ip']);
$params['ip_begin_numeric'] = $ip->numeric();
$params['ip_end_numeric'] = $ip->numeric();
$params['version'] = $ip->getVersion();
} catch (\Exception $exception) {
do_log("[NOT_IP], {$params['ip']}" . $exception->getMessage());
}
}
if (empty($params['version'])) {
throw new \InvalidArgumentException("Invalid IPBlock or IP: " . $params['ip']);
}
} elseif (empty($params['ip']) && !empty($params['ip_begin']) && !empty($params['ip_end'])) {
$ipBegin = IP::create($params['ip_begin']);
$params['ip_begin_numeric'] = $ipBegin->numeric();
$ipEnd = IP::create($params['ip_end']);
$params['ip_end_numeric'] = $ipEnd->numeric();
if ($ipBegin->getVersion() != $ipEnd->getVersion()) {
throw new \InvalidArgumentException("ip_begin/ip_end must be the same version");
}
$params['version'] = $ipEnd->getVersion();
} else {
throw new \InvalidArgumentException("Require ip or ip_begin + ip_end");
}
return SeedBoxRecord::query()->create($params);
return $params;
}
public function update(array $params, $id)
{
$model = Poll::query()->findOrFail($id);
$model = SeedBoxRecord::query()->findOrFail($id);
$params = $this->formatParams($params);
$model->update($params);
$this->clearCache();
return $model;
}
@@ -60,7 +95,54 @@ class SeedBoxRepository extends BaseRepository
public function delete($id, $uid)
{
$this->clearCache();
return SeedBoxRecord::query()->whereIn('id', Arr::wrap($id))->where('uid', $uid)->delete();
}
public function updateStatus(SeedBoxRecord $seedBoxRecord, $status): bool
{
if (Auth::user()->class < User::CLASS_ADMINISTRATOR) {
throw new InsufficientPermissionException();
}
if (!isset(SeedBoxRecord::$status[$status])) {
throw new \InvalidArgumentException("Invalid status: $status");
}
if ($seedBoxRecord->status == $status) {
return true;
}
$message = [
'receiver' => $seedBoxRecord->uid,
'subject' => nexus_trans('seed-box.status_change_message.subject'),
'msg' => nexus_trans('seed-box.status_change_message.body', [
'id' => $seedBoxRecord->id,
'operator' => Auth::user()->username,
'old_status' => $seedBoxRecord->statusText,
'new_status' => nexus_trans('seed-box.status_text.' . $status),
]),
'added' => now()
];
return NexusDB::transaction(function () use ($seedBoxRecord, $status, $message) {
$seedBoxRecord->status = $status;
$seedBoxRecord->save();
$this->clearCache();
return Message::add($message);
});
}
public function renderIcon($ip, $uid): string
{
$result = '';
if ((isIPV4($ip) || isIPV6($ip)) && get_setting('seed_box.enabled') == 'yes' && isIPSeedBox($ip, $uid)) {
$result = '<img src="pic/misc/seed-box.png" style="vertical-align: bottom; height: 16px; margin-left: 4px" title="SeedBox" />';
}
return $result;
}
private function clearCache()
{
NexusDB::redis()->del("nexus_is_ip_seed_box");
}
}
+63 -13
View File
@@ -88,16 +88,23 @@ class TrackerRepository extends BaseRepository
} elseif ($isReAnnounce == self::ANNOUNCE_FIRST) {
$this->checkMinInterval($peerSelf, $queries);
}
$snatch = Snatch::query()
->where('torrentid', $torrent->id)
->where('userid', $user->id)
->orderBy('id', 'desc')
->first();
/**
* Note: Must get before update peer!
*/
$dataTraffic = $this->getDataTraffic($torrent, $queries, $user, $peerSelf);
$dataTraffic = $this->getDataTraffic($torrent, $queries, $user, $peerSelf, $snatch);
/**
* Note: Only check in old session
*/
if ($peerSelf->exists) {
$this->checkCheater($torrent, $dataTraffic, $user, $peerSelf);
$this->checkCheater($torrent, $queries, $dataTraffic, $user, $peerSelf);
$this->checkSeedBox($torrent, $queries, $dataTraffic, $user, $peerSelf);
}
/**
@@ -113,7 +120,7 @@ class TrackerRepository extends BaseRepository
/**
* Note: Must update snatch first, otherwise peer `last_action` already change
*/
$snatch = $this->updateSnatch($peerSelf, $queries, $dataTraffic);
$snatch = $this->updateSnatch($peerSelf, $queries, $dataTraffic, $snatch);
if ($queries['event'] == 'completed') {
$this->handleHitAndRun($user, $torrent, $snatch);
}
@@ -420,6 +427,7 @@ class TrackerRepository extends BaseRepository
if ($user->class >= User::CLASS_VIP) {
return;
}
$gigs = $user->downloaded / (1024*1024*1024);
if ($gigs < 10) {
return;
@@ -485,7 +493,7 @@ class TrackerRepository extends BaseRepository
}
}
protected function checkCheater(Torrent $torrent, $dataTraffic, User $user, Peer $peer)
protected function checkCheater(Torrent $torrent, $queries, $dataTraffic, User $user, Peer $peer)
{
$settingSecurity = Setting::get('security');
$level = $settingSecurity['cheaterdet'];
@@ -560,6 +568,33 @@ class TrackerRepository extends BaseRepository
}
private function checkSeedBox(Torrent $torrent, $queries, $dataTraffic, User $user, Peer $peer)
{
if ($user->class >= User::CLASS_VIP || $user->isDonating()) {
return;
}
$isSeedBoxRuleEnabled = Setting::get('seed_box.enabled') == 'yes';
if (!$isSeedBoxRuleEnabled) {
return;
}
$isIPSeedBox = isIPSeedBox($queries['ip'], $user->id);
if ($isIPSeedBox) {
return;
}
if (!$peer->isValidDate('last_action')) {
//no last action
return;
}
$duration = Carbon::now()->diffInSeconds($peer->last_action);
$upSpeedMbps = ($dataTraffic['uploaded_increment'] / $duration) * 8;
$notSeedBoxMaxSpeedMbps = Setting::get('seed_box.not_seed_box_max_speed');
if ($upSpeedMbps > $notSeedBoxMaxSpeedMbps) {
$user->update(['downloadpos' => 'no']);
do_log("user: {$user->id} downloading privileges have been disabled! (over speed)", 'error');
throw new TrackerException("Your downloading privileges have been disabled! (over speed)");
}
}
private function createOrUpdateCheater(Torrent $torrent, User $user, array $createData)
{
$existsCheater = Cheater::query()
@@ -671,7 +706,7 @@ class TrackerRepository extends BaseRepository
return $real_annnounce_interval;
}
private function getDataTraffic(Torrent $torrent, $queries, User $user, Peer $peer): array
private function getDataTraffic(Torrent $torrent, $queries, User $user, Peer $peer, $snatch): array
{
$log = sprintf(
"torrent: %s, user: %s, peer: %s, queriesUploaded: %s, queriesDownloaded: %s",
@@ -720,12 +755,32 @@ class TrackerRepository extends BaseRepository
$downRatio = 0;
$log .= ", [PEER_NOT_EXISTS], realUploaded: $realUploaded, realDownloaded: $realDownloaded, upRatio: $upRatio, downRatio: $downRatio";
}
$uploadedIncrementForUser = $realUploaded * $upRatio;
$downloadedIncrementForUser = $realDownloaded * $downRatio;
/**
* check seed box rule
*/
$isSeedBoxRuleEnabled = Setting::get('seed_box.enabled') == 'yes';
if ($isSeedBoxRuleEnabled) {
$isIPSeedBox = isIPSeedBox($queries['ip'], $user->id);
if ($isIPSeedBox) {
$uploadedIncrementForUser = $realUploaded;
$downloadedIncrementForUser = $realDownloaded;
$log .= ", isIPSeedBox, increment for user = real";
$maxUploadedTimes = Setting::get('seed_box.max_uploaded');
if ($snatch && $snatch->uploaded >= $torrent->size * $maxUploadedTimes) {
$log .= ", uploaded >= torrentSize * times($maxUploadedTimes), uploadedIncrementForUser = 0";
$uploadedIncrementForUser = 0;
}
}
}
$result = [
'uploaded_increment' => $realUploaded,
'uploaded_increment_for_user' => $realUploaded * $upRatio,
'uploaded_increment_for_user' => $uploadedIncrementForUser,
'downloaded_increment' => $realDownloaded,
'downloaded_increment_for_user' => $realDownloaded * $downRatio,
'downloaded_increment_for_user' => $downloadedIncrementForUser,
];
do_log("$log, result: " . json_encode($result), 'info');
return $result;
@@ -938,15 +993,10 @@ class TrackerRepository extends BaseRepository
* @param $queries
* @param $dataTraffic
*/
private function updateSnatch(Peer $peer, $queries, $dataTraffic)
private function updateSnatch(Peer $peer, $queries, $dataTraffic, $snatch)
{
$nowStr = Carbon::now()->toDateTimeString();
$snatch = Snatch::query()
->where('torrentid', $peer->torrent)
->where('userid', $peer->userid)
->first();
//torrentid, userid, ip, port, uploaded, downloaded, to_go, ,seedtime, leechtime, last_action, startdat, completedat, finished
if (!$snatch) {
$snatch = new Snatch();