diff --git a/app/Filament/Resources/System/TrackerUrlResource.php b/app/Filament/Resources/System/TrackerUrlResource.php new file mode 100644 index 00000000..7b4ef1d6 --- /dev/null +++ b/app/Filament/Resources/System/TrackerUrlResource.php @@ -0,0 +1,116 @@ +schema([ + Forms\Components\TextInput::make('url')->required(), + Forms\Components\Radio::make('is_default') + ->label(__('label.is_default')) + ->options(self::getYesNoOptions()) + ->required(true) + ->inline() + , + Forms\Components\Radio::make('enabled') + ->label(__('label.enabled')) + ->options(self::getEnableDisableOptions(1, 0)) + ->required(true) + ->inline() + , + Forms\Components\TextInput::make('priority') + ->label(__('label.priority'))->numeric() + ->default(0) + ->helperText(__('label.priority_help')) + , + ]); + } + + public static function getEloquentQuery(): Builder + { + return TrackerUrl::query() + ->orderBy('is_default', 'desc') + ->orderBy('priority', 'desc') + ->orderBy('id', 'desc') + ; + } + + public static function table(Table $table): Table + { + return $table + ->columns([ + Tables\Columns\TextColumn::make('id') + , + Tables\Columns\TextColumn::make('url') + , + Tables\Columns\IconColumn::make('is_default') + ->label(__('label.is_default')) + ->boolean() + , + Tables\Columns\IconColumn::make('enabled') + ->label(__('label.enabled')) + ->boolean() + , + Tables\Columns\TextColumn::make('priority') + ->label(__('label.priority')) + , + Tables\Columns\TextColumn::make('updated_at') + ->label(__('label.updated_at')) + , + ]) + ->filters([ + // + ]) + ->actions([ + Tables\Actions\EditAction::make(), + Tables\Actions\DeleteAction::make(), + ]) + ->bulkActions([ + Tables\Actions\BulkActionGroup::make([ + Tables\Actions\DeleteBulkAction::make(), + ]), + ]); + } + + public static function getPages(): array + { + return [ + 'index' => Pages\ManageTrackerUrls::route('/'), + ]; + } +} diff --git a/app/Filament/Resources/System/TrackerUrlResource/Pages/ManageTrackerUrls.php b/app/Filament/Resources/System/TrackerUrlResource/Pages/ManageTrackerUrls.php new file mode 100644 index 00000000..722e07ff --- /dev/null +++ b/app/Filament/Resources/System/TrackerUrlResource/Pages/ManageTrackerUrls.php @@ -0,0 +1,20 @@ +is_default == 1) { + self::query()->where("id", "!=", $model->id)->update(["is_default" => 0]); + } + //添加 id 与 URL 映射 + $redis = NexusDB::redis(); + $redis->del(self::TRACKER_URL_CACHE_KEY); + $list = self::listAll(); + $first = $list->first(); + $hasDefault = false; + foreach ($list as $item) { + $redis->hset(self::TRACKER_URL_CACHE_KEY, $item->id, $item->url); + if ($item->is_default == 1) { + $hasDefault = true; + $redis->set(self::TRACKER_URL_DEFAULT_CACHE_KEY, $item->url); + } + } + if (!$hasDefault && $first) { + $redis->set(self::TRACKER_URL_DEFAULT_CACHE_KEY, $first->url); + } + }); + static::saving(function (TrackerUrl $model) { + if ($model->is_default == 1) { + $model->enabled = 1; + } + }); + } + + public static function listAll() + { + return self::query() + ->where("enabled", 1) + ->orderBy("is_default", "desc") + ->orderBy("priority", "desc") + ->get(); + } + + public static function getById(int $trackerUrlId) + { + $redis = NexusDB::redis(); + if ($trackerUrlId == 0) { + return $redis->get(self::TRACKER_URL_DEFAULT_CACHE_KEY); + } + $result = $redis->hget(self::TRACKER_URL_CACHE_KEY, $trackerUrlId); + if (!$result) { + $result = $redis->get(self::TRACKER_URL_DEFAULT_CACHE_KEY); + } + return $result; + } +} diff --git a/database/migrations/2025_06_19_194137_create_tracker_urls_table.php b/database/migrations/2025_06_19_194137_create_tracker_urls_table.php new file mode 100644 index 00000000..a901202f --- /dev/null +++ b/database/migrations/2025_06_19_194137_create_tracker_urls_table.php @@ -0,0 +1,31 @@ +id(); + $table->string('url'); + $table->tinyInteger('enabled')->default(1); + $table->tinyInteger('is_default')->default(0); + $table->integer('priority')->default(0); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('tracker_urls'); + } +}; diff --git a/database/migrations/2025_06_19_194434_add_tracker_url_id_to_users_table.php b/database/migrations/2025_06_19_194434_add_tracker_url_id_to_users_table.php new file mode 100644 index 00000000..17ee7fe6 --- /dev/null +++ b/database/migrations/2025_06_19_194434_add_tracker_url_id_to_users_table.php @@ -0,0 +1,28 @@ +integer('tracker_url_id')->default(0); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('users', function (Blueprint $table) { + $table->dropColumn('tracker_url_id'); + }); + } +}; diff --git a/include/constants.php b/include/constants.php index 791eb03e..8535a5f4 100644 --- a/include/constants.php +++ b/include/constants.php @@ -1,6 +1,6 @@ '登记', 'checkbox_pm_on_topic_reply' => '论坛帖子有新回复时通知我', 'checkbox_pm_on_hr_reached' => 'H&R 达标时通知我', + 'row_tracker_url' => 'Tracker URL', + 'row_tracker_url_help' => '注意:选择后只能向选中的链接汇报。默认只能向列表中的第 1 个默认链接汇报。', ); ?> diff --git a/lang/cht/lang_usercp.php b/lang/cht/lang_usercp.php index d6674cc8..19164494 100644 --- a/lang/cht/lang_usercp.php +++ b/lang/cht/lang_usercp.php @@ -254,6 +254,8 @@ $lang_usercp = array 'add_seed_box_btn' => '登記', 'checkbox_pm_on_topic_reply' => '論壇帖子有新回復時通知我', 'checkbox_pm_on_hr_reached' => 'H&R 達標時通知我', + 'row_tracker_url' => 'Tracker URL', + 'row_tracker_url_help' => '注意:選擇後只能向選中的鏈接匯報。默認只能向列表中的第 1 個默認鏈接匯報。', ); ?> diff --git a/lang/en/lang_usercp.php b/lang/en/lang_usercp.php index 7f60d108..cc43446c 100644 --- a/lang/en/lang_usercp.php +++ b/lang/en/lang_usercp.php @@ -256,6 +256,8 @@ $lang_usercp = array 'add_seed_box_btn' => 'Register', 'checkbox_pm_on_topic_reply' => 'Notify me when there are new replies to forum posts', 'checkbox_pm_on_hr_reached' => 'Notify me when H&R reaches target', + 'row_tracker_url' => 'Tracker URL', + 'row_tracker_url_help' => 'Note: Once selected, announce can only be sent to the selected link. By default, announce can only be sent to the first default link in the list.', ); ?> diff --git a/nexus/Install/Update.php b/nexus/Install/Update.php index 240ca144..ea2af3bf 100644 --- a/nexus/Install/Update.php +++ b/nexus/Install/Update.php @@ -15,6 +15,7 @@ use App\Models\Setting; use App\Models\Tag; use App\Models\Torrent; use App\Models\TorrentTag; +use App\Models\TrackerUrl; use App\Models\User; use App\Models\UserBanLog; use App\Repositories\AttendanceRepository; @@ -361,6 +362,19 @@ class Update extends Install Artisan::call("upgrade:migrate_snatched_hr_id"); Artisan::call("upgrade:migrate_snatched_buy_log_id"); } + if (!Schema::hasTable("tracker_urls")) { + $this->runMigrate("database/migrations/2025_06_19_194137_create_tracker_urls_table.php"); + $announceUrl = get_setting("security.https_announce_url"); + if (empty($announceUrl)) { + $announceUrl = get_setting("basic.announce_url"); + } + TrackerUrl::query()->create([ + "url" => $announceUrl, + "enabled" => 1, + "is_default" => 1, + ]); + NexusDB::cache_del("nexus_plugin_store_all"); + } } diff --git a/public/announce.php b/public/announce.php index 4a88aa30..0a364ca8 100644 --- a/public/announce.php +++ b/public/announce.php @@ -111,7 +111,7 @@ $seeder = ($left == 0) ? "yes" : "no"; // check passkey if (!$az = $Cache->get_value('user_passkey_'.$passkey.'_content')){ - $res = sql_query("SELECT id, username, downloadpos, enabled, uploaded, downloaded, class, parked, clientselect, showclienterror, passkey, donor, donoruntil, seedbonus FROM users WHERE passkey=". sqlesc($passkey)." LIMIT 1"); + $res = sql_query("SELECT id, username, downloadpos, enabled, uploaded, downloaded, class, parked, clientselect, showclienterror, passkey, donor, donoruntil, seedbonus, tracker_url_id FROM users WHERE passkey=". sqlesc($passkey)." LIMIT 1"); $az = mysql_fetch_array($res); do_log("[check passkey], currentUser: " . nexus_json_encode($az)); $Cache->cache_value('user_passkey_'.$passkey.'_content', $az, 3600); @@ -133,6 +133,13 @@ $CURUSER = $GLOBALS["CURUSER"] = $az; $isDonor = is_donor($az); $az['__is_donor'] = $isDonor; $log = "user: $userid, isDonor: $isDonor, seeder: $seeder, ip: $ip, ipv4: $ipv4, ipv6: $ipv6"; +//check tracker url +$trackerUrl = \App\Models\TrackerUrl::getById($az['tracker_url_id']); +$currentUrl = getSchemeAndHttpHost(); +if (!str_contains($trackerUrl, $currentUrl)) { + do_log("announce check tracker url, trackerUrl: $trackerUrl does not contains: $currentUrl"); + warn("you should announce to: $trackerUrl"); +} //3. CHECK IF CLIENT IS ALLOWED //$clicheck_res = check_client($peer_id,$agent,$client_familyid); diff --git a/public/download.php b/public/download.php index 12df53eb..06d1556f 100644 --- a/public/download.php +++ b/public/download.php @@ -84,9 +84,9 @@ if ($CURUSER['downloadpos']=="no") { denyDownload(); } -$trackerSchemaAndHost = get_tracker_schema_and_host(); -$ssl_torrent = $trackerSchemaAndHost['ssl_torrent']; -$base_announce_url = $trackerSchemaAndHost['base_announce_url']; +//$trackerSchemaAndHost = get_tracker_schema_and_host(); +//$ssl_torrent = $trackerSchemaAndHost['ssl_torrent']; +//$base_announce_url = $trackerSchemaAndHost['base_announce_url']; $res = sql_query("SELECT torrents.name, torrents.filename, torrents.save_as, torrents.size, torrents.owner, torrents.banned, torrents.approval_status, torrents.price, categories.mode as search_box_id FROM torrents left join categories on torrents.category = categories.id WHERE torrents.id = ".sqlesc($id)) or sqlerr(__FILE__, __LINE__); $row = mysql_fetch_assoc($res); @@ -140,7 +140,7 @@ if (strlen($CURUSER['passkey']) != 32) { sql_query("UPDATE users SET passkey=".sqlesc($CURUSER['passkey'])." WHERE id=".sqlesc($CURUSER['id'])); } $dict = \Rhilip\Bencode\Bencode::load($fn); -$dict['announce'] = $ssl_torrent . $base_announce_url . "?passkey=" . $CURUSER['passkey']; +$dict['announce'] = \App\Models\TrackerUrl::getById($CURUSER['tracker_url_id']) . "?passkey=" . $CURUSER['passkey']; $dict['comment'] = getSchemeAndHttpHost(true) . "/details.php?id=" . $id; do_log(sprintf("[ANNOUNCE_URL], user: %s, torrent: %s, url: %s", $CURUSER['id'] ?? '', $id, $dict['announce'])); /** diff --git a/public/settings.php b/public/settings.php index 4dd7f104..b310383e 100644 --- a/public/settings.php +++ b/public/settings.php @@ -369,7 +369,7 @@ elseif ($action == 'securitysettings') //security settings print ("