feat(core): 实现插件加载系统并优化日志管理
- 新增插件加载系统,支持从指定目录加载插件 - 引入log4j2日志框架,优化日志记录和管理 - 重构主程序启动逻辑,增加加载动画和系统信息输出 - 优化窗口样式和布局,提高用户体验
This commit is contained in:
10
build.gradle
10
build.gradle
@@ -30,6 +30,16 @@ dependencies {
|
||||
implementation 'org.commonjava.googlecode.markdown4j:markdown4j:2.2-cj-1.1'
|
||||
// https://mvnrepository.com/artifact/com.google.code.gson/gson
|
||||
implementation 'com.google.code.gson:gson:2.8.9'
|
||||
|
||||
implementation 'org.apache.logging.log4j:log4j-api:2.20.0'
|
||||
implementation 'org.apache.logging.log4j:log4j-core:2.20.0'
|
||||
implementation 'org.apache.logging.log4j:log4j-slf4j-impl:2.20.0'
|
||||
|
||||
implementation 'org.ow2.asm:asm:7.1'
|
||||
implementation 'org.ow2.asm:asm-commons:7.1'
|
||||
implementation 'org.ow2.asm:asm-analysis:7.1'
|
||||
implementation 'org.ow2.asm:asm-util:7.0'
|
||||
implementation 'org.ow2.asm:asm-tree:7.1'
|
||||
}
|
||||
|
||||
application {
|
||||
|
||||
@@ -6,8 +6,12 @@ import com.axis.innovators.box.events.SubscribeEvent;
|
||||
import com.axis.innovators.box.gui.FridaWindow;
|
||||
import com.axis.innovators.box.gui.LocalWindow;
|
||||
import com.axis.innovators.box.gui.MainWindow;
|
||||
import com.axis.innovators.box.gui.LoadIcon;
|
||||
import com.axis.innovators.box.plugins.PluginLoader;
|
||||
import com.axis.innovators.box.tools.LibraryLoad;
|
||||
import org.markdown4j.Markdown4jProcessor;
|
||||
import com.axis.innovators.box.tools.SystemInfoUtil;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
@@ -19,9 +23,23 @@ import java.io.IOException;
|
||||
* @author tzdwindows 7
|
||||
*/
|
||||
public class Main {
|
||||
private static final Logger logger = LogManager.getLogger(Main.class);
|
||||
private static final String VERSIONS = "0.0.1";
|
||||
private static final String[] AUTHOR = new String[]{
|
||||
"tzdwindows 7"
|
||||
};
|
||||
/** 我是总任务数 **/
|
||||
public static int totalTasks = 1;
|
||||
/** 我是当前任务数 **/
|
||||
public static int completedTasks = 0;
|
||||
|
||||
static {
|
||||
LibraryLoad.loadLibrary("FridaNative");
|
||||
try {
|
||||
LibraryLoad.loadLibrary("FridaNative");
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed to load the 'FridaNative' library", e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
@@ -31,60 +49,131 @@ public class Main {
|
||||
placeholder.setForeground(new Color(127, 140, 153));
|
||||
event.content().add(placeholder, BorderLayout.CENTER);
|
||||
|
||||
// 我不想写这个了你们自己实现
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
public static void main(String[] args) {
|
||||
// 输出版本和作者信息
|
||||
logger.info("Application Version: {}", VERSIONS);
|
||||
logger.info("Authors: {}", String.join(", ", AUTHOR));
|
||||
|
||||
// 输出系统信息
|
||||
logger.info("Operating System: {}", SystemInfoUtil.getOSName());
|
||||
logger.info("OS Architecture: {}", SystemInfoUtil.getOSArch());
|
||||
logger.info("CPU: {}", SystemInfoUtil.getCPUInfo());
|
||||
logger.info("GPU: {}", SystemInfoUtil.getGPUInfo());
|
||||
|
||||
// 注册事件
|
||||
GlobalEventBus.EVENT_BUS.register(new Main());
|
||||
|
||||
// 设置系统外观
|
||||
try {
|
||||
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
||||
} catch (Exception ignored) {}
|
||||
} catch (Exception e) {
|
||||
logger.warn("Failed to load the system facade class", e);
|
||||
}
|
||||
|
||||
// 创建窗口
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
MainWindow ex = new MainWindow();
|
||||
int id = 0;
|
||||
MainWindow.ToolCategory debugCategory = new MainWindow.ToolCategory("调试工具",
|
||||
"debug/debug.png",
|
||||
"用于调试指定Windows工具的一个分类");
|
||||
JFrame loadingFrame = new JFrame("加载中...");
|
||||
loadingFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
|
||||
loadingFrame.setSize(400, 200);
|
||||
loadingFrame.setLocationRelativeTo(null);
|
||||
loadingFrame.setIconImage(LoadIcon.loadIcon("logo.png", 64).getImage());
|
||||
|
||||
debugCategory.addTool(new MainWindow.ToolItem("Frida注入工具", "debug/frida/frida_main.png",
|
||||
"使用frida注入目标进程的脚本程序 " +
|
||||
"\n作者:tzdwindows 7", ++id, new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
Window owner = SwingUtilities.windowForComponent((Component) e.getSource());
|
||||
FridaWindow fridaWindow = new FridaWindow(owner);
|
||||
fridaWindow.setVisible(true);
|
||||
JPanel loadingPanel = new JPanel(new BorderLayout());
|
||||
JProgressBar progressBar = new JProgressBar(0, 100);
|
||||
progressBar.setStringPainted(true);
|
||||
JLabel statusLabel = new JLabel("Initializing...", SwingConstants.CENTER);
|
||||
JLabel timeLabel = new JLabel("Time elapsed: 0s", SwingConstants.CENTER);
|
||||
JLabel logoLabel = new JLabel(LoadIcon.loadIcon("logo.png", 64));
|
||||
|
||||
loadingPanel.add(logoLabel, BorderLayout.NORTH);
|
||||
loadingPanel.add(progressBar, BorderLayout.CENTER);
|
||||
loadingPanel.add(statusLabel, BorderLayout.SOUTH);
|
||||
loadingPanel.add(timeLabel, BorderLayout.SOUTH);
|
||||
|
||||
loadingFrame.add(loadingPanel);
|
||||
loadingFrame.setVisible(true);
|
||||
|
||||
new Thread(() -> {
|
||||
long startTime = System.currentTimeMillis();
|
||||
int classifyTask = 0;
|
||||
|
||||
new Thread(() -> {
|
||||
while (completedTasks < totalTasks) {
|
||||
completedTasks++;
|
||||
final int progress = (int) ((completedTasks / (double) totalTasks) * 100);
|
||||
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
progressBar.setValue(progress);
|
||||
statusLabel.setText("Loading: " + progress + "%");
|
||||
long elapsedTime = (System.currentTimeMillis() - startTime) / 1000;
|
||||
timeLabel.setText("Time elapsed: " + elapsedTime + "s");
|
||||
});
|
||||
}
|
||||
}));
|
||||
|
||||
// 在后面注册你自己的项或是添加你自己的分类
|
||||
// ....
|
||||
|
||||
ex.addToolCategory(debugCategory);
|
||||
|
||||
MainWindow.ToolCategory aICategory = new MainWindow.ToolCategory("AI工具",
|
||||
"ai/ai.png",
|
||||
"人工智能/大语言模型");
|
||||
|
||||
aICategory.addTool(new MainWindow.ToolItem("本地AI执行工具", "ai/local/local_main.png",
|
||||
"在本机对开源大语言模型进行推理" +
|
||||
"\n作者:tzdwindows 7", ++id, new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
Window owner = SwingUtilities.windowForComponent((Component) e.getSource());
|
||||
LocalWindow dialog = new LocalWindow(owner);
|
||||
dialog.setVisible(true);
|
||||
});
|
||||
while (completedTasks < totalTasks) {
|
||||
try {
|
||||
if (classifyTask == 0){
|
||||
PluginLoader.loadPlugins();
|
||||
logger.info("Loaded plugins");
|
||||
classifyTask++;
|
||||
}
|
||||
// 非显示任务请添加在这添加
|
||||
// ....
|
||||
} catch (IOException e) {
|
||||
logger.error("Failed to load plugins", e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
ex.addToolCategory(aICategory);
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
loadingFrame.dispose();
|
||||
try {
|
||||
MainWindow ex = new MainWindow();
|
||||
int id = 0;
|
||||
MainWindow.ToolCategory debugCategory = new MainWindow.ToolCategory("调试工具",
|
||||
"debug/debug.png",
|
||||
"用于调试指定Windows工具的一个分类");
|
||||
|
||||
ex.initUI();
|
||||
ex.setVisible(true);
|
||||
});
|
||||
debugCategory.addTool(new MainWindow.ToolItem("Frida注入工具", "debug/frida/frida_main.png",
|
||||
"使用frida注入目标进程的脚本程序 " +
|
||||
"\n作者:tzdwindows 7", ++id, new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
Window owner = SwingUtilities.windowForComponent((Component) e.getSource());
|
||||
FridaWindow fridaWindow = new FridaWindow(owner);
|
||||
fridaWindow.setVisible(true);
|
||||
}
|
||||
}));
|
||||
|
||||
// 在后面注册你自己的项或是添加你自己的分类
|
||||
// ....
|
||||
|
||||
ex.addToolCategory(debugCategory);
|
||||
|
||||
MainWindow.ToolCategory aICategory = new MainWindow.ToolCategory("AI工具",
|
||||
"ai/ai.png",
|
||||
"人工智能/大语言模型");
|
||||
|
||||
aICategory.addTool(new MainWindow.ToolItem("本地AI执行工具", "ai/local/local_main.png",
|
||||
"在本机对开源大语言模型进行推理" +
|
||||
"\n作者:tzdwindows 7", ++id, new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
Window owner = SwingUtilities.windowForComponent((Component) e.getSource());
|
||||
LocalWindow dialog = new LocalWindow(owner);
|
||||
dialog.setVisible(true);
|
||||
}
|
||||
}));
|
||||
|
||||
ex.addToolCategory(aICategory);
|
||||
|
||||
ex.initUI();
|
||||
ex.setVisible(true);
|
||||
} catch (Exception e) {
|
||||
logger.error("There was a problem starting the main thread", e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.axis.innovators.box.gui;
|
||||
|
||||
import org.tzd.frida.windows.CallbackMessage;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.tzd.frida.windows.Frida;
|
||||
import org.tzd.frida.windows.FridaRunnable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
@@ -22,6 +22,7 @@ import java.util.List;
|
||||
* @author tzdwindows 7
|
||||
*/
|
||||
public class FridaWindow extends JDialog {
|
||||
private static final Logger logger = LogManager.getLogger(FridaWindow.class);
|
||||
private JTextArea scriptArea;
|
||||
private JTextArea logArea;
|
||||
private JTextField pidField;
|
||||
@@ -149,32 +150,40 @@ public class FridaWindow extends JDialog {
|
||||
|
||||
Frida frida = new Frida(script, pid);
|
||||
if (!isRepetition) {
|
||||
frida.run(() -> {
|
||||
// 执行注入操作
|
||||
}).execute(frida1 -> frida1.addCallbackMessage(message ->
|
||||
SwingUtilities.invokeLater(() ->
|
||||
logArea.append("[LOG] " + message + "\n")
|
||||
)
|
||||
)).start();
|
||||
try {
|
||||
frida.run(() -> {
|
||||
}).execute(frida1 -> frida1.addCallbackMessage(message ->
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
logger.info("[LOG] {}", message);
|
||||
logArea.append("[LOG] " + message + "\n");
|
||||
})
|
||||
)).start();
|
||||
} catch (Exception ex) {
|
||||
logger.error("Injection failure", ex);
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
isRepetition = true;
|
||||
} else {
|
||||
frida.run(() -> {}).execute(frida12 -> {}).start();
|
||||
try {
|
||||
frida.run(() -> {}).execute(frida12 -> {}).start();
|
||||
} catch (Exception ex) {
|
||||
logger.error("Injection failure", ex);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (NumberFormatException ex) {
|
||||
logger.error("无效的进程ID", ex);
|
||||
JOptionPane.showMessageDialog(this, "无效的进程ID", "错误", JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
||||
private void openProcessSelectionWindow(ActionEvent e) {
|
||||
// 打开一个窗口,显示所有进程的ID、名称和图标
|
||||
ProcessSelectionWindow selectionWindow = new ProcessSelectionWindow(this);
|
||||
selectionWindow.setVisible(true);
|
||||
}
|
||||
|
||||
// 选择进程的子窗口
|
||||
private static class ProcessSelectionWindow extends JDialog {
|
||||
private List<ProcessInfo> processList; // 存储所有进程信息
|
||||
private List<ProcessInfo> processList;
|
||||
private JTable table;
|
||||
|
||||
public ProcessSelectionWindow(Window owner) {
|
||||
@@ -215,7 +224,6 @@ public class FridaWindow extends JDialog {
|
||||
searchPanel.add(searchField, BorderLayout.CENTER);
|
||||
panel.add(searchPanel, BorderLayout.NORTH);
|
||||
|
||||
// 显示进程信息的表格
|
||||
String[] columns = {"进程名称", "进程ID"};
|
||||
Object[][] data = getTableData(processList);
|
||||
table = new JTable(data, columns);
|
||||
@@ -239,11 +247,11 @@ public class FridaWindow extends JDialog {
|
||||
private void filterProcesses(String query) {
|
||||
List<ProcessInfo> filteredList = new ArrayList<>();
|
||||
for (ProcessInfo process : processList) {
|
||||
if (process.getName().toLowerCase().contains(query.toLowerCase())) {
|
||||
if (process.name().toLowerCase().contains(query.toLowerCase())) {
|
||||
filteredList.add(process);
|
||||
}
|
||||
}
|
||||
// 更新表格数据
|
||||
|
||||
Object[][] filteredData = getTableData(filteredList);
|
||||
table.setModel(new DefaultTableModel(filteredData, new String[]{"进程名称", "进程ID"}));
|
||||
}
|
||||
@@ -252,15 +260,18 @@ public class FridaWindow extends JDialog {
|
||||
Object[][] data = new Object[processes.size()][2];
|
||||
for (int i = 0; i < processes.size(); i++) {
|
||||
ProcessInfo process = processes.get(i);
|
||||
data[i] = new Object[]{process.getName(), process.getPid()};
|
||||
data[i] = new Object[]{process.name(), process.pid()};
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行cmd命令获取所有进程信息
|
||||
* @return 进程信息列表
|
||||
*/
|
||||
private List<ProcessInfo> getProcesses() {
|
||||
List<ProcessInfo> processList = new ArrayList<>();
|
||||
try {
|
||||
// 执行cmd命令获取所有进程信息
|
||||
Process process = Runtime.getRuntime().exec("tasklist /fo csv /nh");
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||
String line;
|
||||
@@ -275,28 +286,11 @@ public class FridaWindow extends JDialog {
|
||||
}
|
||||
reader.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
logger.error("Failed to get process information ", e);
|
||||
}
|
||||
return processList;
|
||||
}
|
||||
}
|
||||
|
||||
// 存储进程信息的类
|
||||
private static class ProcessInfo {
|
||||
private long pid;
|
||||
private String name;
|
||||
|
||||
public ProcessInfo(long pid, String name) {
|
||||
this.pid = pid;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public long getPid() {
|
||||
return pid;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
private record ProcessInfo(long pid, String name) {}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package com.axis.innovators.box.gui;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
@@ -10,6 +13,7 @@ import java.net.URL;
|
||||
* @author tzdwindows 7
|
||||
*/
|
||||
public class LoadIcon {
|
||||
private static final Logger logger = LogManager.getLogger(LoadIcon.class);
|
||||
private static final String ICON_PATH = "/icons/";
|
||||
public static ImageIcon loadIcon(String filename, int size) {
|
||||
try {
|
||||
@@ -21,6 +25,7 @@ public class LoadIcon {
|
||||
Image image = new ImageIcon(imgUrl).getImage();
|
||||
return new ImageIcon(image.getScaledInstance(size, size, Image.SCALE_SMOOTH));
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed to load icon image path '{}'", filename, e);
|
||||
return createPlaceholderIcon(size);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.axis.innovators.box.gui;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.tzd.lm.LM;
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
@@ -8,24 +10,21 @@ import java.awt.event.ActionEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* 本地AI执行工具
|
||||
* @author tzdwindows 7
|
||||
*/
|
||||
public class LocalWindow extends JDialog {
|
||||
private static final Logger logger = LogManager.getLogger(LocalWindow.class);
|
||||
private final Color bgColor = new Color(45, 45, 48);
|
||||
private final Color textColor = new Color(240, 240, 240);
|
||||
private final Font mainFont = new Font("微软雅黑", Font.PLAIN, 14);
|
||||
private final Color bgColor1 = new Color(235, 241, 250);
|
||||
private final Color bgColor2 = new Color(255, 255, 255);
|
||||
private final Color userTextColor = new Color(0, 100, 200);
|
||||
private final Color aiTextColor = new Color(0, 150, 0); // AI消息绿色
|
||||
|
||||
private JTextArea chatArea;
|
||||
private JTextField inputField;
|
||||
private JButton sendButton;
|
||||
private JProgressBar progressBar;
|
||||
private JComboBox<String> contextBox;
|
||||
private final LinkedList<Long> contextHandles = new LinkedList<>();
|
||||
@@ -40,19 +39,7 @@ public class LocalWindow extends JDialog {
|
||||
}
|
||||
|
||||
private void initializeUI() {
|
||||
// 主面板设置
|
||||
JPanel mainPanel = new JPanel(new BorderLayout()) {
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
Graphics2D g2d = (Graphics2D) g;
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
GradientPaint gp = new GradientPaint(0, 0, bgColor1, getWidth(), getHeight(), bgColor2);
|
||||
g2d.setPaint(gp);
|
||||
g2d.fillRect(0, 0, getWidth(), getHeight());
|
||||
}
|
||||
};
|
||||
mainPanel.setBorder(new EmptyBorder(10, 10, 10, 10));
|
||||
JPanel mainPanel = getjPanel();
|
||||
|
||||
// 聊天区域
|
||||
chatArea = new JTextArea();
|
||||
@@ -88,6 +75,22 @@ public class LocalWindow extends JDialog {
|
||||
this.setLocationRelativeTo(getOwner());
|
||||
}
|
||||
|
||||
private JPanel getjPanel() {
|
||||
JPanel mainPanel = new JPanel(new BorderLayout()) {
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
Graphics2D g2d = (Graphics2D) g;
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
GradientPaint gp = new GradientPaint(0, 0, bgColor1, getWidth(), getHeight(), bgColor2);
|
||||
g2d.setPaint(gp);
|
||||
g2d.fillRect(0, 0, getWidth(), getHeight());
|
||||
}
|
||||
};
|
||||
mainPanel.setBorder(new EmptyBorder(10, 10, 10, 10));
|
||||
return mainPanel;
|
||||
}
|
||||
|
||||
private JToolBar createToolBar() {
|
||||
JToolBar toolBar = new JToolBar();
|
||||
toolBar.setFloatable(false);
|
||||
@@ -135,11 +138,10 @@ public class LocalWindow extends JDialog {
|
||||
inputField.setForeground(Color.black);
|
||||
inputField.setBackground(Color.white);
|
||||
|
||||
sendButton = new JButton("发送");
|
||||
JButton sendButton = new JButton("发送");
|
||||
styleButton(sendButton);
|
||||
sendButton.addActionListener(this::handleSendMessage);
|
||||
|
||||
// 温度调节
|
||||
tempSpinner = new JSpinner(new SpinnerNumberModel(0.8, 0.0, 1.0, 0.1));
|
||||
tempSpinner.setFont(mainFont);
|
||||
tempSpinner.setBackground(bgColor);
|
||||
@@ -177,6 +179,7 @@ public class LocalWindow extends JDialog {
|
||||
currentModelHandle = get();
|
||||
createNewContext();
|
||||
} catch (Exception ex) {
|
||||
logger.error("Model loading failed , loading location {}", LM.DEEP_SEEK ,ex);
|
||||
JOptionPane.showMessageDialog(LocalWindow.this, "模型加载失败");
|
||||
}
|
||||
progressBar.setVisible(false);
|
||||
@@ -192,7 +195,7 @@ public class LocalWindow extends JDialog {
|
||||
contextBox.setSelectedIndex(contextHandles.size()-1);
|
||||
contextBox.setBackground(Color.lightGray);
|
||||
contextBox.setForeground(Color.black);
|
||||
chatArea.setText(""); // 清除聊天区域内容
|
||||
chatArea.setText("");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,16 +222,26 @@ public class LocalWindow extends JDialog {
|
||||
protected void process(java.util.List<String> chunks) {
|
||||
chunks.forEach(msg -> appendAIMessage(msg));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void done() {
|
||||
try {
|
||||
String result = get();
|
||||
logger.info(result);
|
||||
} catch (Exception ex) {
|
||||
logger.error("SwingWorker execution error: ", ex);
|
||||
}
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
}
|
||||
|
||||
static boolean isTemporary = true;
|
||||
private final List<String> messages = new ArrayList<>();
|
||||
private void appendAIMessage(String message) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
if (isTemporary) {
|
||||
chatArea.append("【AI】\n");
|
||||
logger.info("【AI】");
|
||||
isTemporary = false;
|
||||
}
|
||||
// 处理Markdown语法
|
||||
@@ -237,27 +250,33 @@ public class LocalWindow extends JDialog {
|
||||
.replaceAll("</think>", "</think></fold>");
|
||||
chatArea.append(message2);
|
||||
chatArea.setCaretPosition(chatArea.getDocument().getLength());
|
||||
messages.add(message2);
|
||||
});
|
||||
}
|
||||
|
||||
private void appendMessage(String message) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
logger.info("\n【用户】\n{}", message);
|
||||
chatArea.append("\n【用户】\n" + message + "\n\n");
|
||||
chatArea.setCaretPosition(chatArea.getDocument().getLength());
|
||||
});
|
||||
}
|
||||
|
||||
private void saveConversation() {
|
||||
String content = chatArea.getText();
|
||||
//String content = chatArea.getText();
|
||||
// TODO: 调用保存实现
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
contextHandles.forEach(LM::llamaFreeContext);
|
||||
if (contextHandles.isEmpty()){
|
||||
logger.warn("No context to free");
|
||||
} else {
|
||||
contextHandles.forEach(LM::llamaFreeContext);
|
||||
}
|
||||
if (currentModelHandle != -1) {
|
||||
LM.llamaFreeModel(currentModelHandle);
|
||||
} else {
|
||||
logger.warn("Wrong model handle");
|
||||
}
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package com.axis.innovators.box.gui;
|
||||
|
||||
import com.axis.innovators.box.events.*;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.Timer;
|
||||
@@ -9,7 +11,6 @@ import javax.swing.plaf.basic.BasicScrollBarUI;
|
||||
import javax.swing.plaf.basic.BasicTabbedPaneUI;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.image.BufferedImage;
|
||||
@@ -23,6 +24,7 @@ import java.util.List;
|
||||
* @author tzdwindows 7
|
||||
*/
|
||||
public class MainWindow extends JFrame {
|
||||
private static final Logger logger = LogManager.getLogger(MainWindow.class);
|
||||
private final Map<JComponent, Float> cardScales = new HashMap<>();
|
||||
private final Map<JComponent, Integer> cardElevations = new HashMap<>();
|
||||
// 选项卡颜色
|
||||
@@ -81,7 +83,7 @@ public class MainWindow extends JFrame {
|
||||
|
||||
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
logger.error("Failed to load background image", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -271,11 +273,6 @@ public class MainWindow extends JFrame {
|
||||
JPanel content = new JPanel(new BorderLayout());
|
||||
content.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
|
||||
|
||||
//JLabel placeholder = new JLabel("设置功能开发中...", SwingConstants.CENTER);
|
||||
//placeholder.setFont(new Font("微软雅黑", Font.PLAIN, 24));
|
||||
//placeholder.setForeground(new Color(127, 140, 153));
|
||||
//content.add(placeholder, BorderLayout.CENTER);
|
||||
|
||||
GlobalEventBus.EVENT_BUS.post(new SettingsLoadEvents(dialog, content));
|
||||
|
||||
dialog.add(content);
|
||||
@@ -373,40 +370,6 @@ public class MainWindow extends JFrame {
|
||||
return card;
|
||||
}
|
||||
|
||||
private BufferedImage captureWindowImage(Window window) {
|
||||
try {
|
||||
Rectangle bounds = window.getBounds();
|
||||
BufferedImage capture = new Robot().createScreenCapture(bounds);
|
||||
return capture.getSubimage(0, 0, window.getWidth(), window.getHeight());
|
||||
} catch (AWTException e) {
|
||||
e.printStackTrace();
|
||||
return new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
|
||||
}
|
||||
}
|
||||
|
||||
private static JPanel getjPanel(BufferedImage[] blurredImage, Window window) {
|
||||
JPanel blurPanel = new JPanel() {
|
||||
private float currentOpacity = 1.0f;
|
||||
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
|
||||
if (blurredImage[0] != null) {
|
||||
Graphics2D g2d = (Graphics2D) g.create();
|
||||
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, currentOpacity));
|
||||
g2d.drawImage(blurredImage[0], 0, 0, null);
|
||||
g2d.dispose();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 面板属性设置
|
||||
blurPanel.setBounds(0, 0, window.getWidth(), window.getHeight());
|
||||
blurPanel.setOpaque(false);
|
||||
return blurPanel;
|
||||
}
|
||||
|
||||
|
||||
private String createToolTipHTML(ToolItem tool) {
|
||||
return "<html><body style='width: 300px; padding: 10px;'>" +
|
||||
@@ -415,40 +378,6 @@ public class MainWindow extends JFrame {
|
||||
"</body></html>";
|
||||
}
|
||||
|
||||
private void animateHover(JComponent component, float targetScale, int targetElevation) {
|
||||
final int ANIMATION_DURATION = 200;
|
||||
final float startScale = cardScales.getOrDefault(component, 1.0f);
|
||||
final int startElevation = cardElevations.getOrDefault(component, 2);
|
||||
|
||||
new Timer(10, new AbstractAction() {
|
||||
long startTime = -1;
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (startTime < 0) {
|
||||
startTime = System.currentTimeMillis();
|
||||
}
|
||||
long elapsed = System.currentTimeMillis() - startTime;
|
||||
float progress = Math.min(1.0f, elapsed / (float) ANIMATION_DURATION);
|
||||
|
||||
// 使用缓动函数实现平滑动画
|
||||
float easedProgress = (float) (1 - Math.pow(1 - progress, 3));
|
||||
|
||||
float currentScale = startScale + (targetScale - startScale) * easedProgress;
|
||||
int currentElevation = (int) (startElevation + (targetElevation - startElevation) * easedProgress);
|
||||
|
||||
cardScales.put(component, currentScale);
|
||||
cardElevations.put(component, currentElevation);
|
||||
|
||||
component.repaint();
|
||||
|
||||
if (progress >= 1.0f) {
|
||||
((Timer) e.getSource()).stop();
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
// 工具类别内部类
|
||||
public static class ToolCategory {
|
||||
private final String name;
|
||||
@@ -504,30 +433,6 @@ public class MainWindow extends JFrame {
|
||||
* @param action 工具的点击事件
|
||||
*/
|
||||
public record ToolItem(String title, String icon, String description, int id, Action action) {
|
||||
private static JPanel getjPanel() {
|
||||
JPanel content = new JPanel() {
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
Graphics2D g2d = (Graphics2D) g;
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
|
||||
// 渐变背景
|
||||
GradientPaint gp = new GradientPaint(
|
||||
0, 0, new Color(245, 247, 250),
|
||||
getWidth(), getHeight(), new Color(255, 255, 255)
|
||||
);
|
||||
g2d.setPaint(gp);
|
||||
g2d.fillRoundRect(0, 0, getWidth(), getHeight(), 20, 20);
|
||||
|
||||
// 边框阴影
|
||||
g2d.setColor(new Color(0, 0, 0, 20));
|
||||
g2d.drawRoundRect(0, 0, getWidth() - 1, getHeight() - 1, 20, 20);
|
||||
}
|
||||
};
|
||||
content.setLayout(new BorderLayout(20, 20));
|
||||
content.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
|
||||
return content;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return title;
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.axis.innovators.box.plugins;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author tzdwindows 7
|
||||
*/
|
||||
public class PluginDescriptor {
|
||||
private String id;
|
||||
private String name;
|
||||
private List<String> supportedVersions;
|
||||
private String icon;
|
||||
private String description;
|
||||
private Object instance;
|
||||
|
||||
// Getters and Setters
|
||||
public String getId() { return id; }
|
||||
public void setId(String id) { this.id = id; }
|
||||
public String getName() { return name; }
|
||||
public void setName(String name) { this.name = name; }
|
||||
public List<String> getSupportedVersions() { return supportedVersions; }
|
||||
public void setSupportedVersions(List<String> supportedVersions) { this.supportedVersions = supportedVersions; }
|
||||
public String getIcon() { return icon; }
|
||||
public void setIcon(String icon) { this.icon = icon; }
|
||||
public String getDescription() { return description; }
|
||||
public void setDescription(String description) { this.description = description; }
|
||||
public Object getInstance() { return instance; }
|
||||
public void setInstance(Object instance) { this.instance = instance; }
|
||||
}
|
||||
148
src/main/java/com/axis/innovators/box/plugins/PluginLoader.java
Normal file
148
src/main/java/com/axis/innovators/box/plugins/PluginLoader.java
Normal file
@@ -0,0 +1,148 @@
|
||||
package com.axis.innovators.box.plugins;
|
||||
|
||||
import com.axis.innovators.box.Main;
|
||||
import com.axis.innovators.box.tools.FolderCreator;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.util.*;
|
||||
import java.util.jar.*;
|
||||
|
||||
/**
|
||||
* 加载插件的系统
|
||||
* @author tzdwindows 7
|
||||
*/
|
||||
public class PluginLoader {
|
||||
private static final Logger logger = LogManager.getLogger(PluginLoader.class);
|
||||
public static final String PLUGIN_PATH = FolderCreator.getPluginFolder();
|
||||
private static final List<PluginDescriptor> loadedPlugins = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* 加载插件
|
||||
* @throws IOException 插件加载失败
|
||||
*/
|
||||
public static void loadPlugins() throws IOException {
|
||||
File pluginDir = new File(PLUGIN_PATH);
|
||||
File[] jars = pluginDir.listFiles((dir, name) -> name.toLowerCase().endsWith(".jar"));
|
||||
|
||||
if (jars == null) {
|
||||
return;
|
||||
}
|
||||
Main.totalTasks = jars.length;
|
||||
for (int i = 0; i < jars.length; i++) {
|
||||
processJarFile(jars[i]);
|
||||
Main.completedTasks = i;
|
||||
}
|
||||
}
|
||||
|
||||
private static void processJarFile(File jarFile) throws IOException {
|
||||
try (JarFile jar = new JarFile(jarFile)) {
|
||||
JarEntry pluginFile = jar.getJarEntry("plug-in.box");
|
||||
if (pluginFile != null) {
|
||||
processWithManifest(jar, pluginFile, jarFile);
|
||||
} else {
|
||||
processWithAnnotations(jar, jarFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void processWithManifest(JarFile jar, JarEntry entry, File jarFile) {
|
||||
Properties props = new Properties();
|
||||
try (InputStream is = jar.getInputStream(entry)) {
|
||||
props.load(is);
|
||||
} catch (IOException e) {
|
||||
logger.error("Failed to load plugin from jar: {}", jarFile.getName(), e);
|
||||
return;
|
||||
}
|
||||
|
||||
PluginDescriptor descriptor = new PluginDescriptor();
|
||||
descriptor.setId(props.getProperty("id"));
|
||||
descriptor.setName(props.getProperty("name"));
|
||||
descriptor.setDescription(props.getProperty("description"));
|
||||
descriptor.setIcon(props.getProperty("icon"));
|
||||
descriptor.setSupportedVersions(
|
||||
Arrays.asList(props.getProperty("supportedVersions").split(","))
|
||||
);
|
||||
|
||||
loadMainClass(props.getProperty("mainClass"), jarFile, descriptor);
|
||||
if (descriptor.getInstance() != null) {
|
||||
loadedPlugins.add(descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
private static void processWithAnnotations(JarFile jar, File jarFile) {
|
||||
URLClassLoader classLoader = createClassLoader(jarFile);
|
||||
Enumeration<JarEntry> entries = jar.entries();
|
||||
|
||||
while (entries.hasMoreElements()) {
|
||||
JarEntry entry = entries.nextElement();
|
||||
if (entry.getName().endsWith(".class")) {
|
||||
processClassEntry(entry, classLoader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static URLClassLoader createClassLoader(File jarFile) {
|
||||
try {
|
||||
return new URLClassLoader(
|
||||
new URL[]{jarFile.toURI().toURL()},
|
||||
PluginLoader.class.getClassLoader()
|
||||
);
|
||||
} catch (MalformedURLException e) {
|
||||
logger.error("Error creating URLClassLoader", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void processClassEntry(JarEntry entry, URLClassLoader classLoader) {
|
||||
String className = entry.getName()
|
||||
.replace("/", ".")
|
||||
.replace(".class", "");
|
||||
|
||||
try {
|
||||
Class<?> clazz = classLoader.loadClass(className);
|
||||
PluginMeta meta = clazz.getAnnotation(PluginMeta.class);
|
||||
if (meta != null) {
|
||||
PluginDescriptor descriptor = new PluginDescriptor();
|
||||
descriptor.setId(meta.id());
|
||||
descriptor.setName(meta.name());
|
||||
descriptor.setDescription(meta.description());
|
||||
descriptor.setIcon(meta.icon());
|
||||
descriptor.setSupportedVersions(Arrays.asList(meta.supportedVersions()));
|
||||
|
||||
try {
|
||||
Object instance = clazz.getDeclaredConstructor().newInstance();
|
||||
descriptor.setInstance(instance);
|
||||
loadedPlugins.add(descriptor);
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed to instantiate plugin class: {}", className, e);
|
||||
}
|
||||
}
|
||||
} catch (ClassNotFoundException | NoClassDefFoundError e) {
|
||||
logger.error("Error loading class: {}", className, e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void loadMainClass(String mainClassName, File jarFile, PluginDescriptor descriptor) {
|
||||
if (mainClassName == null || mainClassName.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try (URLClassLoader classLoader = new URLClassLoader(
|
||||
new URL[]{jarFile.toURI().toURL()},
|
||||
PluginLoader.class.getClassLoader())
|
||||
) {
|
||||
Class<?> mainClass = classLoader.loadClass(mainClassName);
|
||||
Object instance = mainClass.getDeclaredConstructor().newInstance();
|
||||
descriptor.setInstance(instance);
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed to load main class: {}", mainClassName, e);
|
||||
}
|
||||
}
|
||||
|
||||
public static List<PluginDescriptor> getLoadedPlugins() {
|
||||
return Collections.unmodifiableList(loadedPlugins);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.axis.innovators.box.plugins;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tzdwindows 7
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
public @interface PluginMeta {
|
||||
String id();
|
||||
String name();
|
||||
String[] supportedVersions();
|
||||
String description();
|
||||
String icon() default "";
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
package com.axis.innovators.box.tools;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
@@ -7,14 +10,24 @@ import java.io.File;
|
||||
* @author tzdwindows 7
|
||||
*/
|
||||
public class FolderCreator {
|
||||
|
||||
private static final Logger logger = LogManager.getLogger(FolderCreator.class);
|
||||
public static final String LIBRARY_NAME = "library";
|
||||
public static final String MODEL_PATH = "model";
|
||||
public static final String PLUGIN_PATH = "plug-in";
|
||||
|
||||
public static String getPluginFolder() {
|
||||
String folder = createFolder(PLUGIN_PATH);
|
||||
if (folder == null) {
|
||||
logger.error("Plugin folder creation failed, please use administrator privileges to execute this procedure");
|
||||
return null;
|
||||
}
|
||||
return folder;
|
||||
}
|
||||
|
||||
public static String getModelFolder() {
|
||||
String folder = createFolder(MODEL_PATH);
|
||||
if (folder == null) {
|
||||
System.out.println("Model folder creation failure");
|
||||
logger.error("Model folder creation failure, please use administrator privileges to execute this procedure");
|
||||
return null;
|
||||
}
|
||||
return folder;
|
||||
@@ -23,7 +36,7 @@ public class FolderCreator {
|
||||
public static String getLibraryFolder() {
|
||||
String folder = createFolder(LIBRARY_NAME);
|
||||
if (folder == null) {
|
||||
System.out.println("Library folder creation failure");
|
||||
logger.error("Library folder creation failed, please use administrator privileges to execute this procedure");
|
||||
return null;
|
||||
}
|
||||
return folder;
|
||||
@@ -39,7 +52,7 @@ public class FolderCreator {
|
||||
File folder = new File(jarDir, folderName);
|
||||
if (!folder.exists()) {
|
||||
if (!folder.mkdir()) {
|
||||
System.out.println("Folder creation failure");
|
||||
logger.error("Folder creation failure");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
package com.axis.innovators.box.tools;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* 获取用户计算机信息
|
||||
* @author tzdwindows 7
|
||||
*/
|
||||
public class SystemInfoUtil {
|
||||
private static final Logger logger = LogManager.getLogger(SystemInfoUtil.class);
|
||||
|
||||
/**
|
||||
* 获取操作系统架构
|
||||
*/
|
||||
public static String getOSArch() {
|
||||
return System.getProperty("os.arch");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取操作系统名称
|
||||
*/
|
||||
public static String getOSName() {
|
||||
return System.getProperty("os.name");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 CPU 信息
|
||||
*/
|
||||
public static String getCPUInfo() {
|
||||
try {
|
||||
if (System.getProperty("os.name").toLowerCase().contains("win")) {
|
||||
// Windows 系统
|
||||
Process process = Runtime.getRuntime().exec("wmic cpu get name");
|
||||
return getString(process);
|
||||
} else if (System.getProperty("os.name").toLowerCase().contains("linux")) {
|
||||
// Linux 系统
|
||||
Process process = Runtime.getRuntime().exec("lscpu");
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
if (line.contains("Model name")) {
|
||||
return line.split(":")[1].trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed to get CPU info", e);
|
||||
}
|
||||
return "Unknown CPU";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 GPU 信息
|
||||
*/
|
||||
public static String getGPUInfo() {
|
||||
try {
|
||||
if (System.getProperty("os.name").toLowerCase().contains("win")) {
|
||||
// Windows 系统
|
||||
Process process = Runtime.getRuntime().exec("wmic path win32_videocontroller get name");
|
||||
return getString(process);
|
||||
} else if (System.getProperty("os.name").toLowerCase().contains("linux")) {
|
||||
// Linux 系统
|
||||
Process process = Runtime.getRuntime().exec("lspci | grep VGA");
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||
String line = reader.readLine();
|
||||
if (line != null) {
|
||||
return line.split(":")[2].trim();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed to get GPU info", e);
|
||||
}
|
||||
return "Unknown GPU";
|
||||
}
|
||||
|
||||
private static String getString(Process process) throws IOException {
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||
String line;
|
||||
List<String> gpuInfo = new ArrayList<>();
|
||||
while ((line = reader.readLine()) != null) {
|
||||
if (!line.trim().isEmpty() && !line.contains("Name")) {
|
||||
gpuInfo.add(line.trim());
|
||||
}
|
||||
}
|
||||
return String.join(", ", gpuInfo);
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,8 @@ package org.tzd.lm;
|
||||
|
||||
import com.axis.innovators.box.tools.FolderCreator;
|
||||
import com.axis.innovators.box.tools.LibraryLoad;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
/**
|
||||
* LM推理类
|
||||
@@ -10,21 +12,32 @@ import com.axis.innovators.box.tools.LibraryLoad;
|
||||
public class LM {
|
||||
public static boolean CUDA = true;
|
||||
public final static String DEEP_SEEK = FolderCreator.getModelFolder() + "\\DeepSeek-R1-Distill-Qwen-1.5B-Q8_0.gguf";
|
||||
private static final Logger logger = LogManager.getLogger(LM.class);
|
||||
|
||||
static {
|
||||
if (!CUDA) {
|
||||
logger.warn("The cpu will be used for inference");
|
||||
LibraryLoad.loadLibrary("cpu/ggml-base");
|
||||
LibraryLoad.loadLibrary("cpu/ggml-cpu");
|
||||
LibraryLoad.loadLibrary("cpu/ggml");
|
||||
LibraryLoad.loadLibrary("cpu/llama");
|
||||
} else {
|
||||
LibraryLoad.loadLibrary("cuda/ggml-base");
|
||||
LibraryLoad.loadLibrary("cuda/ggml-cpu");
|
||||
LibraryLoad.loadLibrary("cuda/ggml-rpc");
|
||||
// cuda版本 cuda-cu12.4-x64(确保你有)
|
||||
LibraryLoad.loadLibrary("cuda/ggml-cuda");
|
||||
LibraryLoad.loadLibrary("cuda/ggml");
|
||||
LibraryLoad.loadLibrary("cuda/llama");
|
||||
try {
|
||||
LibraryLoad.loadLibrary("cuda/ggml-base");
|
||||
LibraryLoad.loadLibrary("cuda/ggml-cpu");
|
||||
LibraryLoad.loadLibrary("cuda/ggml-rpc");
|
||||
// cuda版本 cuda-cu12.4-x64(确保你有)
|
||||
LibraryLoad.loadLibrary("cuda/ggml-cuda");
|
||||
LibraryLoad.loadLibrary("cuda/ggml");
|
||||
LibraryLoad.loadLibrary("cuda/llama");
|
||||
} catch (Exception e) {
|
||||
logger.error("Wrong cuda Settings", e);
|
||||
logger.warn("The cuda library could not be loaded, the cpu will be used for inference");
|
||||
LibraryLoad.loadLibrary("cpu/ggml-base");
|
||||
LibraryLoad.loadLibrary("cpu/ggml-cpu");
|
||||
LibraryLoad.loadLibrary("cpu/ggml");
|
||||
LibraryLoad.loadLibrary("cpu/llama");
|
||||
}
|
||||
}
|
||||
LibraryLoad.loadLibrary("LM");
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
/**
|
||||
* 使用AI接口获取回复
|
||||
* @author tzdwindows 7
|
||||
*/
|
||||
public class LMApi {
|
||||
|
||||
45
src/main/resources/log4j2.xml
Normal file
45
src/main/resources/log4j2.xml
Normal file
@@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Configuration status="WARN">
|
||||
<Appenders>
|
||||
<!-- 固定日志文件(按时间和大小滚动) -->
|
||||
<RollingFile name="MainFileAppender"
|
||||
fileName="logs/app.log"
|
||||
filePattern="logs/app-%d{yyyy-MM-dd}-%i.log">
|
||||
<PatternLayout>
|
||||
<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</Pattern>
|
||||
</PatternLayout>
|
||||
<Policies>
|
||||
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
|
||||
<SizeBasedTriggeringPolicy size="10 MB"/>
|
||||
</Policies>
|
||||
<DefaultRolloverStrategy max="7"/>
|
||||
</RollingFile>
|
||||
|
||||
<!-- 每次运行独立的日志文件(带时间和PID) -->
|
||||
<RollingFile name="SessionFileAppender"
|
||||
fileName="logs/app-${date:yyyy-MM-dd_HH-mm-ss}.log"
|
||||
filePattern="logs/app-%d{yyyy-MM-dd}-%i.log"
|
||||
immediateFlush="true"
|
||||
createOnDemand="false">
|
||||
<PatternLayout>
|
||||
<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</Pattern>
|
||||
</PatternLayout>
|
||||
<Policies>
|
||||
<OnStartupTriggeringPolicy minSize="0"/>
|
||||
</Policies>
|
||||
</RollingFile>
|
||||
|
||||
<Console name="Console" target="SYSTEM_OUT">
|
||||
<PatternLayout pattern="[%t] [%d{yyyy-MM-dd HH:mm:ss}] [%-5level] %msg%n%throwable"/>
|
||||
</Console>
|
||||
</Appenders>
|
||||
|
||||
<Loggers>
|
||||
<Root level="debug">
|
||||
<!-- 同时输出到控制台和两个文件 -->
|
||||
<AppenderRef ref="Console"/>
|
||||
<AppenderRef ref="MainFileAppender"/>
|
||||
<AppenderRef ref="SessionFileAppender"/>
|
||||
</Root>
|
||||
</Loggers>
|
||||
</Configuration>
|
||||
Reference in New Issue
Block a user