添加保活信息;添加tg机器人,推送关键事件;

This commit is contained in:
chuzhongzai 2023-09-02 15:19:29 +08:00
parent 009f8bfa76
commit 32d98b3d84
16 changed files with 138 additions and 40 deletions

View File

@ -106,6 +106,12 @@
<artifactId>netty-all</artifactId> <artifactId>netty-all</artifactId>
<version>4.1.86.Final</version> <version>4.1.86.Final</version>
</dependency> </dependency>
<dependency>
<groupId>com.github.pengrad</groupId>
<artifactId>java-telegram-bot-api</artifactId>
<version>6.7.0</version>
</dependency>
</dependencies> </dependencies>
<build> <build>

View File

@ -0,0 +1,15 @@
package com.lion.lionwebsite.Configuration;
import com.pengrad.telegrambot.TelegramBot;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class CustomBean {
@Bean
public TelegramBot getTelegramBot(@Value("${bot.token}") String token){
return new TelegramBot(token);
}
}

View File

@ -62,11 +62,8 @@ public class PublicController {
@GetMapping("/GetFile/{path}") @GetMapping("/GetFile/{path}")
public void getFile(HttpServletRequest request, HttpServletResponse response, String ShareCode, @PathVariable("path") String path) throws IOException { public void getFile(HttpServletRequest request, HttpServletResponse response, String ShareCode, @PathVariable("path") String path) throws IOException {
synchronized (black_share_codes) { synchronized (black_share_codes) {
if (black_share_codes.contains(ShareCode)) { if (black_share_codes.contains(ShareCode))
String ip = request.getHeader("X-Forwarded-For") == null ? request.getRemoteAddr() : request.getHeader("X-Forwarded-For");
log.info("dispatch request ip:{} file:{}", ip, path);
return; return;
}
} }
log.info("ShareCode:{}", ShareCode); log.info("ShareCode:{}", ShareCode);

View File

@ -28,7 +28,7 @@ public interface GalleryMapper {
@Select("select * from gallery where status in ('已提交', '下载中')") @Select("select * from gallery where status in ('已提交', '下载中')")
Gallery[] selectUnDoneGalleries(); Gallery[] selectUnDoneGalleries();
@Select("select * from gallery") @Select("select * from gallery order by createTime")
Gallery[] selectAllGallery(); Gallery[] selectAllGallery();
@Select("select * from gallery where name like #{name} limit 1") @Select("select * from gallery where name like #{name} limit 1")

View File

@ -15,6 +15,9 @@ public class AbstractMessage {
public static final byte GALLERY_PAGE_QUERY_MESSAGE = 5; public static final byte GALLERY_PAGE_QUERY_MESSAGE = 5;
public static final byte IDENTITY_MESSAGE = 6; public static final byte IDENTITY_MESSAGE = 6;
public static final byte MAINTAIN_MESSAGE = 7;
public static final byte GALLERY_REQUEST_MESSAGE = 101; public static final byte GALLERY_REQUEST_MESSAGE = 101;
public byte messageType; public byte messageType;

View File

@ -0,0 +1,7 @@
package com.lion.lionwebsite.Message;
public class MaintainMessage extends AbstractMessage{
{
messageType = MAINTAIN_MESSAGE;
}
}

View File

@ -45,6 +45,7 @@ public class MessageCodec extends ByteToMessageCodec<AbstractMessage> {
case AbstractMessage.DELETE_GALLERY_MESSAGE -> objectMapper.readValue(metadata, DeleteGalleryMessage.class); case AbstractMessage.DELETE_GALLERY_MESSAGE -> objectMapper.readValue(metadata, DeleteGalleryMessage.class);
case AbstractMessage.GALLERY_PAGE_QUERY_MESSAGE -> objectMapper.readValue(metadata, GalleryPageQueryMessage.class); case AbstractMessage.GALLERY_PAGE_QUERY_MESSAGE -> objectMapper.readValue(metadata, GalleryPageQueryMessage.class);
case AbstractMessage.IDENTITY_MESSAGE -> objectMapper.readValue(metadata, IdentityMessage.class); case AbstractMessage.IDENTITY_MESSAGE -> objectMapper.readValue(metadata, IdentityMessage.class);
case AbstractMessage.MAINTAIN_MESSAGE -> objectMapper.readValue(metadata, MaintainMessage.class);
default -> null; default -> null;
}; };

View File

@ -66,6 +66,9 @@ public class GalleryManageService {
@Resource @Resource
RemoteService remoteService; RemoteService remoteService;
@Resource
PushService pushService;
/** /**
* 创建任务 * 创建任务
* @param link 任务链接 * @param link 任务链接
@ -75,15 +78,20 @@ public class GalleryManageService {
*/ */
public String createTask(String link, String targetResolution, String AuthCode, List<Integer> tidS, byte mode){ public String createTask(String link, String targetResolution, String AuthCode, List<Integer> tidS, byte mode){
Response response = Response.generateResponse(); Response response = Response.generateResponse();
User user = userMapper.selectUserByAuthCode(AuthCode);
// return Response._failure("调试中,请勿提交任务"); // return Response._failure("调试中,请勿提交任务");
if(remoteService.isDead()) if(remoteService.isDead()) {
return Response._failure("节点挂了,找狮子处理"); response.failure("节点挂了,找狮子处理");
pushService.taskCreateReport(user.getUsername(), link, response);
return response.toJSONString();
}
int gid; int gid;
try { try {
gid = Integer.parseInt(link.split("/")[4]); gid = Integer.parseInt(link.split("/")[4]);
}catch (NumberFormatException e){ }catch (NumberFormatException e){
response.failure("链接错误"); response.failure("链接错误");
pushService.taskCreateReport(user.getUsername(), link, response);
return response.toJSONString(); return response.toJSONString();
} }
Gallery gallery; Gallery gallery;
@ -91,6 +99,7 @@ public class GalleryManageService {
//判断数据库中是否有这个任务有则返回状态 //判断数据库中是否有这个任务有则返回状态
if((gallery = galleryMapper.selectGalleryByGid(gid)) != null){ if((gallery = galleryMapper.selectGalleryByGid(gid)) != null){
response.failure("任务队列已有此任务,任务状态: " + gallery.getStatus() + " 请点击查找任务"); response.failure("任务队列已有此任务,任务状态: " + gallery.getStatus() + " 请点击查找任务");
pushService.taskCreateReport(user.getUsername(), link, response);
return response.toJSONString(); return response.toJSONString();
} }
@ -99,28 +108,34 @@ public class GalleryManageService {
gallery = GalleryUtil.parse(link, true, targetResolution); gallery = GalleryUtil.parse(link, true, targetResolution);
if(gallery == null){ if(gallery == null){
log.error("创建任务: {},解析失败", link); log.error("创建任务: {},解析失败", link);
return Response._failure("任务解析失败,未知原因,请检查链接是否正常"); response.failure("任务解析失败,未知原因,请检查链接是否正常");
pushService.taskCreateReport(user.getUsername(), link, response);
return response.toJSONString();
}else{ }else{
log.info("创建任务: {} 目标分辨率:{}", link, targetResolution); log.info("创建任务: {} 目标分辨率:{}", link, targetResolution);
if(remoteService.addGalleryToQueue(gallery, mode) != 0){ if(remoteService.addGalleryToQueue(gallery, mode) != 0){
log.error("传送任务{}失败, 未知原因", gallery.getName()); log.error("传送任务{}失败, 未知原因", gallery.getName());
return Response._failure("任务传送失败,未知原因"); response.failure("任务传送失败,未知原因");
pushService.taskCreateReport(user.getUsername(), link, response);
return response.toJSONString();
} }
} }
}catch (ResolutionNotMatchException e){ }catch (ResolutionNotMatchException e){
e.printStackTrace(); e.printStackTrace();
response.failure("提交失败,分辨率不存在"); response.failure("提交失败,分辨率不存在");
pushService.taskCreateReport(user.getUsername(), link, response);
return response.toJSONString(); return response.toJSONString();
}catch (IOException e){ }catch (IOException e){
e.printStackTrace(); e.printStackTrace();
response.failure("IO错误可能是网络波动"); response.failure("IO错误可能是网络波动");
pushService.taskCreateReport(user.getUsername(), link, response);
return response.toJSONString(); return response.toJSONString();
} }
//处理下载结果将任务插入数据库并且更新每周用量 //处理下载结果将任务插入数据库并且更新每周用量
if(gallery.getStatus().equals("已提交")) { if(gallery.getStatus().equals("已提交")) {
response.success(gallery.toString()); response.success(gallery.toString());
gallery.setDownloader(userMapper.selectUserByAuthCode(AuthCode).getId()); gallery.setDownloader(user.getId());
gallery.setMode(mode); gallery.setMode(mode);
galleryMapper.insertGallery(gallery); galleryMapper.insertGallery(gallery);
@ -136,6 +151,7 @@ public class GalleryManageService {
response.failure("提交失败,未知原因"); response.failure("提交失败,未知原因");
galleryMapper.deleteGalleryByGid(gallery.getGid()); galleryMapper.deleteGalleryByGid(gallery.getGid());
} }
pushService.taskCreateReport(user.getUsername(), link, response);
return response.toJSONString(); return response.toJSONString();
} }

View File

@ -0,0 +1,40 @@
package com.lion.lionwebsite.Service;
import com.lion.lionwebsite.Util.Response;
import com.pengrad.telegrambot.TelegramBot;
import com.pengrad.telegrambot.request.SendMessage;
import jakarta.annotation.Resource;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Service;
@Service
@ConfigurationProperties(prefix = "push-service")
public class PushService {
long self = 686839482;
@Resource
TelegramBot bot;
public void taskCreateReport(String username, String link, Response response){
System.out.println("task report");
if(response.isSuccess())
sendToMe(String.format("用户%s提交下载%s", username, link));
else
sendToMe(String.format("用户%s提交下载%s, 下载失败:%s", username, link, response.get("data")));
}
public void storageNodeOnline(){
sendToMe("存储节点上线");
}
public void storageNodeOffline(){
sendToMe("存储节点掉线");
}
public void sendToMe(String text){
System.out.println(text);
SendMessage sendMessage = new SendMessage(self, text);
bot.execute(sendMessage);
}
}

View File

@ -53,6 +53,9 @@ public class RemoteService {
@Resource @Resource
GalleryMapper galleryMapper; GalleryMapper galleryMapper;
@Resource
PushService pushService;
HashMap<Integer, Promise<AbstractMessage>> promiseHashMap; HashMap<Integer, Promise<AbstractMessage>> promiseHashMap;
EventLoop eventLoopGroup; EventLoop eventLoopGroup;
@ -83,13 +86,16 @@ public class RemoteService {
.handler(new ChannelInitializer<NioSocketChannel>() { .handler(new ChannelInitializer<NioSocketChannel>() {
@Override @Override
protected void initChannel(NioSocketChannel channel){ protected void initChannel(NioSocketChannel channel){
channel.pipeline().addLast(new LengthFieldBasedFrameDecoder(1024, 1, 4)); channel.pipeline().addLast(new LengthFieldBasedFrameDecoder(100000000, 1, 4));
channel.pipeline().addLast(new MessageCodec()); channel.pipeline().addLast(new MessageCodec());
channel.pipeline().addLast(new LoggingHandler()); channel.pipeline().addLast(new LoggingHandler());
channel.pipeline().addLast(new MyChannelInboundHandlerAdapter()); channel.pipeline().addLast(new MyChannelInboundHandlerAdapter());
} }
}).connect(new InetSocketAddress(ip, port)).sync(); }).connect(new InetSocketAddress(ip, port)).sync();
log.info("connect success"); log.info("connect success");
if(pushService != null)
pushService.storageNodeOnline();
channel = channelFuture.channel(); channel = channelFuture.channel();
channel.writeAndFlush(new IdentityMessage()); channel.writeAndFlush(new IdentityMessage());
return true; return true;
@ -289,25 +295,26 @@ public class RemoteService {
public void channelRead(ChannelHandlerContext ctx, Object msg) { public void channelRead(ChannelHandlerContext ctx, Object msg) {
//如果不是响应信息或者响应信息为失败则打印 //如果不是响应信息或者响应信息为失败则打印
if(!(msg instanceof ResponseMessage rm) || rm.getResult() != 0) if(!(msg instanceof ResponseMessage rm) || rm.getResult() != 0)
System.out.println(msg); if(! (msg instanceof MaintainMessage))
System.out.println(msg);
//下载状态 //下载状态
if(msg instanceof DownloadStatusMessage dsm){ if(msg instanceof DownloadStatusMessage dsm){
GalleryTask[] galleryTasks = dsm.getGalleryTasks(); GalleryTask[] galleryTasks = dsm.getGalleryTasks();
for (GalleryTask galleryTask : galleryTasks) { for (GalleryTask galleryTask : galleryTasks) {
Gallery gallery = galleryMapper.selectGalleryByGid(galleryTask.getGid()); Gallery gallery = galleryMapper.selectGalleryByGid(galleryTask.getGid());
if(galleryTask.getStatus() == GalleryTask.DOWNLOAD_COMPLETE){ gallery.setProceeding(galleryTask.getProceeding());
if(!gallery.getName().equals(galleryTask.getName()))
gallery.setName(galleryTask.getName());
if(galleryTask.getStatus() == GalleryTask.DOWNLOAD_COMPLETE)
gallery.setStatus("下载完成"); gallery.setStatus("下载完成");
gallery.setProceeding(galleryTask.getProceeding()); else if(galleryTask.getProceeding() != 0)
galleryMapper.updateGallery(gallery);
}else if(galleryTask.getProceeding() != 0){
gallery.setStatus("下载中"); gallery.setStatus("下载中");
gallery.setProceeding(galleryTask.getProceeding());
if(!gallery.getName().equals(galleryTask.getName())) log.info(gallery.getName() + "下载进度:" + gallery.getProceeding() + "/" + gallery.getPages());
gallery.setName(galleryTask.getName()); galleryMapper.updateGallery(gallery);
galleryMapper.updateGallery(gallery);
log.info(gallery.getName() + "下载进度:" + gallery.getProceeding() + "/" + gallery.getPages());
}
} }
} }
else if(msg instanceof ResponseMessage rsm) else if(msg instanceof ResponseMessage rsm)
@ -320,6 +327,7 @@ public class RemoteService {
public void channelUnregistered(ChannelHandlerContext ctx) { public void channelUnregistered(ChannelHandlerContext ctx) {
if(ctx.channel() != null && ctx.channel().remoteAddress().toString().equals(channel.remoteAddress().toString())){ if(ctx.channel() != null && ctx.channel().remoteAddress().toString().equals(channel.remoteAddress().toString())){
System.out.println("activate monitor thread, waiting for node back online"); System.out.println("activate monitor thread, waiting for node back online");
pushService.storageNodeOffline();
monitor = new Thread(RemoteService.this::monitorFunc); monitor = new Thread(RemoteService.this::monitorFunc);
monitor.start(); monitor.start();
} }

View File

@ -53,6 +53,10 @@ public class Response {
return result.get("data"); return result.get("data");
} }
public boolean isSuccess(){
return result.get("result").equals("success");
}
public static String _failure(String result){ public static String _failure(String result){
Response response = generateResponse(); Response response = generateResponse();

Binary file not shown.

View File

@ -26,15 +26,16 @@ personal-service:
StoragePath: /storage/ StoragePath: /storage/
gallery-manage-service: gallery-manage-service:
target-path: /storage/gallery/ target-path: /root/gallery/
cache-size: 100 cache-size: 100
remote-service: remote-service:
ip: 5.255.110.45 ip: 5.255.110.45
local-service: local-service:
fires: https://api.dler.io/sub?target=clash&new_name=true&url=https%3A%2F%2Ffast.losadhwselfff2332dasd.xyz%2Flink%2Fz0pfwyTvC5naXkbb%3Fclash%3D1&insert=false&config=https%3A%2F%2Fraw.githubusercontent.com%2FACL4SSR%2FACL4SSR%2Fmaster%2FClash%2Fconfig%2FACL4SSR_Online.ini fires: https://api.dler.io/sub?target=clash&new_name=true&url=https%3A%2F%2Ffast.losadhwselfff2332dasd.xyz%2Flink%2Fz0pfwyTvC5naXkbb%3Fclash%3D1&insert=false&config=https%3A%2F%2Fraw.githubusercontent.com%2FACL4SSR%2FACL4SSR%2Fmaster%2FClash%2Fconfig%2FACL4SSR_Online.ini
DouNaiClash: https://aaaa.gay/link/A5CXg2cJATerEEoe?client=clashv2 DouNaiClash: https://aaaa.gay/link/A5CXg2cJATerEEoe?client=clashv2
DouNaiV2ray: https://aaaa.gay/link/A5CXg2cJATerEEoe?client=v2 DouNaiV2ray: https://aaaa.gay/link/A5CXg2cJATerEEoe?client=v2
bot:
token: 5222939329:AAHa6l9ZuVVdNSDLPI_H-c8O_VgeOEw5plA

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -4,7 +4,7 @@
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.ico" /> <link rel="icon" type="image/svg+xml" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<title>Vite + Vue</title> <title>Lion</title>
<meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-capable" content="yes">
<script type="module" crossorigin src="/mobile/index.js"></script> <script type="module" crossorigin src="/mobile/index.js"></script>
<link rel="stylesheet" href="/mobile/index.css"> <link rel="stylesheet" href="/mobile/index.css">