diff --git a/.gitignore b/.gitignore index 46a86c4..ff353a5 100644 --- a/.gitignore +++ b/.gitignore @@ -68,3 +68,4 @@ out/ # 临时环境变量文件 .env +*.sqlite diff --git a/README.md b/README.md index c7e1883..8bbb453 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,12 @@ ```bash mvn clean compile exec:java +``` + +# Maven 来打包成 jar +```bash +mvn clean package ``` 首次运行时会: diff --git a/pom.xml b/pom.xml index 8327b14..72ab366 100644 --- a/pom.xml +++ b/pom.xml @@ -55,6 +55,13 @@ runtime + + org.xerial + sqlite-jdbc + 3.45.2.0 + + + com.fasterxml.jackson.core diff --git a/scripts/release.sh b/scripts/release.sh new file mode 100644 index 0000000..4db3525 --- /dev/null +++ b/scripts/release.sh @@ -0,0 +1,73 @@ +#!/bin/bash + +APP_NAME="ExploitDB" +MAIN_CLASS="xin.ctkqiang.Main" +VERSION="v1.0.0" +RELEASE_DIR="releases/${VERSION}" +OUT_DIR="out" + +# 彩色 ASCII 标题(纯 echo) +ascii_banner() { + echo " _____ _ _ _ _ _ " + echo " | ____|_ ___ __ | | ___ (_) |_(_)___| |_ ___ _ __ " + echo " | _| \ \/ / '_ \| |/ _ \| | __| / __| __/ _ \| '__|" + echo " | |___ > <| |_) | | (_) | | |_| \__ \ || (_) | | " + echo " |_____/_/\_\ .__/|_|\___/|_|\__|_|___/\__\___/|_| " + echo " |_| " +} + +# 动画函数 +wait_animation() { + local MESSAGE=$1 + local DOTS="" + + echo "$MESSAGE" + for i in 1 2 3; do + DOTS="$DOTS." + echo "$DOTS" + sleep 0.3 + done +} + +# 步骤开始 +ascii_banner +wait_animation "🌸 灵儿正在为你编译 Java 11 项目" + +# 清理旧文件 +rm -rf $OUT_DIR $RELEASE_DIR +mkdir -p $OUT_DIR + +# 编译 +find ./src -name "*.java" >sources.txt +javac -source 11 -target 11 -d $OUT_DIR @sources.txt + +if [ $? -ne 0 ]; then + echo "❌ 编译失败了!检查一下语法哦~" + exit 1 +fi + +wait_animation "🎀 编译完成,开始打包成 JAR" + +# 创建 JAR 包 +JAR_NAME="${APP_NAME}-${VERSION}.jar" +jar cfe $JAR_NAME $MAIN_CLASS -C $OUT_DIR . + +if [ $? -ne 0 ]; then + echo "❌ 打包失败了!可能是入口类路径设置错了~" + exit 1 +fi + +# 准备 Release 目录 +mkdir -p $RELEASE_DIR +mv $JAR_NAME $RELEASE_DIR/ + +wait_animation "📦 发布结构整理完成" + +# Release Summary +echo "" +echo "🎉 Release 打包成功!少女完成度 100%~" +echo "📁 输出目录: $RELEASE_DIR" +echo "📦 文件名: $JAR_NAME" +echo "🔮 Java 版本: $(java -version 2>&1 | head -n 1)" +echo "" +echo "下一步:上传 GitHub Release 页面吧 💖" diff --git a/src/main/java/xin/ctkqiang/Main.java b/src/main/java/xin/ctkqiang/Main.java index 559c4f1..1143008 100644 --- a/src/main/java/xin/ctkqiang/Main.java +++ b/src/main/java/xin/ctkqiang/Main.java @@ -4,15 +4,20 @@ import java.util.List; import java.util.Scanner; +import xin.ctkqiang.config.Configuration; import xin.ctkqiang.controller.ExploitDbController; import xin.ctkqiang.controller.UserUtil; +import xin.ctkqiang.dto.Database; public class Main { public static final String VERSION = "1.0"; public static final String TITLE = "ExploitDB 搜索工具"; public static final String AUTHOR = "钟智强"; + public static final String EMAIL = "ctkqiang@dingtalk.com"; + public static final String GITHUB = "https://github.com/ctkqiang"; + public static final String GITCODE = "https://gitcode.com/ctkqiang_sr"; public static final String DESCRIPTION = "ExploitDB 搜索工具"; - public static final String USAGE = "mvn clean compile exec:java"; + public static final String USAGE = "mvn clean compile exec:java 或 java -jar {FILENAME}.jar"; public static final Scanner scanner = new Scanner(System.in); @@ -24,18 +29,63 @@ public class Main { private static List allowed = Arrays.asList("csv", "json", "sql"); private static void PrintBanner() { - System.out.println("==================================="); - System.out.println(" " + TITLE + " v" + VERSION); - System.out.println(" Author: " + AUTHOR); - System.out.println(" " + DESCRIPTION); - System.out.println("===================================\n"); + System.out.println(); + System.out.println("╭─────────────────────────────────────────────────────────────────────────╮"); + System.out.println("│ (๑˃̵ᴗ˂̵)و 欢迎来到灵儿的安全世界呀~♡ (づ。◕‿‿◕。)づ "); + System.out.println("│ "); + System.out.println("│ 工具名称:" + TITLE + " v" + VERSION); + System.out.println("│ 作者昵称:" + AUTHOR + " (๑•̀ㅂ•́)و✧"); + System.out.println("│ 简介说明:" + DESCRIPTION); + System.out.println("│ "); + System.out.println("│ 📧 邮箱联系: " + EMAIL); + System.out.println("│ 💻 GitHub : " + GITHUB); + System.out.println("│ 📂 GitCode : " + GITCODE); + System.out.println("│ "); + System.out.println("│ 🛠️ 使用方法: " + USAGE); + System.out.println("│ "); + System.out.println("│ 💌 小声明哟~我是乖乖的好孩子,这工具是帮大家做好事的~ "); + System.out.println("│ 不是让坏蛋乱用的哦 (ง •̀_•́)ง "); + System.out.println("│ 如果有人坏坏地用了,后果自负哒~我不背锅哦~请保持正义感~♡ "); + System.out.println("╰─────────────────────────────────────────────────────────────────────────╯"); + System.out.println(); } public static void main(String[] args) { try { Main.PrintBanner(); - int pages = userUtil.askForPositiveInt("📄 想爬多少页咧~?(建议填个50以上更爽!):"); + /** + * 嘻嘻~这里是数据库模式设置哦 ♡ + * 你可以从 {@link xin.ctkqiang.dto.Database Database} 枚举里选一个最爱滴数据库: + * + * + * 小提示✨:默认模式是 MYSQL 哦,要用 SQLite 的话,记得把下面的代码改成 + * Configuration.setDatabaseMode(Database.SQLITE); 才能生效呢~ + * + * 举个栗子给你看👇: + * + * 乖乖用【默认】 MySQL 嘛 ~ + * + *
+             * Configuration.setDatabaseMode(Database.MYSQL);
+             * 
+ * + * 想用 SQLite ~ + * + *
+             * Configuration.setDatabaseMode(Database.SQLITE);
+             * 
+ * + * 嘻嘻,这样就能轻轻松松切换数据库, 你棒棒啦!🎀🌸💖 + */ + Configuration.setDatabaseMode(Database.MYSQL); + + int pages = userUtil.askForPositiveInt("📄 想爬多少页咧~?【建议填个50以上更爽!】"); boolean isExport = userUtil.askForYesNo("💾 要不要顺便导出数据嘞?(支持 .csv/.json/.sql哦)✨:"); if (isExport) { diff --git a/src/main/java/xin/ctkqiang/config/Configuration.java b/src/main/java/xin/ctkqiang/config/Configuration.java index b87fd99..2c08799 100644 --- a/src/main/java/xin/ctkqiang/config/Configuration.java +++ b/src/main/java/xin/ctkqiang/config/Configuration.java @@ -1,13 +1,28 @@ package xin.ctkqiang.config; +import xin.ctkqiang.dto.Database; + public class Configuration { + private static String DatabaseMode = Database.MYSQL.getValue(); + public static final String DB_NAME = "ExploitDB"; public static final String DB_URL = "jdbc:mysql://localhost:3306/" + DB_NAME + "?serverTimezone=UTC&allowPublicKeyRetrieval=true&useSSL=false"; - public static final String DB_USER = "root"; // 改成你的数据库用户名 - public static final String DB_PASSWORD = ""; // 改成你的数据库密码 + public static final String DB_SQLITE_URL = "jdbc:sqlite:ling.sqlite"; + + public static final String DB_USER = "root"; + public static final String DB_PASSWORD = ""; public static final String DB_DRIVER = "com.mysql.cj.jdbc.Driver"; public static final boolean DEBUG = false; + + public static String getDatabaseMode() { + return DatabaseMode; + } + + public static void setDatabaseMode(Database databaseMode) { + DatabaseMode = databaseMode.getValue(); + System.out.println(String.format("🎀 你当前选择的数据库模式是:「%s」~酱酱 ♪(๑˃ᴗ˂)ﻭ \n", getDatabaseMode())); + } } diff --git a/src/main/java/xin/ctkqiang/controller/DatabaseController.java b/src/main/java/xin/ctkqiang/controller/DatabaseController.java index d3a9bb5..dbbc4a3 100644 --- a/src/main/java/xin/ctkqiang/controller/DatabaseController.java +++ b/src/main/java/xin/ctkqiang/controller/DatabaseController.java @@ -18,6 +18,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import xin.ctkqiang.config.Configuration; +import xin.ctkqiang.dto.Database; import xin.ctkqiang.dto.Exploit; /** @@ -32,7 +33,7 @@ public class DatabaseController { /** 数据库名称 */ protected final static String DB_NAME = Configuration.DB_NAME; - /** 数据库连接URL */ + /** MYSQL 数据库连接URL */ protected final static String DB_URL = Configuration.DB_URL; /** 数据库用户名 */ @@ -44,6 +45,9 @@ public class DatabaseController { /** 数据库驱动类名 */ protected final static String DB_DRIVER = Configuration.DB_DRIVER; + /** SQLITE 数据库连接URL */ + protected final static String DB_SQLITE_URL = Configuration.DB_SQLITE_URL; + /** * 静态初始化块 * 在类加载时尝试加载数据库驱动 @@ -63,7 +67,35 @@ public class DatabaseController { * @throws SQLException 如果连接数据库时发生错误 */ protected Connection getConnection() throws SQLException { - return DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD); + String mode = Configuration.getDatabaseMode(); + String upperMode = mode.toUpperCase(); + System.out.println("💡 切换数据库模式 -> " + upperMode); + + switch (upperMode) { + case "SQLITE": + try { + Class.forName("org.sqlite.JDBC"); + System.out.println("📦 嘻嘻~SQLite 驱动已加载好惹!我已经抱好数据库小可爱啦~ฅ(^・ω・^ฅ)"); + } catch (ClassNotFoundException e) { + System.err.println("❌ 哎呀呀!SQLite JDBC 驱动不见惹~人家找不到驱动怎么贴贴数据库嘛喵呜呜。゚(゚´ω`゚)゚。"); + throw new SQLException("找不到 SQLite 驱动喵~要不要检查一下依赖有没有加对呀?"); + } + return DriverManager.getConnection(DatabaseController.DB_SQLITE_URL); + + case "MYSQL": + default: + try { + Class.forName(DatabaseController.DB_DRIVER); + System.out.println("📦 MySQL 驱动加载完成!我打扮好了,要去连接数据库小哥哥啦~(๑•̀ㅂ•́)و✧"); + } catch (ClassNotFoundException e) { + System.err.println("❌ 呜呜呜 MySQL JDBC 驱动不见了~是不是打包的时候忘记带灵儿一起走啦 >///< "); + throw new SQLException("MySQL 驱动加载失败了喵~快检查一下 `.jar` 有没有遗漏吧!"); + } + return DriverManager.getConnection( + DatabaseController.DB_URL, + DatabaseController.DB_USER, + DatabaseController.DB_PASSWORD); + } } /** @@ -109,20 +141,52 @@ public void CreateTableIfNotExists() { + ");"; try { - // 确保数据库驱动已加载 - Class.forName(DatabaseController.DB_DRIVER); - - // 创建数据库连接并执行建表语句 - try (Connection conn = DriverManager.getConnection( - DatabaseController.DB_URL, - DatabaseController.DB_USER, - DatabaseController.DB_PASSWORD); - Statement stmt = conn.createStatement()) { - stmt.execute(query); - System.out.println("💾 数据表【内容信息】初始化成功!"); + + String mode = Configuration.getDatabaseMode(); + Database dbMode; + + try { + dbMode = Database.fromValue(mode); + } catch (IllegalArgumentException e) { + dbMode = null; + } + + if (dbMode == null) { + System.out.println("🥴 吃嗯的!这个数据库模式不认识喔:\"" + mode + "\" 妹妹我拒绝连接!"); + return; + } + + switch (dbMode) { + case SQLITE: + // 加载 SQLite JDBC 驱动 + Class.forName("org.sqlite.JDBC"); + + // 构建连接(数据库文件叫 ling.sqlite) + try (Connection conn = DriverManager.getConnection(DatabaseController.DB_SQLITE_URL); + Statement stmt = conn.createStatement()) { + stmt.execute(query); + System.out.println("🎀 SQLite 模式下,表结构初始化好啦!已经准备好可爱的记录了喵~"); + } + + break; + case MYSQL: + default: + // 确保数据库驱动已加载 + Class.forName(DatabaseController.DB_DRIVER); + + // 创建数据库连接并执行建表语句 + try (Connection conn = DriverManager.getConnection( + DatabaseController.DB_URL, + DatabaseController.DB_USER, + DatabaseController.DB_PASSWORD); + Statement stmt = conn.createStatement()) { + stmt.execute(query); + System.out.println("💾 MySQL 模式下,数据表【内容信息】初始化成功~♡"); + } } + } catch (Exception e) { - System.err.println("❌ 数据表创建失败:" + e.getMessage()); + System.err.println("❌ 表创建失败惹呜呜呜呜:妹抖崩坏 > <\n" + e.getMessage()); e.printStackTrace(); } } diff --git a/src/main/java/xin/ctkqiang/controller/UserUtil.java b/src/main/java/xin/ctkqiang/controller/UserUtil.java index a8412b7..817212f 100644 --- a/src/main/java/xin/ctkqiang/controller/UserUtil.java +++ b/src/main/java/xin/ctkqiang/controller/UserUtil.java @@ -15,7 +15,7 @@ public int askForPositiveInt(String prompt) { int result = DEFAULT; while (true) { - System.out.print(prompt + " (默认 " + DEFAULT + "): "); + System.out.print(prompt + " (默认 " + DEFAULT + "): 🌼 "); String input = scanner.nextLine().trim(); if (input.isEmpty()) { diff --git a/src/main/java/xin/ctkqiang/dto/Database.java b/src/main/java/xin/ctkqiang/dto/Database.java new file mode 100644 index 0000000..dd3429f --- /dev/null +++ b/src/main/java/xin/ctkqiang/dto/Database.java @@ -0,0 +1,25 @@ +package xin.ctkqiang.dto; + +public enum Database { + MYSQL("MySQL"), + SQLITE("SQLite"); + + private final String value; + + Database(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + + public static Database fromValue(String value) { + for (Database db : values()) { + if (db.value.equalsIgnoreCase(value)) { + return db; + } + } + throw new IllegalArgumentException("Unknown database type: " + value); + } +}