feat(register): 重构工具注册逻辑并添加设置功能

- 重新设计了工具分类和工具项的注册流程
- 增加了插件管理和基础设置功能- 添加了主题颜色和字体选择功能
- 优化了CUDA设置和AI推理库加载逻辑
- 新增了ToolsRegistrationError异常类
This commit is contained in:
tzdwindows 7
2025-02-11 22:14:09 +08:00
parent e027bbe791
commit 3049ceb9f9
6 changed files with 306 additions and 49 deletions

View File

@@ -5,16 +5,21 @@ import com.axis.innovators.box.events.SettingsLoadEvents;
import com.axis.innovators.box.events.StartupEvent;
import com.axis.innovators.box.events.SubscribeEvent;
import com.axis.innovators.box.gui.*;
import com.axis.innovators.box.plugins.PluginDescriptor;
import com.axis.innovators.box.plugins.PluginLoader;
import com.axis.innovators.box.register.RegistrationTool;
import com.axis.innovators.box.tools.LibraryLoad;
import com.axis.innovators.box.tools.SystemInfoUtil;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.tzd.lm.LM;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.util.Enumeration;
import java.util.List;
/**
* 主类
@@ -46,6 +51,7 @@ public class Main {
static {
try {
LibraryLoad.loadLibrary("FridaNative");
LM.loadLibrary(LM.CUDA);
} catch (Exception e) {
logger.error("Failed to load the 'FridaNative' library", e);
throw new RuntimeException(e);
@@ -97,10 +103,202 @@ public class Main {
@SubscribeEvent
public void onSettingsLoad(SettingsLoadEvents event) {
JLabel placeholder = new JLabel("设置功能开发中...", SwingConstants.CENTER);
placeholder.setFont(new Font("微软雅黑", Font.PLAIN, 24));
placeholder.setForeground(new Color(127, 140, 153));
event.content().add(placeholder, BorderLayout.CENTER);
JTabbedPane tabbedPane = new JTabbedPane();
JPanel pluginPanel = createPluginSettingsPanel();
tabbedPane.addTab("插件", null, pluginPanel, "插件管理");
JPanel generalPanel = createGeneralSettingsPanel();
tabbedPane.addTab("基础设置", null, generalPanel, "外观设置");
JPanel aboutPanel = createAboutPanel();
tabbedPane.addTab("关于", null, aboutPanel, "版本信息");
event.content().add(tabbedPane, BorderLayout.CENTER);
}
private JPanel createAboutPanel() {
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
JTextArea infoArea = new JTextArea();
infoArea.setEditable(false);
infoArea.setLineWrap(true);
infoArea.setWrapStyleWord(true);
infoArea.append("软件版本: " + Main.VERSIONS + "\n\n");
infoArea.append("开发作者:\n");
for (String author : Main.AUTHOR) {
infoArea.append("" + author + "\n");
}
panel.add(new JScrollPane(infoArea), BorderLayout.CENTER);
return panel;
}
// 字体选择器内部类
private static class FontChooser extends JPanel {
private final JComboBox<String> fontFamilyCombo;
private final JSpinner fontSizeSpinner;
public FontChooser(Font currentFont) {
setLayout(new GridLayout(2, 2, 5, 5));
// 字体族选择
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
String[] fontFamilies = ge.getAvailableFontFamilyNames();
fontFamilyCombo = new JComboBox<>(fontFamilies);
fontFamilyCombo.setSelectedItem(currentFont.getFamily());
// 字体大小选择
SpinnerNumberModel sizeModel = new SpinnerNumberModel(
currentFont.getSize(), 8, 48, 1
);
fontSizeSpinner = new JSpinner(sizeModel);
add(new JLabel("字体:"));
add(fontFamilyCombo);
add(new JLabel("大小:"));
add(fontSizeSpinner);
}
public Font getSelectedFont() {
return new Font(
(String) fontFamilyCombo.getSelectedItem(),
Font.PLAIN,
(Integer) fontSizeSpinner.getValue()
);
}
}
// 应用主题颜色
private void applyThemeColor(Color color) {
// 更新全局颜色设置
UIManager.put("Panel.background", color);
UIManager.put("TabbedPane.background", color);
// 更新现有界面
SwingUtilities.updateComponentTreeUI(Main.getMain().getMainWindow());
}
private JPanel createPluginSettingsPanel() {
JPanel panel = new JPanel(new BorderLayout());
// 表格列配置
String[] columns = {"插件名称", "版本支持", "描述"};
DefaultTableModel model = new DefaultTableModel(columns, 0) {
@Override
public boolean isCellEditable(int row, int column) {
return false; // 禁止编辑
}
};
// 从PluginLoader获取插件数据
List<PluginDescriptor> plugins = PluginLoader.getLoadedPlugins();
for (PluginDescriptor plugin : plugins) {
model.addRow(new Object[]{
plugin.getName(),
String.join(", ", plugin.getSupportedVersions()),
plugin.getDescription()
});
}
JTable table = new JTable(model);
table.setRowHeight(30);
table.getTableHeader().setFont(new Font("微软雅黑", Font.BOLD, 14));
// 添加滚动面板
JScrollPane scrollPane = new JScrollPane(table);
scrollPane.setBorder(BorderFactory.createTitledBorder("已加载插件列表"));
panel.add(scrollPane, BorderLayout.CENTER);
return panel;
}
private JPanel createGeneralSettingsPanel() {
JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(5, 5, 5, 5);
gbc.anchor = GridBagConstraints.WEST;
// 颜色选择组件
gbc.gridx = 0;
gbc.gridy = 0;
panel.add(new JLabel("界面主题颜色:"), gbc);
JButton colorBtn = new JButton("选择颜色");
colorBtn.addActionListener(e -> {
Color color = JColorChooser.showDialog(panel, "选择主题颜色", Color.WHITE);
if (color != null) {
applyThemeColor(color);
}
});
gbc.gridx = 1;
panel.add(colorBtn, gbc);
// 字体选择组件
gbc.gridy++;
gbc.gridx = 0;
panel.add(new JLabel("界面字体:"), gbc);
JButton fontBtn = new JButton("选择字体");
fontBtn.addActionListener(e -> {
Font currentFont = UIManager.getFont("Label.font");
FontChooser fontChooser = new FontChooser(currentFont);
int result = JOptionPane.showConfirmDialog(
panel,
fontChooser,
"选择字体",
JOptionPane.OK_CANCEL_OPTION
);
if (result == JOptionPane.OK_OPTION) {
applyUIFont(fontChooser.getSelectedFont());
}
});
gbc.gridx = 1;
panel.add(fontBtn, gbc);
// 添加CUDA选项
gbc.gridy++;
gbc.gridx = 0;
panel.add(new JLabel("AI推理时使用CUDA"), gbc);
JCheckBox cudaCheckBox = new JCheckBox("启用CUDA加速", LM.CUDA);
cudaCheckBox.addActionListener(e -> {
boolean useCUDA = cudaCheckBox.isSelected();
LM.CUDA = useCUDA;
logger.info("CUDA加速设置已更新: " + (useCUDA ? "启用" : "禁用"));
try {
LM.loadLibrary(useCUDA);
logger.info("AI推理库已重新加载");
} catch (Exception ex) {
logger.error("无法重新加载AI推理库", ex);
JOptionPane.showMessageDialog(panel, "无法重新加载AI推理库请检查CUDA环境", "错误", JOptionPane.ERROR_MESSAGE);
}
});
gbc.gridx = 1;
panel.add(cudaCheckBox, gbc);
return panel;
}
// 应用全局字体
private void applyUIFont(Font font) {
Enumeration<Object> keys = UIManager.getLookAndFeelDefaults().keys();
while (keys.hasMoreElements()) {
Object key = keys.nextElement();
Object value = UIManager.get(key);
if (value instanceof Font) {
Font derived = font.deriveFont(((Font)value).getStyle());
UIManager.put(key, derived);
}
}
// 更新所有窗口
for (Window window : Window.getWindows()) {
SwingUtilities.updateComponentTreeUI(window);
}
}
public static void main(String[] args) {
@@ -146,42 +344,6 @@ public class Main {
}
public void runWindow() {
int id = 0;
MainWindow.ToolCategory debugCategory = new MainWindow.ToolCategory("调试工具",
"debug/debug.png",
"用于调试指定Windows工具的一个分类");
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);
// 主任务2加载工具栏
progressBarManager.updateMainProgress(++completedTasks);
if (!registrationTool.getToolCategories().isEmpty()) {

View File

@@ -396,6 +396,7 @@ public class MainWindow extends JFrame {
private final String icon;
private final ImageIcon iconImage;
private final String description;
private final UUID id = UUID.randomUUID();
private final List<ToolItem> tools = new ArrayList<>();
/**
@@ -445,6 +446,10 @@ public class MainWindow extends JFrame {
public ImageIcon getIconImage() {
return iconImage;
}
public UUID getId() {
return id;
}
}
// 工具项数据类

View File

@@ -6,8 +6,6 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.*;
import java.util.*;
import java.util.jar.*;

View File

@@ -1,12 +1,18 @@
package com.axis.innovators.box.register;
import com.axis.innovators.box.Main;
import com.axis.innovators.box.gui.FridaWindow;
import com.axis.innovators.box.gui.LocalWindow;
import com.axis.innovators.box.gui.MainWindow;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
/**
* 负责注册Registration项限定时机在执行.run之前可设置
@@ -16,23 +22,100 @@ public class RegistrationTool {
private static final Logger logger = LogManager.getLogger(RegistrationTool.class);
private final List<MainWindow.ToolCategory> toolCategories = new ArrayList<>();
private final Main main;
private final List<UUID> uuidList = new ArrayList<>();
private final List<String> registeredNameList = new ArrayList<>();
public RegistrationTool(Main mainWindow){
public RegistrationTool(Main mainWindow) {
this.main = mainWindow;
int id = 0;
MainWindow.ToolCategory debugCategory = new MainWindow.ToolCategory("调试工具",
"debug/debug.png",
"用于调试指定Windows工具的一个分类");
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);
}
}));
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);
}
}));
addToolCategory(debugCategory, "system:debugTools");
addToolCategory(aICategory,"system:fridaTools");
}
/**
* 注册ToolCategory
* @param toolCategory ToolCategory
*/
public void addToolCategory(MainWindow.ToolCategory toolCategory){
public void addToolCategory(MainWindow.ToolCategory toolCategory,
String registeredName) {
if (!main.isWindow()) {
if (registeredNameList.contains(registeredName)) {
throw new ToolsRegistrationError(registeredName + " duplicate registered names");
}
uuidList.add(toolCategory.getId());
registeredNameList.add(registeredName);
toolCategories.add(toolCategory);
} else {
logger.warn("Wrong time to add tools");
}
}
/**
* 根据UUID获取ToolCategory
* @param id UUID
* @return ToolCategory对象
*/
public MainWindow.ToolCategory getToolCategory(UUID id) {
if (!main.isWindow()) {
for (MainWindow.ToolCategory toolCategory : toolCategories) {
if (toolCategory.getId().equals(id)) {
return toolCategory;
}
}
} else {
logger.warn("Wrong time to operation tools");
}
return null;
}
/**
* 根据注册名获取UUID
* @param registeredName 注册名
* @return UUID
*/
public UUID getUUID(String registeredName){
if (!main.isWindow()) {
for (int i = 0; i < registeredNameList.size(); i++) {
if (registeredNameList.get(i).equals(registeredName)) {
return uuidList.get(i);
}
}
} else {
logger.warn("Wrong time to operation tools");
}
return null;
}
public List<MainWindow.ToolCategory> getToolCategories() {
return toolCategories;
}

View File

@@ -0,0 +1,13 @@
package com.axis.innovators.box.register;
/**
* 当工具注册失败时抛出此错误
* @author tzdwindows 7
*/
public class ToolsRegistrationError extends Error{
public ToolsRegistrationError(String message) {
super(message);
}
}

View File

@@ -14,11 +14,7 @@ public class LM {
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 {
loadLibrary(CUDA);
}
private static void loadLibrary(boolean cuda){
public static void loadLibrary(boolean cuda){
if (!cuda) {
logger.warn("The cpu will be used for inference");
try {