Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v7.3.3 #920

Merged
merged 68 commits into from
Jan 19, 2025
Merged

v7.3.3 #920

merged 68 commits into from
Jan 19, 2025

Conversation

Ghost-chu
Copy link
Collaborator

@Ghost-chu Ghost-chu commented Jan 18, 2025

提前祝各位新年快乐~ 在接下来的春节假期和元宵佳节期间,PBH-BTN 将暂停一段时间的开发、技术支持工作。除非有严重错误,我们在未来一段时间内都不会发布的新的正式版本。

享受假期,快乐过年!下次见!


Note

对使用 BiglyBT 下载器的用户:PeerBanHelper 自本版本起需要 PBH-Adapter-BiglyBT 的 1.2.9 或者更高版本,请升级您的适配器插件版本。当版本过低时,WebUI 将显示 “需要采取行动” 提示,并在升级之前无法正常工作。有关 PBH-Adapter-BiglyBT 的相关更改,请参见对应的版本发行说明

错误修复

  • 修复 NoGUI 模式下,日志队列发生内存泄漏的问题,可能导致长时间运行崩溃的问题 @Ghost-chu
  • 修复 BitComet 下载器的 “忽略私有种子” 功能不起作用的问题 @Ghost-chu
  • 修复 BTN 提交历史记录能力在遇到单次提交超过 10,000 条的时候会导致除最近 10,000 条的数据外剩余数据被丢弃的问题。现在将会正确的进行分批提交,并丢弃 30 天前的历史数据 @Ghost-chu
  • [WebUI] 修复更新日志在特定情况下内容区域背景颜色异常导致内容不可读的问题 @Gaojianli

改进

  • 降低提交历史记录时每批提交的数量(从 10,000 降低到 5,000),超过 5,000 的数据将拆分到下一个请求以降低生成提交数据时的 RAM 使用 @Ghost-chu
  • 优化 GUI 日志记录速度过快时的内存占用峰值问题 @Ghost-chu
  • 此前需要修改启动命令 -D 添加的自定义 Flags 现在支持通过环境变量传递 @Gaojianli
    • 如果过去的自定义 Flag 包含符号 .-,则替换为 _
    • 所有 ASCII 字符均大写

安全改进

  • 现在不再暴露 WebAPI 端点列表到 /route-view @Ghost-chu
  • 现在将通过检查 User-Agent 的方式,屏蔽下列网络空间测绘引擎的请求,避免 PeerBanHelper 被如下测绘引擎或者端口扫描工具的端口扫描探测: @Ghost-chu
    • Censys
    • Shodan
    • ZoomEye
    • ThreatBook
    • FOFA
    • zmap (默认配置时)
    • nmap (默认配置时)
    • 所有以上 User-Agent 的请求都将返回 404 not found 提示信息和 404 状态码

BTN 更改

  • 协议版本号从 8 提升到 10 以对应协议更新 @Ghost-chu

实验室功能

  • 使用已知数据填充缺失的记录
    • 使用上一个已知的数据记录填充查询的流量记录的空白条目以尝试修复流量统计不准确的问题。但当查询范围开头也无数据时,此功能不生效。需要手动开启实验。

数据收集范围更改披露

@Ghost-chu

PeerBanHelper 严格遵守和执行 PeerBanHelper 隐私政策,并确保用户的知情权。当我们在隐私政策或者收集的内容范围作出更改时,将通过公告等形式向您告知。

以下是有关本次更新中 “BTN 网络” 收集数据的更改告知以及其用途说明:

影响范围:PeerBanHelper v7.3.3 或更高版本,且使用了由 PBH-BTN 官方维护的 Sparkle BTN 的 BTN 实例 (btn-prod.ghostchu-services.top, sparkle.ghostchu-services.top, btn-dev.ghostchu-services.top, sparkle.ghostchu.com) 并且打开了 设置-基础设置-BTN-启用提交 开关的用户

新增收集的数据列表如下所示:

1. [新增] is_private_torrent

作用: 指示一个 torrent_identifier 对应的是否是一个私有种子
适用范围: 提交封禁列表和提交历史记录,包括之前的数据(如果被再次更新)
收集条件: 当对应下载器未启用 “忽略私有种子” 开关或者下载器不支持 “忽略私有种子”,并且连接到了 Sparkle BTN 实例,且打开了“启用提交”开关,并且产生了下列数据的情况下,新的数据可能会被收集
数据用途: 帮助 BTN 服务端程序识别对应 torrent_identifier 的 “私有种子” 类型,以便单独处理可能由 PT 站点等私有种子产生的数据,例如用于分析和统计用途。
收集的数据能够:

  1. 能够识别一条数据是否由一个私有种子产生

收集的数据无法:

  1. 无法在未提前得知 info_hash 的情况下推断数据对应的 info_hash 是什么,参见 BTN-Spec info_hash 匿名化哈希算法
  2. 无法推断出对应的数据是否来自某个具体的 Tracker

数据示例:

  • is_private_torrent = true // 指示本条数据由一个私有种子产生
  • is_private_torrent = false // 指示本条数据由一个公共种子产生

术语解释:

  1. torrent_identifier: 使用 BTN-Spec info_hash 匿名化哈希算法 将一个种子的 info_hash 转换为的匿名哈希值,以便在无需得知种子的实际 info_hash 的匿名情况下识别两个 torrent_identifier 对应的是否是同一个实际种子的技术
  2. 提交封禁列表: 向 BTN 提交自 PBH 启动/上次提交以来的新增封禁记录的过程 技术资料
  3. 提交历史记录: 向 BTN 提交自上次提交以来的新增 Peer 活动连接记录的过程 技术资料
  4. 私有种子: 由 BEP-0027 Private Torrents 中定义的一种种子类型,通常被 PT 站使用

未实装的功能

以下功能因时间因素未在本版本中适配前端界面,但仍可通过 WebAPI 调用:

  1. 批量替换下载器的种子的 Trackers (暂仅支持 qBittorrent, Transmission, BiglyBT)

Docker

DockerHub: ghostchu/peerbanhelper:v7.3.3
阿里云国内镜像加速: registry.cn-hangzhou.aliyuncs.com/ghostchu/peerbanhelper:v7.3.3

Summary by CodeRabbit

以下是 PeerBanHelper 的版本 7.3.3 的发行说明:

新功能

  • 添加了跨下载器的 Tracker 管理实用工具
  • 引入了新的实验性功能,用于填充流量统计中缺失的数据
  • 为多个下载器(BiglyBT、BitComet、qBittorrent 等)添加了 Tracker 管理支持
  • 新增了用于替换 Torrent 的 Tracker 的 API 端点

改进

  • 优化了配置获取方式,引入 ExternalSwitch 工具类
  • 改进了数据库性能,添加后台优化模块
  • 增强了错误处理和日志记录机制
  • 更新了多个下载器的适配器版本和兼容性
  • 改进了 Markdown 渲染的主题支持

修复

  • 修复了多个下载器中的 Tracker 管理问题
  • 改进了系统属性和配置的获取方式
  • 修复了一些潜在的并发和同步问题
  • 更新了文档链接以指向正确的资源

实验性功能

  • 新增实验性功能:使用已知数据填充流量统计中缺失的记录

注意事项

  • 建议升级到最新版本以获得改进和修复
  • 某些实验性功能可能不稳定,请谨慎使用

Ghost-chu and others added 30 commits January 14, 2025 21:37
…HUtilitiesController.java

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
…n-6.x

Update docker/build-push-action action to v6.12.0
…-jdk18on-1.x

Update dependency org.bouncycastle:bcprov-jdk18on to v1.80
…dk18on-1.x

Update dependency org.bouncycastle:bcpg-jdk18on to v1.80
fix dark mode on light system
fix light mode on dark system
close #890
@Ghost-chu Ghost-chu requested review from a team as code owners January 18, 2025 11:36
Copy link
Contributor

coderabbitai bot commented Jan 18, 2025

概述

工作流程

这个拉取请求(PR)包含了 PeerBanHelper 项目的多个重要更新,涉及代码重构、新功能添加和系统配置管理。主要变更包括引入 ExternalSwitch 类来集中配置管理、添加对种子跟踪器的支持、更新依赖版本,以及改进错误处理和用户界面。

变更

文件 变更摘要
.github/workflows/* 更新 Docker 构建操作版本从 v6.11.0 到 v6.12.0
pom.xml 项目版本升级到 7.3.3,Bouncy Castle 库更新到 1.80
src/main/java/com/ghostchu/peerbanhelper/ExternalSwitch.java 新增配置管理实用类,支持从系统属性和环境变量获取配置
多个下载器实现类 添加获取和设置种子跟踪器的方法
数据库相关类 增加对种子隐私状态的支持

可能相关的 PR

建议的审阅者

  • Gaojianli
  • paulzzh

详细变更

工作流程更新

GitHub Actions 工作流文件 .github/workflows/jvm-ci.yml.github/workflows/jvm-release.yml 中的 Docker 构建操作版本从 v6.11.0 更新到 v6.12.0。这是一个次要版本更新,通常包含错误修复和小的改进。

配置管理增强

引入了 ExternalSwitch 类,提供了一个集中的配置管理机制。这个类允许从系统属性和环境变量中获取配置,并提供了多种数据类型的解析方法。这种方法使配置管理更加灵活和集中。

种子跟踪器支持

新增了 Tracker 接口和 TrackerImpl 实现,为不同的下载器提供了统一的跟踪器管理方法。多个下载器实现(如 BiglyBT、BitComet、Transmission)现在支持获取和设置种子的跟踪器列表。

数据库和实体变更

  • TorrentEntity 添加了 privateTorrent 字段,支持记录种子的隐私状态
  • 数据库升级逻辑增加了对新字段的处理
  • 相关类(如 PeerRecordDao)更新以支持种子隐私状态

错误处理和国际化

  • messages.yml 文件中添加了新的错误消息和状态通知
  • 改进了跟踪器相关操作的错误消息
  • 为 BiglyBT 适配器版本兼容性添加了警告消息

用户界面改进

  • Web UI 的 Markdown 渲染现在支持主题感知
  • 添加了新的实用工具控制器,支持替换种子跟踪器

性能和安全性

  • 使用 CountDownLatch 替换 AtomicBoolean 改进了线程同步
  • 在 Web 容器中添加了用户代理安全检查

总结

这个 PR 是一个全面的更新,重点关注配置管理、种子跟踪器支持和系统可用性。通过引入 ExternalSwitch、统一的跟踪器接口和改进的错误处理,项目变得更加灵活和用户友好。


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4fc53e5 and f3ed673.

📒 Files selected for processing (2)
  • src/main/java/com/ghostchu/peerbanhelper/gui/impl/swing/SwingGuiImpl.java (2 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/util/logger/JListAppender.java (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/main/java/com/ghostchu/peerbanhelper/gui/impl/swing/SwingGuiImpl.java
  • src/main/java/com/ghostchu/peerbanhelper/util/logger/JListAppender.java
⏰ Context from checks skipped due to timeout of 300000ms (2)
  • GitHub Check: Build_Installers / install4jc
  • GitHub Check: Build_Docker

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 10

🔭 Outside diff range comments (2)
src/main/java/com/ghostchu/peerbanhelper/util/PBHPortMapper.java (1)

Line range hint 114-119: 建议改进错误处理逻辑

当前实现存在以下问题:

  1. 使用递归调用 mapPort 进行重试可能导致栈溢出
  2. 缺少重试次数限制
  3. 错误消息可以更详细

建议按如下方式重构:

-                                if (ExternalSwitch.parse("pbh.portMapper.disableRefreshFailRetry", "false").equals("true")) {
-                                    return;
-                                }
-                                log.error(tlUI(Lang.PORT_MAPPER_PORT_MAPPING_FAILED, mapper.getSourceAddress().getHostAddress(), mappedPort.getPortType().name(), mappedPort.getInternalPort()), e);
-                                mapPort(mappers, portType, localPort);
+                                if (!ExternalSwitch.parse("pbh.portMapper.disableRefreshFailRetry", "false").equals("true")) {
+                                    log.error(tlUI(Lang.PORT_MAPPER_PORT_MAPPING_FAILED, 
+                                            mapper.getSourceAddress().getHostAddress(),
+                                            mappedPort.getPortType().name(), 
+                                            mappedPort.getInternalPort()) + 
+                                            " 重试次数: " + retryCount, e);
+                                    
+                                    // 使用调度器进行重试而不是递归
+                                    if (retryCount < MAX_RETRY_ATTEMPTS) {
+                                        sched.schedule(() -> {
+                                            mapPort(mappers, portType, localPort);
+                                        }, RETRY_DELAY_SECONDS, TimeUnit.SECONDS);
+                                    } else {
+                                        log.error("端口映射刷新重试次数已达上限,将不再重试");
+                                    }
+                                }

这样可以:

  1. 避免递归调用导致的栈溢出
  2. 添加重试次数限制
  3. 提供更详细的错误信息
  4. 使用调度器进行重试
src/main/java/com/ghostchu/peerbanhelper/Main.java (1)

Line range hint 233-259: 配置目录设置逻辑需要增强错误处理

当前的配置目录设置逻辑存在以下问题:

  1. 缺少对配置目录路径有效性的验证
  2. 没有处理目录创建失败的情况
  3. 环境变量路径可能包含特殊字符

建议添加以下增强:

 private static void setupConfDirectory(String[] args) {
+    try {
         String osName = System.getProperty("os.name");
         String root = "data";
         if (ExternalSwitch.parseBoolean("pbh.usePlatformConfigLocation")) {
             if (osName.contains("Windows")) {
-                root = new File(System.getenv("LOCALAPPDATA"), "PeerBanHelper").getAbsolutePath();
+                String localAppData = System.getenv("LOCALAPPDATA");
+                if (localAppData == null || localAppData.trim().isEmpty()) {
+                    throw new IllegalStateException("LOCALAPPDATA environment variable is not set");
+                }
+                root = new File(localAppData, "PeerBanHelper").getAbsolutePath();
             } else {
                 // ... existing code ...
             }
         }

         if (ExternalSwitch.parse("pbh.datadir") != null) {
-            root = ExternalSwitch.parse("pbh.datadir");
+            String customDataDir = ExternalSwitch.parse("pbh.datadir");
+            if (!new File(customDataDir).isAbsolute()) {
+                throw new IllegalArgumentException("Custom data directory must be an absolute path");
+            }
+            root = customDataDir;
         }

         dataDirectory = new File(root);
+        if (!dataDirectory.exists() && !dataDirectory.mkdirs()) {
+            throw new IOException("Failed to create data directory: " + dataDirectory);
+        }
         // ... similar checks for other directories ...
+    } catch (Exception e) {
+        log.error("Failed to setup configuration directories", e);
+        throw new RuntimeException("Failed to setup configuration directories", e);
+    }
 }
🧹 Nitpick comments (29)
src/main/java/com/ghostchu/peerbanhelper/gui/impl/console/ConsoleGuiImpl.java (1)

35-35: 关闭方法实现更加简洁!

使用 countDownLatch.countDown() 替换同步块和通知机制:

  • 移除了显式同步的复杂性
  • 代码更加简洁明了
  • 正确地通知等待线程

建议:考虑添加日志记录,以便于调试和监控。

 @Override
 public void close() {
+    log.debug("正在关闭控制台GUI实现...");
     countDownLatch.countDown();
+    log.debug("控制台GUI实现已关闭");
 }
src/main/java/com/ghostchu/peerbanhelper/downloader/impl/qbittorrent/AbstractQbittorrent.java (1)

216-284: Tracker 管理实现建议改进

当前实现基本完善,但建议做如下改进:

  1. addTracker 方法中添加对 tracker URL 的格式验证
  2. 在错误信息中包含更具体的失败原因,而不是仅显示状态码

建议的改进实现:

 private void addTracker(Torrent torrent, List<Tracker> newAdded) {
     StringJoiner joiner = new StringJoiner("\n");
-    newAdded.forEach(t -> t.getTrackersInGroup().forEach(joiner::add));
+    newAdded.forEach(t -> t.getTrackersInGroup().forEach(url -> {
+        if (!isValidTrackerUrl(url)) {
+            throw new IllegalArgumentException("Invalid tracker URL: " + url);
+        }
+        joiner.add(url);
+    }));
     try {
         HttpResponse<String> request = httpClient.send(MutableRequest
                         .POST(apiEndpoint + "/torrents/addTrackers", FormBodyPublisher.newBuilder()
                                 .query("hash", torrent.getId())
                                 .query("urls", joiner.toString()).build())
                         .header("Content-Type", "application/x-www-form-urlencoded")
                 , HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8));
         if (request.statusCode() != 200) {
-            throw new IllegalStateException("Add qBittorrent tracker error: statusCode=" + request.statusCode());
+            throw new IllegalStateException(String.format("Failed to add trackers: status=%d, response=%s", 
+                request.statusCode(), request.body()));
         }
     } catch (Exception e) {
         throw new IllegalStateException(e);
     }
 }

+private boolean isValidTrackerUrl(String url) {
+    try {
+        new URL(url);
+        return true;
+    } catch (MalformedURLException e) {
+        return false;
+    }
+}
src/main/java/com/ghostchu/peerbanhelper/torrent/TrackerImpl.java (1)

24-27: 建议重命名构造函数参数以提高可读性

在构造函数public TrackerImpl(List<String> string)中,参数string实际上是一个字符串列表。建议将参数名称修改为stringstrackerList,以提高代码的可读性并减少混淆。

src/main/java/com/ghostchu/peerbanhelper/downloader/impl/transmission/Transmission.java (2)

133-136: 建议将硬编码字符串提取为常量

在第133行,ExternalSwitch.parse方法中直接使用了一个非常长的硬编码字符串。为了提高代码的可维护性和可读性,建议将该字符串提取为常量或配置项。


244-246: 建议将硬编码字符串提取为常量

在第244行,ExternalSwitch.parse方法中直接使用了硬编码字符串。为提升代码的可维护性,建议将此字符串提取为常量或配置项。

git-hooks/pre-commit (1)

18-20: 显著提升了代码检查性能

通过 xargs -P 4 实现并行处理,可以加快 prettier 和 eslint 的执行速度。建议考虑将并行度设置为可配置项,以适应不同的硬件环境。

Also applies to: 26-28

src/main/java/com/ghostchu/peerbanhelper/downloader/impl/qbittorrent/impl/QBittorrentTorrentTrackers.java (1)

10-25: 建议添加字段说明文档

虽然字段命名清晰,但建议为每个字段添加 Javadoc 注释,说明其用途和可能的取值范围,特别是 status 字段的不同状态含义。

示例文档格式:

+    /**
+     * 跟踪器状态码
+     * 1: 工作中
+     * 2: 更新中
+     * 3: 未能连接
+     * 4: 禁用
+     */
     @JsonProperty("status")
     private Integer status;
webui/src/components/markdown.vue (1)

20-23: 主题切换实现合理

通过 data-theme 属性实现深色/浅色主题切换的方法很好,但建议考虑以下几点改进:

  1. 考虑添加主题切换过渡动画以提升用户体验
  2. 建议将 CSS 样式提取到单独的样式文件中

建议的实现方式:

     <html data-theme="${darkStore.isDark ? 'dark' : 'light'}">
+    <style>
+      html {
+        transition: background-color 0.3s ease;
+      }
+    </style>
     <link rel="stylesheet" href="./style/github-markdown-css.css"/>
src/main/java/com/ghostchu/peerbanhelper/downloader/impl/biglybt/network/wrapper/DownloadRecord.java (1)

33-33: 建议优化 trackers 字段的数据结构

使用嵌套的 List<List> 结构可能会导致内存使用效率低下。建议考虑以下几点:

  1. 使用专门的 Tracker 类来封装tracker信息
  2. 考虑使用 Set 来避免重复数据
  3. 为大量数据场景添加分页支持
-    private List<List<String>> trackers;
+    private Set<TrackerInfo> trackers;
src/main/java/com/ghostchu/peerbanhelper/downloader/impl/bitcomet/resp/BCTaskTrackersResponse.java (2)

13-18: 建议添加错误码验证逻辑

errorCode 字段应该添加验证逻辑,建议:

  1. 定义错误码常量
  2. 添加错误码验证方法

23-40: 优化 TrackersDTO 类的性能和可靠性

建议进行以下优化:

  1. 将 Integer 类型改为原始类型 int,减少装箱拆箱开销
  2. 添加字段非空检查
  3. 为 status 和 flag 字段添加枚举类型约束
-        private Integer retries;
-        private Integer seeders;
-        private Integer leechers;
-        private Integer peers;
-        private Integer downloaded;
+        private int retries;
+        private int seeders;
+        private int leechers;
+        private int peers;
+        private int downloaded;

-        private String status;
-        private String flag;
+        private TrackerStatus status;
+        private TrackerFlag flag;
src/main/java/com/ghostchu/peerbanhelper/downloader/impl/transmission/TRTorrent.java (1)

73-76: 建议添加空值检查

建议在调用 backend.getTrackerList() 时添加空值检查,以防止 NPE:

     public List<Tracker> getTrackers() {
-        return TrackerImpl.parseFromTrackerList(backend.getTrackerList());
+        List<String> trackerList = backend.getTrackerList();
+        return trackerList != null ? TrackerImpl.parseFromTrackerList(trackerList) : Collections.emptyList();
     }
src/main/java/com/ghostchu/peerbanhelper/decentralized/DecentralizedManager.java (2)

45-46: 优化重复的 ExternalSwitch.parse 调用

建议将重复的 ExternalSwitch.parse("pbh.kuboRPC") 调用优化为单次调用:

-            if (ExternalSwitch.parse("pbh.kuboRPC") != null) {
-                ipfsRpc = ExternalSwitch.parse("pbh.kuboRPC");
+            String kuboRpc = ExternalSwitch.parse("pbh.kuboRPC");
+            if (kuboRpc != null) {
+                ipfsRpc = kuboRpc;
             }

45-46: 建议将配置键值提取为常量

建议将魔法字符串 "pbh.kuboRPC" 提取为类级别的常量:

 public class DecentralizedManager implements AutoCloseable, Reloadable {
+    private static final String KUBO_RPC_KEY = "pbh.kuboRPC";
     private final Laboratory laboratory;
src/main/java/com/ghostchu/peerbanhelper/database/dao/impl/TorrentDao.java (1)

46-49: 建议添加注释说明私有种子状态更新逻辑

为了提高代码可维护性,建议添加注释说明仅在现有记录的 privateTorrent 为空且新数据不为空时才更新的业务逻辑原因:

+        // 仅当现有记录中未设置私有状态且新数据包含私有状态时才更新,
+        // 这样可以避免已确认的私有状态被覆盖
         if (entity.getPrivateTorrent() == null && data.getPrivateTorrent() != null) {
             entity.setPrivateTorrent(data.getPrivateTorrent());
             anyUpdated = true;
         }
src/main/java/com/ghostchu/peerbanhelper/downloader/impl/biglybt/network/BiglyBTTorrent.java (2)

10-10: 建议简化 trackers 数据结构

List<List<String>> 的嵌套结构较为复杂,建议创建专门的 TrackerGroup 类来封装这个数据结构,提高代码可读性和可维护性:

public class TrackerGroup {
    private final List<String> urls;
    // 构造函数、getter等
}

然后修改字段类型:

-    private final List<List<String>> trackers;
+    private final List<TrackerGroup> trackers;

79-81: 建议添加 @OverRide 注解

getTrackers() 方法应该添加 @Override 注解,因为它实现了接口方法:

+    @Override
     public List<List<String>> getTrackers() {
         return trackers;
     }
src/main/java/com/ghostchu/peerbanhelper/ExternalSwitch.java (1)

8-15: 建议增加异常处理和文档说明

  1. 建议添加 JavaDoc 说明环境变量的命名规则转换(例如:my.config 转换为 MY_CONFIG
  2. 建议添加参数非空检查
 public class ExternalSwitch {
+    /**
+     * 从系统属性或环境变量中解析配置值。
+     * 环境变量命名规则:
+     * - 将点号(.)替换为下划线(_)
+     * - 将连字符(-)替换为下划线(_)
+     * - 转换为大写
+     * 例如:my.config-name -> MY_CONFIG_NAME
+     *
+     * @param args 配置键名
+     * @param def 默认值
+     * @return 解析后的值,如未找到则返回默认值
+     * @throws IllegalArgumentException 当参数为 null 时
+     */
     public static String parse(String args, @Nullable String def) {
+        if (args == null) {
+            throw new IllegalArgumentException("args cannot be null");
+        }
         var value = System.getProperty(args);
src/main/java/com/ghostchu/peerbanhelper/downloader/Downloader.java (1)

98-110: 建议为 setTrackers 方法添加参数验证

为了确保接口的健壮性,建议在 setTrackers 方法的文档中说明参数验证规则,比如:

  • trackers 列表是否可以为 null
  • trackers 列表是否可以为空
  • torrent 是否必须存在
src/main/java/com/ghostchu/peerbanhelper/database/DatabaseHelper.java (1)

83-92: 建议改进数据库升级错误处理

当前的错误处理比较简单,建议:

  1. 记录具体的 SQL 语句到错误日志
  2. 区分不同类型的 SQL 异常(如列已存在、权限问题等)
  3. 考虑添加回滚机制
 try {
     // add new column: privateTorrent, nullable
     var torrentDao = DaoManager.createDao(getDataSource(), TorrentEntity.class);
-    torrentDao.executeRaw("ALTER TABLE " + torrentDao.getTableName() + " ADD COLUMN privateTorrent BOOLEAN NULL");
+    String sql = "ALTER TABLE " + torrentDao.getTableName() + " ADD COLUMN privateTorrent BOOLEAN NULL";
+    log.debug("执行数据库升级 SQL: {}", sql);
+    torrentDao.executeRaw(sql);
 } catch (Exception err) {
-    log.error("Unable to upgrade database schema", err);
+    log.error("数据库升级失败,SQL 执行出错: {}", err.getMessage(), err);
+    if (err instanceof SQLException sqlException) {
+        log.error("SQL 状态: {}, 错误码: {}", sqlException.getSQLState(), sqlException.getErrorCode());
+    }
 }
src/main/java/com/ghostchu/peerbanhelper/database/Database.java (1)

Line range hint 83-107: 建议改进数据库备份逻辑

当前的备份和清理逻辑可以进一步优化:

  1. 建议添加备份文件的保留时间配置
  2. 考虑在备份失败时提供重试机制
  3. 可以添加备份文件的压缩级别配置
 try {
     backupDatabase(file, outputBackup);
     long fileSize = file.length();
     stmt.executeUpdate("VACUUM;");
     long newFileSize = file.length();
     log.info(tlUI(Lang.SQLITE_VACUUM_SUCCESS, MsgUtil.humanReadableByteCountBin(fileSize), MsgUtil.humanReadableByteCountBin(newFileSize)));
 } catch (IOException e) {
     log.warn(tlUI(Lang.SQLITE_VACUUM_BACKUP_FAILED), e);
+    // 添加重试逻辑
+    if (laboratory.isExperimentActivated(Experiments.BACKUP_RETRY.getExperiment())) {
+        log.info(tlUI(Lang.SQLITE_VACUUM_BACKUP_RETRY));
+        // 实现重试逻辑
+    }
 } finally {
-    outputBackup.delete();
+    if (outputBackup.exists() && !keepBackup()) {
+        outputBackup.delete();
+    }
 }
src/main/java/com/ghostchu/peerbanhelper/web/JavalinWebContainer.java (2)

48-48: 配置管理优化建议

建议将被阻止的 User-Agent 列表移至配置文件中,而不是硬编码在代码中。这样可以更灵活地管理和更新阻止列表。

建议添加配置项:

-private static final String[] blockUserAgent = new String[]{"censys", "shodan", "zoomeye", "threatbook", "fofa", "zmap", "nmap", "archive"};
+private static final String[] blockUserAgent = ExternalSwitch.parse("PBH_BLOCK_USER_AGENTS", "censys,shodan,zoomeye,threatbook,fofa,zmap,nmap,archive").split(",");

Also applies to: 68-68


162-163: 注释掉的代码需要清理

建议删除被注释掉的 robots.txt 相关代码,保持代码整洁。

-//.get("/robots.txt", ctx -> ctx.result("User-agent: *\nDisallow: /"));
src/main/java/com/ghostchu/peerbanhelper/module/impl/rule/ExpressionRule.java (1)

170-170: 安全开关命名建议

当前的安全开关名称过长且可读性较差。建议:

  1. 使用更简洁的命名
  2. 将警告信息移至文档或日志中
-var value = ExternalSwitch.parse("pbh.please-disable-safe-network-environment-check-i-know-this-is-very-dangerous-and-i-may-lose-my-data-and-hacker-may-attack-me-via-this-endpoint-and-steal-my-data-or-destroy-my-computer-i-am-fully-responsible-for-this-action-and-i-will-not-blame-the-developer-for-any-loss");
+var value = ExternalSwitch.parse("pbh.disable_safe_network_check");
+if (value != null && value.equals("true")) {
+    log.warn("安全网络环境检查已禁用。这可能导致安全风险,包括数据泄露或系统损坏。请确保您了解相关风险。");
+    return true;
+}
src/main/java/com/ghostchu/peerbanhelper/module/impl/rule/ProgressCheatBlocker.java (1)

305-305: 建议优化配置检查逻辑

当前的配置检查逻辑可以进一步优化:

  1. ExternalSwitch.parse("pbh.pcb.disable-completed-excessive") == null 的判断可能不够严谨,建议使用 ExternalSwitch.parseBoolean() 来明确处理布尔值
  2. 考虑添加配置项的默认值,避免空值判断

建议修改为:

-} else if (ExternalSwitch.parse("pbh.pcb.disable-completed-excessive") == null && completedSize > 0 && actualUploaded > completedSize) {
+} else if (!ExternalSwitch.parseBoolean("pbh.pcb.disable-completed-excessive", false) && completedSize > 0 && actualUploaded > completedSize) {
src/main/java/com/ghostchu/peerbanhelper/module/impl/webapi/PBHGeneralController.java (1)

164-167: 建议添加版本号验证

在获取发布版本时:

  1. 建议添加版本号格式验证
  2. 考虑缓存版本号,避免重复解析

建议添加版本号验证:

+private static final Pattern VERSION_PATTERN = Pattern.compile("^\\d+\\.\\d+\\.\\d+(?:-[a-zA-Z0-9]+)?$");
+private static String cachedRelease;

 private Map<String, Object> generatePbhData() {
-    String release = ExternalSwitch.parse("pbh.release");
-    if (release == null) {
-        release = "unknown";
-    }
+    if (cachedRelease == null) {
+        String release = ExternalSwitch.parse("pbh.release");
+        if (release != null && VERSION_PATTERN.matcher(release).matches()) {
+            cachedRelease = release;
+        } else {
+            cachedRelease = "unknown";
+        }
+    }
src/main/java/com/ghostchu/peerbanhelper/downloader/impl/bitcomet/BitComet.java (1)

333-358: 实现正确,建议优化!

getTrackers() 方法实现合理,但建议考虑以下优化:

  • 考虑将 tracker URL 过滤逻辑抽取为单独的方法,提高代码可读性
  • 可以添加对 tracker 响应超时的处理
src/main/resources/lang/zh_cn/messages.yml (1)

566-567: 消息描述准确,但需要添加文件结束换行符!

两条消息的描述都很准确:

  • Tracker 替换成功消息清晰地显示了替换的数量
  • BiglyBT 适配器版本不兼容的错误消息包含了版本要求信息

建议在文件末尾添加换行符:

DOWNLOADER_BIGLYBT_INCORRECT_ADAPTER_VERSION: "当前使用的 BiglyBT 适配器版本不受支持,请升级到 {} 或更高版本"
+
🧰 Tools
🪛 yamllint (1.35.1)

[error] 567-567: no new line character at the end of file

(new-line-at-end-of-file)

src/main/resources/lang/en_us/messages.yml (1)

570-570: 修复英文翻译中的多余空格

英文翻译中 "to" 和 "or" 之间存在多余的空格。

-DOWNLOADER_BIGLYBT_INCORRECT_ADAPTER_VERSION: "Currently installed BiglyBT adapter version is NOT supported, please upgrade to  {} or higher."
+DOWNLOADER_BIGLYBT_INCORRECT_ADAPTER_VERSION: "Currently installed BiglyBT adapter version is NOT supported, please upgrade to {} or higher."
🧰 Tools
🪛 yamllint (1.35.1)

[error] 570-570: no new line character at the end of file

(new-line-at-end-of-file)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between acda442 and 5c79ad2.

📒 Files selected for processing (50)
  • .github/workflows/jvm-ci.yml (2 hunks)
  • .github/workflows/jvm-release.yml (2 hunks)
  • git-hooks/pre-commit (1 hunks)
  • pom.xml (2 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/BuildMeta.java (1 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/ExternalSwitch.java (1 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/Main.java (8 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/PeerBanHelperServer.java (3 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/btn/ability/BtnAbilitySubmitHistory.java (4 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/btn/ping/BtnPeer.java (2 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/btn/ping/BtnPeerHistory.java (1 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/database/Database.java (2 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/database/DatabaseHelper.java (1 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/database/dao/impl/PeerRecordDao.java (2 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/database/dao/impl/TorrentDao.java (1 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/database/table/TorrentEntity.java (2 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/decentralized/DecentralizedManager.java (2 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/downloader/Downloader.java (3 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/downloader/impl/biglybt/BiglyBT.java (8 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/downloader/impl/biglybt/network/BiglyBTTorrent.java (1 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/downloader/impl/biglybt/network/wrapper/DownloadRecord.java (1 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/downloader/impl/bitcomet/BCEndpoint.java (1 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/downloader/impl/bitcomet/BitComet.java (4 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/downloader/impl/bitcomet/resp/BCTaskTrackersResponse.java (1 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/downloader/impl/deluge/Deluge.java (3 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/downloader/impl/qbittorrent/AbstractQbittorrent.java (7 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/downloader/impl/qbittorrent/impl/QBittorrentTorrentTrackers.java (1 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/downloader/impl/transmission/TRTorrent.java (2 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/downloader/impl/transmission/Transmission.java (7 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/gui/impl/console/ConsoleGuiImpl.java (2 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/metric/impl/persist/PersistMetrics.java (1 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/module/impl/rule/ExpressionRule.java (2 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/module/impl/rule/ProgressCheatBlocker.java (2 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/module/impl/webapi/PBHEasterEggController.java (1 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/module/impl/webapi/PBHGeneralController.java (2 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/module/impl/webapi/PBHUtilitiesController.java (1 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/text/Lang.java (1 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/torrent/Tracker.java (1 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/torrent/TrackerImpl.java (1 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/util/PBHPortMapper.java (2 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/util/network/DFSSLSocketFactory.java (2 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/web/JavalinWebContainer.java (5 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/wrapper/TorrentWrapper.java (2 hunks)
  • src/main/java/raccoonfink/deluge/DelugeServer.java (0 hunks)
  • src/main/resources/lang/en_us/messages.yml (1 hunks)
  • src/main/resources/lang/messages_fallback.yml (1 hunks)
  • src/main/resources/lang/zh_cn/messages.yml (1 hunks)
  • webui/public/style/github-markdown-css.css (3 hunks)
  • webui/src/components/markdown.vue (1 hunks)
  • webui/src/views/settings/components/config/components/btn.vue (2 hunks)
💤 Files with no reviewable changes (1)
  • src/main/java/raccoonfink/deluge/DelugeServer.java
✅ Files skipped from review due to trivial changes (4)
  • src/main/java/com/ghostchu/peerbanhelper/downloader/impl/bitcomet/BCEndpoint.java
  • webui/src/views/settings/components/config/components/btn.vue
  • .github/workflows/jvm-release.yml
  • .github/workflows/jvm-ci.yml
🧰 Additional context used
📓 Learnings (1)
src/main/java/com/ghostchu/peerbanhelper/module/impl/webapi/PBHEasterEggController.java (1)
Learnt from: Ghost-chu
PR: PBH-BTN/PeerBanHelper#880
File: src/main/java/com/ghostchu/peerbanhelper/module/impl/webapi/PBHEasterEggController.java:75-86
Timestamp: 2025-01-08T17:57:58.596Z
Learning: The playful implementation in PBHEasterEggController, including casual error messages and non-standard HTTP status codes, is intentionally designed as part of the easter egg functionality and should not be "professionalized".
🪛 yamllint (1.35.1)
src/main/resources/lang/messages_fallback.yml

[error] 570-570: no new line character at the end of file

(new-line-at-end-of-file)

src/main/resources/lang/en_us/messages.yml

[error] 570-570: no new line character at the end of file

(new-line-at-end-of-file)

src/main/resources/lang/zh_cn/messages.yml

[error] 567-567: no new line character at the end of file

(new-line-at-end-of-file)

🔇 Additional comments (47)
src/main/java/com/ghostchu/peerbanhelper/util/PBHPortMapper.java (1)

3-3: 导入声明看起来不错!

新增的 ExternalSwitch 导入符合代码重构的目标。

src/main/java/com/ghostchu/peerbanhelper/gui/impl/console/ConsoleGuiImpl.java (3)

7-7: 导入声明看起来不错!

新增的 CountDownLatch 导入语句与代码改动保持一致。


12-12: 很好的同步机制改进!

使用 CountDownLatch 替换 AtomicBoolean 是个明智的选择:

  • CountDownLatch 更适合实现一次性的线程同步
  • 代码更简洁,更易于理解
  • 减少了显式锁定的需求

30-30: 同步方法实现更加优雅!

使用 countDownLatch.await() 替换原有的 while 循环检查:

  • 消除了可能的忙等待问题
  • 提高了代码的可读性
  • 更好地处理线程中断情况
src/main/java/com/ghostchu/peerbanhelper/downloader/impl/qbittorrent/AbstractQbittorrent.java (3)

164-167: 登录验证逻辑的改进!

将登录验证从检查 qt 版本改为检查 libtorrent 版本是一个更可靠的方案,因为 libtorrent 是 qBittorrent 的核心组件。


Line range hint 184-214: 种子列表获取逻辑优化!

代码改进:

  1. 通过 fetchTorrents() 方法统一处理种子列表获取逻辑
  2. 新增 getAllTorrents() 方法提供更灵活的获取选项
  3. 根据配置正确处理私有种子的过滤

这些更改提高了代码的可维护性和灵活性。


457-458: Record 定义清晰简洁!

TorrentProperties record 的定义符合 Java 最佳实践,使用了 record 特性来简化数据类的定义。

src/main/java/com/ghostchu/peerbanhelper/util/network/DFSSLSocketFactory.java (2)

3-3: 导入更改看起来不错!

引入 ExternalSwitch 类的导入符合代码库中统一配置管理的最佳实践。


37-37: 请验证域前置(Domain Fronting)配置更改的安全影响

配置获取方式的更改看起来是正确的,但建议:

  1. 验证此更改不会影响现有的域前置功能
  2. 在文档中说明如何通过环境变量配置此选项

执行以下脚本来验证配置更改的影响:

✅ Verification successful

域前置配置更改已验证安全

配置变更从 System.getPropertyExternalSwitch 是一项改进:

  • 同时支持系统属性(pbh.domain-fronting)和环境变量(PBH_DOMAIN_FRONTING
  • 保持了原有的默认值(true)
  • 实现安全且健壮

建议:在项目文档中添加配置说明,特别是环境变量的使用方法。

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# 描述:检查域前置配置的使用情况和相关安全设置

# 搜索域前置配置的使用位置
rg -l "pbh.domain-fronting"

# 检查是否有相关的安全测试
rg -l "test.*domain.*front" --type-add 'test:*{Test,test}.java' --type test

Length of output: 332


Script:

#!/bin/bash
# Check ExternalSwitch implementation
echo "=== ExternalSwitch Implementation ==="
ast-grep --pattern 'class ExternalSwitch {
  $$$
}'

# Look for any domain fronting related tests with broader patterns
echo -e "\n=== Domain Fronting Tests ==="
rg -l "DFSSLSocketFactory" --type-add 'test:*{Test,test}.java' --type test

# Search for documentation
echo -e "\n=== Configuration Documentation ==="
fd -e md -e txt . | xargs rg -l "domain.*front|pbh\.domain-fronting"

Length of output: 595


Script:

#!/bin/bash
# Try to find ExternalSwitch file
echo "=== ExternalSwitch File ==="
fd ExternalSwitch

# Look for SSL related tests
echo -e "\n=== SSL Tests ==="
rg -l "SSL|Socket" --type-add 'test:*{Test,test}.java' --type test

# Check imports in DFSSLSocketFactory
echo -e "\n=== DFSSLSocketFactory Imports ==="
rg "^import.*ExternalSwitch" src/main/java/com/ghostchu/peerbanhelper/util/network/DFSSLSocketFactory.java

Length of output: 658


Script:

#!/bin/bash
# Check ExternalSwitch implementation
echo "=== ExternalSwitch Implementation ==="
cat src/main/java/com/ghostchu/peerbanhelper/ExternalSwitch.java

# Check if there are any existing environment variable docs
echo -e "\n=== Environment Variable Documentation ==="
fd README -e md | xargs rg -l "环境变量|environment.*variable"

Length of output: 3197

src/main/java/com/ghostchu/peerbanhelper/torrent/TrackerImpl.java (1)

35-40: ⚠️ Potential issue

修复getLeadingTracker()方法中的错误

getLeadingTracker()方法中,List接口不存在getFirst()方法。应使用trackers.get(0)来获取第一个元素,否则会导致编译错误。

建议修改代码如下:

-        return trackers.getFirst();
+        return trackers.get(0);

Likely invalid or redundant comment.

src/main/java/com/ghostchu/peerbanhelper/btn/ability/BtnAbilitySubmitHistory.java (1)

137-138: ⚠️ Potential issue

修复btnPeers.getLast()方法的用法

List接口没有getLast()方法,应使用btnPeers.get(btnPeers.size() - 1)来获取最后一个元素,否则会导致编译错误。

建议修改代码如下:

-                    var lastRecordAt = btnPeers.getLast().getLastTimeSeen().getTime();
+                    var lastRecordAt = btnPeers.get(btnPeers.size() - 1).getLastTimeSeen().getTime();

Likely invalid or redundant comment.

src/main/java/com/ghostchu/peerbanhelper/downloader/impl/transmission/Transmission.java (3)

142-143: 代码逻辑清晰

getTorrents方法正确调用了fetchTorrents并传递了适当的参数,逻辑清晰且实现正确。


145-148: 新增getAllTorrents方法

getAllTorrents方法能够获取所有种子,包括私有种子,逻辑正确,实现合理。


170-174: getTrackers方法实现正确

成功获取指定种子的Tracker列表,逻辑正确。

src/main/java/com/ghostchu/peerbanhelper/downloader/impl/biglybt/BiglyBT.java (2)

220-227: getTrackers方法实现正确

成功从BiglyBTTorrent对象中获取Tracker列表,逻辑正确。


229-248: setTrackers方法实现正确

成功更新种子的Tracker列表,并对响应结果进行了验证,逻辑合理。

src/main/java/com/ghostchu/peerbanhelper/torrent/Tracker.java (1)

1-10: 新增Tracker接口

新接口Tracker定义了获取Tracker组列表和主Tracker的方法,设计合理,便于扩展。

src/main/java/com/ghostchu/peerbanhelper/database/table/TorrentEntity.java (1)

23-25: 新增的 privateTorrent 字段实现合理

字段的类型选择和注解使用都很恰当。使用包装类型 Boolean 而不是原始类型 boolean 是个好的选择,因为它可以表示未知状态(null)。

git-hooks/pre-commit (1)

15-17: 优化了文件路径处理逻辑

使用 sed 命令移除 webui/ 前缀的方法简洁有效。

src/main/java/com/ghostchu/peerbanhelper/downloader/impl/qbittorrent/impl/QBittorrentTorrentTrackers.java (1)

7-9: 类的注解使用恰当

使用 Lombok 的 @NoArgsConstructor@DaTa 注解可以有效减少样板代码。

src/main/java/com/ghostchu/peerbanhelper/wrapper/TorrentWrapper.java (1)

17-17: 代码变更正确实现了私有种子标记

privateTorrent 字段的添加和初始化逻辑符合预期,能够正确标识私有种子状态。

Also applies to: 28-28

src/main/java/com/ghostchu/peerbanhelper/BuildMeta.java (1)

20-21: 建议增强配置读取的错误处理

当前使用 ExternalSwitch.parse 读取配置值,但缺少以下处理:

  1. 配置值为空的错误处理
  2. 配置格式验证
  3. 日志记录

建议验证配置读取的健壮性:

src/main/java/com/ghostchu/peerbanhelper/btn/ping/BtnPeerHistory.java (1)

24-25: 新增私有种子标识字段

字段添加合理,使用 @SerializedName 注解确保了与 JSON 序列化的兼容性。这个改动与 PR 中提到的新增私有种子识别功能相符。

src/main/java/com/ghostchu/peerbanhelper/btn/ping/BtnPeer.java (2)

27-28: 新增私有种子标识字段

字段添加合理,与 BtnPeerHistory 类保持一致。


58-58: 正确设置私有种子状态

通过 torrent.isPrivateTorrent() 设置私有种子状态,实现完整。

src/main/java/com/ghostchu/peerbanhelper/module/impl/webapi/PBHEasterEggController.java (2)

70-71: API 路径结构优化

将 neuro 相关端点移至 /api/egg 路径下,提高了 API 结构的清晰度和一致性。


77-77: 资源文件命名更新

资源文件从 "neuro.png" 更新为 "Neuro.png"。请确保部署时资源文件名大小写正确,避免在大小写敏感的文件系统中出现问题。

✅ Verification successful

资源文件名称验证完成

已确认资源文件 src/main/resources/assets/other/Neuro.png 存在且大小写完全匹配代码中的引用。无需进行任何更改。

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# 验证资源文件是否存在且大小写正确
find src/main/resources -type f -name "Neuro.png" -o -name "neuro.png" | sort

Length of output: 117

src/main/java/com/ghostchu/peerbanhelper/downloader/Downloader.java (1)

83-89: 方法签名和文档看起来不错!

新增的 getAllTorrents() 方法补充了现有的 getTorrents() 方法,使接口更加完整。

src/main/java/com/ghostchu/peerbanhelper/database/dao/impl/PeerRecordDao.java (2)

50-50: 请确认更改排序顺序的影响

lastTimeSeen 的排序从降序改为升序可能会影响数据处理的顺序。请确认:

  1. 上游代码是否依赖于特定的排序顺序
  2. 性能是否会受到影响(例如索引使用)

59-60: privateTorrent 参数的添加符合预期

新增的 privateTorrent 参数集成得当,保持了代码的清晰度。

src/main/java/com/ghostchu/peerbanhelper/database/Database.java (1)

75-75: 配置管理改进很好

使用 ExternalSwitch.parse 替换 System.getProperty 是个很好的改进:

  1. 提供了更统一的配置管理方式
  2. 使配置更容易维护和文档化

Also applies to: 83-83

src/main/java/com/ghostchu/peerbanhelper/metric/impl/persist/PersistMetrics.java (1)

102-103: 代码变更正确且符合需求!

新增的 isPrivateTorrent() 参数用于跟踪种子的私有状态,这与 PR 目标中提到的"数据收集变更"相符。

src/main/java/com/ghostchu/peerbanhelper/web/JavalinWebContainer.java (1)

124-128: 安全检查实现正确

安全检查的实现符合 PR 目标中提到的安全增强要求,通过检查 User-Agent 来阻止特定的网络扫描工具。

src/main/java/com/ghostchu/peerbanhelper/text/Lang.java (1)

499-504: 新增的常量需要确保在 messages.yml 中有对应的翻译

这些新增的常量涉及下载器和 Tracker 相关的错误处理,请确保:

  1. messages.ymlmessages_fallback.yml 中添加对应的翻译文本
  2. 所有支持的语言都有这些新消息的翻译
✅ Verification successful

所有新增常量已有对应翻译

所有新增的常量已在中文翻译文件和后备翻译文件中找到对应的翻译文本。

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# 检查新增常量是否在消息文件中有对应的翻译
for constant in "BTN_CONFIG_STATUS_EXCEPTION" "DOWNLOADER_FAILED_REQUEST_TRACKER_LIST_ON_TORRENT" "TRACKER_FAILED_TO_UPDATE_TRACKER" "UTILITIES_TRACKER_REPLACED" "DOWNLOADER_BIGLYBT_INCORRECT_ADAPTER_VERSION"; do
  echo "Checking translations for $constant"
  rg -l "$constant" src/main/resources/messages*.yml || echo "Missing translation for $constant"
done

Length of output: 3139


Script:

#!/bin/bash
# First, find all message files
echo "Looking for message files:"
fd messages.yml
fd messages_.*\.yml

# Then check the content of these files
echo -e "\nChecking file contents:"
fd messages.*\.yml -x cat {}

Length of output: 111326


Script:

#!/bin/bash
echo "检查中文翻译文件内容:"
for constant in "BTN_CONFIG_STATUS_EXCEPTION" "MATCH_STRING_STARTS_WITH" "DOWNLOADER_FAILED_REQUEST_TRACKER_LIST_ON_TORRENT" "TRACKER_FAILED_TO_UPDATE_TRACKER" "UTILITIES_TRACKER_REPLACED" "DOWNLOADER_BIGLYBT_INCORRECT_ADAPTER_VERSION"; do
  echo "检查 $constant"
  rg "$constant:" "src/main/resources/lang/zh_cn/messages.yml"
done

echo -e "\n检查后备翻译文件内容:"
for constant in "BTN_CONFIG_STATUS_EXCEPTION" "MATCH_STRING_STARTS_WITH" "DOWNLOADER_FAILED_REQUEST_TRACKER_LIST_ON_TORRENT" "TRACKER_FAILED_TO_UPDATE_TRACKER" "UTILITIES_TRACKER_REPLACED" "DOWNLOADER_BIGLYBT_INCORRECT_ADAPTER_VERSION"; do
  echo "检查 $constant"
  rg "$constant:" "src/main/resources/lang/messages_fallback.yml"
done

Length of output: 5767

src/main/java/com/ghostchu/peerbanhelper/Main.java (1)

100-101: 协议版本更新需要确保兼容性

协议版本从 8 升级到 10 是一个重要变更:

  1. 需要确保与旧版本客户端的向后兼容性
  2. 建议在更新日志中说明协议版本变更的原因和影响
  3. 考虑添加协议版本协商机制
src/main/java/com/ghostchu/peerbanhelper/downloader/impl/bitcomet/BitComet.java (3)

268-278: 代码重构得当!

getTorrents() 和 getAllTorrents() 方法的实现通过复用 fetchTorrents() 提高了代码的可维护性。同时通过参数控制是否包含私有种子,增加了灵活性。


Line range hint 281-331: 实现完善,处理得当!

fetchTorrents() 方法实现了以下亮点:

  • 完善的错误处理机制
  • 高效的流式处理
  • 合理的私有种子过滤逻辑

398-399: 兼容性处理得当!

getPeers() 方法中的修改很好地处理了不同版本 BitComet 客户端的兼容性问题,通过灵活的过滤条件支持了多个版本。

src/main/java/com/ghostchu/peerbanhelper/PeerBanHelperServer.java (2)

200-201: 条件判断逻辑清晰!

使用 ExternalSwitch.parse() 替代直接的系统属性检查,提高了配置管理的灵活性。


737-737: 模块注册完善!

新增 PBHUtilitiesController 模块的注册,保持了代码结构的一致性。

pom.xml (2)

9-9: 版本更新合理!

项目版本从 7.3.2 升级到 7.3.3,符合语义化版本规范。


435-441: 依赖版本更新恰当!

Bouncy Castle 库(bcprov-jdk18on 和 bcpg-jdk18on)更新到 1.80 版本,建议验证此版本的兼容性。

✅ Verification successful

Bouncy Castle 1.80 版本更新验证完成!

经过代码分析,确认此版本更新是安全的:

  • 仅在 BCAESTool.java 中使用了 Bouncy Castle
  • 使用的都是稳定的核心加密 API
  • 未发现任何兼容性风险
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# 检查 Maven 中央仓库中 Bouncy Castle 1.80 版本的发布日期和兼容性说明
curl -s "https://repo1.maven.org/maven2/org/bouncycastle/bcprov-jdk18on/1.80/bcprov-jdk18on-1.80.pom" | grep -A 5 "<description>"

Length of output: 551


Script:

#!/bin/bash
# Search for Bouncy Castle API usage
echo "=== Searching for BouncyCastle imports ==="
rg "import org\.bouncycastle" -l

echo -e "\n=== Searching for BC provider initialization ==="
rg "Security\.addProvider.*BC|new BouncyCastleProvider" -l

echo -e "\n=== Searching for specific BC API usage ==="
rg "PGP|GPG|SecurityProvider|BouncyCastle" -l

Length of output: 850


Script:

#!/bin/bash
echo "=== Checking BCAESTool implementation ==="
cat src/main/java/com/ghostchu/peerbanhelper/downloader/impl/bitcomet/crypto/BCAESTool.java

Length of output: 2734

webui/public/style/github-markdown-css.css (2)

11-16: 主题样式设置合理!

为 html 元素添加明确的背景色设置:

  • 浅色主题使用 #fff
  • 深色主题使用 #2a2a2b
    确保了主题切换时的视觉一致性。

49-49: 主题变量定义清晰!

markdown-body 的主题变量设置合理:

  • 深色主题背景色设为 #2a2a2b
  • 浅色主题背景色设为 #fff
    避免了对其他变量的依赖。

Also applies to: 102-102

src/main/resources/lang/zh_cn/messages.yml (3)

563-564: 消息格式正确且清晰!

错误消息格式正确,包含了必要的错误详情占位符。


564-565: 错误消息描述准确!

消息清晰地描述了获取种子 Tracker 列表失败的情况,并包含了所有必要的错误详情占位符。


565-566: 更新失败消息描述准确!

消息准确描述了更新种子 Tracker 列表失败的情况,并包含了所有必要的错误信息占位符。

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 83210cc and 6d95dce.

📒 Files selected for processing (2)
  • src/main/java/com/ghostchu/peerbanhelper/PeerBanHelperServer.java (4 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/module/impl/background/BackgroundModule.java (1 hunks)
⏰ Context from checks skipped due to timeout of 300000ms (1)
  • GitHub Check: Build_Installers / install4jc
🔇 Additional comments (9)
src/main/java/com/ghostchu/peerbanhelper/module/impl/background/BackgroundModule.java (6)

22-25: 构造函数实现正确!

构造函数正确调用了父类构造函数并初始化了 torrentDao 字段。


27-30: 方法实现正确!

方法正确地表明此模块不可配置。


32-35: 方法实现正确!

方法返回了一个描述性的模块名称,并正确使用了 @NotNull 注解。


37-40: 方法实现正确!

方法返回了一个合适的配置标识符,并正确使用了 @NotNull 注解。


47-53: 方法实现正确!

方法正确执行了 SQLite PRAGMA optimize 命令,并适当处理了异常情况。


55-58: 方法实现正确!

方法正确调用了父类的实现,并使用了 @Override 注解。

src/main/java/com/ghostchu/peerbanhelper/PeerBanHelperServer.java (3)

30-30: 导入语句正确!

导入语句正确引入了新的 BackgroundModule 类。


201-201: 方法实现正确!

方法正确使用 ExternalSwitch.parse 检查调试模式。


738-739: 模块注册正确!

代码正确注册了 PBHUtilitiesControllerBackgroundModule 两个新模块。

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (2)
src/main/resources/lang/messages_fallback.yml (1)

572-572: 🛠️ Refactor suggestion

需要在文件末尾添加换行符

根据 YAML 规范,文件末尾应该有一个换行符。

 LAB_EXPERIMENT_FILL_MISSING_DATA_IN_TRAFFIC_SUMMARY_DESCRIPTION: "使用上一条的已知的数据尝试填充流量统计中缺失的数据以尝试修正错误的流量统计数据(仅在非开头区域中缺失记录时有效)。这是一种实验性算法,且提供的数据可能仍旧不准确。"
+
🧰 Tools
🪛 yamllint (1.35.1)

[error] 572-572: no new line character at the end of file

(new-line-at-end-of-file)

src/main/resources/lang/en_us/messages.yml (1)

572-572: 🛠️ Refactor suggestion

需要在文件末尾添加换行符

根据 YAML 规范,文件末尾应该有一个换行符。

 LAB_EXPERIMENT_FILL_MISSING_DATA_IN_TRAFFIC_SUMMARY_DESCRIPTION: "Use known data to fill in missing data in traffic summary to try to correct incorrect traffic statistics data (only effective when records are missing in the non-starting area). This is an experimental algorithm, and the provided data may still be inaccurate."
+
🧰 Tools
🪛 yamllint (1.35.1)

[error] 572-572: no new line character at the end of file

(new-line-at-end-of-file)

🧹 Nitpick comments (1)
src/main/java/com/ghostchu/peerbanhelper/database/dao/impl/TrafficJournalDao.java (1)

58-72: 建议使用 TimeUnit 类替代硬编码的毫秒值

在代码中多次使用了硬编码的毫秒值 86400000(一天的毫秒数)来进行时间计算。为提高代码的可读性和可维护性,建议使用 TimeUnit.DAYS.toMillis(1) 来替代硬编码的数值。

在文件顶部添加导入语句:

+import java.util.concurrent.TimeUnit;

然后修改相应的代码:

 if (laboratory.isExperimentActivated(Experiments.FILL_MISSING_DATA_IN_TRAFFIC_SUMMARY.getExperiment())) {
     // 计算时间差
     long timeDifference = target.getTimestamp().getTime() - base.getTimestamp().getTime();

     // 如果时间差大于一天,说明有跳过的日期,使用上一条数据填充中间跳过的所有天
-    if (timeDifference > 86400000) {
-        long days = timeDifference / 86400000;
+    if (timeDifference > TimeUnit.DAYS.toMillis(1)) {
+        long days = timeDifference / TimeUnit.DAYS.toMillis(1);
         for (long i = 1; i < days; i++) {
-            var newTimestamp = new Timestamp(base.getTimestamp().getTime() + 86400000 * i);
+            var newTimestamp = new Timestamp(base.getTimestamp().getTime() + TimeUnit.DAYS.toMillis(i));
             var newRecord = new TrafficJournalDao.TrafficData(newTimestamp, base.getDataOverallUploaded(), base.getDataOverallDownloaded());
             fixTimeZone.accept(newRecord);
             records.add(newRecord);
         }
     }
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6d95dce and 09c1fc6.

📒 Files selected for processing (6)
  • src/main/java/com/ghostchu/peerbanhelper/database/dao/impl/TrafficJournalDao.java (3 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/lab/Experiments.java (1 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/text/Lang.java (1 hunks)
  • src/main/resources/lang/en_us/messages.yml (1 hunks)
  • src/main/resources/lang/messages_fallback.yml (1 hunks)
  • src/main/resources/lang/zh_cn/messages.yml (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/main/java/com/ghostchu/peerbanhelper/text/Lang.java
🧰 Additional context used
🪛 yamllint (1.35.1)
src/main/resources/lang/en_us/messages.yml

[error] 572-572: no new line character at the end of file

(new-line-at-end-of-file)

src/main/resources/lang/messages_fallback.yml

[error] 572-572: no new line character at the end of file

(new-line-at-end-of-file)

src/main/resources/lang/zh_cn/messages.yml

[error] 569-569: no new line character at the end of file

(new-line-at-end-of-file)

⏰ Context from checks skipped due to timeout of 300000ms (2)
  • GitHub Check: Build_Installers / install4jc
  • GitHub Check: Build_PKG / pkg (13.4)
🔇 Additional comments (9)
src/main/java/com/ghostchu/peerbanhelper/lab/Experiments.java (3)

6-6: 导入语句正确添加!

Collections 的导入位置正确,且确实被新的枚举常量所使用。


12-12: 格式调整合理!

SQLITE_VACUUM 常量的格式调整使代码更加整洁,保持了与新添加枚举常量的一致性。


13-13: 请验证新实验的翻译组件!

新添加的实验功能 FILL_MISSING_DATA_IN_TRAFFIC_SUMMARY 的实现看起来合理,但需要确认以下几点:

  1. 请确认 Lang.LAB_EXPERIMENT_FILL_MISSING_DATA_IN_TRAFFIC_SUMMARY_TITLELang.LAB_EXPERIMENT_FILL_MISSING_DATA_IN_TRAFFIC_SUMMARY_DESCRIPTION 已在语言文件中定义。
  2. 建议在注释中说明此实验的具体用途和预期行为。
✅ Verification successful

翻译组件验证通过!

经检查,新实验功能 FILL_MISSING_DATA_IN_TRAFFIC_SUMMARY 的翻译键已在所有必要的语言文件中正确定义,包括英文(en_us)、中文(zh_cn)以及后备语言文件中。实现完整且符合国际化要求。

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# 检查翻译键是否在语言文件中定义
rg -l "LAB_EXPERIMENT_FILL_MISSING_DATA_IN_TRAFFIC_SUMMARY_(TITLE|DESCRIPTION)" src/

Length of output: 336

src/main/resources/lang/zh_cn/messages.yml (1)

563-569: 新增的消息翻译准确且完整! 🎉

新增的错误消息和实验性功能的描述翻译准确,保持了与英文版本的一致性。

🧰 Tools
🪛 yamllint (1.35.1)

[error] 569-569: no new line character at the end of file

(new-line-at-end-of-file)

src/main/resources/lang/messages_fallback.yml (1)

566-572: 后备消息内容完整且正确! 🎉

新增的后备消息与中文版本内容一致,可以作为良好的回退选项。

🧰 Tools
🪛 yamllint (1.35.1)

[error] 572-572: no new line character at the end of file

(new-line-at-end-of-file)

src/main/resources/lang/en_us/messages.yml (1)

566-572: 英文翻译准确且地道! 🎉

新增的英文翻译准确表达了原始含义,并且使用了地道的英文表达方式。

🧰 Tools
🪛 yamllint (1.35.1)

[error] 572-572: no new line character at the end of file

(new-line-at-end-of-file)

src/main/java/com/ghostchu/peerbanhelper/database/dao/impl/TrafficJournalDao.java (3)

6-7: 导入需要的类以支持实验功能

成功导入了 ExperimentsLaboratory 类,为实验功能提供了支持。


27-27: 声明 Laboratory 实例变量

正确添加了 private final Laboratory laboratory;,确保了实验室实例在类中的可用性。


29-31: 请验证所有 TrafficJournalDao 的实例化是否已更新

由于构造函数添加了新的参数 Laboratory laboratory,需要确保代码库中所有创建 TrafficJournalDao 实例的地方都已更新,并正确传递了 Laboratory 对象。

请运行以下脚本以查找所有创建 TrafficJournalDao 实例的代码位置:

✅ Verification successful

验证完成:TrafficJournalDao 的依赖注入配置无需更新

  • TrafficJournalDao 是一个 Spring 组件(@component),其生命周期由 Spring 容器管理
  • 所有使用到 TrafficJournalDao 的地方都是通过依赖注入方式注入,没有发现手动实例化的代码
  • Spring 容器会自动处理新增的 Laboratory 参数的注入,无需手动修改任何代码
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# 描述:查找所有实例化 TrafficJournalDao 的位置,以确保传递了新的 Laboratory 参数

# 搜索创建 TrafficJournalDao 实例的代码
rg 'new\s+TrafficJournalDao\s*\(' -A 2

Length of output: 40


Script:

#!/bin/bash
# 搜索 TrafficJournalDao 的类定义和注解
ast-grep --pattern 'class TrafficJournalDao' -A 5

# 搜索可能的配置类中创建 TrafficJournalDao 的 @Bean 方法
rg "@Bean.*TrafficJournalDao" -B 2 -A 2

# 搜索包含 TrafficJournalDao 的配置文件
rg "TrafficJournalDao" --type xml

Length of output: 127


Script:

#!/bin/bash
# 搜索所有 Java 文件中的 TrafficJournalDao 引用
rg "TrafficJournalDao" --type java -B 3 -A 3

# 搜索可能的 Spring 注解
rg "(@Component|@Service|@Repository).*TrafficJournalDao" --type java

# 搜索所有注入 TrafficJournalDao 的地方
rg "@Autowired.*TrafficJournalDao" --type java -B 2 -A 2

Length of output: 13332

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🔭 Outside diff range comments (1)
src/main/java/com/ghostchu/peerbanhelper/database/dao/impl/TrafficJournalDao.java (1)

建议使用参数化查询替代 MsgUtil.escapeSql

当前的 SQL 注入防护存在安全隐患:

  1. MsgUtil.escapeSql 仅转义单引号,无法防御其他 SQL 注入向量
  2. 手动字符串转义容易出错且不推荐使用

建议:

  • 使用查询构建器的参数绑定功能(如 ? 占位符)
  • 完全避免手动字符串转义
  • 如果必须保留 escapeSql,至少应该增加对其他特殊字符的转义处理
🔗 Analysis chain

Line range hint 109-116: 建议检查 SQL 注入防护措施

当前实现使用 MsgUtil.escapeSql 来处理 downloader 参数。建议验证:

  1. MsgUtil.escapeSql 的实现是否足够安全
  2. 考虑使用 PreparedStatement 或 ORM 的参数绑定机制来替代手动转义
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# 检查 MsgUtil.escapeSql 的实现
rg -A 10 "escapeSql" .

Length of output: 7641

🧹 Nitpick comments (2)
src/main/java/com/ghostchu/peerbanhelper/database/dao/impl/TrafficJournalDao.java (1)

58-72: 建议改进时间计算的实现方式

当前实现有以下几个可以改进的地方:

  1. 建议将魔法数字 86400000(一天的毫秒数)提取为常量
  2. 可以使用 Java 8 的 Duration API 来提高代码可读性
  3. 时间计算逻辑可以抽取为独立的方法

建议按如下方式重构:

+ private static final long MILLISECONDS_PER_DAY = 86400000L;

  if (laboratory.isExperimentActivated(Experiments.FILL_MISSING_DATA_IN_TRAFFIC_SUMMARY.getExperiment())) {
-     long timeDifference = target.getTimestamp().getTime() - base.getTimestamp().getTime();
+     Duration timeDifference = Duration.between(base.getTimestamp().toInstant(), 
+         target.getTimestamp().toInstant());
      
-     if (timeDifference > 86400000) {
-         long days = timeDifference / 86400000;
+     if (timeDifference.toDays() > 1) {
+         long days = timeDifference.toDays();
          for (long i = 1; i < days; i++) {
-             var newTimestamp = new Timestamp(base.getTimestamp().getTime() + 86400000 * i);
+             var newTimestamp = new Timestamp(base.getTimestamp().getTime() + MILLISECONDS_PER_DAY * i);
              var newRecord = new TrafficJournalDao.TrafficData(newTimestamp,
                  base.getDataOverallUploaded(), base.getDataOverallDownloaded());
              fixTimeZone.accept(newRecord);
              records.add(newRecord);
          }
      }
  }
src/main/java/com/ghostchu/peerbanhelper/module/impl/background/BackgroundModule.java (1)

64-68: 建议优雅地关闭调度线程池

onDisable方法中使用pool.shutdownNow()可能会强制终止正在执行的任务,导致未完成的任务无法正常结束。建议改为使用pool.shutdown()并等待线程池终止,以确保所有任务都能正常完成。

可以考虑以下修改:

@Override
public void onDisable() {
    if (pool != null) {
-       pool.shutdownNow();
+       pool.shutdown();
+       try {
+           if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
+               pool.shutdownNow();
+           }
+       } catch (InterruptedException e) {
+           pool.shutdownNow();
+           Thread.currentThread().interrupt();
+       }
    }
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 09c1fc6 and 7bb59e0.

📒 Files selected for processing (2)
  • src/main/java/com/ghostchu/peerbanhelper/database/dao/impl/TrafficJournalDao.java (3 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/module/impl/background/BackgroundModule.java (1 hunks)
🔇 Additional comments (4)
src/main/java/com/ghostchu/peerbanhelper/database/dao/impl/TrafficJournalDao.java (2)

6-7: 导入语句和字段声明看起来没有问题

新添加的 Laboratory 相关的导入和字段声明符合最佳实践。字段被正确声明为 private final,这确保了不可变性。

Also applies to: 27-27


29-31: 构造函数的修改符合依赖注入规范

构造函数的修改正确地使用了 @Autowired 注解,并且正确初始化了 laboratory 字段。

src/main/java/com/ghostchu/peerbanhelper/module/impl/background/BackgroundModule.java (2)

22-23: 资源管理正确,解决了之前的资源泄漏问题

当前代码保存了调度线程池的引用pool,并在onDisable方法中正确地关闭了线程池,防止了资源泄漏。


46-46: 请验证虚拟线程的兼容性

在创建调度线程池时,使用了Thread.ofVirtual().factory()来创建虚拟线程。请确保您的运行环境支持虚拟线程(需要 Java 19 或更高版本),并且已正确启用了相应的预览特性。

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (5)
src/main/java/com/ghostchu/peerbanhelper/gui/impl/swing/SwingGuiImpl.java (2)

139-139: 请考虑使用 invokeLater 来避免性能问题

invokeLater 改为 invokeAndWait 可能会导致性能下降,因为它会阻塞直到日志更新完成。除非有特殊需求要求严格的日志顺序,否则建议使用非阻塞的 invokeLater

-                    SwingUtilities.invokeAndWait(() -> {
+                    SwingUtilities.invokeLater(() -> {

151-152: 异常处理逻辑完善,建议补充中断标志处理

异常处理的添加很好,但对于 InterruptedException 的处理可以更完善。建议在捕获中断异常时恢复中断标志。

                 } catch (InterruptedException | InvocationTargetException e) {
                     log.warn("Failed to update log list", e);
+                    if (e instanceof InterruptedException) {
+                        Thread.currentThread().interrupt();
+                    }
                 }
src/main/java/com/ghostchu/peerbanhelper/util/logger/JListAppender.java (2)

16-17: 建议改进数据结构的访问控制和容量设置

  1. 这些队列被声明为 public static final,可能会导致外部代码直接访问和修改,建议:
    • 将访问级别改为 private
    • 添加公共方法来安全地访问这些队列
  2. 容量的具体数值(200和100)应该:
    • 抽取为配置常量
    • 通过配置文件或环境变量来设置

建议按照以下方式重构:

- public static final LinkedBlockingDeque<LogEntry> logEntryDeque = new LinkedBlockingDeque<>(200);
- public static final EvictingQueue<LogEntry> ringDeque = EvictingQueue.create(100);
+ private static final int LOG_ENTRY_CAPACITY = 200;
+ private static final int RING_CAPACITY = 100;
+ private static final LinkedBlockingDeque<LogEntry> logEntryDeque = new LinkedBlockingDeque<>(LOG_ENTRY_CAPACITY);
+ private static final EvictingQueue<LogEntry> ringDeque = EvictingQueue.create(RING_CAPACITY);

38-49: 建议优化日志级别转换逻辑

当前的日志级别转换使用了多个 if-else 语句,代码较为冗长。建议使用 Java 的 switch 表达式或映射表来简化此逻辑。

建议重构为:

- Level slf4jLevel = Level.INFO;
- if (eventObject.getLevel() == ch.qos.logback.classic.Level.WARN) {
-     slf4jLevel = Level.WARN;
- } else if (eventObject.getLevel() == ch.qos.logback.classic.Level.ERROR) {
-     slf4jLevel = Level.ERROR;
- } else if (eventObject.getLevel() == ch.qos.logback.classic.Level.DEBUG) {
-     slf4jLevel = Level.DEBUG;
- } else if (eventObject.getLevel() == ch.qos.logback.classic.Level.TRACE) {
-     slf4jLevel = Level.TRACE;
- } else if (eventObject.getLevel() == ch.qos.logback.classic.Level.OFF) {
-     return;
- }
+ Level slf4jLevel = switch (eventObject.getLevel().levelInt) {
+     case ch.qos.logback.classic.Level.WARN_INT -> Level.WARN;
+     case ch.qos.logback.classic.Level.ERROR_INT -> Level.ERROR;
+     case ch.qos.logback.classic.Level.DEBUG_INT -> Level.DEBUG;
+     case ch.qos.logback.classic.Level.TRACE_INT -> Level.TRACE;
+     case ch.qos.logback.classic.Level.OFF_INT -> null;
+     default -> Level.INFO;
+ };
+ if (slf4jLevel == null) return;
src/main/java/com/ghostchu/peerbanhelper/PeerBanHelperServer.java (1)

201-204: 发布检查逻辑清晰!

通过 ExternalSwitch 检查发布类型的实现方式合理。建议为此检查添加注释,说明其用途。

建议添加如下注释:

+// 仅在 LiveDebug 环境下执行测试代码
 if (!"LiveDebug".equalsIgnoreCase(ExternalSwitch.parse("pbh.release"))) {
     return;
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7bb59e0 and cada622.

📒 Files selected for processing (3)
  • src/main/java/com/ghostchu/peerbanhelper/PeerBanHelperServer.java (4 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/gui/impl/swing/SwingGuiImpl.java (2 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/util/logger/JListAppender.java (2 hunks)
⏰ Context from checks skipped due to timeout of 300000ms (1)
  • GitHub Check: Build_Installers / install4jc
🔇 Additional comments (3)
src/main/java/com/ghostchu/peerbanhelper/PeerBanHelperServer.java (3)

30-30: 导入语句正确添加!

新增的 BackgroundModule 导入语句位置恰当,与其他模块导入保持一致。


387-389: API Token 获取逻辑优化合理!

使用 ExternalSwitch 获取 API Token 的方式符合环境变量支持的需求,同时保留了配置文件作为回退方案,实现稳健。


737-738: 新模块注册正确!

新增的两个模块(PBHUtilitiesController 和 BackgroundModule)注册位置正确。建议验证这些模块的初始化顺序是否会影响其他模块。

请运行以下脚本检查模块间的依赖关系:

✅ Verification successful

模块注册顺序验证完成!

经过验证,PBHUtilitiesController 和 BackgroundModule 的注册位置合理且安全:

  • 核心模块优先注册
  • Web控制器随后注册
  • 工具类和后台模块最后注册
  • Spring依赖注入确保了正确的初始化顺序
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# 检查新模块是否有被其他模块依赖的情况
rg -A 5 "PBHUtilitiesController|BackgroundModule" --type java

Length of output: 3653


Script:

#!/bin/bash
# Check registration order of dependencies
rg -B 5 "moduleManager\.register" --type java

Length of output: 4601

@Ghost-chu Ghost-chu merged commit 8c3cf52 into release Jan 19, 2025
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants