优化

Change-Id: I27b0b1a4cfb5b199c2c97929cc6183d328797bab
diff --git a/src/main/java/com/ptp/ptplatform/config/WebConfig.java b/src/main/java/com/ptp/ptplatform/config/WebConfig.java
index bb81631..714681c 100644
--- a/src/main/java/com/ptp/ptplatform/config/WebConfig.java
+++ b/src/main/java/com/ptp/ptplatform/config/WebConfig.java
@@ -13,9 +13,14 @@
     public void addCorsMappings(CorsRegistry registry) {
 
         registry.addMapping("/**")  // 允许所有路径跨源请求
-                .allowedOrigins("http://localhost:3000")  // 允许指定来源
-                .allowedMethods("GET", "POST", "PUT", "DELETE")  // 允许的请求方法
+                .allowedOrigins(
+                        "http://localhost:3000"
+//                        "http://team2.10813352.xyz"
+                )
+                .allowedMethods("GET","POST","DELETE","PUT","OPTIONS")  // 允许的请求方法
+//                .allowedHeaders("*")  // 允许所有请求头(包括 Authorization)
                 .allowCredentials(true);  // 是否允许携带凭证
 
+
     }
 }
diff --git a/src/main/java/com/ptp/ptplatform/controller/NotificationController.java b/src/main/java/com/ptp/ptplatform/controller/NotificationController.java
index 61a0f12..91058a2 100644
--- a/src/main/java/com/ptp/ptplatform/controller/NotificationController.java
+++ b/src/main/java/com/ptp/ptplatform/controller/NotificationController.java
@@ -23,7 +23,13 @@
 
     @PostMapping("/{id}/read")
     public Result markAsRead(@PathVariable("id") Integer id) {
-        notificationService.markAsRead(id);
-        return Result.ok().message("通知已标记为已读");
+        try {
+            Notification updatedNotification = notificationService.markAsRead(id);
+            return Result.ok()
+                    .message("通知已标记为已读")
+                    .data("notification", updatedNotification);
+        } catch (RuntimeException e) {
+            return Result.error(500).message(e.getMessage());
+        }
     }
 }
diff --git a/src/main/java/com/ptp/ptplatform/controller/RecommendController.java b/src/main/java/com/ptp/ptplatform/controller/RecommendController.java
index 69e9b88..ad78fe8 100644
--- a/src/main/java/com/ptp/ptplatform/controller/RecommendController.java
+++ b/src/main/java/com/ptp/ptplatform/controller/RecommendController.java
@@ -36,4 +36,28 @@
         }
         return ResponseEntity.ok(recommenderService.recommendForUser(user.getUsername(), limit));
     }
+
+    @PostMapping("/mark-shown/{torrentId}")
+    public ResponseEntity<Void> markRecommendationShown(
+            HttpServletRequest request,
+            @PathVariable Integer torrentId) {
+        USER user = userController.getUserInRequest(request);
+        if (user == null) {
+            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
+        }
+        recommenderService.markRecommendationAsShown(user.getUsername(), torrentId);
+        return ResponseEntity.ok().build();
+    }
+
+    @PostMapping("/mark-clicked/{torrentId}")
+    public ResponseEntity<Void> markRecommendationClicked(
+            HttpServletRequest request,
+            @PathVariable Integer torrentId) {
+        USER user = userController.getUserInRequest(request);
+        if (user == null) {
+            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
+        }
+        recommenderService.markRecommendationAsClicked(user.getUsername(), torrentId);
+        return ResponseEntity.ok().build();
+    }
 }
\ No newline at end of file
diff --git a/src/main/java/com/ptp/ptplatform/controller/TorrentController.java b/src/main/java/com/ptp/ptplatform/controller/TorrentController.java
index fa0f92e..bef9e8e 100644
--- a/src/main/java/com/ptp/ptplatform/controller/TorrentController.java
+++ b/src/main/java/com/ptp/ptplatform/controller/TorrentController.java
@@ -30,7 +30,9 @@
 import java.io.File;
 import java.io.IOException;
 import java.net.InetAddress;
+import java.net.ServerSocket;
 import java.net.UnknownHostException;
+import java.net.URLDecoder;
 import java.nio.ByteBuffer;
 import java.nio.file.Files;
 import java.nio.file.Paths;
@@ -343,7 +345,7 @@
     }
 
     //根据本机创建peer对象
-    public TrackedPeer createTrackedPeer(HttpServletRequest request, TrackedTorrent trackedTorrent, int torrentid) throws UnknownHostException {
+    public TrackedPeer createTrackedPeer(HttpServletRequest request, TrackedTorrent trackedTorrent, int torrentid) throws IOException {
         // 修改为获取request请求的地址
         //String ip = request.getRemoteAddr();
 
@@ -352,7 +354,7 @@
         String ip = inetAddress.getHostAddress();
         USER user = userController.getUserInRequest(request);
 
-        int port = 6881; // 使用固定端口
+        int port = findAvailablePort(6881, 6999); // 使用固定端口
 
         // 创建Peer ID
         String peerIdString = UUID.randomUUID().toString();
@@ -367,6 +369,16 @@
         return trackedPeer;
     }
 
+    private int findAvailablePort(int start, int end) throws IOException {
+        for (int port = start; port <= end; port++) {
+            try (ServerSocket serverSocket = new ServerSocket(port)) {
+                return port;
+            } catch (IOException ignored) {
+            }
+        }
+        throw new IOException("No available ports in range [" + start + ", " + end + "]");
+    }
+
     //种子下载 根据id获取数据
     // 能成功获取到数据
     // 能够根据此值,完成对相关数据的修改
@@ -376,10 +388,19 @@
                              @RequestParam String downloadPath) throws Exception {
         // 1. 获取种子和用户信息
         TORRENT torrent = torrentMapper.selectByID(id);
-        if (torrent == null) {
-            logger.error("尝试下载不存在的种子,ID: {}", id);
-            return Result.error(404).message("种子不存在");
-        }
+        String decodedPath = URLDecoder.decode(downloadPath, "UTF-8");
+//        String normalizedPath = decodedPath.replace("\\", "/"); // 统一为斜杠
+//        if (!normalizedPath.endsWith("/")) {
+//            normalizedPath += "/"; // 确保以斜杠结尾
+//        }
+//
+//        logger.info("下载请求 - 种子ID: {}, 原始路径: {}, 解码后路径: {}, 标准化路径: {}",
+//                id, downloadPath, decodedPath, normalizedPath);
+//
+//        if (torrent == null) {
+//            logger.error("尝试下载不存在的种子,ID: {}", id);
+//            return Result.error(404).message("种子不存在");
+//        }
         USER userDownload = userController.getUserInRequest(request);
         USER userUpload = userMapper.selectByUsername(torrent.getUsername());
 
@@ -396,10 +417,10 @@
         }
 
         // 4. 执行下载
-        try {
+//        try {
             // 4.1 调用客户端服务下载
 
-            clientservice.downloadTorrent(torrent.getFilePath(), downloadPath, userDownload.getUsername());
+            clientservice.downloadTorrent(torrent.getFilePath(), decodedPath, userDownload.getUsername());
             // 4.2 更新Tracker信息
             TrackedTorrent tt = trackerservice.getTrackedTorrent(torrent.getHash());
             TrackedPeer tp = createTrackedPeer(request, tt, torrent.getId());
@@ -407,19 +428,19 @@
             tt.addPeer(tp);
             trackerservice.serTracker();
 
-        // 通知下载完成
-        Notification downloadCompleteNotice = new Notification();
-        downloadCompleteNotice.setUserId(userDownload.getUsername());
-        downloadCompleteNotice.setType("DOWNLOAD_COMPLETE");
-        downloadCompleteNotice.setTitle("下载完成提醒");
-        downloadCompleteNotice.setContent(
-                "您下载的种子 \"" + torrent.getTorrentName() + "\" 已经成功完成。"
-        );
-        downloadCompleteNotice.setTargetId(id);
-        downloadCompleteNotice.setTargetType("TORRENT");
-        downloadCompleteNotice.setIsRead(false);
-        downloadCompleteNotice.setCreateTime(LocalDateTime.now());
-        notificationService.saveNotification(downloadCompleteNotice);
+//        // 通知下载完成
+//        Notification downloadCompleteNotice = new Notification();
+//        downloadCompleteNotice.setUserId(userDownload.getUsername());
+//        downloadCompleteNotice.setType("DOWNLOAD_COMPLETE");
+//        downloadCompleteNotice.setTitle("下载完成提醒");
+//        downloadCompleteNotice.setContent(
+//                "您下载的种子 \"" + torrent.getTorrentName() + "\" 已经成功完成。"
+//        );
+//        downloadCompleteNotice.setTargetId(id);
+//        downloadCompleteNotice.setTargetType("TORRENT");
+//        downloadCompleteNotice.setIsRead(false);
+//        downloadCompleteNotice.setCreateTime(LocalDateTime.now());
+//        notificationService.saveNotification(downloadCompleteNotice);
 
             // 4.3 更新用户数据(只有下载他人种子时才更新)
             if (!userDownload.getUsername().equals(userUpload.getUsername())) {
@@ -435,10 +456,10 @@
             logger.info("用户 {} 成功下载种子 {}", userDownload.getUsername(), id);
             return Result.ok().data("fileName", torrent.getTorrentName())
                     .data("taskId", torrent.getHash());
-        }catch (Exception e) {
-            logger.error("下载种子失败", e);
-            return Result.error(500).message("下载失败: " + e.getMessage());
-        }
+//        }catch (Exception e) {
+//            logger.error("下载种子失败", e);
+//            return Result.error(500).message("下载失败: " + e.getMessage());
+//        }
     }
 
     @GetMapping("/getProgress")
diff --git a/src/main/java/com/ptp/ptplatform/service/ClientService.java b/src/main/java/com/ptp/ptplatform/service/ClientService.java
index 848b132..5810e44 100644
--- a/src/main/java/com/ptp/ptplatform/service/ClientService.java
+++ b/src/main/java/com/ptp/ptplatform/service/ClientService.java
@@ -21,7 +21,7 @@
     public boolean downloadTorrent(String torrentFilePath, String outputDirectory, String username) throws Exception {
         InetAddress address = InetAddress.getLocalHost();
         try {
-            client.downloadTorrentAsync(torrentFilePath, outputDirectory, address);
+            client.downloadTorrent(torrentFilePath, outputDirectory, address);
             tasks.add(new String[] {username, torrentFilePath});
             return true;
         } catch (Exception e) {
diff --git a/src/main/java/com/ptp/ptplatform/service/NotificationService.java b/src/main/java/com/ptp/ptplatform/service/NotificationService.java
index d213484..6757e4b 100644
--- a/src/main/java/com/ptp/ptplatform/service/NotificationService.java
+++ b/src/main/java/com/ptp/ptplatform/service/NotificationService.java
@@ -6,5 +6,5 @@
 public interface NotificationService {
     void saveNotification(Notification notification);
     List<Notification> listByUser(String userId);
-    void markAsRead(Integer id);
+    Notification markAsRead(Integer id);
 }
\ No newline at end of file
diff --git a/src/main/java/com/ptp/ptplatform/service/impl/NotificationServiceImpl.java b/src/main/java/com/ptp/ptplatform/service/impl/NotificationServiceImpl.java
index faeae12..381c372 100644
--- a/src/main/java/com/ptp/ptplatform/service/impl/NotificationServiceImpl.java
+++ b/src/main/java/com/ptp/ptplatform/service/impl/NotificationServiceImpl.java
@@ -6,6 +6,7 @@
 import com.ptp.ptplatform.service.NotificationService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 import java.time.LocalDateTime;
 import java.util.List;
@@ -32,10 +33,26 @@
     }
 
     @Override
-    public void markAsRead(Integer id) {
-        Notification n = new Notification();
-        n.setId(id);
-        n.setIsRead(true);
-        notificationMapper.updateById(n);
+    @Transactional
+    public Notification markAsRead(Integer id) {
+        // 先查询通知是否存在
+        Notification notification = notificationMapper.selectById(id);
+        if (notification == null) {
+            throw new RuntimeException("通知不存在");
+        }
+
+        // 更新通知状态
+        Notification update = new Notification();
+        update.setId(id);
+        update.setIsRead(true);
+//        update.setReadTime(LocalDateTime.now());
+
+        int affected = notificationMapper.updateById(update);
+        if (affected == 0) {
+            throw new RuntimeException("标记已读失败");
+        }
+
+        // 返回更新后的通知对象
+        return notificationMapper.selectById(id);
     }
 }
\ No newline at end of file
diff --git a/src/main/java/com/ptp/ptplatform/service/impl/RecommenderServiceImpl.java b/src/main/java/com/ptp/ptplatform/service/impl/RecommenderServiceImpl.java
index 11221bf..c9a4654 100644
--- a/src/main/java/com/ptp/ptplatform/service/impl/RecommenderServiceImpl.java
+++ b/src/main/java/com/ptp/ptplatform/service/impl/RecommenderServiceImpl.java
@@ -48,20 +48,24 @@
         Set<Integer> excludedIds = new HashSet<>();
         excludedIds.addAll(alreadyRecommended);
         excludedIds.addAll(alreadyDownloaded);
+        System.out.println("excludedIds: " + excludedIds);
 
         // 4. 获取原始推荐结果(80%)
         List<TORRENT> originalRecommendations = getOriginalRecommendations(username,
                 (int)(limit * 0.8), excludedIds);
+        System.out.println("originalRecommendations 数量: " + originalRecommendations.size());
 
         // 5. 获取随机推荐(20%),同样排除已推荐和已下载的
         List<TORRENT> randomRecommendations = getRandomRecommendations(
                 limit - originalRecommendations.size(), excludedIds);
+        System.out.println("randomRecommendations 数量: " + randomRecommendations.size());
 
         // 6. 合并结果
         List<TORRENT> finalRecommendations = new ArrayList<>();
         finalRecommendations.addAll(originalRecommendations);
         finalRecommendations.addAll(randomRecommendations);
         Collections.shuffle(finalRecommendations);
+        System.out.println("最终推荐数量: " + finalRecommendations.size());
 
         // 7. 记录本次推荐
         recordRecommendations(username, finalRecommendations);
diff --git a/torrents/155abb132f8da56b9fe1298f2038d774_4.mp4.torrent b/torrents/155abb132f8da56b9fe1298f2038d774_4.mp4.torrent
new file mode 100644
index 0000000..276afc3
--- /dev/null
+++ b/torrents/155abb132f8da56b9fe1298f2038d774_4.mp4.torrent
Binary files differ
diff --git "a/torrents/1749291627534_\344\270\244\346\235\206\345\244\247\347\203\237\346\236\252BD\344\270\255\350\213\261\345\217\214\345\255\227.mp4.torrent" "b/torrents/1749291627534_\344\270\244\346\235\206\345\244\247\347\203\237\346\236\252BD\344\270\255\350\213\261\345\217\214\345\255\227.mp4.torrent"
new file mode 100644
index 0000000..0db6347
--- /dev/null
+++ "b/torrents/1749291627534_\344\270\244\346\235\206\345\244\247\347\203\237\346\236\252BD\344\270\255\350\213\261\345\217\214\345\255\227.mp4.torrent"
Binary files differ
diff --git "a/torrents/1749292000194_\344\270\244\346\235\206\345\244\247\347\203\237\346\236\252BD\344\270\255\350\213\261\345\217\214\345\255\227.mp4.torrent" "b/torrents/1749292000194_\344\270\244\346\235\206\345\244\247\347\203\237\346\236\252BD\344\270\255\350\213\261\345\217\214\345\255\227.mp4.torrent"
new file mode 100644
index 0000000..0db6347
--- /dev/null
+++ "b/torrents/1749292000194_\344\270\244\346\235\206\345\244\247\347\203\237\346\236\252BD\344\270\255\350\213\261\345\217\214\345\255\227.mp4.torrent"
Binary files differ
diff --git "a/torrents/1749292377878_\133\347\224\265\345\275\261\345\244\251\345\240\202www.dytt89.com\135\344\270\244\346\235\206\345\244\247\347\203\237\346\236\252BD\344\270\255\350\213\261\345\217\214\345\255\227.mp4.torrent" "b/torrents/1749292377878_\133\347\224\265\345\275\261\345\244\251\345\240\202www.dytt89.com\135\344\270\244\346\235\206\345\244\247\347\203\237\346\236\252BD\344\270\255\350\213\261\345\217\214\345\255\227.mp4.torrent"
new file mode 100644
index 0000000..0db6347
--- /dev/null
+++ "b/torrents/1749292377878_\133\347\224\265\345\275\261\345\244\251\345\240\202www.dytt89.com\135\344\270\244\346\235\206\345\244\247\347\203\237\346\236\252BD\344\270\255\350\213\261\345\217\214\345\255\227.mp4.torrent"
Binary files differ
diff --git a/torrents/1749298047736_155abb132f8da56b9fe1298f2038d774_4.mp4.torrent b/torrents/1749298047736_155abb132f8da56b9fe1298f2038d774_4.mp4.torrent
new file mode 100644
index 0000000..276afc3
--- /dev/null
+++ b/torrents/1749298047736_155abb132f8da56b9fe1298f2038d774_4.mp4.torrent
Binary files differ
diff --git a/torrents/1749298536186_32e995db2ab833ae6a12a3b1d521e5b.jpg.torrent b/torrents/1749298536186_32e995db2ab833ae6a12a3b1d521e5b.jpg.torrent
new file mode 100644
index 0000000..7e57dcc
--- /dev/null
+++ b/torrents/1749298536186_32e995db2ab833ae6a12a3b1d521e5b.jpg.torrent
@@ -0,0 +1 @@
+d8:announce30:http://localhost:6969/announce10:created by21:qBittorrent v4.5.3.1013:creation datei1748520246e4:infod6:lengthi53458e4:name35:32e995db2ab833ae6a12a3b1d521e5b.jpg12:piece lengthi16384e6:pieces80:6<MÙ>¿€?ï™ÿ!v`™÷F™€—¤zj„&â“þS¹’²jùk“50Õ·ÁIó™¶I»®þ¦ÄbÏ$:âm«%»®#ô~å'5\~4¨U.*ee
\ No newline at end of file
diff --git "a/torrents/1749299138151_\350\247\206\351\242\221.mp4.torrent" "b/torrents/1749299138151_\350\247\206\351\242\221.mp4.torrent"
new file mode 100644
index 0000000..058c500
--- /dev/null
+++ "b/torrents/1749299138151_\350\247\206\351\242\221.mp4.torrent"
Binary files differ
diff --git "a/torrents/1749299640675_\345\212\237\350\203\275\346\210\252\345\233\276.docx.torrent" "b/torrents/1749299640675_\345\212\237\350\203\275\346\210\252\345\233\276.docx.torrent"
new file mode 100644
index 0000000..3c7d3ad
--- /dev/null
+++ "b/torrents/1749299640675_\345\212\237\350\203\275\346\210\252\345\233\276.docx.torrent"
Binary files differ
diff --git "a/torrents/1749299825048_\345\212\237\350\203\275\346\210\252\345\233\276.docx.torrent" "b/torrents/1749299825048_\345\212\237\350\203\275\346\210\252\345\233\276.docx.torrent"
new file mode 100644
index 0000000..3c7d3ad
--- /dev/null
+++ "b/torrents/1749299825048_\345\212\237\350\203\275\346\210\252\345\233\276.docx.torrent"
Binary files differ
diff --git a/torrents/1749300178593_G2-ptPlatform-frontend.zip.torrent b/torrents/1749300178593_G2-ptPlatform-frontend.zip.torrent
new file mode 100644
index 0000000..edaec90
--- /dev/null
+++ b/torrents/1749300178593_G2-ptPlatform-frontend.zip.torrent
Binary files differ
diff --git a/torrents/1749300933385_G2-ptPlatform-frontend.torrent b/torrents/1749300933385_G2-ptPlatform-frontend.torrent
new file mode 100644
index 0000000..744e0fa
--- /dev/null
+++ b/torrents/1749300933385_G2-ptPlatform-frontend.torrent
Binary files differ
diff --git "a/torrents/1749301888395_\350\247\206\351\242\221.mp4.torrent" "b/torrents/1749301888395_\350\247\206\351\242\221.mp4.torrent"
new file mode 100644
index 0000000..058c500
--- /dev/null
+++ "b/torrents/1749301888395_\350\247\206\351\242\221.mp4.torrent"
Binary files differ
diff --git a/torrents/G2-ptPlatform-frontend.torrent b/torrents/G2-ptPlatform-frontend.torrent
new file mode 100644
index 0000000..744e0fa
--- /dev/null
+++ b/torrents/G2-ptPlatform-frontend.torrent
Binary files differ
diff --git a/torrents/G2-ptPlatform-frontend.zip.torrent b/torrents/G2-ptPlatform-frontend.zip.torrent
new file mode 100644
index 0000000..edaec90
--- /dev/null
+++ b/torrents/G2-ptPlatform-frontend.zip.torrent
Binary files differ
diff --git "a/torrents/\345\212\237\350\203\275\346\210\252\345\233\276.docx.torrent" "b/torrents/\345\212\237\350\203\275\346\210\252\345\233\276.docx.torrent"
new file mode 100644
index 0000000..3c7d3ad
--- /dev/null
+++ "b/torrents/\345\212\237\350\203\275\346\210\252\345\233\276.docx.torrent"
Binary files differ
diff --git "a/torrents/\350\247\206\351\242\221.mp4.torrent" "b/torrents/\350\247\206\351\242\221.mp4.torrent"
new file mode 100644
index 0000000..bc43edf
--- /dev/null
+++ "b/torrents/\350\247\206\351\242\221.mp4.torrent"
Binary files differ
diff --git a/tracker.json b/tracker.json
index b632be7..a55709b 100644
--- a/tracker.json
+++ b/tracker.json
@@ -1 +1 @@
-{"trackedTorrents":[{"announceInterval":10,"peers":{"PeerUID{address=/10.61.51.238:6881, torrent hash='53475A61645AA5B1141807367D7AA258016E1215'}":{"address":"10.61.51.238:6881","peerId":"NjE5ZDk5NTEtN2ExOS00MDRlLWIzOTktYzQ5YWU4YTJhNTJj","hexPeerId":"36313964393935312D376131392D343034652D623339392D633439616538613261353263","hexInfoHash":null,"uploaded":0,"downloaded":0,"left":53458,"completed":true,"port":6881,"ip":"10.61.51.238","rawIp":"Cj0z7g==","peerIdArray":"NjE5ZDk5NTEtN2ExOS00MDRlLWIzOTktYzQ5YWU4YTJhNTJj","hostIdentifier":"/10.61.51.238:6881","stringPeerId":"619d9951-7a19-404e-b399-c49ae8a2a52c","shortHexPeerId":"..353263"},"PeerUID{address=/127.0.0.1:62128, torrent hash='53475A61645AA5B1141807367D7AA258016E1215'}":{"address":"127.0.0.1:62128","peerId":"LXFCNDUzQS1WTEdLODI4S1lLRUc=","hexPeerId":"2D7142343533412D564C474B3832384B594B4547","hexInfoHash":null,"uploaded":320748,"downloaded":0,"left":0,"completed":true,"port":62128,"ip":"127.0.0.1","rawIp":"fwAAAQ==","peerIdArray":"LXFCNDUzQS1WTEdLODI4S1lLRUc=","hostIdentifier":"/127.0.0.1:62128","stringPeerId":"-qB453A-VLGK828KYKEG","shortHexPeerId":"..4B4547"},"PeerUID{address=/[0:0:0:0:0:0:0:1]:62128, torrent hash='53475A61645AA5B1141807367D7AA258016E1215'}":{"address":"[0:0:0:0:0:0:0:1]:62128","peerId":"LXFCNDUzQS1WTEdLODI4S1lLRUc=","hexPeerId":"2D7142343533412D564C474B3832384B594B4547","hexInfoHash":null,"uploaded":320748,"downloaded":0,"left":0,"completed":true,"port":62128,"ip":"0:0:0:0:0:0:0:1","rawIp":"AAAAAAAAAAAAAAAAAAAAAQ==","peerIdArray":"LXFCNDUzQS1WTEdLODI4S1lLRUc=","hostIdentifier":"/0:0:0:0:0:0:0:1:62128","stringPeerId":"-qB453A-VLGK828KYKEG","shortHexPeerId":"..4B4547"}},"hexInfoHash":"53475A61645AA5B1141807367D7AA258016E1215","infoHash":"U0daYWRapbEUGAc2fXqiWAFuEhU="}],"announceUrl":"http://LAPTOP-C3Q7MHHD:6969/announce","announceURI":"http://LAPTOP-C3Q7MHHD:6969/announce"}
\ No newline at end of file
+{"trackedTorrents":[{"announceInterval":10,"peers":{"PeerUID{address=/127.0.0.1:62128, torrent hash='5E5EB93FDA29E3DB0A603750670F9C261E8EA816'}":{"address":"127.0.0.1:62128","peerId":"LXFCNDUzQS1RMWMob01tTCpBcF8=","hexPeerId":"2D7142343533412D513163286F4D6D4C2A41705F","hexInfoHash":null,"uploaded":411277284,"downloaded":0,"left":0,"completed":true,"port":62128,"peerIdArray":"LXFCNDUzQS1RMWMob01tTCpBcF8=","hostIdentifier":"/127.0.0.1:62128","stringPeerId":"-qB453A-Q1c(oMmL*Ap_","shortHexPeerId":"..41705F","ip":"127.0.0.1","rawIp":"fwAAAQ=="},"PeerUID{address=/[0:0:0:0:0:0:0:1]:62128, torrent hash='5E5EB93FDA29E3DB0A603750670F9C261E8EA816'}":{"address":"[0:0:0:0:0:0:0:1]:62128","peerId":"LXFCNDUzQS1RMWMob01tTCpBcF8=","hexPeerId":"2D7142343533412D513163286F4D6D4C2A41705F","hexInfoHash":null,"uploaded":411277284,"downloaded":0,"left":0,"completed":true,"port":62128,"peerIdArray":"LXFCNDUzQS1RMWMob01tTCpBcF8=","hostIdentifier":"/0:0:0:0:0:0:0:1:62128","stringPeerId":"-qB453A-Q1c(oMmL*Ap_","shortHexPeerId":"..41705F","ip":"0:0:0:0:0:0:0:1","rawIp":"AAAAAAAAAAAAAAAAAAAAAQ=="}},"hexInfoHash":"5E5EB93FDA29E3DB0A603750670F9C261E8EA816","infoHash":"Xl65P9op49sKYDdQZw+cJh6OqBY="},{"announceInterval":10,"peers":{"PeerUID{address=/10.61.51.238:6883, torrent hash='4071E1A83F0DD92869B098E6C61CE2F2AA4EEB15'}":{"address":"10.61.51.238:6883","peerId":"LVRPMDA0Mi1hMjZjZDlmOTE0MGM=","hexPeerId":"2D544F303034322D613236636439663931343063","hexInfoHash":null,"uploaded":0,"downloaded":0,"left":2148043,"completed":false,"port":6883,"peerIdArray":"LVRPMDA0Mi1hMjZjZDlmOTE0MGM=","hostIdentifier":"/10.61.51.238:6883","stringPeerId":"-TO0042-a26cd9f9140c","shortHexPeerId":"..343063","ip":"10.61.51.238","rawIp":"Cj0z7g=="},"PeerUID{address=/10.61.51.238:6884, torrent hash='4071E1A83F0DD92869B098E6C61CE2F2AA4EEB15'}":{"address":"10.61.51.238:6884","peerId":"YmU2YzEzNWUtOTFlNi00YzI4LWEzNmMtZGFjMzJiZWJhYTAy","hexPeerId":"62653663313335652D393165362D346332382D613336632D646163333262656261613032","hexInfoHash":null,"uploaded":0,"downloaded":0,"left":2148043,"completed":true,"port":6884,"peerIdArray":"YmU2YzEzNWUtOTFlNi00YzI4LWEzNmMtZGFjMzJiZWJhYTAy","hostIdentifier":"/10.61.51.238:6884","stringPeerId":"be6c135e-91e6-4c28-a36c-dac32bebaa02","shortHexPeerId":"..613032","ip":"10.61.51.238","rawIp":"Cj0z7g=="},"PeerUID{address=/10.61.51.238:6881, torrent hash='4071E1A83F0DD92869B098E6C61CE2F2AA4EEB15'}":{"address":"10.61.51.238:6881","peerId":"LVRPMDA0Mi1jMzVlNzFlN2QzNDU=","hexPeerId":"2D544F303034322D633335653731653764333435","hexInfoHash":null,"uploaded":0,"downloaded":2148043,"left":0,"completed":true,"port":6881,"peerIdArray":"LVRPMDA0Mi1jMzVlNzFlN2QzNDU=","hostIdentifier":"/10.61.51.238:6881","stringPeerId":"-TO0042-c35e71e7d345","shortHexPeerId":"..333435","ip":"10.61.51.238","rawIp":"Cj0z7g=="},"PeerUID{address=/127.0.0.1:62128, torrent hash='4071E1A83F0DD92869B098E6C61CE2F2AA4EEB15'}":{"address":"127.0.0.1:62128","peerId":"LXFCNDUzQS1nenRybTAwOWQ5WE8=","hexPeerId":"2D7142343533412D677A74726D3030396439584F","hexInfoHash":null,"uploaded":4330593,"downloaded":0,"left":0,"completed":true,"port":62128,"peerIdArray":"LXFCNDUzQS1nenRybTAwOWQ5WE8=","hostIdentifier":"/127.0.0.1:62128","stringPeerId":"-qB453A-gztrm009d9XO","shortHexPeerId":"..39584F","ip":"127.0.0.1","rawIp":"fwAAAQ=="},"PeerUID{address=/[0:0:0:0:0:0:0:1]:62128, torrent hash='4071E1A83F0DD92869B098E6C61CE2F2AA4EEB15'}":{"address":"[0:0:0:0:0:0:0:1]:62128","peerId":"LXFCNDUzQS1nenRybTAwOWQ5WE8=","hexPeerId":"2D7142343533412D677A74726D3030396439584F","hexInfoHash":null,"uploaded":4330593,"downloaded":0,"left":0,"completed":true,"port":62128,"peerIdArray":"LXFCNDUzQS1nenRybTAwOWQ5WE8=","hostIdentifier":"/0:0:0:0:0:0:0:1:62128","stringPeerId":"-qB453A-gztrm009d9XO","shortHexPeerId":"..39584F","ip":"0:0:0:0:0:0:0:1","rawIp":"AAAAAAAAAAAAAAAAAAAAAQ=="},"PeerUID{address=/10.61.51.238:6882, torrent hash='4071E1A83F0DD92869B098E6C61CE2F2AA4EEB15'}":{"address":"10.61.51.238:6882","peerId":"LVRPMDA0Mi1jYzVlZTBlNmY4MzQ=","hexPeerId":"2D544F303034322D636335656530653666383334","hexInfoHash":null,"uploaded":0,"downloaded":2148043,"left":0,"completed":true,"port":6882,"peerIdArray":"LVRPMDA0Mi1jYzVlZTBlNmY4MzQ=","hostIdentifier":"/10.61.51.238:6882","stringPeerId":"-TO0042-cc5ee0e6f834","shortHexPeerId":"..383334","ip":"10.61.51.238","rawIp":"Cj0z7g=="}},"hexInfoHash":"4071E1A83F0DD92869B098E6C61CE2F2AA4EEB15","infoHash":"QHHhqD8N2ShpsJjmxhzi8qpO6xU="},{"announceInterval":10,"peers":{"PeerUID{address=/10.61.51.238:6882, torrent hash='D06484CECF1EDBC5FBFDD61A5FEEA0F2E3BAA74F'}":{"address":"10.61.51.238:6882","peerId":"LVRPMDA0Mi1jYzVlZTBlNmY4MzQ=","hexPeerId":"2D544F303034322D636335656530653666383334","hexInfoHash":null,"uploaded":0,"downloaded":0,"left":0,"completed":true,"port":6882,"peerIdArray":"LVRPMDA0Mi1jYzVlZTBlNmY4MzQ=","hostIdentifier":"/10.61.51.238:6882","stringPeerId":"-TO0042-cc5ee0e6f834","shortHexPeerId":"..383334","ip":"10.61.51.238","rawIp":"Cj0z7g=="},"PeerUID{address=/10.61.51.238:6881, torrent hash='D06484CECF1EDBC5FBFDD61A5FEEA0F2E3BAA74F'}":{"address":"10.61.51.238:6881","peerId":"LVRPMDA0Mi1jMzVlNzFlN2QzNDU=","hexPeerId":"2D544F303034322D633335653731653764333435","hexInfoHash":null,"uploaded":0,"downloaded":0,"left":0,"completed":true,"port":6881,"peerIdArray":"LVRPMDA0Mi1jMzVlNzFlN2QzNDU=","hostIdentifier":"/10.61.51.238:6881","stringPeerId":"-TO0042-c35e71e7d345","shortHexPeerId":"..333435","ip":"10.61.51.238","rawIp":"Cj0z7g=="},"PeerUID{address=/127.0.0.1:62128, torrent hash='D06484CECF1EDBC5FBFDD61A5FEEA0F2E3BAA74F'}":{"address":"127.0.0.1:62128","peerId":"LXFCNDUzQS1nM1JVV05oQShoMFA=","hexPeerId":"2D7142343533412D67335255574E684128683050","hexInfoHash":null,"uploaded":654160709,"downloaded":0,"left":0,"completed":true,"port":62128,"peerIdArray":"LXFCNDUzQS1nM1JVV05oQShoMFA=","hostIdentifier":"/127.0.0.1:62128","stringPeerId":"-qB453A-g3RUWNhA(h0P","shortHexPeerId":"..683050","ip":"127.0.0.1","rawIp":"fwAAAQ=="},"PeerUID{address=/[0:0:0:0:0:0:0:1]:62128, torrent hash='D06484CECF1EDBC5FBFDD61A5FEEA0F2E3BAA74F'}":{"address":"[0:0:0:0:0:0:0:1]:62128","peerId":"LXFCNDUzQS1nM1JVV05oQShoMFA=","hexPeerId":"2D7142343533412D67335255574E684128683050","hexInfoHash":null,"uploaded":654160709,"downloaded":0,"left":0,"completed":true,"port":62128,"peerIdArray":"LXFCNDUzQS1nM1JVV05oQShoMFA=","hostIdentifier":"/0:0:0:0:0:0:0:1:62128","stringPeerId":"-qB453A-g3RUWNhA(h0P","shortHexPeerId":"..683050","ip":"0:0:0:0:0:0:0:1","rawIp":"AAAAAAAAAAAAAAAAAAAAAQ=="},"PeerUID{address=/10.61.51.238:6883, torrent hash='D06484CECF1EDBC5FBFDD61A5FEEA0F2E3BAA74F'}":{"address":"10.61.51.238:6883","peerId":"MDQ4NTU3ZTQtYTVlNi00OTc3LWFkNjEtMzhiNGE4Y2FmMWRl","hexPeerId":"30343835353765342D613565362D343937372D616436312D333862346138636166316465","hexInfoHash":null,"uploaded":0,"downloaded":0,"left":652374853,"completed":true,"port":6883,"peerIdArray":"MDQ4NTU3ZTQtYTVlNi00OTc3LWFkNjEtMzhiNGE4Y2FmMWRl","hostIdentifier":"/10.61.51.238:6883","stringPeerId":"048557e4-a5e6-4977-ad61-38b4a8caf1de","shortHexPeerId":"..316465","ip":"10.61.51.238","rawIp":"Cj0z7g=="}},"hexInfoHash":"D06484CECF1EDBC5FBFDD61A5FEEA0F2E3BAA74F","infoHash":"0GSEzs8e28X7/dYaX+6g8uO6p08="},{"announceInterval":10,"peers":{"PeerUID{address=/127.0.0.1:62128, torrent hash='53475A61645AA5B1141807367D7AA258016E1215'}":{"address":"127.0.0.1:62128","peerId":"LXFCNDUzQS1Qdm1iIUlXTnVlTDI=","hexPeerId":"2D7142343533412D50766D622149574E75654C32","hexInfoHash":null,"uploaded":213832,"downloaded":0,"left":0,"completed":true,"port":62128,"peerIdArray":"LXFCNDUzQS1Qdm1iIUlXTnVlTDI=","hostIdentifier":"/127.0.0.1:62128","stringPeerId":"-qB453A-Pvmb!IWNueL2","shortHexPeerId":"..654C32","ip":"127.0.0.1","rawIp":"fwAAAQ=="},"PeerUID{address=/[0:0:0:0:0:0:0:1]:62128, torrent hash='53475A61645AA5B1141807367D7AA258016E1215'}":{"address":"[0:0:0:0:0:0:0:1]:62128","peerId":"LXFCNDUzQS1Qdm1iIUlXTnVlTDI=","hexPeerId":"2D7142343533412D50766D622149574E75654C32","hexInfoHash":null,"uploaded":213832,"downloaded":0,"left":0,"completed":true,"port":62128,"peerIdArray":"LXFCNDUzQS1Qdm1iIUlXTnVlTDI=","hostIdentifier":"/0:0:0:0:0:0:0:1:62128","stringPeerId":"-qB453A-Pvmb!IWNueL2","shortHexPeerId":"..654C32","ip":"0:0:0:0:0:0:0:1","rawIp":"AAAAAAAAAAAAAAAAAAAAAQ=="}},"hexInfoHash":"53475A61645AA5B1141807367D7AA258016E1215","infoHash":"U0daYWRapbEUGAc2fXqiWAFuEhU="},{"announceInterval":10,"peers":{"PeerUID{address=/[0:0:0:0:0:0:0:1]:62128, torrent hash='7F22190707CC95889A398E3DF940B7507C23D8AC'}":{"address":"[0:0:0:0:0:0:0:1]:62128","peerId":"LXFCNDUzQS1JKWtxdTlpVkkyTFc=","hexPeerId":"2D7142343533412D49296B717539695649324C57","hexInfoHash":null,"uploaded":0,"downloaded":0,"left":0,"completed":true,"port":62128,"peerIdArray":"LXFCNDUzQS1JKWtxdTlpVkkyTFc=","hostIdentifier":"/0:0:0:0:0:0:0:1:62128","stringPeerId":"-qB453A-I)kqu9iVI2LW","shortHexPeerId":"..324C57","ip":"0:0:0:0:0:0:0:1","rawIp":"AAAAAAAAAAAAAAAAAAAAAQ=="},"PeerUID{address=/127.0.0.1:62128, torrent hash='7F22190707CC95889A398E3DF940B7507C23D8AC'}":{"address":"127.0.0.1:62128","peerId":"LXFCNDUzQS1JKWtxdTlpVkkyTFc=","hexPeerId":"2D7142343533412D49296B717539695649324C57","hexInfoHash":null,"uploaded":0,"downloaded":0,"left":0,"completed":true,"port":62128,"peerIdArray":"LXFCNDUzQS1JKWtxdTlpVkkyTFc=","hostIdentifier":"/127.0.0.1:62128","stringPeerId":"-qB453A-I)kqu9iVI2LW","shortHexPeerId":"..324C57","ip":"127.0.0.1","rawIp":"fwAAAQ=="}},"hexInfoHash":"7F22190707CC95889A398E3DF940B7507C23D8AC","infoHash":"fyIZBwfMlYiaOY49+UC3UHwj2Kw="},{"announceInterval":10,"peers":{"PeerUID{address=/[0:0:0:0:0:0:0:1]:62128, torrent hash='031E5512B72FD1E2CEA290163F10E7B842A67E8B'}":{"address":"[0:0:0:0:0:0:0:1]:62128","peerId":"LXFCNDUzQS0oNTRNbE41d1BJTjY=","hexPeerId":"2D7142343533412D2835344D6C4E357750494E36","hexInfoHash":null,"uploaded":1108877,"downloaded":0,"left":0,"completed":true,"port":62128,"peerIdArray":"LXFCNDUzQS0oNTRNbE41d1BJTjY=","hostIdentifier":"/0:0:0:0:0:0:0:1:62128","stringPeerId":"-qB453A-(54MlN5wPIN6","shortHexPeerId":"..494E36","ip":"0:0:0:0:0:0:0:1","rawIp":"AAAAAAAAAAAAAAAAAAAAAQ=="},"PeerUID{address=/127.0.0.1:62128, torrent hash='031E5512B72FD1E2CEA290163F10E7B842A67E8B'}":{"address":"127.0.0.1:62128","peerId":"LXFCNDUzQS0oNTRNbE41d1BJTjY=","hexPeerId":"2D7142343533412D2835344D6C4E357750494E36","hexInfoHash":null,"uploaded":1108877,"downloaded":0,"left":0,"completed":true,"port":62128,"peerIdArray":"LXFCNDUzQS0oNTRNbE41d1BJTjY=","hostIdentifier":"/127.0.0.1:62128","stringPeerId":"-qB453A-(54MlN5wPIN6","shortHexPeerId":"..494E36","ip":"127.0.0.1","rawIp":"fwAAAQ=="}},"hexInfoHash":"031E5512B72FD1E2CEA290163F10E7B842A67E8B","infoHash":"Ax5VErcv0eLOopAWPxDnuEKmfos="}],"announceURI":"http://LAPTOP-C3Q7MHHD:6969/announce","announceUrl":"http://LAPTOP-C3Q7MHHD:6969/announce"}
\ No newline at end of file