mirror of
				https://github.com/LamGC/ContentGrabbingJi.git
				synced 2025-11-04 02:26:57 +00:00 
			
		
		
		
	[Change] Issue #12 调整框架启动机器人应用的方式, 增加一个用于机器人应用内部共享数据的类;
[Fix] BotEventHandler, ImageCacheStore 增加ShutdownHook用于关闭线程池, 解决线程池阻塞关闭过程的问题; [Change] BotEventHandler 调整'match(String)'方法; [Change] BotAdminCommandProcess 调整'savePushList()'方法对文件创建失败的行为;
This commit is contained in:
		@ -12,6 +12,7 @@ import net.lamgc.cgj.bot.framework.mirai.MiraiMain;
 | 
			
		||||
import net.lamgc.cgj.pixiv.PixivDownload;
 | 
			
		||||
import net.lamgc.cgj.pixiv.PixivSearchBuilder;
 | 
			
		||||
import net.lamgc.cgj.pixiv.PixivURL;
 | 
			
		||||
import net.lamgc.cgj.util.PropertiesUtils;
 | 
			
		||||
import net.lamgc.plps.PixivLoginProxyServer;
 | 
			
		||||
import net.lamgc.utils.base.ArgumentsProperties;
 | 
			
		||||
import net.lamgc.utils.base.runner.Argument;
 | 
			
		||||
@ -54,11 +55,13 @@ public class Main {
 | 
			
		||||
        log.trace("ContentGrabbingJi 正在启动...");
 | 
			
		||||
        log.debug("Args: {}, LogsPath: {}", Arrays.toString(args), System.getProperty("cgj.logsPath"));
 | 
			
		||||
        log.debug("运行目录: {}", System.getProperty("user.dir"));
 | 
			
		||||
 | 
			
		||||
        ApplicationBoot.initialApplication(args);
 | 
			
		||||
        log.debug("botDataDir: {}", System.getProperty("cgj.botDataDir"));
 | 
			
		||||
        ArgumentsProperties argsProp = new ArgumentsProperties(args);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        if(!getSettingToSysProp(argsProp, "proxy", null)) {
 | 
			
		||||
            getEnvSettingToSysProp("CGJ_PROXY", "proxy", null);
 | 
			
		||||
        if(!PropertiesUtils.getSettingToSysProp(argsProp, "proxy", null)) {
 | 
			
		||||
            PropertiesUtils.getEnvSettingToSysProp("CGJ_PROXY", "proxy", null);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        String proxyAddress = System.getProperty("cgj.proxy");
 | 
			
		||||
@ -70,20 +73,7 @@ public class Main {
 | 
			
		||||
            proxy = null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(!storeDir.exists() && !storeDir.mkdirs()) {
 | 
			
		||||
            log.error("创建文件夹失败!");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(!getSettingToSysProp(argsProp, "botDataDir", "./") &&
 | 
			
		||||
                !getEnvSettingToSysProp("CGJ_BOT_DATA_DIR", "botDataDir", "./")) {
 | 
			
		||||
            log.warn("未设置botDataDir, 当前运行目录将作为酷Q机器人所在目录.");
 | 
			
		||||
        }
 | 
			
		||||
        if(!getSettingToSysProp(argsProp, "redisAddress", "127.0.0.1") &&
 | 
			
		||||
                !getEnvSettingToSysProp("CGJ_REDIS_URI", "redisAddress", "127.0.0.1")) {
 | 
			
		||||
            log.warn("未设置RedisAddress, 将使用默认值连接Redis服务器(127.0.0.1:6379)");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        File cookieStoreFile = new File(System.getProperty("cgj.botDataDir"), "cookies.store");
 | 
			
		||||
        File cookieStoreFile = new File(BotGlobal.getGlobal().getDataStoreDir(), "cookies.store");
 | 
			
		||||
        if(!cookieStoreFile.exists()) {
 | 
			
		||||
            log.warn("未找到cookies.store文件, 是否启动PixivLoginProxyServer? (yes/no)");
 | 
			
		||||
            try(Scanner scanner = new Scanner(System.in)) {
 | 
			
		||||
@ -104,37 +94,7 @@ public class Main {
 | 
			
		||||
        log.debug("传入参数: {}", Arrays.toString(args));
 | 
			
		||||
 | 
			
		||||
        ArgumentsRunner.run(Main.class, args);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 从ArgumentsProperties获取设置项到System Properties
 | 
			
		||||
     * @param prop ArgumentsProperties对象
 | 
			
		||||
     * @param key 设置项key
 | 
			
		||||
     * @param defaultValue 默认值
 | 
			
		||||
     * @return 如果成功从ArgumentsProperties获得设置项, 返回true, 如未找到(使用了defaultValue或null), 返回false;
 | 
			
		||||
     */
 | 
			
		||||
    private static boolean getSettingToSysProp(ArgumentsProperties prop, String key, String defaultValue) {
 | 
			
		||||
        if(prop.containsKey(key)) {
 | 
			
		||||
            log.info("{}: {}", key, prop.getValue(key));
 | 
			
		||||
            System.setProperty("cgj." + key, prop.getValue(key));
 | 
			
		||||
            return true;
 | 
			
		||||
        } else {
 | 
			
		||||
            if(defaultValue != null) {
 | 
			
		||||
                System.setProperty("cgj." + key, defaultValue);
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static boolean getEnvSettingToSysProp(String envKey, String sysPropKey, String defaultValue) {
 | 
			
		||||
        String env = System.getenv(envKey);
 | 
			
		||||
        if(env != null) {
 | 
			
		||||
            System.setProperty("cgj." + sysPropKey, env);
 | 
			
		||||
            return true;
 | 
			
		||||
        } else if(defaultValue != null) {
 | 
			
		||||
            System.setProperty("cgj." + sysPropKey, defaultValue);
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
        System.exit(0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Command
 | 
			
		||||
@ -146,10 +106,7 @@ public class Main {
 | 
			
		||||
 | 
			
		||||
    @Command
 | 
			
		||||
    public static void pluginMode(@Argument(name = "args", force = false) String argsStr) {
 | 
			
		||||
        if(!System.getProperty("cgj.botDataDir").endsWith("\\") && !System.getProperty("cgj.botDataDir").endsWith("/")) {
 | 
			
		||||
            System.setProperty("cgj.botDataDir", System.getProperty("cgj.botDataDir") + "/");
 | 
			
		||||
        }
 | 
			
		||||
        log.info("酷Q机器人根目录: {}", System.getProperty("cgj.botDataDir"));
 | 
			
		||||
        log.info("酷Q机器人根目录: {}", BotGlobal.getGlobal().getDataStoreDir().getPath());
 | 
			
		||||
        CQConfig.init();
 | 
			
		||||
        Pattern pattern = Pattern.compile("/\\s*(\".+?\"|[^:\\s])+((\\s*:\\s*(\".+?\"|[^\\s])+)|)|(\".+?\"|[^\"\\s])+");
 | 
			
		||||
        Matcher matcher = pattern.matcher(Strings.nullToEmpty(argsStr));
 | 
			
		||||
@ -165,7 +122,7 @@ public class Main {
 | 
			
		||||
    @Command
 | 
			
		||||
    public static void collectionDownload() throws IOException {
 | 
			
		||||
        PixivDownload pixivDownload = new PixivDownload(Objects.requireNonNull(cookieStore), proxy);
 | 
			
		||||
        File outputFile = new File(storeDir, "collection.zip");
 | 
			
		||||
        File outputFile = new File(getStoreDir(), "collection.zip");
 | 
			
		||||
        if(!outputFile.exists() && !outputFile.createNewFile()) {
 | 
			
		||||
            log.error("文件创建失败: " + outputFile.getAbsolutePath());
 | 
			
		||||
        }
 | 
			
		||||
@ -192,10 +149,10 @@ public class Main {
 | 
			
		||||
        PixivDownload pixivDownload = new PixivDownload(Objects.requireNonNull(cookieStore), proxy);
 | 
			
		||||
        String date = new SimpleDateFormat("yyyyMMdd").format(new Date());
 | 
			
		||||
        int id = 1;
 | 
			
		||||
        File outputFile = new File(storeDir, "recommends-" + date + "-" + id + ".zip");
 | 
			
		||||
        File outputFile = new File(getStoreDir(), "recommends-" + date + "-" + id + ".zip");
 | 
			
		||||
        while(outputFile.exists()) {
 | 
			
		||||
            id++;
 | 
			
		||||
            outputFile = new File(storeDir, "recommends-" + date + "-" + id + ".zip");
 | 
			
		||||
            outputFile = new File(getStoreDir(), "recommends-" + date + "-" + id + ".zip");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(!outputFile.createNewFile()) {
 | 
			
		||||
@ -259,10 +216,10 @@ public class Main {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        int id = 1;
 | 
			
		||||
        File outputFile = new File(storeDir, "ranking" + rankingMode.modeParam + "-" + date + "-" + id + ".zip");
 | 
			
		||||
        File outputFile = new File(getStoreDir(), "ranking" + rankingMode.modeParam + "-" + date + "-" + id + ".zip");
 | 
			
		||||
        while(outputFile.exists()) {
 | 
			
		||||
            id++;
 | 
			
		||||
            outputFile = new File(storeDir, "ranking" + rankingMode.modeParam + "-" + date + "-" + id + ".zip");
 | 
			
		||||
            outputFile = new File(getStoreDir(), "ranking" + rankingMode.modeParam + "-" + date + "-" + id + ".zip");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(!outputFile.createNewFile()) {
 | 
			
		||||
@ -401,7 +358,7 @@ public class Main {
 | 
			
		||||
 | 
			
		||||
    private static void saveCookieStoreToFile() throws IOException {
 | 
			
		||||
        log.info("正在保存CookieStore...");
 | 
			
		||||
        File outputFile = new File(System.getProperty("cgj.botDataDir"), "cookies.store");
 | 
			
		||||
        File outputFile = new File(BotGlobal.getGlobal().getDataStoreDir(), "cookies.store");
 | 
			
		||||
        if(!outputFile.exists() && !outputFile.createNewFile()){
 | 
			
		||||
            log.error("保存CookieStore失败.");
 | 
			
		||||
            return;
 | 
			
		||||
@ -450,4 +407,11 @@ public class Main {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static File getStoreDir() {
 | 
			
		||||
        if(!storeDir.exists() && !storeDir.mkdirs()) {
 | 
			
		||||
            log.error("创建文件夹失败!");
 | 
			
		||||
        }
 | 
			
		||||
        return storeDir;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -5,6 +5,7 @@ import com.google.gson.Gson;
 | 
			
		||||
import com.google.gson.GsonBuilder;
 | 
			
		||||
import com.google.gson.JsonObject;
 | 
			
		||||
import com.google.gson.reflect.TypeToken;
 | 
			
		||||
import net.lamgc.cgj.bot.boot.BotGlobal;
 | 
			
		||||
import net.lamgc.cgj.bot.message.MessageSenderBuilder;
 | 
			
		||||
import net.lamgc.cgj.bot.message.MessageSource;
 | 
			
		||||
import net.lamgc.cgj.pixiv.PixivDownload;
 | 
			
		||||
@ -22,7 +23,7 @@ public class BotAdminCommandProcess {
 | 
			
		||||
 | 
			
		||||
    private final static Logger log = LoggerFactory.getLogger(BotAdminCommandProcess.class.getName());
 | 
			
		||||
 | 
			
		||||
    private final static File pushListFile = new File(System.getProperty("cgj.botDataDir"), "pushList.json");
 | 
			
		||||
    private final static File pushListFile = new File(BotGlobal.getGlobal().getDataStoreDir(), "pushList.json");
 | 
			
		||||
 | 
			
		||||
    private final static Hashtable<Long, JsonObject> pushInfoMap = new Hashtable<>();
 | 
			
		||||
 | 
			
		||||
@ -182,8 +183,8 @@ public class BotAdminCommandProcess {
 | 
			
		||||
    @Command
 | 
			
		||||
    public static String savePushList() {
 | 
			
		||||
        try {
 | 
			
		||||
            if(!pushListFile.exists()) {
 | 
			
		||||
                pushListFile.createNewFile();
 | 
			
		||||
            if(!pushListFile.exists() && !pushListFile.createNewFile()) {
 | 
			
		||||
                throw new IOException("文件夹创建失败!(Path: " + pushListFile.getPath() + ")");
 | 
			
		||||
            }
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            log.error("PushList.json文件创建失败", e);
 | 
			
		||||
 | 
			
		||||
@ -5,8 +5,8 @@ import com.google.common.base.Throwables;
 | 
			
		||||
import com.google.gson.*;
 | 
			
		||||
import io.netty.handler.codec.http.HttpHeaderNames;
 | 
			
		||||
import net.lamgc.cgj.Main;
 | 
			
		||||
import net.lamgc.cgj.bot.boot.BotGlobal;
 | 
			
		||||
import net.lamgc.cgj.bot.cache.*;
 | 
			
		||||
import net.lamgc.cgj.bot.event.BotEventHandler;
 | 
			
		||||
import net.lamgc.cgj.bot.event.BufferMessageEvent;
 | 
			
		||||
import net.lamgc.cgj.bot.sort.PreLoadDataComparator;
 | 
			
		||||
import net.lamgc.cgj.pixiv.PixivDownload;
 | 
			
		||||
@ -41,7 +41,7 @@ public class BotCommandProcess {
 | 
			
		||||
 | 
			
		||||
    private final static Logger log = LoggerFactory.getLogger(BotCommandProcess.class.getName());
 | 
			
		||||
 | 
			
		||||
    private final static File imageStoreDir = new File(System.getProperty("cgj.botDataDir"), "data/image/cgj/");
 | 
			
		||||
    private final static File imageStoreDir = new File(BotGlobal.getGlobal().getDataStoreDir(), "data/image/cgj/");
 | 
			
		||||
    private final static Gson gson = new GsonBuilder()
 | 
			
		||||
            .serializeNulls()
 | 
			
		||||
            .create();
 | 
			
		||||
@ -54,38 +54,38 @@ public class BotCommandProcess {
 | 
			
		||||
     * 作品信息缓存 - 不过期
 | 
			
		||||
     */
 | 
			
		||||
    private final static CacheStore<JsonElement> illustInfoCache =
 | 
			
		||||
            new JsonRedisCacheStore(BotEventHandler.redisServer, "illustInfo", gson);
 | 
			
		||||
            new JsonRedisCacheStore(BotGlobal.getGlobal().getRedisServer(), "illustInfo", gson);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 作品信息预加载数据 - 有效期 2 小时, 本地缓存有效期1 ± 0.25
 | 
			
		||||
     */
 | 
			
		||||
    private final static CacheStore<JsonElement> illustPreLoadDataCache =
 | 
			
		||||
            CacheStoreUtils.hashLocalHotDataStore(
 | 
			
		||||
                new JsonRedisCacheStore(BotEventHandler.redisServer, "illustPreLoadData", gson),
 | 
			
		||||
                new JsonRedisCacheStore(BotGlobal.getGlobal().getRedisServer(), "illustPreLoadData", gson),
 | 
			
		||||
                3600000, 900000);
 | 
			
		||||
    /**
 | 
			
		||||
     * 搜索内容缓存, 有效期 2 小时
 | 
			
		||||
     */
 | 
			
		||||
    private final static CacheStore<JsonElement> searchBodyCache =
 | 
			
		||||
            new JsonRedisCacheStore(BotEventHandler.redisServer, "searchBody", gson);
 | 
			
		||||
            new JsonRedisCacheStore(BotGlobal.getGlobal().getRedisServer(), "searchBody", gson);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 排行榜缓存, 不过期
 | 
			
		||||
     */
 | 
			
		||||
    private final static CacheStore<List<JsonObject>> rankingCache =
 | 
			
		||||
            new JsonObjectRedisListCacheStore(BotEventHandler.redisServer, "ranking", gson);
 | 
			
		||||
            new JsonObjectRedisListCacheStore(BotGlobal.getGlobal().getRedisServer(), "ranking", gson);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 作品页面下载链接缓存 - 不过期
 | 
			
		||||
     */
 | 
			
		||||
    private final static CacheStore<List<String>> pagesCache =
 | 
			
		||||
            new StringListRedisCacheStore(BotEventHandler.redisServer, "imagePages");
 | 
			
		||||
            new StringListRedisCacheStore(BotGlobal.getGlobal().getRedisServer(), "imagePages");
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 作品报告存储 - 不过期
 | 
			
		||||
     */
 | 
			
		||||
    public final static CacheStore<JsonElement> reportStore =
 | 
			
		||||
            new JsonRedisCacheStore(BotEventHandler.redisServer, "report", gson);
 | 
			
		||||
            new JsonRedisCacheStore(BotGlobal.getGlobal().getRedisServer(), "report", gson);
 | 
			
		||||
 | 
			
		||||
    private final static RankingUpdateTimer updateTimer = new RankingUpdateTimer();
 | 
			
		||||
 | 
			
		||||
@ -462,8 +462,6 @@ public class BotCommandProcess {
 | 
			
		||||
                        PixivURL.getPixivRefererLink(illustId)
 | 
			
		||||
                );
 | 
			
		||||
 | 
			
		||||
                //pageCount
 | 
			
		||||
 | 
			
		||||
                String imageMsg = getImageById(fromGroup, illustId, PixivDownload.PageQuality.REGULAR, 1);
 | 
			
		||||
                if (isNoSafe(illustId, SettingProperties.getProperties(fromGroup), true)) {
 | 
			
		||||
                    log.warn("作品Id {} 为R-18作品, 跳过.", illustId);
 | 
			
		||||
@ -663,7 +661,7 @@ public class BotCommandProcess {
 | 
			
		||||
        illustPreLoadDataCache.clear();
 | 
			
		||||
        pagesCache.clear();
 | 
			
		||||
        searchBodyCache.clear();
 | 
			
		||||
        File imageStoreDir = new File(System.getProperty("cgj.botDataDir") + "data/image/cgj/");
 | 
			
		||||
        File imageStoreDir = new File(BotGlobal.getGlobal().getDataStoreDir(), "data/image/cgj/");
 | 
			
		||||
        File[] listFiles = imageStoreDir.listFiles();
 | 
			
		||||
        if (listFiles == null) {
 | 
			
		||||
            log.debug("图片缓存目录为空或内部文件获取失败!");
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,7 @@
 | 
			
		||||
package net.lamgc.cgj.bot;
 | 
			
		||||
 | 
			
		||||
import com.google.common.base.Throwables;
 | 
			
		||||
import net.lamgc.cgj.bot.boot.BotGlobal;
 | 
			
		||||
import org.slf4j.Logger;
 | 
			
		||||
import org.slf4j.LoggerFactory;
 | 
			
		||||
 | 
			
		||||
@ -157,7 +158,7 @@ public final class SettingProperties {
 | 
			
		||||
     * @return 返回目录File对象.
 | 
			
		||||
     */
 | 
			
		||||
    private static File getPropertiesDir() {
 | 
			
		||||
        File propDir = new File(System.getProperty("cgj.botDataDir"), "/setting/");
 | 
			
		||||
        File propDir = new File(BotGlobal.getGlobal().getDataStoreDir(), "/setting/");
 | 
			
		||||
        if(!propDir.exists() && !propDir.mkdirs()) {
 | 
			
		||||
            log.warn("Setting文件夹创建失败!");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										43
									
								
								src/main/java/net/lamgc/cgj/bot/boot/ApplicationBoot.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								src/main/java/net/lamgc/cgj/bot/boot/ApplicationBoot.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,43 @@
 | 
			
		||||
package net.lamgc.cgj.bot.boot;
 | 
			
		||||
 | 
			
		||||
import net.lamgc.cgj.bot.event.BotEventHandler;
 | 
			
		||||
import net.lamgc.cgj.util.PropertiesUtils;
 | 
			
		||||
import net.lamgc.utils.base.ArgumentsProperties;
 | 
			
		||||
import org.slf4j.Logger;
 | 
			
		||||
import org.slf4j.LoggerFactory;
 | 
			
		||||
 | 
			
		||||
public final class ApplicationBoot {
 | 
			
		||||
 | 
			
		||||
    private final static Logger log = LoggerFactory.getLogger(ApplicationBoot.class);
 | 
			
		||||
 | 
			
		||||
    private ApplicationBoot() {}
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 初始化应用.
 | 
			
		||||
     * <p>该方法不会初始化机器人, 仅初始化应用所需的配置信息.</p>
 | 
			
		||||
     */
 | 
			
		||||
    public static void initialApplication(String[] args) {
 | 
			
		||||
        ArgumentsProperties argsProp = new ArgumentsProperties(args);
 | 
			
		||||
        if(!PropertiesUtils.getSettingToSysProp(argsProp, "botDataDir", "./") &&
 | 
			
		||||
                !PropertiesUtils.getEnvSettingToSysProp("CGJ_BOT_DATA_DIR", "botDataDir", "./")) {
 | 
			
		||||
            log.warn("未设置botDataDir, 当前运行目录将作为酷Q机器人所在目录.");
 | 
			
		||||
        }
 | 
			
		||||
        if(!PropertiesUtils.getSettingToSysProp(argsProp, "redisAddress", "127.0.0.1") &&
 | 
			
		||||
                !PropertiesUtils.getEnvSettingToSysProp("CGJ_REDIS_URI", "redisAddress", "127.0.0.1")) {
 | 
			
		||||
            log.warn("未设置RedisAddress, 将使用默认值连接Redis服务器(127.0.0.1:6379)");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 初始化 BotGlobal
 | 
			
		||||
        //noinspection ResultOfMethodCallIgnored 这里仅仅是加载BotGlobal而已
 | 
			
		||||
        BotGlobal.getGlobal();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 初始化机器人.
 | 
			
		||||
     * <p>本方法由框架调用.</p>
 | 
			
		||||
     */
 | 
			
		||||
    public static void initialBot() {
 | 
			
		||||
        BotEventHandler.initial();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										56
									
								
								src/main/java/net/lamgc/cgj/bot/boot/BotGlobal.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								src/main/java/net/lamgc/cgj/bot/boot/BotGlobal.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,56 @@
 | 
			
		||||
package net.lamgc.cgj.bot.boot;
 | 
			
		||||
 | 
			
		||||
import org.slf4j.Logger;
 | 
			
		||||
import org.slf4j.LoggerFactory;
 | 
			
		||||
import redis.clients.jedis.JedisPool;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.net.URI;
 | 
			
		||||
 | 
			
		||||
public final class BotGlobal {
 | 
			
		||||
 | 
			
		||||
    private final static BotGlobal instance = new BotGlobal();
 | 
			
		||||
 | 
			
		||||
    public static BotGlobal getGlobal() {
 | 
			
		||||
        if(instance == null) {
 | 
			
		||||
            throw new IllegalStateException("");
 | 
			
		||||
        }
 | 
			
		||||
        return instance;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private final static Logger log = LoggerFactory.getLogger(BotGlobal.class);
 | 
			
		||||
 | 
			
		||||
    private final URI redisUri;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 所有缓存共用的JedisPool
 | 
			
		||||
     */
 | 
			
		||||
    private final JedisPool redisServer;
 | 
			
		||||
 | 
			
		||||
    private final File dataStoreDir;
 | 
			
		||||
 | 
			
		||||
    private BotGlobal() {
 | 
			
		||||
        this.redisUri = URI.create("redis://" + System.getProperty("cgj.redisAddress"));
 | 
			
		||||
        this.redisServer = new JedisPool(
 | 
			
		||||
                getRedisUri().getHost(),
 | 
			
		||||
                getRedisUri().getPort() == -1 ? 6379 : getRedisUri().getPort());
 | 
			
		||||
        String dataStoreDirPath = System.getProperty("cgj.botDataDir");
 | 
			
		||||
        this.dataStoreDir = new File((!dataStoreDirPath.endsWith("/") || !dataStoreDirPath.endsWith("\\")) ?
 | 
			
		||||
                dataStoreDirPath + System.getProperty("file.separator") : dataStoreDirPath);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public URI getRedisUri() {
 | 
			
		||||
        return redisUri;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public File getDataStoreDir() {
 | 
			
		||||
        if(!dataStoreDir.exists() && !dataStoreDir.mkdirs()) {
 | 
			
		||||
            log.error("DataStoreDir 创建失败, 数据存储可能失效!");
 | 
			
		||||
        }
 | 
			
		||||
        return dataStoreDir;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public JedisPool getRedisServer() {
 | 
			
		||||
        return redisServer;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -33,6 +33,12 @@ public final class ImageCacheStore {
 | 
			
		||||
 | 
			
		||||
    private final static ImageCacheHandler handler = new ImageCacheHandler();
 | 
			
		||||
 | 
			
		||||
    static {
 | 
			
		||||
        Thread shutdownThread = new Thread(imageCacheExecutor::shutdownNow);
 | 
			
		||||
        shutdownThread.setName("Thread-ImageCacheShutdown");
 | 
			
		||||
        Runtime.getRuntime().addShutdownHook(shutdownThread);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private ImageCacheStore() {}
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 | 
			
		||||
@ -20,10 +20,8 @@ import net.lamgc.utils.event.EventObject;
 | 
			
		||||
 | 
			
		||||
import org.slf4j.Logger;
 | 
			
		||||
import org.slf4j.LoggerFactory;
 | 
			
		||||
import redis.clients.jedis.JedisPool;
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.Method;
 | 
			
		||||
import java.net.URI;
 | 
			
		||||
import java.text.SimpleDateFormat;
 | 
			
		||||
import java.util.*;
 | 
			
		||||
import java.util.concurrent.LinkedBlockingQueue;
 | 
			
		||||
@ -44,12 +42,6 @@ public class BotEventHandler implements EventHandler {
 | 
			
		||||
 | 
			
		||||
    private final static Map<Long, AtomicBoolean> muteStateMap = new Hashtable<>();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 所有缓存共用的JedisPool
 | 
			
		||||
     */
 | 
			
		||||
    private final static URI redisServerUri = URI.create("redis://" + System.getProperty("cgj.redisAddress"));
 | 
			
		||||
    public final static JedisPool redisServer = new JedisPool(redisServerUri.getHost(), redisServerUri.getPort() == -1 ? 6379 : redisServerUri.getPort());
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 消息事件执行器
 | 
			
		||||
     */
 | 
			
		||||
@ -66,10 +58,10 @@ public class BotEventHandler implements EventHandler {
 | 
			
		||||
    ));
 | 
			
		||||
 | 
			
		||||
    private static boolean initialled = false;
 | 
			
		||||
    static {
 | 
			
		||||
        initial();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 初始化BotEventHandler
 | 
			
		||||
     */
 | 
			
		||||
    public synchronized static void initial() {
 | 
			
		||||
        if(initialled) {
 | 
			
		||||
            Logger logger = LoggerFactory.getLogger("BotEventHandler@<init>");
 | 
			
		||||
@ -92,25 +84,19 @@ public class BotEventHandler implements EventHandler {
 | 
			
		||||
        });
 | 
			
		||||
        try {
 | 
			
		||||
            executor.addHandler(new BotEventHandler());
 | 
			
		||||
            Thread shutdownThread = new Thread(() -> executor.shutdown(true));
 | 
			
		||||
            shutdownThread.setName("Thread-EventHandlerShutdown");
 | 
			
		||||
            Runtime.getRuntime().addShutdownHook(shutdownThread);
 | 
			
		||||
        } catch (IllegalAccessException e) {
 | 
			
		||||
            LoggerFactory.getLogger("BotEventHandler@Static").error("添加Handler时发生异常", e);
 | 
			
		||||
        }
 | 
			
		||||
        initialled = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private final static AtomicBoolean preLoaded = new AtomicBoolean();
 | 
			
		||||
    /**
 | 
			
		||||
     * 预加载
 | 
			
		||||
     */
 | 
			
		||||
    public synchronized static void preLoad() {
 | 
			
		||||
        if(preLoaded.get()) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        try {
 | 
			
		||||
            BotAdminCommandProcess.loadPushList();
 | 
			
		||||
        } finally {
 | 
			
		||||
            preLoaded.set(true);
 | 
			
		||||
        } catch(Throwable e) {
 | 
			
		||||
            log.error("加载推送列表失败", e);
 | 
			
		||||
        }
 | 
			
		||||
        initialled = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private BotEventHandler() {
 | 
			
		||||
@ -159,7 +145,7 @@ public class BotEventHandler implements EventHandler {
 | 
			
		||||
    public void processMessage(MessageEvent event) {
 | 
			
		||||
        String msg = event.getMessage();
 | 
			
		||||
        log.debug(event.toString());
 | 
			
		||||
        if(!match(msg)) {
 | 
			
		||||
        if(mismatch(msg)) {
 | 
			
		||||
            return;
 | 
			
		||||
        } else if(isMute(event.getFromGroup())) {
 | 
			
		||||
            log.debug("机器人已被禁言, 忽略请求.");
 | 
			
		||||
@ -253,8 +239,8 @@ public class BotEventHandler implements EventHandler {
 | 
			
		||||
     * @param message 要检查的消息
 | 
			
		||||
     * @return 如果为true则提交
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean match(String message) {
 | 
			
		||||
        return message.startsWith(COMMAND_PREFIX) || message.startsWith(ADMIN_COMMAND_PREFIX);
 | 
			
		||||
    public static boolean mismatch(String message) {
 | 
			
		||||
        return !message.startsWith(COMMAND_PREFIX) && !message.startsWith(ADMIN_COMMAND_PREFIX);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static boolean isMute(long groupId) {
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,6 @@
 | 
			
		||||
package net.lamgc.cgj.bot.framework.coolq;
 | 
			
		||||
 | 
			
		||||
import net.lamgc.cgj.bot.boot.ApplicationBoot;
 | 
			
		||||
import net.lamgc.cgj.bot.event.BotEventHandler;
 | 
			
		||||
import net.lamgc.cgj.bot.framework.coolq.message.SpringCQMessageEvent;
 | 
			
		||||
import net.lamgc.utils.event.EventHandler;
 | 
			
		||||
@ -18,7 +19,7 @@ public class CQPluginMain extends CQPlugin implements EventHandler {
 | 
			
		||||
    public CQPluginMain() {
 | 
			
		||||
        // TODO(LamGC, 2020.04.21): SpringCQ无法适配MessageSenderBuilder
 | 
			
		||||
        // MessageSenderBuilder.setCurrentMessageSenderFactory(new SpringCQMessageSenderFactory());
 | 
			
		||||
        BotEventHandler.preLoad();
 | 
			
		||||
        ApplicationBoot.initialBot();
 | 
			
		||||
        LoggerFactory.getLogger(CQPluginMain.class.getName())
 | 
			
		||||
                .info("BotEventHandler.COMMAND_PREFIX = {}", BotEventHandler.COMMAND_PREFIX);
 | 
			
		||||
    }
 | 
			
		||||
@ -45,7 +46,7 @@ public class CQPluginMain extends CQPlugin implements EventHandler {
 | 
			
		||||
     * @return 是否拦截消息
 | 
			
		||||
     */
 | 
			
		||||
    private static int processMessage(CoolQ cq, CQMessageEvent event) {
 | 
			
		||||
        if(!BotEventHandler.match(event.getMessage())) {
 | 
			
		||||
        if(BotEventHandler.mismatch(event.getMessage())) {
 | 
			
		||||
            return MESSAGE_IGNORE;
 | 
			
		||||
        }
 | 
			
		||||
        BotEventHandler.executeMessageEvent(new SpringCQMessageEvent(cq, event));
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,7 @@
 | 
			
		||||
package net.lamgc.cgj.bot.framework.mirai;
 | 
			
		||||
 | 
			
		||||
import net.lamgc.cgj.bot.boot.ApplicationBoot;
 | 
			
		||||
import net.lamgc.cgj.bot.boot.BotGlobal;
 | 
			
		||||
import net.lamgc.cgj.bot.event.BotEventHandler;
 | 
			
		||||
import net.lamgc.cgj.bot.framework.mirai.message.MiraiMessageEvent;
 | 
			
		||||
import net.lamgc.cgj.bot.message.MessageSenderBuilder;
 | 
			
		||||
@ -35,7 +37,7 @@ public class MiraiMain implements Closeable {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        File botPropFile = new File(System.getProperty("cgj.botDataDir"), "./bot.properties");
 | 
			
		||||
        File botPropFile = new File(BotGlobal.getGlobal().getDataStoreDir(), "./bot.properties");
 | 
			
		||||
        try (Reader reader = new BufferedReader(new FileReader(botPropFile))) {
 | 
			
		||||
            botProperties.load(reader);
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
@ -55,7 +57,7 @@ public class MiraiMain implements Closeable {
 | 
			
		||||
                event -> BotEventHandler.setMuteState(event.getGroup().getId(), false));
 | 
			
		||||
        bot.login();
 | 
			
		||||
        MessageSenderBuilder.setCurrentMessageSenderFactory(new MiraiMessageSenderFactory(bot));
 | 
			
		||||
        BotEventHandler.preLoad();
 | 
			
		||||
        ApplicationBoot.initialBot();
 | 
			
		||||
        bot.join();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -2,11 +2,11 @@ package net.lamgc.cgj.bot.framework.mirai.message;
 | 
			
		||||
 | 
			
		||||
import com.google.common.base.Strings;
 | 
			
		||||
import net.lamgc.cgj.bot.BotCode;
 | 
			
		||||
import net.lamgc.cgj.bot.boot.BotGlobal;
 | 
			
		||||
import net.lamgc.cgj.bot.cache.CacheStore;
 | 
			
		||||
import net.lamgc.cgj.bot.cache.HotDataCacheStore;
 | 
			
		||||
import net.lamgc.cgj.bot.cache.LocalHashCacheStore;
 | 
			
		||||
import net.lamgc.cgj.bot.cache.StringRedisCacheStore;
 | 
			
		||||
import net.lamgc.cgj.bot.event.BotEventHandler;
 | 
			
		||||
import net.lamgc.cgj.bot.message.MessageSender;
 | 
			
		||||
import net.lamgc.cgj.bot.message.MessageSource;
 | 
			
		||||
import net.mamoe.mirai.Bot;
 | 
			
		||||
@ -28,7 +28,7 @@ public class MiraiMessageSender implements MessageSender {
 | 
			
		||||
    private final MessageSource source;
 | 
			
		||||
    private final static Logger log = LoggerFactory.getLogger(MiraiMessageSender.class.getName());
 | 
			
		||||
    private final static CacheStore<String> imageIdCache = new HotDataCacheStore<>(
 | 
			
		||||
            new StringRedisCacheStore(BotEventHandler.redisServer, "mirai.imageId"),
 | 
			
		||||
            new StringRedisCacheStore(BotGlobal.getGlobal().getRedisServer(), "mirai.imageId"),
 | 
			
		||||
            new LocalHashCacheStore<>(),
 | 
			
		||||
            5400000, 1800000, true);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user