mirror of
				https://github.com/LamGC/ContentGrabbingJi.git
				synced 2025-11-04 02:26:57 +00:00 
			
		
		
		
	[Update] 重构Setting Properties, 使其支持分群配置;
This commit is contained in:
		@ -22,8 +22,6 @@ public class BotAdminCommandProcess {
 | 
			
		||||
 | 
			
		||||
    private final static Logger log = LoggerFactory.getLogger(BotAdminCommandProcess.class.getSimpleName());
 | 
			
		||||
 | 
			
		||||
    private final static File globalPropFile = new File(System.getProperty("cgj.botDataDir"), "global.properties");
 | 
			
		||||
 | 
			
		||||
    private final static File pushListFile = new File(System.getProperty("cgj.botDataDir"), "pushList.json");
 | 
			
		||||
 | 
			
		||||
    private final static Hashtable<Long, JsonObject> pushInfoMap = new Hashtable<>();
 | 
			
		||||
@ -39,59 +37,46 @@ public class BotAdminCommandProcess {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Command
 | 
			
		||||
    public static String setGlobalProperty(@Argument(name = "key") String key, @Argument(name = "value") String value, @Argument(name = "save", force = false) boolean saveNow) {
 | 
			
		||||
        String lastValue = BotCommandProcess.globalProp.getProperty(key);
 | 
			
		||||
        BotCommandProcess.globalProp.setProperty(key, Strings.nullToEmpty(value));
 | 
			
		||||
        if(saveNow) {
 | 
			
		||||
            saveGlobalProperties();
 | 
			
		||||
    public static String setProperty(
 | 
			
		||||
            @Argument(name = "group", force = false) long groupId,
 | 
			
		||||
            @Argument(name = "key") String key,
 | 
			
		||||
            @Argument(name = "value") String value
 | 
			
		||||
    ) {
 | 
			
		||||
        if(Strings.isNullOrEmpty(key)) {
 | 
			
		||||
            return "未选择配置项key.";
 | 
			
		||||
        }
 | 
			
		||||
        return "全局配置项 " + key + " 现已设置为: " + value + " (设置前的值: " + lastValue + ")";
 | 
			
		||||
        String lastValue = SettingProperties.setProperty(groupId, key, value.equals("null") ? null : value);
 | 
			
		||||
        return (groupId <= 0 ? "已更改全局配置 " : "已更改群组 " + groupId + " 配置 ") +
 | 
			
		||||
                key + " 的值: '" + value + "' (原配置值: '" + lastValue + "')";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Command
 | 
			
		||||
    public static String getGlobalProperty(@Argument(name = "key") String key) {
 | 
			
		||||
        return "全局配置项 " + key + " 当前值: " + BotCommandProcess.globalProp.getProperty(key, "(Empty)");
 | 
			
		||||
    public static String getProperty(
 | 
			
		||||
            @Argument(name = "group", force = false) long groupId,
 | 
			
		||||
            @Argument(name = "key") String key
 | 
			
		||||
    ) {
 | 
			
		||||
        if(Strings.isNullOrEmpty(key)) {
 | 
			
		||||
            return "未选择配置项key.";
 | 
			
		||||
        }
 | 
			
		||||
        return (groupId <= 0 ? "全局配置 " : "群组 " + groupId + " 配置 ") +
 | 
			
		||||
                key + " 设定值: '" + SettingProperties.getProperty(groupId, key, "(empty)") + "'";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Command
 | 
			
		||||
    public static String saveGlobalProperties() {
 | 
			
		||||
    public static String saveProperties() {
 | 
			
		||||
        log.info("正在保存全局配置文件...");
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            if(!globalPropFile.exists()) {
 | 
			
		||||
                if(!globalPropFile.createNewFile()) {
 | 
			
		||||
                    log.error("全局配置项文件保存失败!({})", "文件创建失败");
 | 
			
		||||
                    return "全局配置项文件保存失败!";
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            BotCommandProcess.globalProp.store(new FileOutputStream(globalPropFile), "");
 | 
			
		||||
            log.info("全局配置文件保存成功!");
 | 
			
		||||
            return "保存全局配置文件 - 操作已完成.";
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            log.error("全局配置项文件保存失败!", e);
 | 
			
		||||
            return "全局配置项文件保存失败!";
 | 
			
		||||
        }
 | 
			
		||||
        SettingProperties.saveProperties();
 | 
			
		||||
        return "保存全局配置文件 - 操作已完成.";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Command
 | 
			
		||||
    public static String loadGlobalProperties(@Argument(name = "reload", force = false) boolean reload) {
 | 
			
		||||
        Properties cache = new Properties();
 | 
			
		||||
        if(!globalPropFile.exists()) {
 | 
			
		||||
            return "未找到全局配置文件, 无法重载";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        try(Reader reader = new BufferedReader(new FileReader(globalPropFile))) {
 | 
			
		||||
            cache.load(reader);
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            log.error("重载全局配置文件时发生异常", e);
 | 
			
		||||
            return "加载全局配置文件时发生错误!";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    public static String loadProperties(@Argument(name = "reload", force = false) boolean reload) {
 | 
			
		||||
        if(reload) {
 | 
			
		||||
            BotCommandProcess.globalProp.clear();
 | 
			
		||||
            SettingProperties.clearProperties();
 | 
			
		||||
        }
 | 
			
		||||
        BotCommandProcess.globalProp.putAll(cache);
 | 
			
		||||
        return "全局配置文件重载完成.";
 | 
			
		||||
 | 
			
		||||
        SettingProperties.loadProperties();
 | 
			
		||||
        return "操作已完成.";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Command
 | 
			
		||||
 | 
			
		||||
@ -25,7 +25,6 @@ import org.slf4j.Logger;
 | 
			
		||||
import org.slf4j.LoggerFactory;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.FileInputStream;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.nio.charset.StandardCharsets;
 | 
			
		||||
import java.text.SimpleDateFormat;
 | 
			
		||||
@ -43,7 +42,6 @@ public class BotCommandProcess {
 | 
			
		||||
    private final static Logger log = LoggerFactory.getLogger(BotCommandProcess.class.getSimpleName());
 | 
			
		||||
 | 
			
		||||
    private final static File imageStoreDir = new File(System.getProperty("cgj.botDataDir"), "data/image/cgj/");
 | 
			
		||||
    public final static Properties globalProp = new Properties();
 | 
			
		||||
    private final static Gson gson = new GsonBuilder()
 | 
			
		||||
            .serializeNulls()
 | 
			
		||||
            .create();
 | 
			
		||||
@ -77,18 +75,7 @@ public class BotCommandProcess {
 | 
			
		||||
    public static void initialize() {
 | 
			
		||||
        log.info("正在初始化...");
 | 
			
		||||
 | 
			
		||||
        File globalPropFile = new File(System.getProperty("cgj.botDataDir"), "global.properties");
 | 
			
		||||
        if(globalPropFile.exists() && globalPropFile.isFile()) {
 | 
			
		||||
            log.info("正在加载全局配置文件...");
 | 
			
		||||
            try {
 | 
			
		||||
                globalProp.load(new FileInputStream(globalPropFile));
 | 
			
		||||
                log.info("全局配置文件加载完成.");
 | 
			
		||||
            } catch (IOException e) {
 | 
			
		||||
                log.error("加载全局配置文件时发生异常", e);
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            log.info("未找到全局配置文件,跳过加载.");
 | 
			
		||||
        }
 | 
			
		||||
        SettingProperties.loadProperties();
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            imageCacheExecutor.addHandler(new ImageCacheHandler());
 | 
			
		||||
@ -143,13 +130,13 @@ public class BotCommandProcess {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Command(commandName = "info")
 | 
			
		||||
    public static String artworkInfo(@Argument(name = "id") int illustId) {
 | 
			
		||||
    public static String artworkInfo(@Argument(name = "$fromGroup") long fromGroup, @Argument(name = "id") int illustId) {
 | 
			
		||||
        if(illustId <= 0) {
 | 
			
		||||
            return "错误的作品id!";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            if(isNoSafe(illustId, globalProp, false) || isReported(illustId)) {
 | 
			
		||||
            if(isNoSafe(illustId, SettingProperties.getProperties(fromGroup), false) || isReported(illustId)) {
 | 
			
		||||
                return "阅览禁止:该作品已被封印!!";
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@ -165,7 +152,7 @@ public class BotCommandProcess {
 | 
			
		||||
            builder.append("评论数:").append(illustPreLoadData.get(PreLoadDataComparator.Attribute.COMMENT.attrName).getAsInt()).append("\n");
 | 
			
		||||
            builder.append("页数:").append(illustPreLoadData.get(PreLoadDataComparator.Attribute.PAGE.attrName).getAsInt()).append("页\n");
 | 
			
		||||
            builder.append("---------------- 作品图片 ----------------\n");
 | 
			
		||||
            builder.append(getImageById(illustId, PixivDownload.PageQuality.REGULAR, 1)).append("\n");
 | 
			
		||||
            builder.append(getImageById(fromGroup, illustId, PixivDownload.PageQuality.REGULAR, 1)).append("\n");
 | 
			
		||||
            builder.append("使用 \".cgj image -id ")
 | 
			
		||||
                    .append(illustId)
 | 
			
		||||
                    .append("\" 获取原图。\n如有不当作品,可使用\".cgj report -id ")
 | 
			
		||||
@ -179,6 +166,7 @@ public class BotCommandProcess {
 | 
			
		||||
 | 
			
		||||
    @Command
 | 
			
		||||
    public static String ranking(
 | 
			
		||||
            @Argument(name = "$fromGroup") long fromGroup,
 | 
			
		||||
            @Argument(force = false, name = "date") Date queryTime,
 | 
			
		||||
            @Argument(force = false, name = "mode", defaultValue = "DAILY") String contentMode,
 | 
			
		||||
            @Argument(force = false, name = "type", defaultValue = "ILLUST") String contentType
 | 
			
		||||
@ -232,7 +220,8 @@ public class BotCommandProcess {
 | 
			
		||||
            int itemLimit = 10;
 | 
			
		||||
            String itemLimitPropertyKey = "ranking.ItemCountLimit";
 | 
			
		||||
            try {
 | 
			
		||||
                itemLimit = Integer.parseInt(globalProp.getProperty(itemLimitPropertyKey, "10"));
 | 
			
		||||
                itemLimit = Integer.parseInt(SettingProperties
 | 
			
		||||
                        .getProperty(SettingProperties.GLOBAL, itemLimitPropertyKey, "10"));
 | 
			
		||||
            } catch(NumberFormatException e) {
 | 
			
		||||
                log.warn("配置项 {} 的参数值格式有误!", itemLimitPropertyKey);
 | 
			
		||||
            }
 | 
			
		||||
@ -240,7 +229,8 @@ public class BotCommandProcess {
 | 
			
		||||
            int imageLimit = 3;
 | 
			
		||||
            String imageLimitPropertyKey = "ranking.imageCountLimit";
 | 
			
		||||
            try {
 | 
			
		||||
                imageLimit = Integer.parseInt(globalProp.getProperty(imageLimitPropertyKey, "3"));
 | 
			
		||||
                imageLimit = Integer.parseInt(
 | 
			
		||||
                        SettingProperties.getProperty(SettingProperties.GLOBAL, imageLimitPropertyKey, "3"));
 | 
			
		||||
            } catch(NumberFormatException e) {
 | 
			
		||||
                log.warn("配置项 {} 的参数值格式有误!", imageLimitPropertyKey);
 | 
			
		||||
            }
 | 
			
		||||
@ -261,7 +251,7 @@ public class BotCommandProcess {
 | 
			
		||||
                resultBuilder.append(rank).append(". (id: ").append(illustId).append(") ").append(title)
 | 
			
		||||
                        .append("(Author: ").append(authorName).append(",").append(authorId).append(") ").append(pagesCount).append("p.\n");
 | 
			
		||||
                if (index <= imageLimit) {
 | 
			
		||||
                    resultBuilder.append(getImageById(illustId, PixivDownload.PageQuality.REGULAR, 1)).append("\n");
 | 
			
		||||
                    resultBuilder.append(getImageById(fromGroup, illustId, PixivDownload.PageQuality.REGULAR, 1)).append("\n");
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
@ -290,13 +280,15 @@ public class BotCommandProcess {
 | 
			
		||||
     * @throws IOException 当搜索发生异常时抛出
 | 
			
		||||
     */
 | 
			
		||||
    @Command
 | 
			
		||||
    public static String search(@Argument(name = "content") String content,
 | 
			
		||||
                                @Argument(name = "type", force = false) String type,
 | 
			
		||||
                                @Argument(name = "area", force = false) String area,
 | 
			
		||||
                                @Argument(name = "in", force = false) String includeKeywords,
 | 
			
		||||
                                @Argument(name = "ex", force = false) String excludeKeywords,
 | 
			
		||||
                                @Argument(name = "contentOption", force = false) String contentOption,
 | 
			
		||||
                                @Argument(name = "page", force = false, defaultValue = "1") int pagesIndex
 | 
			
		||||
    public static String search(
 | 
			
		||||
            @Argument(name = "$fromGroup") long fromGroup,
 | 
			
		||||
            @Argument(name = "content") String content,
 | 
			
		||||
            @Argument(name = "type", force = false) String type,
 | 
			
		||||
            @Argument(name = "area", force = false) String area,
 | 
			
		||||
            @Argument(name = "in", force = false) String includeKeywords,
 | 
			
		||||
            @Argument(name = "ex", force = false) String excludeKeywords,
 | 
			
		||||
            @Argument(name = "contentOption", force = false) String contentOption,
 | 
			
		||||
            @Argument(name = "page", force = false, defaultValue = "1") int pagesIndex
 | 
			
		||||
    ) throws IOException {
 | 
			
		||||
        log.info("正在执行搜索...");
 | 
			
		||||
        PixivSearchBuilder searchBuilder = new PixivSearchBuilder(Strings.isNullOrEmpty(content) ? "" : content);
 | 
			
		||||
@ -360,7 +352,8 @@ public class BotCommandProcess {
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    long expire = 7200 * 1000;
 | 
			
		||||
                    String propValue = globalProp.getProperty("cache.searchBody.expire", "7200000");
 | 
			
		||||
                    String propValue = SettingProperties
 | 
			
		||||
                            .getProperty(SettingProperties.GLOBAL, "cache.searchBody.expire", "7200000");
 | 
			
		||||
                    try {
 | 
			
		||||
                        expire = Long.parseLong(propValue);
 | 
			
		||||
                    } catch (Exception e) {
 | 
			
		||||
@ -385,7 +378,8 @@ public class BotCommandProcess {
 | 
			
		||||
        log.debug("正在处理信息...");
 | 
			
		||||
        int limit = 8;
 | 
			
		||||
        try {
 | 
			
		||||
            limit = Integer.parseInt(globalProp.getProperty("search.ItemCountLimit", "8"));
 | 
			
		||||
            limit = Integer.parseInt(SettingProperties.
 | 
			
		||||
                    getProperty(SettingProperties.GLOBAL, "search.ItemCountLimit", "8"));
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            log.warn("参数转换异常!将使用默认值(" + limit + ")", e);
 | 
			
		||||
        }
 | 
			
		||||
@ -429,8 +423,8 @@ public class BotCommandProcess {
 | 
			
		||||
 | 
			
		||||
                //pageCount
 | 
			
		||||
 | 
			
		||||
                String imageMsg = getImageById(illustId, PixivDownload.PageQuality.REGULAR, 1);
 | 
			
		||||
                if (isNoSafe(illustId, globalProp, true)) {
 | 
			
		||||
                String imageMsg = getImageById(fromGroup, illustId, PixivDownload.PageQuality.REGULAR, 1);
 | 
			
		||||
                if (isNoSafe(illustId, SettingProperties.getProperties(SettingProperties.GLOBAL), true)) {
 | 
			
		||||
                    log.warn("作品Id {} 为R-18作品, 跳过.", illustId);
 | 
			
		||||
                    continue;
 | 
			
		||||
                } else if(isReported(illustId)) {
 | 
			
		||||
@ -453,7 +447,9 @@ public class BotCommandProcess {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Command(commandName = "pages")
 | 
			
		||||
    public static String getPagesList(@Argument(name = "id") int illustId, @Argument(name = "quality", force = false) PixivDownload.PageQuality quality) {
 | 
			
		||||
    public static String getPagesList(
 | 
			
		||||
            @Argument(name = "id") int illustId,
 | 
			
		||||
            @Argument(name = "quality", force = false) PixivDownload.PageQuality quality) {
 | 
			
		||||
        try {
 | 
			
		||||
            List<String> pagesList = PixivDownload.getIllustAllPageDownload(pixivDownload.getHttpClient(), pixivDownload.getCookieStore(), illustId, quality);
 | 
			
		||||
            StringBuilder builder = new StringBuilder("作品ID ").append(illustId).append(" 共有").append(pagesList.size()).append("页:").append("\n");
 | 
			
		||||
@ -469,9 +465,9 @@ public class BotCommandProcess {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Command(commandName = "link")
 | 
			
		||||
    public static String artworksLink(@Argument(name = "id") int illustId) {
 | 
			
		||||
    public static String artworksLink(@Argument(name = "$fromGroup") long fromGroup, @Argument(name = "id") int illustId) {
 | 
			
		||||
        try {
 | 
			
		||||
            if (isNoSafe(illustId, globalProp, false)) {
 | 
			
		||||
            if (isNoSafe(illustId, SettingProperties.getProperties(fromGroup), false)) {
 | 
			
		||||
                log.warn("作品Id {} 已被屏蔽.", illustId);
 | 
			
		||||
                return "由于相关设置,该作品已被屏蔽!";
 | 
			
		||||
            } else if(isReported(illustId)) {
 | 
			
		||||
@ -493,9 +489,11 @@ public class BotCommandProcess {
 | 
			
		||||
     * @return 如果成功, 返回BotCode, 否则返回错误信息.
 | 
			
		||||
     */
 | 
			
		||||
    @Command(commandName = "image")
 | 
			
		||||
    public static String getImageById(@Argument(name = "id") int illustId,
 | 
			
		||||
                                                   @Argument(name = "quality", force = false) PixivDownload.PageQuality quality,
 | 
			
		||||
                                                   @Argument(name = "page", force = false, defaultValue = "1") int pageIndex) {
 | 
			
		||||
    public static String getImageById(
 | 
			
		||||
            @Argument(name = "$fromGroup") long fromGroup,
 | 
			
		||||
            @Argument(name = "id") int illustId,
 | 
			
		||||
            @Argument(name = "quality", force = false) PixivDownload.PageQuality quality,
 | 
			
		||||
            @Argument(name = "page", force = false, defaultValue = "1") int pageIndex) {
 | 
			
		||||
        log.debug("IllustId: {}, Quality: {}, PageIndex: {}", illustId, quality.name(), pageIndex);
 | 
			
		||||
        List<String> pagesList;
 | 
			
		||||
        try {
 | 
			
		||||
@ -518,7 +516,7 @@ public class BotCommandProcess {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            if (isNoSafe(illustId, globalProp, false)) {
 | 
			
		||||
            if (isNoSafe(illustId, SettingProperties.getProperties(fromGroup), false)) {
 | 
			
		||||
                log.warn("作品 {} 存在R-18内容且设置\"image.allowR18\"为false,将屏蔽该作品不发送.", illustId);
 | 
			
		||||
                return "(根据设置,该作品已被屏蔽!)";
 | 
			
		||||
            } else if(isReported(illustId)) {
 | 
			
		||||
@ -690,7 +688,8 @@ public class BotCommandProcess {
 | 
			
		||||
                            .getAsJsonObject(Integer.toString(illustId));
 | 
			
		||||
 | 
			
		||||
                    long expire = 7200 * 1000;
 | 
			
		||||
                    String propValue = globalProp.getProperty("cache.illustPreLoadData.expire", "7200000");
 | 
			
		||||
                    String propValue = SettingProperties.
 | 
			
		||||
                            getProperty(SettingProperties.GLOBAL, "cache.illustPreLoadData.expire", "7200000");
 | 
			
		||||
                    log.debug("PreLoadData有效时间设定: {}", propValue);
 | 
			
		||||
                    try {
 | 
			
		||||
                        expire = Long.parseLong(propValue);
 | 
			
		||||
 | 
			
		||||
@ -77,7 +77,7 @@ public class RandomRankingArtworksSender extends AutoSender {
 | 
			
		||||
 | 
			
		||||
            JsonObject rankingInfo = rankingList.get(0);
 | 
			
		||||
            int illustId = rankingInfo.get("illust_id").getAsInt();
 | 
			
		||||
            if(BotCommandProcess.isNoSafe(illustId, BotCommandProcess.globalProp, false)) {
 | 
			
		||||
            if(BotCommandProcess.isNoSafe(illustId, SettingProperties.getProperties(SettingProperties.GLOBAL), false)) {
 | 
			
		||||
                log.warn("作品为r18作品, 取消本次发送.");
 | 
			
		||||
                return;
 | 
			
		||||
            } else if(BotCommandProcess.isReported(illustId)) {
 | 
			
		||||
@ -89,7 +89,7 @@ public class RandomRankingArtworksSender extends AutoSender {
 | 
			
		||||
            message.append("#美图推送 - 今日排行榜 第 ").append(rankingInfo.get("rank").getAsInt()).append(" 名\n");
 | 
			
		||||
            message.append("标题:").append(rankingInfo.get("title").getAsString()).append("(").append(illustId).append(")\n");
 | 
			
		||||
            message.append("作者:").append(rankingInfo.get("user_name").getAsString()).append("\n");
 | 
			
		||||
            message.append(BotCommandProcess.getImageById(illustId, quality, 1));
 | 
			
		||||
            message.append(BotCommandProcess.getImageById(0, illustId, quality, 1));
 | 
			
		||||
            message.append("\n如有不当作品,可使用\".cgj report -id ").append(illustId).append("\"向色图姬反馈。");
 | 
			
		||||
            getMessageSender().sendMessage(message.toString());
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										232
									
								
								src/main/java/net/lamgc/cgj/bot/SettingProperties.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										232
									
								
								src/main/java/net/lamgc/cgj/bot/SettingProperties.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,232 @@
 | 
			
		||||
package net.lamgc.cgj.bot;
 | 
			
		||||
 | 
			
		||||
import com.google.common.base.Throwables;
 | 
			
		||||
import org.slf4j.Logger;
 | 
			
		||||
import org.slf4j.LoggerFactory;
 | 
			
		||||
 | 
			
		||||
import java.io.*;
 | 
			
		||||
import java.nio.charset.StandardCharsets;
 | 
			
		||||
import java.util.*;
 | 
			
		||||
 | 
			
		||||
public final class SettingProperties {
 | 
			
		||||
 | 
			
		||||
    private final static Logger log = LoggerFactory.getLogger("SettingProperties");
 | 
			
		||||
 | 
			
		||||
    private final static File globalPropFile = new File(getPropertiesDir(), "global.properties");
 | 
			
		||||
    private final static Properties globalProp = new Properties();
 | 
			
		||||
 | 
			
		||||
    private final static Map<Long, Properties> groupPropMap = new HashMap<>();
 | 
			
		||||
 | 
			
		||||
    private final static Set<Long> changeList = Collections.synchronizedSet(new HashSet<>());
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 全局配置项
 | 
			
		||||
     */
 | 
			
		||||
    public final static long GLOBAL = 0;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 清空所有Properties.
 | 
			
		||||
     */
 | 
			
		||||
    public static void clearProperties() {
 | 
			
		||||
        groupPropMap.clear();
 | 
			
		||||
        globalProp.clear();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 加载配置文件
 | 
			
		||||
     */
 | 
			
		||||
    public static void loadProperties() {
 | 
			
		||||
        loadGlobalProperties();
 | 
			
		||||
 | 
			
		||||
        File[] files = getPropertiesDir()
 | 
			
		||||
                .listFiles((dir, fileName) -> fileName.startsWith("group.") && fileName.endsWith(".properties"));
 | 
			
		||||
        if(files == null) {
 | 
			
		||||
            log.error("检索群组配置文件失败, 可能是被拒绝访问.");
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (File file : files) {
 | 
			
		||||
            String name = file.getName();
 | 
			
		||||
            long groupId;
 | 
			
		||||
            try {
 | 
			
		||||
                groupId = Long.parseLong(name.substring(name.indexOf("group.") + 6, name.lastIndexOf(".properties")));
 | 
			
		||||
            } catch (NumberFormatException e) {
 | 
			
		||||
                log.error("非法的配置文件名: {}", name);
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            if(!groupPropMap.containsKey(groupId)) {
 | 
			
		||||
                groupPropMap.put(groupId, new Properties(globalProp));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            loadGroupProperties(groupId, groupPropMap.get(groupId));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 保存配置项
 | 
			
		||||
     */
 | 
			
		||||
    public static void saveProperties() {
 | 
			
		||||
        log.info("正在保存所有配置...");
 | 
			
		||||
        saveGlobalProperties();
 | 
			
		||||
 | 
			
		||||
        for (Long groupId : groupPropMap.keySet()) {
 | 
			
		||||
            if(!changeList.contains(groupId)) {
 | 
			
		||||
                log.debug("群组 {} 配置无改动, 忽略保存.", groupId);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            log.debug("正在保存群组 {} 配置文件...", groupId);
 | 
			
		||||
            saveGroupProperties(groupId);
 | 
			
		||||
        }
 | 
			
		||||
        log.info("配置保存完成.");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 保存指定群组的配置文件
 | 
			
		||||
     * @param groupId 要保存配置的群组Id
 | 
			
		||||
     */
 | 
			
		||||
    private static void saveGroupProperties(long groupId) {
 | 
			
		||||
        try {
 | 
			
		||||
            saveGroupProperties(groupId, getGroupProperties(groupId));
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            log.error("群组 {} 配置保存失败\n{}", groupId, Throwables.getStackTraceAsString(e));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static void saveGroupProperties(Long groupId, Properties properties) throws IOException {
 | 
			
		||||
        File groupPropFile = new File(getPropertiesDir(), "group." + groupId + ".properties");
 | 
			
		||||
        if((!groupPropFile.exists() || !groupPropFile.isFile()) && (!groupPropFile.delete() || !groupPropFile.createNewFile())) {
 | 
			
		||||
            log.error("群组 {} 配置文件创建失败!", groupId);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        saveProperties(properties, new FileOutputStream(groupPropFile));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static void loadGlobalProperties() {
 | 
			
		||||
        if(globalPropFile.exists() && globalPropFile.isFile()) {
 | 
			
		||||
            log.info("正在加载全局配置文件...");
 | 
			
		||||
            try (Reader reader = new InputStreamReader(new FileInputStream(globalPropFile), StandardCharsets.UTF_8)) {
 | 
			
		||||
                globalProp.load(reader);
 | 
			
		||||
                log.info("全局配置文件加载完成.");
 | 
			
		||||
            } catch (IOException e) {
 | 
			
		||||
                log.error("加载全局配置文件时发生异常", e);
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            log.info("未找到全局配置文件,跳过加载.");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 保存全局配置项
 | 
			
		||||
     */
 | 
			
		||||
    private static void saveGlobalProperties() {
 | 
			
		||||
        try {
 | 
			
		||||
            if((!globalPropFile.exists() || !globalPropFile.isFile()) && (!globalPropFile.delete() || !globalPropFile.createNewFile())) {
 | 
			
		||||
                log.error("创建全局配置文件失败.");
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            saveProperties(globalProp, new FileOutputStream(globalPropFile));
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            log.error("全局配置文件保存时发生异常", e);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static void loadGroupProperties(long groupId, Properties properties) {
 | 
			
		||||
        File propFile = new File(getPropertiesDir(), "group." + groupId + ".properties");
 | 
			
		||||
        Properties groupProp = Objects.requireNonNull(properties);
 | 
			
		||||
        if(!propFile.exists() || !propFile.isFile()) {
 | 
			
		||||
            log.warn("群组 {} 配置文件不存在, 或不是一个文件.({})", groupId, propFile.getAbsolutePath());
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        try (Reader reader = new InputStreamReader(new FileInputStream(propFile), StandardCharsets.UTF_8)) {
 | 
			
		||||
            groupProp.load(reader);
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            log.error("读取群组 {} 群配置文件时发生异常:\n{}", groupId, Throwables.getStackTraceAsString(e));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static void saveProperties(Properties properties, OutputStream stream) throws IOException {
 | 
			
		||||
        properties.store(new OutputStreamWriter(stream, StandardCharsets.UTF_8), null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 获取配置文件目录
 | 
			
		||||
     * @return 返回目录File对象.
 | 
			
		||||
     */
 | 
			
		||||
    private static File getPropertiesDir() {
 | 
			
		||||
        File propDir = new File(System.getProperty("cgj.botDataDir"), "/setting/");
 | 
			
		||||
        if((!propDir.exists() || !propDir.isDirectory()) && (!propDir.delete() || !propDir.mkdirs())) {
 | 
			
		||||
            log.warn("Setting文件夹创建失败!");
 | 
			
		||||
        }
 | 
			
		||||
        return propDir;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static String getProperty(long groupId, String key) {
 | 
			
		||||
        return getProperty(groupId, key, null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static String getProperty(long groupId, String key, String defaultValue) {
 | 
			
		||||
        if(groupId <= 0) {
 | 
			
		||||
            return globalProp.getProperty(key, defaultValue);
 | 
			
		||||
        } else {
 | 
			
		||||
            Properties properties = groupPropMap.get(groupId);
 | 
			
		||||
            return properties == null ? defaultValue : properties.getProperty(key, defaultValue);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 设置配置项
 | 
			
		||||
     * @param groupId 群组Id, 如为0或负数则为全局配置
 | 
			
		||||
     * @param key 配置项key名
 | 
			
		||||
     * @param value 欲设置的新值, 如为null则删除该配置项
 | 
			
		||||
     * @return 返回上一次设定值
 | 
			
		||||
     */
 | 
			
		||||
    public static String setProperty(long groupId, String key, String value) {
 | 
			
		||||
        Objects.requireNonNull(key);
 | 
			
		||||
        Properties targetProperties = groupId <= 0 ? globalProp : getGroupProperties(groupId);
 | 
			
		||||
        String lastValue = targetProperties.getProperty(key);
 | 
			
		||||
        if(value != null) {
 | 
			
		||||
            targetProperties.setProperty(key, value);
 | 
			
		||||
        } else {
 | 
			
		||||
            targetProperties.remove(key);
 | 
			
		||||
        }
 | 
			
		||||
        return lastValue;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 获取GlobalProperties
 | 
			
		||||
     * @return 全局Properties
 | 
			
		||||
     */
 | 
			
		||||
    private static Properties getGlobalProperties() {
 | 
			
		||||
        return globalProp;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 获取群组Properties
 | 
			
		||||
     * @param groupId 群组Id
 | 
			
		||||
     * @return 如果存在, 返回Properties, 不存在返回null.
 | 
			
		||||
     * @throws IllegalArgumentException 当群组Id 小于或等于0 时抛出.
 | 
			
		||||
     */
 | 
			
		||||
    private static Properties getGroupProperties(long groupId) {
 | 
			
		||||
        if (groupId <= 0) {
 | 
			
		||||
            throw new IllegalArgumentException("Group number cannot be 0 or negative: " + groupId);
 | 
			
		||||
        }
 | 
			
		||||
        return groupPropMap.get(groupId);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 获取群组 Properties, 如果指定群组没有 Properties, 则使用GlobalProperties.
 | 
			
		||||
     * @param groupId 指定群组Id
 | 
			
		||||
     * @return 如果群组存在所属Properties, 则返回群组Properties, 否则返回GlobalProperties.
 | 
			
		||||
     */
 | 
			
		||||
    public static Properties getProperties(long groupId) {
 | 
			
		||||
        if(groupPropMap.containsKey(groupId)) {
 | 
			
		||||
            return groupPropMap.get(groupId);
 | 
			
		||||
        }
 | 
			
		||||
        return getGlobalProperties();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -6,6 +6,7 @@ import com.google.common.util.concurrent.ThreadFactoryBuilder;
 | 
			
		||||
import net.lamgc.cgj.bot.BotAdminCommandProcess;
 | 
			
		||||
import net.lamgc.cgj.bot.BotCommandProcess;
 | 
			
		||||
import net.lamgc.cgj.bot.MessageEventExecutionDebugger;
 | 
			
		||||
import net.lamgc.cgj.bot.SettingProperties;
 | 
			
		||||
import net.lamgc.cgj.util.DateParser;
 | 
			
		||||
import net.lamgc.cgj.util.PagesQualityParser;
 | 
			
		||||
import net.lamgc.cgj.util.TimeLimitThreadPoolExecutor;
 | 
			
		||||
@ -50,7 +51,7 @@ public class BotEventHandler implements EventHandler {
 | 
			
		||||
     * 消息事件执行器
 | 
			
		||||
     */
 | 
			
		||||
    private final static EventExecutor executor = new EventExecutor(new TimeLimitThreadPoolExecutor(
 | 
			
		||||
            60 * 1000,
 | 
			
		||||
            0,
 | 
			
		||||
            Math.max(Runtime.getRuntime().availableProcessors(), 4),
 | 
			
		||||
            Math.max(Math.max(Runtime.getRuntime().availableProcessors() * 2, 4), 32),
 | 
			
		||||
            30L,
 | 
			
		||||
@ -130,12 +131,12 @@ public class BotEventHandler implements EventHandler {
 | 
			
		||||
     */
 | 
			
		||||
    @NotAccepted
 | 
			
		||||
    public static void executeMessageEvent(MessageEvent event) {
 | 
			
		||||
        String debuggerName;
 | 
			
		||||
        String debuggerName = SettingProperties.getProperty(0, "debug.debugger");
 | 
			
		||||
        if(!event.getMessage().startsWith(ADMIN_COMMAND_PREFIX) &&
 | 
			
		||||
                !Strings.isNullOrEmpty(debuggerName = BotCommandProcess.globalProp.getProperty("debug.debugger"))) {
 | 
			
		||||
                !Strings.isNullOrEmpty(debuggerName)) {
 | 
			
		||||
            try {
 | 
			
		||||
                MessageEventExecutionDebugger debugger = MessageEventExecutionDebugger.valueOf(debuggerName.toUpperCase());
 | 
			
		||||
                debugger.debugger.accept(executor, event, BotCommandProcess.globalProp,
 | 
			
		||||
                debugger.debugger.accept(executor, event, SettingProperties.getProperties(SettingProperties.GLOBAL),
 | 
			
		||||
                                MessageEventExecutionDebugger.getDebuggerLogger(debugger));
 | 
			
		||||
            } catch(IllegalArgumentException e) {
 | 
			
		||||
                log.warn("未找到指定调试器: '{}'", debuggerName);
 | 
			
		||||
@ -195,7 +196,8 @@ public class BotEventHandler implements EventHandler {
 | 
			
		||||
        Object result;
 | 
			
		||||
        try {
 | 
			
		||||
            if(msg.toLowerCase().startsWith(ADMIN_COMMAND_PREFIX)) {
 | 
			
		||||
                if(!String.valueOf(event.getFromQQ()).equals(BotCommandProcess.globalProp.getProperty("admin.adminId"))) {
 | 
			
		||||
                if(!String.valueOf(event.getFromQQ())
 | 
			
		||||
                        .equals(SettingProperties.getProperty(0, "admin.adminId"))) {
 | 
			
		||||
                    result = "你没有执行该命令的权限!";
 | 
			
		||||
                } else {
 | 
			
		||||
                    result = adminRunner.run(args.length <= 1 ? new String[0] : Arrays.copyOfRange(args, 1, args.length));
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user