# storageNode 项目结构

## 概述
分布式存储/下载节点服务端，用于画廊网站。职责包括：从远程源下载图片集、压缩为 ZIP 归档、通过 HTTP 提供下载（支持断点续传）、管理代理订阅配置（V2Ray/Clash），并通过 Netty 自定义 TCP 协议与中心服务器通信。

- **Group ID:** `org.lion`
- **Version:** `1.0`
- **Java 版本:** 21
- **构建工具:** Maven（单模块）
- **编译目标:** GraalVM 原生镜像

---

## 目录结构

```
storageNode/
├── pom.xml                                              # Maven 构建配置
└── src/
    ├── main/
    │   ├── java/
    │   │   └── lion/
    │   │       ├── Main.java                            # 程序入口
    │   │       ├── storageNode.java                     # Netty TCP 核心节点
    │   │       ├── CustomUtil.java                      # 工具方法（HTTP 通知、端口查找、ObjectMapper）
    │   │       ├── MultiThreadedHTTPServer.java          # HTTP 文件下载服务（端口 8888）
    │   │       ├── Config/
    │   │       │   └── Config.java                      # 加载 config.properties
    │   │       ├── Domain/
    │   │       │   └── GalleryTask.java                  # 下载任务领域模型
    │   │       ├── ErrorCode/
    │   │       │   └── ErrorCode.java                   # 错误码常量
    │   │       ├── Externel/
    │   │       │   └── BackupSubServer.java             # 代理订阅文件服务（端口 8889）
    │   │       ├── Message/
    │   │       │   ├── AbstractMessage.java             # 消息基类 + 消息类型常量
    │   │       │   ├── MessageCodec.java                # Netty 编解码器（ByteBuf ↔ AbstractMessage，JSON 格式）
    │   │       │   └── Main/
    │   │       │       ├── AvailableCheckMessage.java   # 可用性检查（type=8）
    │   │       │       ├── DeleteGalleryMessage.java    # 删除画廊请求（type=3）
    │   │       │       ├── DownloadPostMessage.java     # 提交下载任务（type=1）
    │   │       │       ├── DownloadStatusMessage.java   # 上报任务状态（type=2）
    │   │       │       ├── IdentityMessage.java         # 身份认证握手（type=6）
    │   │       │       ├── MaintainMessage.java         # 心跳维持（type=7）
    │   │       │       └── ResponseMessage.java         # 通用响应（type=0）
    │   │       └── Service/
    │   │           ├── DeleteService.java               # 删除画廊目录
    │   │           └── DownloadCheckService.java        # 下载监控与压缩服务
    │   └── resources/
    │       ├── config.properties                        # DouNai 订阅地址配置
    │       ├── simplelogger.properties                  # SLF4J 日志配置（输出到 run.out）
    │       └── reflect-config.json                      # GraalVM 反射配置（Jackson 序列化）
    └── test/
        └── java/                                        # 空目录（无单元测试）
```

---

## 关键依赖

| 依赖 | 版本 | 用途 |
|---|---|---|
| `io.netty:netty-all` | 4.1.101.Final | TCP 服务端/客户端 |
| `com.fasterxml.jackson.core:jackson-databind` | 2.15.2 | JSON 序列化 |
| `org.projectlombok:lombok` | 1.18.30 | 简化样板代码（`@Data`, `@Slf4j`） |
| `cn.hutool:hutool-all` | 5.8.26 | 文件操作、ZIP 压缩、HTTP 请求 |
| `org.apache.httpcomponents:httpclient` | 4.5.14 | HTTP 客户端 |
| `org.graalvm.buildtools:native-maven-plugin` | 0.9.28 | 原生镜像编译 |

---

## 启动流程

1. `Main.main()` → 调用 `boot()`（遗留的 Netty Bootstrap），然后执行 `Config.loadConfig()`
2. 在新线程中启动 `BackupSubServer`（端口 8889）— 提供代理订阅文件下载
3. 在新线程中启动 `MultiThreadedHTTPServer`（端口 8888）— 提供画廊 ZIP 文件下载
4. 主线程创建 `storageNode()` 实例（阻塞构造函数，永不返回）：
   - 从端口 26321 开始查找空闲端口，绑定 Netty TCP 服务端
   - 作为 TCP 客户端连接 `lionwebsite.xyz:26322~26342`，唤醒中心服务器
   - 启动 `DownloadCheckService` 和 5 秒定时任务 `mainThread()`

---

## 通信协议（Netty TCP）

自定义协议格式：`[1字节类型] + [4字节长度] + [JSON 负载]`

| 类型字节 | 消息类 | 方向 |
|---|---|---|
| 0 | `ResponseMessage` | 响应 |
| 1 | `DownloadPostMessage` | 服务端 → 节点 |
| 2 | `DownloadStatusMessage` | 节点 → 服务端 |
| 3 | `DeleteGalleryMessage` | 服务端 → 节点 |
| 6 | `IdentityMessage` | 握手 |
| 7 | `MaintainMessage` | 心跳 |
| 8 | `AvailableCheckMessage` | 可用性检查 |

---

## HTTP 服务

### MultiThreadedHTTPServer（端口 8888）
- 提供压缩后的画廊 ZIP 文件下载
- 仅接受来自 `lionwebsite.xyz` IP 的连接
- 支持 HTTP 206 Partial Content（断点续传）
- 参数：`AuthCode`（管理员访问）、`gid`（画廊 ID）

### BackupSubServer（端口 8889）
- 提供 V2Ray 和 Clash 代理订阅文件
- 每 12 小时从配置的 URL 下载最新订阅数据
- 过滤高比例代理节点
- 文件存储于 `sub/DouNaiV2ray.txt` 和 `sub/DouNaiClash.txt`
- 通过路径密钥进行身份验证

---

## 核心服务

### DownloadCheckService
- 扫描下载目录（`/root/gallery/hentai/download/`）监控进度
- 通过检测 `galleryinfo.txt` 文件判断下载完成
- 将完成的下载任务移入压缩队列
- 后台线程每 5 秒执行 ZIP 压缩，完成后删除源目录

### DeleteService
- 按名称删除画廊目录
- 失败时返回 `ErrorCode.IO_ERROR` 或 `ErrorCode.FILE_NOT_FOUND`

---

## 配置说明

### config.properties（从 `/root/gallery/storageNode/config.properties` 加载）
```properties
DouNaiV2ray=https://aaaa.gay/link/X7zEqkIx5gtIGugO?client=v2
DouNaiClash=https://aaaa.gay/link/X7zEqkIx5gtIGugO?client=clashmeta
```

### simplelogger.properties
- 日志级别：`info`
- 时间戳格式：`yyyy-MM-dd HH:mm:ss`
- 输出文件：`run.out`

---

## 架构说明

- 单模块 Maven 项目，无单元测试
- 硬编码文件系统路径（`/root/gallery/...`）→ 仅限 Linux 部署
- 外部连接：`lionwebsite.xyz`、`personal.lionwebsite.xyz`、`aaaa.gay`
- GraalVM 原生镜像编译，包含 Jackson 反射配置
- 大量使用 Lombok（`@Data`、`@Slf4j`）
- 使用 Hutool 工具库处理文件/ZIP/HTTP 操作