diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..aa00ffa
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 05b1f4c..eb53fe3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -58,6 +58,12 @@
commons-compress
1.25.0
+
+
+ org.apache.httpcomponents
+ httpclient
+ 4.5.14
+
diff --git a/src/main/java/lion/Config/Config.java b/src/main/java/lion/Config/Config.java
new file mode 100644
index 0000000..8462194
--- /dev/null
+++ b/src/main/java/lion/Config/Config.java
@@ -0,0 +1,23 @@
+package lion.Config;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+public class Config {
+ public static String DouNaiV2ray;
+ public static String DouNaiClash;
+
+ public static void loadConfig(){
+ Properties prop = new Properties();
+
+ try (InputStream input = new FileInputStream("/root/gallery/storageNode/config.properties")) {
+ prop.load(input);
+ DouNaiV2ray = prop.getProperty("DouNaiV2ray");
+ DouNaiClash = prop.getProperty("DouNaiClash");
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ }
+ }
+}
diff --git a/src/main/java/lion/CustomUtil.java b/src/main/java/lion/CustomUtil.java
index 3c7ca07..a10b556 100644
--- a/src/main/java/lion/CustomUtil.java
+++ b/src/main/java/lion/CustomUtil.java
@@ -1,10 +1,10 @@
package lion;
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpResponse;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
-import java.io.IOException;
-import java.net.ServerSocket;
import java.util.concurrent.atomic.AtomicInteger;
@@ -15,14 +15,14 @@ public class CustomUtil {
public static ObjectMapper objectMapper = new ObjectMapper();
- public static int _findIdlePort(int port) {
- for(int i=port; i<65535; i++){
- try(ServerSocket ignored = new ServerSocket(i)){
- ignored.close();
- return i;
- }catch (IOException ignored) {
+ public static void notifyMe(String message) {
+ String url = "https://personal.lionwebsite.xyz/message2me?AuthCode=alone&message=" + message;
+ HttpRequest request = HttpRequest.post(url);
+ request.header("User-Agent", "Mozilla/5.0");
+ try(HttpResponse response = request.execute()) {
+ if(response.getStatus() != 200) {
+ System.out.println("通知失败, status code:" + response.getStatus() + ", message:" + message);
}
}
- return -1;
}
}
diff --git a/src/main/java/lion/Externel/BackupSubServer.java b/src/main/java/lion/Externel/BackupSubServer.java
new file mode 100644
index 0000000..ba4611c
--- /dev/null
+++ b/src/main/java/lion/Externel/BackupSubServer.java
@@ -0,0 +1,290 @@
+package lion.Externel;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.http.HttpEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+
+import java.io.*;
+import java.net.*;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.time.LocalDateTime;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import static lion.Config.Config.DouNaiClash;
+import static lion.Config.Config.DouNaiV2ray;
+
+@Slf4j
+public class BackupSubServer {
+
+ public static void main(String[] args) {
+ updateSub();
+ ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(1);
+ threadPool.scheduleAtFixedRate(BackupSubServer::updateSub, 0, 12, TimeUnit.HOURS);
+
+ String ip = "";
+ try(ServerSocket serverSocket = new ServerSocket(8889)) {
+ log.info("Sub Server listening on port {}", 8889);
+ while (true) {
+ Socket clientSocket = serverSocket.accept();
+ ip = clientSocket.getInetAddress().getHostAddress();
+ log.info("Client connected:{}", ip);
+ // 线程池处理下载请求
+ handleClientRequest(clientSocket);
+ }
+ } catch (IOException e) {
+ log.error("处理http请求时出错,IP:{},ERROR:{}", ip, e.getMessage());
+ }
+ }
+
+ public static void updateSub(){
+ File DouNaiClashFile = new File("sub/DouNaiClash.txt");
+ File DouNaiV2rayFile = new File("sub/DouNaiV2ray.txt");
+ File directory = new File("sub");
+
+ if(!directory.isDirectory())
+ try {
+ Files.createDirectory(Paths.get("sub"));
+ } catch (IOException e) {
+ log.error("create directory error:{}", e.getMessage());
+ }
+
+ List DouNaiClash_profile;
+
+ //下载豆奶v2ray订阅
+ try(FileWriter writer = new FileWriter(DouNaiV2rayFile)) {
+ String DouNaiV2rayRaw = Get(DouNaiV2ray).getFirst();
+ String[] v2rayPlain = new String(Base64.getDecoder().decode(DouNaiV2rayRaw)).split("\n");
+ StringBuilder stringBuilder = new StringBuilder();
+ Pattern pattern = Pattern.compile("-?\\d+(\\.\\d+)?");
+
+ //过滤高倍率节点
+ for(String node: v2rayPlain){
+ String name = URLDecoder.decode(node.split("#")[1], StandardCharsets.UTF_8);
+ if(name.contains("流量")){
+ Matcher matcher = pattern.matcher(name.substring(name.indexOf("(") + 1, name.indexOf(")")));
+
+ if (matcher.find()) {
+ // 将匹配到的数字添加到列表中
+ float ratio = Float.parseFloat(matcher.group());
+ if(ratio <= 2) {
+ stringBuilder.append(node).append("\n");
+ continue;
+ }
+ }
+ stringBuilder.append(node).append("\n");
+ }
+ else{
+ stringBuilder.append(node).append("\n");
+ }
+ }
+ writer.write(new String(Base64.getEncoder().encode(stringBuilder.toString().getBytes(StandardCharsets.UTF_8))));
+
+ log.info("load DouNai v2ray complete");
+ }catch (IOException e){
+ log.error("load DouNai v2ray failure: {}", e.getMessage());
+ }
+
+ //下载豆奶clash订阅
+ try(FileWriter writer = new FileWriter(DouNaiClashFile)) {
+ DouNaiClash_profile = Get(DouNaiClash);
+ //过滤高倍率节点
+ ArrayList clashProcessed = new ArrayList<>();
+ boolean isProxies = false;
+ boolean skip = false;
+ for(String line: DouNaiClash_profile){
+ if(line.equals("proxies:"))
+ isProxies = true;
+ else if(line.equals("proxy-groups:") && isProxies)
+ isProxies = false;
+
+ if(isProxies) {
+ if (line.contains("name"))
+ skip = line.contains("流量");
+ if (!skip)
+ clashProcessed.add(line);
+ }
+ else
+ if (!line.contains("流量"))
+ clashProcessed.add(line);
+ }
+
+ for(String line: clashProcessed)
+ writer.write(line + "\n");
+
+ log.info("load DouNai clash complete");
+ }catch (IOException e){
+ log.error("load DouNai clash failure: {}", e.getMessage());
+ }
+ }
+
+
+ public static ArrayList Get(String url) throws IOException {
+ CloseableHttpClient httpClient = HttpClients.createDefault();
+ CloseableHttpResponse httpResponse;
+ HttpGet httpGet = new HttpGet(url);
+
+ httpResponse = httpClient.execute(httpGet);
+
+ HttpEntity responseEntity = httpResponse.getEntity();
+ int statusCode = httpResponse.getStatusLine().getStatusCode();
+ ArrayList temp = new ArrayList<>();
+
+ if (statusCode == 200) {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(responseEntity.getContent()));
+ String str;
+ while ((str = reader.readLine()) != null)
+ temp.add(str);
+ }
+
+ httpClient.close();
+ httpResponse.close();
+ return temp;
+ }
+
+ private static void handleClientRequest(Socket clientSocket) {
+ String fileName = "";
+ try {
+ BufferedReader requestReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
+ String requestLine = requestReader.readLine();
+
+ // Parse the request line to get the method and path
+ String[] requestParts = requestLine.split(" ");
+ String method = requestParts[0];
+ Map paramMap = parseRequestLine(requestParts[1]);//path
+ if(paramMap == null){
+ sendErrorResponse(clientSocket, "404");
+ return;
+ }
+ log.info(Arrays.toString(requestParts));
+
+ // Only handle GET requests
+ if (method.equals("GET")) {
+ // Set the file path for download
+ File file = new File(fileName);
+ switch (paramMap.get("Client")) {
+ case "v2" -> file = new File("sub/DouNaiV2ray.txt");
+ case "cat" -> file = new File("sub/DouNaiClash.txt");
+ }
+ fileName = file.getName();
+ log.info(file.getAbsolutePath());
+ // Check if the file exists and is readable
+ if (file.exists() && file.isFile() && file.canRead()) {
+ // Get the file length
+ long fileLength = file.length();
+
+ // Get the range information for resuming download
+ long startByte = 0;
+ long endByte = fileLength - 1;
+ String rangeHeader = getRequestHeader(requestReader);
+ if (rangeHeader != null && rangeHeader.startsWith("bytes=")) {
+ String[] rangeValues = rangeHeader.substring(6).split("-");
+ startByte = Long.parseLong(rangeValues[0]);
+ if (rangeValues.length > 1 && !rangeValues[1].isEmpty()) {
+ endByte = Long.parseLong(rangeValues[1]);
+ }
+ }
+
+ // Send the HTTP response headers
+ OutputStream responseStream = clientSocket.getOutputStream();
+ PrintWriter responseWriter = new PrintWriter(responseStream, true);
+ responseWriter.println("HTTP/1.1 206 Partial Content");
+ responseWriter.println("Content-Type: application/octet-stream");
+ responseWriter.println("Accept-Ranges: bytes");
+ responseWriter.println("Content-Length: " + (endByte - startByte + 1));
+ responseWriter.println("Content-Range: bytes " + startByte + "-" + endByte + "/" + fileLength);
+ responseWriter.println();
+
+ // Send the file content
+ try (RandomAccessFile randomAccessFile = new RandomAccessFile(file, "r")) {
+ randomAccessFile.seek(startByte);
+ byte[] buffer = new byte[1024];
+ int bytesRead;
+ long bytesRemaining = endByte - startByte + 1;
+ while (bytesRemaining > 0 && (bytesRead = randomAccessFile.read(buffer, 0, (int) Math.min(buffer.length, bytesRemaining))) != -1) {
+ responseStream.write(buffer, 0, bytesRead);
+ bytesRemaining -= bytesRead;
+ }
+ }catch (SocketException ignore){
+
+ }
+
+ // Close the response output stream
+ responseStream.close();
+ } else {
+ // File not found or not readable, send 404 response
+ sendErrorResponse(clientSocket, "404 Not Found");
+ }
+ } else {
+ // Non-GET requests, send 501 response
+ sendErrorResponse(clientSocket, "501 Not Implemented");
+ }
+
+ // Close the request reader and client socket
+ requestReader.close();
+ clientSocket.close();
+ } catch (IOException e) {
+ log.error("处理文件下载时出错,IP:{}, 文件:{}, ERROR:{}", clientSocket.getInetAddress().getHostAddress(), fileName, e.getMessage());
+ }
+ }
+
+ private static String getRequestHeader(BufferedReader requestReader) throws IOException {
+ String line;
+ while ((line = requestReader.readLine()) != null) {
+ if (line.trim().isEmpty()) {
+ break;
+ }
+
+ if (line.startsWith("Range" + ":")) {
+ return line.substring("Range".length() + 1).trim();
+ }
+ }
+ return null;
+ }
+
+ public static Map parseRequestLine(String requestLine) {
+ Map pathParams = new HashMap<>();
+
+ if(requestLine == null)
+ return null;
+
+ String path;
+ if(requestLine.contains("?"))
+ path = requestLine.split("\\?")[0];
+ else
+ path = requestLine;
+
+ String[] vars = path.split("/");
+
+ if(vars.length < 4)
+ return null;
+
+ pathParams.put("Key", vars[3]);
+ pathParams.put("Client", vars[2]);
+
+ if(!pathParams.get("Client").equals("cat") && !pathParams.get("Client").equals("v2"))
+ return null;
+
+ if(pathParams.get("Key").length()<6)
+ return null;
+
+ return pathParams;
+ }
+
+ private static void sendErrorResponse(Socket clientSocket, String statusCode) throws IOException {
+ OutputStream responseStream = clientSocket.getOutputStream();
+ PrintWriter responseWriter = new PrintWriter(responseStream, true);
+ responseWriter.println("HTTP/1.1 " + statusCode);
+ responseWriter.println("Content-Type: text/html");
+ responseWriter.println();
+ responseWriter.println("" + statusCode + "
");
+ responseStream.close();
+ }
+}
diff --git a/src/main/java/lion/Extranel/AESUtils.java b/src/main/java/lion/Extranel/AESUtils.java
deleted file mode 100644
index 8797821..0000000
--- a/src/main/java/lion/Extranel/AESUtils.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package lion.Extranel;
-
-import javax.crypto.Cipher;
-import javax.crypto.spec.SecretKeySpec;
-import java.security.Key;
-
-public class AESUtils {
- private static final String ALGORITHM = "AES";
- private static final String TRANSFORMATION = "AES/ECB/PKCS5Padding";
-
- private static final byte[] keyBytes = "ThisIsA128BitKey".getBytes();
-
- public static byte[] encrypt(byte[] data) throws Exception {
- Key key = new SecretKeySpec(keyBytes, ALGORITHM);
- Cipher cipher = Cipher.getInstance(TRANSFORMATION);
- cipher.init(Cipher.ENCRYPT_MODE, key);
- return cipher.doFinal(data);
- }
-
- public static byte[] decrypt(byte[] encryptedData) throws Exception {
- Key key = new SecretKeySpec(keyBytes, ALGORITHM);
- Cipher cipher = Cipher.getInstance(TRANSFORMATION);
- cipher.init(Cipher.DECRYPT_MODE, key);
- return cipher.doFinal(encryptedData);
- }
-}
diff --git a/src/main/java/lion/Extranel/Server.java b/src/main/java/lion/Extranel/Server.java
deleted file mode 100644
index 770b0c4..0000000
--- a/src/main/java/lion/Extranel/Server.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package lion.Extranel;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import lion.CustomUtil;
-import lombok.extern.slf4j.Slf4j;
-
-import java.io.BufferedInputStream;
-import java.io.IOException;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.net.URI;
-import java.net.URL;
-import java.util.HashMap;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-@Slf4j
-public class Server {
-
- ExecutorService thread_pool;
-
- ObjectMapper objectMapper;
-
- public static void main(String[] args) {
- new Server();
- }
-
- public Server(){
- log.info("开始监听:55555");
- objectMapper = CustomUtil.objectMapper;
- thread_pool = Executors.newFixedThreadPool(2);
- thread_pool.submit(() -> {
- try(ServerSocket server = new ServerSocket(55555)){
- server.setSoTimeout(1000000);
- while (true){
- Socket socket = server.accept();
- thread_pool.submit(() -> handleSocket(socket));
- }
- }catch (IOException e){
- log.error(e.getMessage());
- }
- });
- }
-
-
- public void handleSocket(Socket socket){
- try{
- BufferedInputStream inputStream = new BufferedInputStream(socket.getInputStream());
- Thread.sleep(500);
- byte[] buf = new byte[inputStream.available()];
- inputStream.read(buf);
- byte[] bytes = AESUtils.decrypt(buf);
-
- HashMap map = (HashMap) objectMapper.readValue(bytes, HashMap.class);
- URL url = new URI(map.get("path")).toURL();
- log.info("处理反代 ip: {},路径: {}", socket.getInetAddress().getHostAddress(), map.get("path"));
- bytes = url.openConnection().getInputStream().readAllBytes();
- socket.getOutputStream().write(AESUtils.encrypt(bytes));
- socket.getOutputStream().flush();
- socket.getOutputStream().close();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-}
diff --git a/src/main/java/lion/Main.java b/src/main/java/lion/Main.java
index af58463..235ab32 100644
--- a/src/main/java/lion/Main.java
+++ b/src/main/java/lion/Main.java
@@ -1,7 +1,8 @@
package lion;
import io.netty.bootstrap.Bootstrap;
-import lion.Extranel.Server;
+import lion.Config.Config;
+import lion.Externel.BackupSubServer;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@@ -9,8 +10,9 @@ public class Main {
public static void main(String[] args) {
boot();
+ Config.loadConfig();
+ new Thread(() -> BackupSubServer.main(null)).start();
new Thread(() -> MultiThreadedHTTPServer.main(null)).start();
- new Thread(() -> Server.main(null)).start();
new storageNode();
}
diff --git a/src/main/java/lion/MultiThreadedHTTPServer.java b/src/main/java/lion/MultiThreadedHTTPServer.java
index c8ca647..a7d33eb 100644
--- a/src/main/java/lion/MultiThreadedHTTPServer.java
+++ b/src/main/java/lion/MultiThreadedHTTPServer.java
@@ -127,6 +127,7 @@ public class MultiThreadedHTTPServer {
responseWriter.println("Accept-Ranges: bytes");
responseWriter.println("Content-Length: " + (endByte - startByte + 1));
responseWriter.println("Content-Range: bytes " + startByte + "-" + endByte + "/" + fileLength);
+ responseWriter.println("Content-Disposition: attachment; filename=\"" + fileName + "\"");
responseWriter.println();
// Send the file content
diff --git a/src/main/java/lion/Service/DownloadCheckService.java b/src/main/java/lion/Service/DownloadCheckService.java
index 14a4920..8d0c844 100644
--- a/src/main/java/lion/Service/DownloadCheckService.java
+++ b/src/main/java/lion/Service/DownloadCheckService.java
@@ -4,6 +4,7 @@ import io.netty.channel.Channel;
import io.netty.channel.DefaultEventLoop;
import io.netty.channel.EventLoop;
import io.netty.util.concurrent.Promise;
+import lion.CustomUtil;
import lion.Domain.GalleryTask;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ZipUtil;
@@ -21,7 +22,7 @@ import java.util.concurrent.locks.ReentrantLock;
@Slf4j
@Data
public class DownloadCheckService {
- ArrayList queue;
+ Map queue;
String downloadPath = "/root/gallery/hentai/download/";
@@ -37,7 +38,7 @@ public class DownloadCheckService {
EventLoop eventLoop;
- public DownloadCheckService(ArrayList queue, HashMap> promises){
+ public DownloadCheckService(Map queue, HashMap> promises){
this.queue = queue;
this.promises = promises;
eventLoop = new DefaultEventLoop();
@@ -49,7 +50,7 @@ public class DownloadCheckService {
public boolean downloadCheck(){
if(queue.isEmpty())
return false;
- log.info("下载检查:" + Arrays.toString(queue.toArray()));
+ log.info("下载检查:{}", Arrays.toString(queue.values().toArray()));
File downloadDirectory = new File(downloadPath);
File[] fileArray = downloadDirectory.listFiles();
@@ -62,7 +63,7 @@ public class DownloadCheckService {
boolean result = false;
//扫描进度
Iterator fileIterator = files.iterator();
- for(GalleryTask galleryTask: queue){
+ for(GalleryTask galleryTask: queue.values()){
//跳过已经下载完成或者压缩完成的任务
if(galleryTask.is_compress_complete() || galleryTask.is_compressing()) {
result = true;
@@ -96,7 +97,7 @@ public class DownloadCheckService {
}
//压缩队列
- for(GalleryTask galleryTask: queue)
+ for(GalleryTask galleryTask: queue.values())
if (galleryTask.is_download_complete()) {
galleryTask.setStatus(GalleryTask.COMPRESSING);
compress_queue.add(galleryTask);
@@ -139,4 +140,35 @@ public class DownloadCheckService {
}
}
}
+
+ /**
+ * 检查改任务是否为已完成任务,如已完成则返回true,若未完成则加入队列
+ * @return true if compress complete, false otherwise
+ */
+ public boolean addToQueue(GalleryTask galleryTask){
+ //是否含有名字,进行中任务一般有名字,没有名字则肯定为初始任务,存在名字至少在下载路径出现过
+ if(galleryTask.getName() == null || galleryTask.getName().isEmpty()){
+ queue.putIfAbsent(galleryTask.getGid(), galleryTask);
+ return false;
+ }
+
+ //查询hah下载路径中,是否存在该任务下载路径,存在则为下载中或下载完成任务,加入队列
+ if(new File(downloadPath + galleryTask.getGid()).isDirectory()){
+ queue.putIfAbsent(galleryTask.getGid(), galleryTask);
+ return false;
+ }
+
+
+ //查询存放路径中是否含有该任务的压缩包,存在则为下载完成任务
+ if(new File(storagePath + galleryTask.getName() + "/" + galleryTask.getName() + ".zip").exists()){
+ galleryTask.setStatus(GalleryTask.COMPRESS_COMPLETE);
+ CustomUtil.notifyMe(String.format("任务:%s在添加时已下载完成,更新任务状态", galleryTask.getName()));
+ return true;
+ }
+
+
+ //异常情况,发送通知
+ CustomUtil.notifyMe(String.format("任务:%s存在名字,但是下载路径为空且不存在压缩包", galleryTask.getName()));
+ return false;
+ }
}
diff --git a/src/main/java/lion/storageNode.java b/src/main/java/lion/storageNode.java
index db521d1..3719c80 100644
--- a/src/main/java/lion/storageNode.java
+++ b/src/main/java/lion/storageNode.java
@@ -17,8 +17,8 @@ import lombok.extern.slf4j.Slf4j;
import java.net.InetSocketAddress;
import java.net.Socket;
-import java.util.ArrayList;
import java.util.HashMap;
+import java.util.Map;
import java.util.concurrent.*;
import java.util.concurrent.locks.ReentrantLock;
@@ -33,9 +33,9 @@ public class storageNode {
DownloadCheckService downloadCheckService;
- ArrayList queue;
+ Map queue;
- ArrayList tempQueue;
+ Map tempQueue;
ScheduledExecutorService checkThreadPool;
@@ -48,8 +48,8 @@ public class storageNode {
public static String storagePath = "/root/gallery/gallery/";
public storageNode(){
- queue = new ArrayList<>(0);
- tempQueue = new ArrayList<>(0);
+ queue = new HashMap<>();
+ tempQueue = new HashMap<>();
lock = new ReentrantLock();
counter = 0;
promises = new HashMap<>();
@@ -94,7 +94,7 @@ public class storageNode {
try {
lock.lock();
if(!tempQueue.isEmpty()){
- queue.addAll(tempQueue);
+ queue.putAll(tempQueue);
tempQueue.clear();
}
lock.unlock();
@@ -103,7 +103,7 @@ public class storageNode {
boolean isSkip = true;
//返回false之后,还要额外检查是否有压缩完成的任务
if(!queue.isEmpty())
- for (GalleryTask galleryTask : queue)
+ for (GalleryTask galleryTask : queue.values())
if (galleryTask.is_compress_complete()) {
isSkip = false;
break;
@@ -121,11 +121,13 @@ public class storageNode {
//上锁后再发送,避免出现发送完之后再下载完成
lock.lock();
DownloadStatusMessage downloadStatusMessage = new DownloadStatusMessage();
- downloadStatusMessage.setGalleryTasks(queue.toArray(GalleryTask[]::new));
+ downloadStatusMessage.setGalleryTasks(queue.values().toArray(GalleryTask[]::new));
server.writeAndFlush(downloadStatusMessage);
+
+ queue.entrySet().removeIf(entry -> entry.getValue().is_compress_complete());
log.info("任务状态发送完成");
- queue.removeIf(GalleryTask::is_compress_complete);
+
lock.unlock();
}catch (Exception e){
log.error("发送任务状态时发生异常:{}", e.getMessage());
@@ -133,9 +135,9 @@ public class storageNode {
}
class MyChannelInboundHandlerAdapter extends ChannelInboundHandlerAdapter{
- ArrayList queue;
+ Map queue;
- public MyChannelInboundHandlerAdapter(ArrayList queue) {
+ public MyChannelInboundHandlerAdapter(Map queue) {
this.queue = queue;
}
@@ -159,7 +161,12 @@ public class storageNode {
case AbstractMessage.DOWNLOAD_POST_MESSAGE -> {
DownloadPostMessage dpm = (DownloadPostMessage) abstractMessage;
lock.lock();
- queue.add(dpm.getGalleryTask());
+ //添加到队列方法返回真说明该任务已下载完成,直接发送下载进度
+ if(downloadCheckService.addToQueue(dpm.getGalleryTask())){
+ DownloadStatusMessage downloadStatusMessage = new DownloadStatusMessage();
+ downloadStatusMessage.setGalleryTasks(new GalleryTask[]{dpm.getGalleryTask()});
+ server.writeAndFlush(downloadStatusMessage);
+ }
log.info(String.valueOf(queue));
lock.unlock();
ctx.writeAndFlush(new ResponseMessage(dpm.messageId, (byte) 0));
diff --git a/src/main/resources/config.properties b/src/main/resources/config.properties
new file mode 100644
index 0000000..427b6b4
--- /dev/null
+++ b/src/main/resources/config.properties
@@ -0,0 +1,2 @@
+DouNaiV2ray=https://aaaa.gay/link/X7zEqkIx5gtIGugO?client=v2
+DouNaiClash=https://aaaa.gay/link/X7zEqkIx5gtIGugO?client=clashmeta
\ No newline at end of file