添加bt与tracker交互
Change-Id: I1327c2ed89a76bee8e2abeb8cb3014b56357689a
diff --git a/src/main/java/com/pt/service/TorrentService.java b/src/main/java/com/pt/service/TorrentService.java
index dcbee69..1fdb700 100644
--- a/src/main/java/com/pt/service/TorrentService.java
+++ b/src/main/java/com/pt/service/TorrentService.java
@@ -2,77 +2,62 @@
import com.pt.entity.TorrentMeta;
import com.pt.repository.TorrentMetaRepository;
-import com.pt.utils.BencodeUtils;
+import com.pt.utils.BencodeCodec;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
-import java.io.*;
import java.security.MessageDigest;
import java.time.LocalDateTime;
-import java.util.LinkedHashMap;
+import java.util.List;
import java.util.Map;
@Service
public class TorrentService {
- // Tracker 服务器的 announce 地址
- private static final String ANNOUNCE_URL = "http://localhost:8080/announce";
- private static final int PIECE_LENGTH = 256 * 1024;
-
@Autowired
private TorrentMetaRepository torrentMetaRepository;
- public byte[] generateTorrentBytes(String sourceFilePath) throws Exception {
- File sourceFile = new File(sourceFilePath);
-
- // 构造 info 字典
- Map<String, Object> infoDict = new LinkedHashMap<>();
- infoDict.put("name", sourceFile.getName());
- infoDict.put("length", sourceFile.length());
- infoDict.put("piece length", PIECE_LENGTH);
- infoDict.put("pieces", calcPiecesHashes(sourceFile));
-
- // 构造完整 torrent 字典
- Map<String, Object> torrentDict = new LinkedHashMap<>();
- torrentDict.put("announce", ANNOUNCE_URL);
- torrentDict.put("info", infoDict);
-
- // 编码成种子数据字节数组
- byte[] bencodedTorrent = BencodeUtils.encode(torrentDict);
-
- // 计算 info_hash 并保存到数据库(如果需要的话)
- MessageDigest sha1 = MessageDigest.getInstance("SHA-1");
- byte[] infoEncoded = BencodeUtils.encode(infoDict);
- sha1.update(infoEncoded);
- String infoHash = bytesToHex(sha1.digest());
-
- TorrentMeta meta = new TorrentMeta();
- meta.setFilename(sourceFile.getName());
- meta.setInfoHash(infoHash);
- meta.setSize(sourceFile.length());
- meta.setUploadTime(LocalDateTime.now());
- torrentMetaRepository.save(meta);
-
- return bencodedTorrent;
- }
-
-
- private byte[] calcPiecesHashes(File file) throws Exception {
- MessageDigest sha1 = MessageDigest.getInstance("SHA-1");
- try (InputStream fis = new FileInputStream(file)) {
- byte[] buffer = new byte[PIECE_LENGTH];
- ByteArrayOutputStream piecesBuffer = new ByteArrayOutputStream();
-
- int read;
- while ((read = fis.read(buffer)) > 0) {
- sha1.reset();
- sha1.update(buffer, 0, read);
- piecesBuffer.write(sha1.digest());
- }
- return piecesBuffer.toByteArray();
+ public TorrentMeta parseAndSaveTorrent(byte[] torrentBytes) throws Exception {
+ Map<String, Object> torrentDict = (Map<String, Object>) BencodeCodec.decode(torrentBytes);
+ if (!torrentDict.containsKey("info")) {
+ throw new IllegalArgumentException("Invalid torrent file: missing 'info' dictionary");
}
+
+ Map<String, Object> infoDict = (Map<String, Object>) torrentDict.get("info");
+
+ // 计算 info_hash
+ byte[] infoEncoded = BencodeCodec.encode(infoDict);
+ MessageDigest sha1 = MessageDigest.getInstance("SHA-1");
+ byte[] infoHashBytes = sha1.digest(infoEncoded);
+ String infoHash = bytesToHex(infoHashBytes);
+
+ // 获取文件名,大小等
+ String name = (String) infoDict.get("name");
+ long length = 0;
+ if (infoDict.containsKey("length")) {
+ length = ((Number) infoDict.get("length")).longValue();
+ } else if (infoDict.containsKey("files")) {
+ long totalLength = 0;
+ List<Map<String, Object>> files = (List<Map<String, Object>>) infoDict.get("files");
+ for (Map<String, Object> file : files) {
+ totalLength += ((Number) file.get("length")).longValue();
+ }
+ length = totalLength;
+ }
+
+ // 保存到数据库
+ TorrentMeta meta = new TorrentMeta();
+ meta.setFilename(name);
+ meta.setInfoHash(infoHash);
+ meta.setSize(length);
+ meta.setUploadTime(LocalDateTime.now());
+ meta.setTorrentData(torrentBytes);
+
+ torrentMetaRepository.save(meta);
+ return meta;
}
+
private String bytesToHex(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
@@ -80,4 +65,4 @@
}
return sb.toString();
}
-}
\ No newline at end of file
+}