diff --git a/app/Filament/Resources/User/UserResource/Pages/UserProfile.php b/app/Filament/Resources/User/UserResource/Pages/UserProfile.php index ab12ae66..ca8fdc51 100644 --- a/app/Filament/Resources/User/UserResource/Pages/UserProfile.php +++ b/app/Filament/Resources/User/UserResource/Pages/UserProfile.php @@ -60,6 +60,7 @@ class UserProfile extends Page } $actions[] = $this->buildResetPasswordAction(); $actions[] = $this->buildEnableDisableAction(); + $actions[] = $this->buildEnableDisableDownloadPrivilegesAction(); } return $actions; } @@ -234,13 +235,20 @@ class UserProfile extends Page } - - - -// protected function getViewData(): array -// { -// return [ -// 'enableDisableAction' => $this->buildEnableDisableAction(), -// ]; -// } + private function buildEnableDisableDownloadPrivilegesAction(): Actions\Action + { + return Actions\Action::make($this->record->downloadpos == 'yes' ? __('admin.resources.user.actions.disable_download_privileges_btn') : __('admin.resources.user.actions.enable_download_privileges_btn')) +// ->modalHeading($this->record->enabled == 'yes' ? __('admin.resources.user.actions.disable_modal_title') : __('admin.resources.user.actions.enable_modal_title')) + ->requiresConfirmation() + ->action(function () { + $userRep = new UserRepository(); + try { + $userRep->toggleDownloadPrivileges(Auth::user(), $this->record->id); + $this->notify('success', 'Success!'); + $this->emitSelf(self::EVENT_RECORD_UPDATED, $this->record->id); + } catch (\Exception $exception) { + $this->notify('danger', $exception->getMessage()); + } + }); + } } diff --git a/app/Models/User.php b/app/Models/User.php index 048ca29b..609ba094 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -146,7 +146,7 @@ class User extends Authenticatable implements FilamentUser, HasName protected $fillable = [ 'username', 'email', 'passhash', 'secret', 'stylesheet', 'editsecret', 'added', 'modcomment', 'enabled', 'status', 'leechwarn', 'leechwarnuntil', 'page', 'class', 'uploaded', 'downloaded', 'clientselect', 'showclienterror', 'last_home', - 'seedbonus', 'bonuscomment', + 'seedbonus', 'bonuscomment', 'downloadpos' ]; /** @@ -189,7 +189,7 @@ class User extends Authenticatable implements FilamentUser, HasName 'id', 'username', 'email', 'class', 'status', 'added', 'avatar', 'uploaded', 'downloaded', 'seedbonus', 'seedtime', 'leechtime', 'invited_by', 'enabled', 'seed_points', 'last_access', 'invites', - 'lang', 'attendance_card', 'privacy', 'noad', + 'lang', 'attendance_card', 'privacy', 'noad', 'downloadpos', ]; public static function getDefaultUserAttributes(): array diff --git a/app/Repositories/TrackerRepository.php b/app/Repositories/TrackerRepository.php index 8e502c6d..65d001bf 100644 --- a/app/Repositories/TrackerRepository.php +++ b/app/Repositories/TrackerRepository.php @@ -586,8 +586,9 @@ class TrackerRepository extends BaseRepository return; } $duration = Carbon::now()->diffInSeconds($peer->last_action); - $upSpeedMbps = ($dataTraffic['uploaded_increment'] / $duration) * 8; + $upSpeedMbps = number_format(($dataTraffic['uploaded_increment'] / $duration / 1024 / 1024) * 8); $notSeedBoxMaxSpeedMbps = Setting::get('seed_box.not_seed_box_max_speed'); + do_log("upSpeedMbps: $upSpeedMbps, notSeedBoxMaxSpeedMbps: $notSeedBoxMaxSpeedMbps"); if ($upSpeedMbps > $notSeedBoxMaxSpeedMbps) { $user->update(['downloadpos' => 'no']); do_log("user: {$user->id} downloading privileges have been disabled! (over speed)", 'error'); @@ -708,84 +709,26 @@ class TrackerRepository extends BaseRepository private function getDataTraffic(Torrent $torrent, $queries, User $user, Peer $peer, $snatch): array { - $log = sprintf( - "torrent: %s, user: %s, peer: %s, queriesUploaded: %s, queriesDownloaded: %s", - $torrent->id, $user->id, json_encode($peer->only(['uploaded', 'downloaded'])), $queries['uploaded'], $queries['downloaded'] - ); + $torrentInfo = $torrent->toArray(); + $userInfo = $user->toArray(); + $userInfo['__is_donor'] = $user->isDonating(); + + $peerInfo = []; if ($peer->exists) { - $realUploaded = max(bcsub($queries['uploaded'], $peer->uploaded), 0); - $realDownloaded = max(bcsub($queries['downloaded'], $peer->downloaded), 0); - $log .= ", [PEER_EXISTS], realUploaded: $realUploaded, realDownloaded: $realDownloaded"; - $spStateReal = $torrent->spStateReal; - $log .= "[SP_STATE_REAL]: $spStateReal"; - $promotionInfo = apply_filter('torrent_promotion', $torrent->toArray()); - do_log("promotionInfo from filter torrent_promotion by torrent: " . $torrent->id . ", get : " . json_encode($promotionInfo)); - if (isset($promotionInfo['__ignore_global_sp_state']) && $promotionInfo['sp_state'] != $spStateReal) { - $spStateReal = $promotionInfo['sp_state']; - $log .= "[CHANGE_SP_STATE_REAL_BY_FILTER_TORRENT_PROMOTION]: $spStateReal"; - } - $uploaderRatio = Setting::get('torrent.uploaderdouble'); - $log .= ", spStateReal: $spStateReal, uploaderRatio: $uploaderRatio"; - if ($torrent->owner == $user->id) { - //uploader, use the bigger one - $upRatio = max($uploaderRatio, Torrent::$promotionTypes[$spStateReal]['up_multiplier']); - $log .= ", [IS_UPLOADER], upRatio: $upRatio"; - } else { - $upRatio = Torrent::$promotionTypes[$spStateReal]['up_multiplier']; - $log .= ", [IS_NOT_UPLOADER], upRatio: $upRatio"; - } - /** - * VIP do not calculate downloaded - * @since 1.7.13 - */ - if ($user->class == User::CLASS_VIP) { - $downRatio = 0; - $log .= ", [IS_VIP], downRatio: $downRatio"; - } else { - $downRatio = Torrent::$promotionTypes[$spStateReal]['down_multiplier']; - $log .= ", [IS_NOT_VIP], downRatio: $downRatio"; - } - } else { - $realUploaded = $queries['uploaded']; - $realDownloaded = $queries['downloaded']; - /** - * If peer not exits, user increment = 0; - */ - $upRatio = 0; - $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; - } - } + $peerInfo = $peer->toArray(); } - $result = [ - 'uploaded_increment' => $realUploaded, - 'uploaded_increment_for_user' => $uploadedIncrementForUser, - 'downloaded_increment' => $realDownloaded, - 'downloaded_increment_for_user' => $downloadedIncrementForUser, - ]; - do_log("$log, result: " . json_encode($result), 'info'); - return $result; + $snatchInfo = []; + if ($snatch instanceof Snatch) { + $snatchInfo = $snatch->toArray(); + } + + $promotionInfo = apply_filter('torrent_promotion', $torrentInfo); + + return \getDataTraffic($torrentInfo, $queries, $userInfo, $peerInfo, $snatchInfo, $promotionInfo); } + private function givePeers($originalPeers, $compact, $noPeerId, int $filterFlag = FILTER_FLAG_IPV4): string|array { $peers = []; diff --git a/app/Repositories/UserRepository.php b/app/Repositories/UserRepository.php index 8e4d6074..c7f0d22a 100644 --- a/app/Repositories/UserRepository.php +++ b/app/Repositories/UserRepository.php @@ -1,6 +1,7 @@ findOrFail($id, ['id', 'username', 'class']); - if (Auth::user()->class <= $user->class) { - throw new \LogicException("Sorry, you don't have enough permission to reset this user's password."); - } + $this->checkPermission(Auth::user(), $user); $secret = mksecret(); $passhash = md5($secret . $password . $secret); $update = [ @@ -162,9 +161,7 @@ class UserRepository extends BaseRepository if ($targetUser->enabled == User::ENABLED_NO) { throw new NexusException('Already disabled !'); } - if ($operator->class <= $targetUser->class) { - throw new NexusException('No Permission !'); - } + $this->checkPermission($operator, $targetUser); $banLog = [ 'uid' => $uid, 'username' => $targetUser->username, @@ -186,9 +183,7 @@ class UserRepository extends BaseRepository if ($targetUser->enabled == User::ENABLED_YES) { throw new NexusException('Already enabled !'); } - if ($operator->class <= $targetUser->class) { - throw new NexusException('No Permission !'); - } + $this->checkPermission($operator, $targetUser); $update = [ 'enabled' => User::ENABLED_YES ]; @@ -233,9 +228,7 @@ class UserRepository extends BaseRepository } $sourceField = $fieldMap[$field]; $targetUser = User::query()->findOrFail($uid, User::$commonFields); - if (Auth::user()->class <= $targetUser->class) { - throw new NexusException("No permission !"); - } + $this->checkPermission($operator, $targetUser); $old = $targetUser->{$sourceField}; $valueAtomic = $value; $formatSize = false; @@ -301,12 +294,10 @@ class UserRepository extends BaseRepository public function removeLeechWarn($operator, $uid): bool { - $operator = $this->getOperator($operator); + $operator = $this->getUser($operator); $classRequire = Setting::get('authority.prfmanage'); - if ($operator->class <= $classRequire) { - throw new \RuntimeException("No permission."); - } $user = User::query()->findOrFail($uid, User::$commonFields); + $this->checkPermission($operator, $user); NexusDB::cache_del('user_'.$uid.'_content'); $user->leechwarn = 'no'; $user->leechwarnuntil = null; @@ -315,24 +306,50 @@ class UserRepository extends BaseRepository public function removeTwoStepAuthentication($operator, $uid): bool { - $operator = $this->getOperator($operator); if (!$operator->canAccessAdmin()) { throw new \RuntimeException("No permission."); } $user = User::query()->findOrFail($uid, User::$commonFields); - if ($operator->class <= $user->class) { - throw new \RuntimeException("No permission!"); - } + $this->checkPermission($operator, $user); $user->two_step_secret = ''; return $user->save(); } - private function getOperator($operator) + + public function toggleDownloadPrivileges($operator, $id) { - if (!$operator instanceof User) { - $operator = User::query()->findOrFail(intval($operator), User::$commonFields); + $targetUser = User::query()->findOrFail($id, User::$commonFields); + $operator = $this->getUser($operator); + $this->checkPermission($operator, $targetUser); + $message = [ + 'added' => now(), + 'receiver' => $targetUser->id, + ]; + if ($targetUser->downloadpos == 'yes') { + $update = ['downloadpos' => 'no']; + $modComment = date('Y-m-d') . " - Download disable by " . $operator->username; + $message['subject'] = nexus_trans('message.download_disable.subject', [], $targetUser->locale); + $message['msg'] = nexus_trans('message.download_disable.body', ['operator' => $operator->username], $targetUser->locale); + } else { + $update = ['downloadpos' => 'yes']; + $modComment = date('Y-m-d') . " - Download enable by " . $operator->username; + $message['subject'] = nexus_trans('message.download_enable.subject', [], $targetUser->locale); + $message['msg'] = nexus_trans('message.download_enable.body', ['operator' => $operator->username], $targetUser->locale); + } + return NexusDB::transaction(function () use ($targetUser, $update, $modComment, $message) { + Message::add($message); + return $targetUser->updateWithModComment($update, $modComment); + }); + } + + + private function checkPermission($operator, User $user, $minAuthClass = 'authority.prfmanage') + { + $operator = $this->getUser($operator); + $classRequire = Setting::get($minAuthClass); + if ($operator->class < $classRequire || $operator->class <= $user->class) { + throw new InsufficientPermissionException(); } - return $operator; } diff --git a/composer.json b/composer.json index b0429985..91ae5225 100644 --- a/composer.json +++ b/composer.json @@ -31,6 +31,7 @@ "ext-pcntl": "*", "ext-redis": "*", "ext-xml": "*", + "ext-gmp": "*", "doctrine/dbal": "^3.1", "elasticsearch/elasticsearch": "^7.16", "filament/filament": "2.14.2", diff --git a/include/globalfunctions.php b/include/globalfunctions.php index c6888daf..67098d29 100644 --- a/include/globalfunctions.php +++ b/include/globalfunctions.php @@ -2,20 +2,18 @@ function get_global_sp_state() { - global $Cache; static $global_promotion_state; - if (!$global_promotion_state){ - if (!$global_promotion_state = $Cache->get_value('global_promotion_state')){ - $res = mysql_query("SELECT * FROM torrents_state"); - $row = mysql_fetch_assoc($res); + if (!$global_promotion_state) { + if (!$global_promotion_state = \Nexus\Database\NexusDB::cache_get('global_promotion_state')){ + $row = \Nexus\Database\NexusDB::getOne('torrents_state', 1); if (isset($row['deadline']) && $row['deadline'] < date('Y-m-d H:i:s')) { //expired $global_promotion_state = \App\Models\Torrent::PROMOTION_NORMAL; } else { $global_promotion_state = $row["global_sp_state"]; } - $Cache->cache_value('global_promotion_state', $global_promotion_state, 600); - $Cache->cache_value('global_promotion_state_deadline', $row['deadline'], 600); + \Nexus\Database\NexusDB::cache_put('global_promotion_state', $global_promotion_state, 600); + \Nexus\Database\NexusDB::cache_put('global_promotion_state_deadline', $row['deadline'], 600); } } return $global_promotion_state; @@ -809,3 +807,101 @@ function isIPSeedBox($ip, $uid = null, $withoutCache = false): bool do_log("$hashKey, no result, false"); return false; } + +function getDataTraffic(array $torrent, array $queries, array $user, $peer, $snatch, $promotionInfo) +{ + if (!isset($user['__is_donor'])) { + throw new \InvalidArgumentException("user no '__is_donor' field"); + } + $log = sprintf( + "torrent: %s, user: %s, peerUploaded: %s, peerDownloaded: %s, queriesUploaded: %s, queriesDownloaded: %s", + $torrent['id'], $user['id'], $peer['uploaded'] ?? '', $peer['downloaded'] ?? '', $queries['uploaded'], $queries['downloaded'] + ); + if (!empty($peer)) { + $realUploaded = max(bcsub($queries['uploaded'], $peer['uploaded']), 0); + $realDownloaded = max(bcsub($queries['downloaded'], $peer['downloaded']), 0); + $log .= ", [PEER_EXISTS], realUploaded: $realUploaded, realDownloaded: $realDownloaded, [SP_STATE]"; + $spStateGlobal = get_global_sp_state(); + $spStateNormal = \App\Models\Torrent::PROMOTION_NORMAL; + if (!empty($promotionInfo) && isset($promotionInfo['__ignore_global_sp_state'])) { + $log .= ', use promotionInfo'; + $spStateReal = $promotionInfo['sp_state']; + } elseif ($spStateGlobal != $spStateNormal) { + $log .= ", use global"; + $spStateReal = $spStateGlobal; + } else { + $log .= ", use torrent individual"; + $spStateReal = $torrent['sp_state']; + } + if (!isset(\App\Models\Torrent::$promotionTypes[$spStateReal])) { + $log .= ", spStateReal = $spStateReal, invalid, reset to: $spStateNormal"; + $spStateReal = $spStateNormal; + } + $uploaderRatio = get_setting('torrent.uploaderdouble'); + $log .= ", uploaderRatio: $uploaderRatio"; + if ($torrent['owner'] == $user['id']) { + //uploader, use the bigger one + $upRatio = max($uploaderRatio, \App\Models\Torrent::$promotionTypes[$spStateReal]['up_multiplier']); + $log .= ", [IS_UPLOADER], upRatio: $upRatio"; + } else { + $upRatio = \App\Models\Torrent::$promotionTypes[$spStateReal]['up_multiplier']; + $log .= ", [IS_NOT_UPLOADER], upRatio: $upRatio"; + } + /** + * VIP do not calculate downloaded + * @since 1.7.13 + */ + if ($user['class'] == \App\Models\User::CLASS_VIP) { + $downRatio = 0; + $log .= ", [IS_VIP], downRatio: $downRatio"; + } else { + $downRatio = \App\Models\Torrent::$promotionTypes[$spStateReal]['down_multiplier']; + $log .= ", [IS_NOT_VIP], downRatio: $downRatio"; + } + } else { + $realUploaded = $queries['uploaded']; + $realDownloaded = $queries['downloaded']; + /** + * If peer not exits, user increment = 0; + */ + $upRatio = 0; + $downRatio = 0; + $log .= ", [PEER_NOT_EXISTS], realUploaded: $realUploaded, realDownloaded: $realDownloaded, upRatio: $upRatio, downRatio: $downRatio"; + } + $uploadedIncrementForUser = $realUploaded * $upRatio; + $downloadedIncrementForUser = $realDownloaded * $downRatio; + $log .= ", uploadedIncrementForUser: $uploadedIncrementForUser, downloadedIncrementForUser: $downloadedIncrementForUser"; + + /** + * check seed box rule + */ + $isSeedBoxRuleEnabled = get_setting('seed_box.enabled') == 'yes'; + $log .= ", isSeedBoxRuleEnabled: $isSeedBoxRuleEnabled, user class: {$user['class']}, __is_donor: {$user['__is_donor']}"; + if ($isSeedBoxRuleEnabled && !($user['class'] >= \App\Models\User::CLASS_VIP || $user['__is_donor'])) { + $isIPSeedBox = isIPSeedBox($queries['ip'], $user['id']); + $log .= ", isIPSeedBox: $isIPSeedBox"; + if ($isIPSeedBox) { + $isSeedBoxNoPromotion = get_setting('seed_box.no_promotion') == 'yes'; + $log .= ", isSeedBoxNoPromotion: $isSeedBoxNoPromotion"; + if ($isSeedBoxNoPromotion) { + $uploadedIncrementForUser = $realUploaded; + $downloadedIncrementForUser = $realDownloaded; + $log .= ", isIPSeedBox && isSeedBoxNoPromotion, increment for user = real"; + } + $maxUploadedTimes = get_setting('seed_box.max_uploaded'); + if (!empty($snatch) && isset($torrent['size']) && $snatch['uploaded'] >= $torrent['size'] * $maxUploadedTimes) { + $log .= ", snatchUploaded >= torrentSize * times($maxUploadedTimes), uploadedIncrementForUser = 0"; + $uploadedIncrementForUser = 0; + } + } + } + + $result = [ + 'uploaded_increment' => $realUploaded, + 'uploaded_increment_for_user' => $uploadedIncrementForUser, + 'downloaded_increment' => $realDownloaded, + 'downloaded_increment_for_user' => $downloadedIncrementForUser, + ]; + do_log("$log, result: " . json_encode($result), 'info'); + return $result; +} diff --git a/lang/_target/lang_modtask.php b/lang/_target/lang_modtask.php index 8d9c491c..e51fcab3 100644 --- a/lang/_target/lang_modtask.php +++ b/lang/_target/lang_modtask.php @@ -82,7 +82,7 @@ $lang_modtask_target = array 'msg_probably_reason_two' => "取消了你的上传权限,可能的原因是种子违规,nfo文件或简介内容不当。", 'msg_download_rights_restored' => "下载权限恢复", 'msg_your_download_rights_restored' => "管理员", - 'msg_you_can_download' => "恢复了你的上传权限,你现在可以下载种子。", + 'msg_you_can_download' => "恢复了你的下载权限,你现在可以下载种子。", 'msg_download_rights_removed' => "下载权限取消", 'msg_your_download_rights_removed' => "管理员", 'msg_probably_reason_three' => "取消了你的下载权限,可能的原因是过低的分享率或行为不当。", @@ -132,7 +132,7 @@ $lang_modtask_target = array 'msg_probably_reason_two' => "取消了你的上傳許可權,可能的原因是種子違規,nfo檔或簡介內容不當。", 'msg_download_rights_restored' => "下載許可權恢復", 'msg_your_download_rights_restored' => "管理員", - 'msg_you_can_download' => "恢復了你的上傳許可權,你現在可以下載種子。", + 'msg_you_can_download' => "恢復了你的下載許可權,你現在可以下載種子。", 'msg_download_rights_removed' => "下載許可權取消", 'msg_your_download_rights_removed' => "管理員", 'msg_probably_reason_three' => "取消了你的下載許可權,可能的原因是過低的分享率或行為不當。", diff --git a/public/announce.php b/public/announce.php index ea202f01..134c2923 100644 --- a/public/announce.php +++ b/public/announce.php @@ -66,6 +66,7 @@ if (strlen($passkey) != 32) err("Invalid passkey (" . strlen($passkey) . " - $pa //4. GET IP AND CHECK PORT $ip = getip(); // avoid to get the spoof ip from some agent +$_GET['ip'] = $ip; if (!$port || $port > 0xffff) err("invalid port"); if (!ip2long($ip)) //Disable compact announce with IPv6 @@ -121,6 +122,8 @@ $userid = intval($az['id'] ?? 0); unset($GLOBALS['CURUSER']); $CURUSER = $GLOBALS["CURUSER"] = $az; $isDonor = $az['donor'] == 'yes' && ($az['donoruntil'] === null || $az['donoruntil'] == '0000-00-00 00:00:00' || $az['donoruntil'] > date('Y-m-d H:i:s')); +$az['__is_donor'] = $isDonor; +$log = "user: $userid, isDonor: $isDonor, seeder: $seeder, ip: $ip, ipv4: $ipv4, ipv6: $ipv6"; //3. CHECK IF CLIENT IS ALLOWED //$clicheck_res = check_client($peer_id,$agent,$client_familyid); @@ -180,8 +183,8 @@ if (!$torrent) { $torrentid = $torrent["id"]; $numpeers = $torrent["seeders"]+$torrent["leechers"]; -$torrent = apply_filter('torrent_detail', $torrent); - +$promotionInfo = apply_filter('torrent_promotion', $torrent); +$log .= ", torrent: $torrentid"; if ($seeder == 'yes'){ //Don't report seeds to other seeders $only_leech_query = " AND seeder = 'no' "; $newnumpeers = $torrent["leechers"]; @@ -284,12 +287,14 @@ if(isset($self) && empty($_GET['event']) && $self['prevts'] > (TIMENOW - $announ err('There is a minimum announce time of ' . $announce_wait . ' seconds'); } - $isSeedBoxRuleEnabled = get_setting('seed_box.enabled') == 'yes'; $isIPSeedBox = false; if ($isSeedBoxRuleEnabled && !($az['class'] >= \App\Models\User::CLASS_VIP || $isDonor)) { $isIPSeedBox = isIPSeedBox($ip, $userid); } +$log .= ", isSeedBoxRuleEnabled: $isSeedBoxRuleEnabled, isIPSeedBox: $isIPSeedBox"; + +do_log($log); // current peer_id, or you could say session with tracker not found in table peers if (!isset($self)) @@ -346,11 +351,13 @@ else // continue an existing session $snatchInfo = mysql_fetch_assoc(sql_query(sprintf('select * from snatched where torrentid = %s and userid = %s order by id desc limit 1', $torrentid, $userid))); $upthis = $trueupthis = max(0, $uploaded - $self["uploaded"]); $downthis = $truedownthis = max(0, $downloaded - $self["downloaded"]); + $announcetime = ($self["seeder"] == "yes" ? "seedtime = seedtime + {$self['announcetime']}" : "leechtime = leechtime + {$self['announcetime']}"); $is_cheater = false; $notSeedBoxMaxSpeedMbps = get_setting('seed_box.not_seed_box_max_speed'); - $upSpeedMbps = ($trueupthis / $self['announcetime']) * 8; - if ($isSeedBoxRuleEnabled && !$isIPSeedBox && $upSpeedMbps > $notSeedBoxMaxSpeedMbps) { + $upSpeedMbps = number_format(($trueupthis / $self['announcetime'] / 1024 / 1024) * 8); + do_log("notSeedBoxMaxSpeedMbps: $notSeedBoxMaxSpeedMbps, upSpeedMbps: $upSpeedMbps"); + if ($isSeedBoxRuleEnabled && !($az['class'] >= \App\Models\User::CLASS_VIP || $isDonor) && !$isIPSeedBox && $upSpeedMbps > $notSeedBoxMaxSpeedMbps) { sql_query("update users set downloadpos = 'no' where id = $userid"); do_log("user: $userid downloading privileges have been disabled! (over speed)", 'error'); err("Your downloading privileges have been disabled! (over speed)"); @@ -367,106 +374,96 @@ else // continue an existing session if (!$is_cheater && ($trueupthis > 0 || $truedownthis > 0)) { - if ($isSeedBoxRuleEnabled && $isIPSeedBox) { - $tmpLog = "[SEED_BOX_RULE_ENABLED_AND_IS_IP_SEED_BOX]"; - $maxUploadedTimes = get_setting('seed_box.max_uploaded'); - $userUploadedIncrement = $trueupthis; - $userDownloadedIncrement = $truedownthis; - if (!empty($snatchInfo) && isset($torrent['size']) && $snatchInfo['uploaded'] >= $torrent['size'] * $maxUploadedTimes) { - $tmpLog .= ", uploaded >= torrentSize * times($maxUploadedTimes), userUploadedIncrement = 0"; - $userUploadedIncrement = 0; - } - $USERUPDATESET[] = "uploaded = uploaded + $userUploadedIncrement"; - $USERUPDATESET[] = "downloaded = downloaded + $userDownloadedIncrement"; - do_log($tmpLog); - } else { - $global_promotion_state = get_global_sp_state(); - if (isset($torrent['__ignore_global_sp_state']) && $torrent['__ignore_global_sp_state']) { - do_log("[IGNORE_GLOBAL_SP_STATE], sp_state: {$torrent['sp_state']}"); - $global_promotion_state = 1; - } - if($global_promotion_state == 1)// Normal, see individual torrent - { - if($torrent['sp_state']==3) //2X - { - $USERUPDATESET[] = "uploaded = uploaded + 2*$trueupthis"; - $USERUPDATESET[] = "downloaded = downloaded + $truedownthis"; - } - elseif($torrent['sp_state']==4) //2X Free - { - $USERUPDATESET[] = "uploaded = uploaded + 2*$trueupthis"; - } - elseif($torrent['sp_state']==6) //2X 50% - { - $USERUPDATESET[] = "uploaded = uploaded + 2*$trueupthis"; - $USERUPDATESET[] = "downloaded = downloaded + $truedownthis/2"; - } - else{ - if ($torrent['owner'] == $userid && $uploaderdouble_torrent > 0) - $upthis = $trueupthis * $uploaderdouble_torrent; + $dataTraffic = getDataTraffic($torrent, $_GET, $az, $self, $snatchInfo, $promotionInfo); + $USERUPDATESET[] = "uploaded = uploaded + " . $dataTraffic['uploaded_increment_for_user']; + $USERUPDATESET[] = "downloaded = downloaded + " . $dataTraffic['downloaded_increment_for_user']; - if($torrent['sp_state']==2) //Free - { - $USERUPDATESET[] = "uploaded = uploaded + $upthis"; - } - elseif($torrent['sp_state']==5) //50% - { - $USERUPDATESET[] = "uploaded = uploaded + $upthis"; - $USERUPDATESET[] = "downloaded = downloaded + $truedownthis/2"; - } - elseif($torrent['sp_state']==7) //30% - { - $USERUPDATESET[] = "uploaded = uploaded + $upthis"; - $USERUPDATESET[] = "downloaded = downloaded + $truedownthis*3/10"; - } - elseif($torrent['sp_state']==1) //Normal - { - $USERUPDATESET[] = "uploaded = uploaded + $upthis"; - $USERUPDATESET[] = "downloaded = downloaded + $truedownthis"; - } - } - } - elseif($global_promotion_state == 2) //Free - { - if ($torrent['owner'] == $userid && $uploaderdouble_torrent > 0) - $upthis = $trueupthis * $uploaderdouble_torrent; - $USERUPDATESET[] = "uploaded = uploaded + $upthis"; - } - elseif($global_promotion_state == 3) //2X - { - if ($uploaderdouble_torrent > 2 && $torrent['owner'] == $userid && $uploaderdouble_torrent > 0) - $upthis = $trueupthis * $uploaderdouble_torrent; - else $upthis = 2*$trueupthis; - $USERUPDATESET[] = "uploaded = uploaded + $upthis"; - $USERUPDATESET[] = "downloaded = downloaded + $truedownthis"; - } - elseif($global_promotion_state == 4) //2X Free - { - if ($uploaderdouble_torrent > 2 && $torrent['owner'] == $userid && $uploaderdouble_torrent > 0) - $upthis = $trueupthis * $uploaderdouble_torrent; - else $upthis = 2*$trueupthis; - $USERUPDATESET[] = "uploaded = uploaded + $upthis"; - } - elseif($global_promotion_state == 5){ // 50% - if ($torrent['owner'] == $userid && $uploaderdouble_torrent > 0) - $upthis = $trueupthis * $uploaderdouble_torrent; - $USERUPDATESET[] = "uploaded = uploaded + $upthis"; - $USERUPDATESET[] = "downloaded = downloaded + $truedownthis/2"; - } - elseif($global_promotion_state == 6){ //2X 50% - if ($uploaderdouble_torrent > 2 && $torrent['owner'] == $userid && $uploaderdouble_torrent > 0) - $upthis = $trueupthis * $uploaderdouble_torrent; - else $upthis = 2*$trueupthis; - $USERUPDATESET[] = "uploaded = uploaded + $upthis"; - $USERUPDATESET[] = "downloaded = downloaded + $truedownthis/2"; - } - elseif($global_promotion_state == 7){ //30% - if ($torrent['owner'] == $userid && $uploaderdouble_torrent > 0) - $upthis = $trueupthis * $uploaderdouble_torrent; - $USERUPDATESET[] = "uploaded = uploaded + $upthis"; - $USERUPDATESET[] = "downloaded = downloaded + $truedownthis*3/10"; - } - } +// $global_promotion_state = get_global_sp_state(); +// if (isset($torrent['__ignore_global_sp_state']) && $torrent['__ignore_global_sp_state']) { +// do_log("[IGNORE_GLOBAL_SP_STATE], sp_state: {$torrent['sp_state']}"); +// $global_promotion_state = 1; +// } +// if($global_promotion_state == 1)// Normal, see individual torrent +// { +// if($torrent['sp_state']==3) //2X +// { +// $USERUPDATESET[] = "uploaded = uploaded + 2*$trueupthis"; +// $USERUPDATESET[] = "downloaded = downloaded + $truedownthis"; +// } +// elseif($torrent['sp_state']==4) //2X Free +// { +// $USERUPDATESET[] = "uploaded = uploaded + 2*$trueupthis"; +// } +// elseif($torrent['sp_state']==6) //2X 50% +// { +// $USERUPDATESET[] = "uploaded = uploaded + 2*$trueupthis"; +// $USERUPDATESET[] = "downloaded = downloaded + $truedownthis/2"; +// } +// else{ +// if ($torrent['owner'] == $userid && $uploaderdouble_torrent > 0) +// $upthis = $trueupthis * $uploaderdouble_torrent; +// +// if($torrent['sp_state']==2) //Free +// { +// $USERUPDATESET[] = "uploaded = uploaded + $upthis"; +// } +// elseif($torrent['sp_state']==5) //50% +// { +// $USERUPDATESET[] = "uploaded = uploaded + $upthis"; +// $USERUPDATESET[] = "downloaded = downloaded + $truedownthis/2"; +// } +// elseif($torrent['sp_state']==7) //30% +// { +// $USERUPDATESET[] = "uploaded = uploaded + $upthis"; +// $USERUPDATESET[] = "downloaded = downloaded + $truedownthis*3/10"; +// } +// elseif($torrent['sp_state']==1) //Normal +// { +// $USERUPDATESET[] = "uploaded = uploaded + $upthis"; +// $USERUPDATESET[] = "downloaded = downloaded + $truedownthis"; +// } +// } +// } +// elseif($global_promotion_state == 2) //Free +// { +// if ($torrent['owner'] == $userid && $uploaderdouble_torrent > 0) +// $upthis = $trueupthis * $uploaderdouble_torrent; +// $USERUPDATESET[] = "uploaded = uploaded + $upthis"; +// } +// elseif($global_promotion_state == 3) //2X +// { +// if ($uploaderdouble_torrent > 2 && $torrent['owner'] == $userid && $uploaderdouble_torrent > 0) +// $upthis = $trueupthis * $uploaderdouble_torrent; +// else $upthis = 2*$trueupthis; +// $USERUPDATESET[] = "uploaded = uploaded + $upthis"; +// $USERUPDATESET[] = "downloaded = downloaded + $truedownthis"; +// } +// elseif($global_promotion_state == 4) //2X Free +// { +// if ($uploaderdouble_torrent > 2 && $torrent['owner'] == $userid && $uploaderdouble_torrent > 0) +// $upthis = $trueupthis * $uploaderdouble_torrent; +// else $upthis = 2*$trueupthis; +// $USERUPDATESET[] = "uploaded = uploaded + $upthis"; +// } +// elseif($global_promotion_state == 5){ // 50% +// if ($torrent['owner'] == $userid && $uploaderdouble_torrent > 0) +// $upthis = $trueupthis * $uploaderdouble_torrent; +// $USERUPDATESET[] = "uploaded = uploaded + $upthis"; +// $USERUPDATESET[] = "downloaded = downloaded + $truedownthis/2"; +// } +// elseif($global_promotion_state == 6){ //2X 50% +// if ($uploaderdouble_torrent > 2 && $torrent['owner'] == $userid && $uploaderdouble_torrent > 0) +// $upthis = $trueupthis * $uploaderdouble_torrent; +// else $upthis = 2*$trueupthis; +// $USERUPDATESET[] = "uploaded = uploaded + $upthis"; +// $USERUPDATESET[] = "downloaded = downloaded + $truedownthis/2"; +// } +// elseif($global_promotion_state == 7){ //30% +// if ($torrent['owner'] == $userid && $uploaderdouble_torrent > 0) +// $upthis = $trueupthis * $uploaderdouble_torrent; +// $USERUPDATESET[] = "uploaded = uploaded + $upthis"; +// $USERUPDATESET[] = "downloaded = downloaded + $truedownthis*3/10"; +// } } } diff --git a/public/modtask.php b/public/modtask.php index 7a4c78e5..205b3bd7 100644 --- a/public/modtask.php +++ b/public/modtask.php @@ -26,6 +26,7 @@ if ($action == "confirmuser") if ($action == "edituser") { $userid = $_POST["userid"]; + $userInfo = \App\Models\User::query()->findOrFail($userid, ['id', 'passkey']); $class = intval($_POST["class"] ?? 0); $vip_added = ($_POST["vip_added"] == 'yes' ? 'yes' : 'no'); $vip_until = !empty($_POST["vip_until"]) ? $_POST['vip_until'] : null; @@ -344,6 +345,7 @@ if ($action == "edituser") \App\Models\UserBanLog::query()->insert($banLog); } \Nexus\Database\NexusDB::cache_del("user_{$userid}_content"); + \Nexus\Database\NexusDB::cache_del('user_passkey_'.$userInfo->passkey.'_content'); $returnto = htmlspecialchars($_POST["returnto"]); header("Location: " . get_protocol_prefix() . "$BASEURL/$returnto"); die; diff --git a/public/viewpeerlist.php b/public/viewpeerlist.php index 9551aa03..8bf251f6 100644 --- a/public/viewpeerlist.php +++ b/public/viewpeerlist.php @@ -72,9 +72,9 @@ function dltable($name, $arr, $torrent) $ips[] = $e['ipv6']; } $title = sprintf('%s%s%s', $lang_functions['text_user_ip'], ': ', implode(', ', $ips)); - $addressStr = implode(' + ', $address); + $addressStr = implode('
', $address); $location = get_user_class() >= $userprofile_class ? "
" . $addressStr . "
" : $addressStr; - $s .= "" . $location . "\n"; + $s .= "" . $location . "\n"; } elseif (get_user_class() >= $userprofile_class){ $location = implode(', ', array_filter([$e['ipv4'], $e['ipv6']])); diff --git a/resources/lang/en/admin.php b/resources/lang/en/admin.php index 1f9cb00d..89953deb 100644 --- a/resources/lang/en/admin.php +++ b/resources/lang/en/admin.php @@ -55,6 +55,8 @@ return [ 'grant_medal_duration_label' => 'Duration', 'grant_medal_duration_help' => 'Unit: days. If left blank, the user has permanent possession', 'confirm_btn' => 'Confirm', + 'disable_download_privileges_btn' => 'Enable download', + 'enable_download_privileges_btn' => 'Disable download', ] ], 'exam_user' => [ diff --git a/resources/lang/en/label.php b/resources/lang/en/label.php index 8b0b7462..d660048a 100644 --- a/resources/lang/en/label.php +++ b/resources/lang/en/label.php @@ -74,6 +74,7 @@ return [ 'invite_by' => 'Inviter', 'two_step_authentication' => 'Two-step authentication', 'seed_points' => 'Seed points', + 'downloadpos' => 'Download privileges', ], 'medal' => [ 'label' => 'Medal', diff --git a/resources/lang/en/message.php b/resources/lang/en/message.php index 4d08c542..8ff8e25c 100644 --- a/resources/lang/en/message.php +++ b/resources/lang/en/message.php @@ -10,4 +10,13 @@ return [ ], 'field_value_change_message_body' => ':field is changed from :old to :new by :operator. Reason::reason.', 'field_value_change_message_subject' => ':field changed', + + 'download_disable' => [ + 'subject' => 'Download permission cancellation', + 'body' => 'Administrator: :operator has revoked your download privileges, possibly due to low sharing rates or misbehavior.', + ], + 'download_enable' => [ + 'subject' => 'Download permission restored', + 'body' => 'Administrator: :operator restored your download privileges, you can now download torrents.', + ], ]; diff --git a/resources/lang/zh_CN/admin.php b/resources/lang/zh_CN/admin.php index d39e870a..2a4a4494 100644 --- a/resources/lang/zh_CN/admin.php +++ b/resources/lang/zh_CN/admin.php @@ -55,6 +55,8 @@ return [ 'grant_medal_duration_label' => '有效时长', 'grant_medal_duration_help' => '单位:天。如果留空,用户永久拥有', 'confirm_btn' => '确认', + 'disable_download_privileges_btn' => '禁用下载权限', + 'enable_download_privileges_btn' => '启用下载权限', ] ], 'exam_user' => [ diff --git a/resources/lang/zh_CN/label.php b/resources/lang/zh_CN/label.php index aaca47c8..c17c71ee 100644 --- a/resources/lang/zh_CN/label.php +++ b/resources/lang/zh_CN/label.php @@ -84,6 +84,7 @@ return [ 'invite_by' => '邀请人', 'two_step_authentication' => '两步验证', 'seed_points' => '做种积分', + 'downloadpos' => '下载权限', ], 'medal' => [ 'label' => '勋章', diff --git a/resources/lang/zh_CN/message.php b/resources/lang/zh_CN/message.php index fdbf49f2..b290a6c9 100644 --- a/resources/lang/zh_CN/message.php +++ b/resources/lang/zh_CN/message.php @@ -10,4 +10,13 @@ return [ ], 'field_value_change_message_body' => ':field 被管理员 :operator 从 :old 改为 :new。理由::reason。', 'field_value_change_message_subject' => ':field 改变', + + 'download_disable' => [ + 'subject' => '下载权限取消', + 'body' => '管理员::operator 取消了你的下载权限,可能的原因是过低的分享率或行为不当。', + ], + 'download_enable' => [ + 'subject' => '下载权限恢复', + 'body' => '管理员::operator 恢复了你的下载权限,你现在可以下载种子。', + ], ]; diff --git a/resources/lang/zh_TW/admin.php b/resources/lang/zh_TW/admin.php index c2916da1..b07a6eb6 100644 --- a/resources/lang/zh_TW/admin.php +++ b/resources/lang/zh_TW/admin.php @@ -55,6 +55,8 @@ return [ 'grant_medal_duration_label' => '有效時長', 'grant_medal_duration_help' => '單位:天。如果留空,用戶永久擁有', 'confirm_btn' => '確認', + 'disable_download_privileges_btn' => '禁用下載權限', + 'enable_download_privileges_btn' => '啟用下載權限', ] ], 'exam_user' => [ diff --git a/resources/lang/zh_TW/label.php b/resources/lang/zh_TW/label.php index d0c324a0..45e9f1ae 100644 --- a/resources/lang/zh_TW/label.php +++ b/resources/lang/zh_TW/label.php @@ -74,6 +74,7 @@ return [ 'invite_by' => '邀請人', 'two_step_authentication' => '兩步驗證', 'seed_points' => '做種積分', + 'downloadpos' => '下載權限', ], 'medal' => [ 'label' => '勛章', diff --git a/resources/lang/zh_TW/message.php b/resources/lang/zh_TW/message.php index 4a03e7ad..0457e864 100644 --- a/resources/lang/zh_TW/message.php +++ b/resources/lang/zh_TW/message.php @@ -10,4 +10,12 @@ return [ ], 'field_value_change_message_body' => ':field 被管理員 :operator 從 :old 改為 :new。理由::reason。', 'field_value_change_message_subject' => ':field 改變', + 'download_disable' => [ + 'subject' => '下載權限取消', + 'body' => '管理員::operator 取消了你的下載權限,可能的原因是過低的分享率或行為不當。', + ], + 'download_enable' => [ + 'subject' => '下載權限恢復', + 'body' => '管理員::operator 恢復了你的下載權限,你現在可以下載種子。', + ], ]; diff --git a/resources/views/filament/resources/user/user-resource/pages/user-profile.blade.php b/resources/views/filament/resources/user/user-resource/pages/user-profile.blade.php index ca7ce928..fed7a594 100644 --- a/resources/views/filament/resources/user/user-resource/pages/user-profile.blade.php +++ b/resources/views/filament/resources/user/user-resource/pages/user-profile.blade.php @@ -52,6 +52,11 @@ {{$record->two_step_secret ? 'Enabled' : 'Disabled'}} + + {{__('label.user.downloadpos')}} + {{$record->downloadpos}} + + {{__('label.user.seed_points')}} {{$record->seed_points}}