feat(i18n): 添加多语言支持并优化用户界面

- 新增 LanguageManager 类实现语言管理功能
- 在 FridaWindow 中添加多语言支持
- 优化 LoadIcon 类的图片加载逻辑- 更新 BoxClassLoader 和 AxisInnovatorsBox 类以支持新功能- 添加 FolderCleaner 工具类用于清理日志文件
- 更新构建配置,添加新的依赖项
This commit is contained in:
tzdwindows 7
2025-02-14 09:45:11 +08:00
parent 3049ceb9f9
commit 97b071ece8
31 changed files with 2407 additions and 598 deletions

View File

@@ -37,6 +37,13 @@ dependencies {
implementation 'org.ow2.asm:asm-analysis:7.1'
implementation 'org.ow2.asm:asm-util:7.0'
implementation 'org.ow2.asm:asm-tree:7.1'
implementation 'org.jsoup:jsoup:1.17.2'
implementation 'com.google.code.gson:gson:2.8.9'
implementation 'com.formdev:flatlaf:0.26'
implementation 'commons-io:commons-io:2.11.0'
}
// 分离依赖项到 libs 目录

View File

@@ -0,0 +1,99 @@
default_theme.system.topicName=Default Theme
default_theme.default.tip=Default theme
metal_theme.system.topicName=Metal Style
metal_theme.default.tip=Metal style
motif_theme.system.topicName=Motif Style
motif_theme.default.tip=Motif style
flatLightLaf_theme.system.topicName=flatLightLaf Style
flatLightLaf_theme.default.tip=flatLightLaf style
mainWindow.title=Axis Creation Toolbox v1.0
mainWindow.title.2=Axis Creation Toolbox
mainWindow.settings.title=System Settings
andShow.title=Program Crash Report
andShow.title.2=<html><h2 style='color: #D32F2F;'>A serious error occurred in the program</h2></html>
andShow.title.3=<html><h3 style='color: #FF0000;'>Please report it to us!</h3></html>
andShow.pluginInfo.title==== Loaded Plugins ===
andShow.pluginInfo.title.1=Plugin Name:
andShow.pluginInfo.title.2=Plugin Description:
andShow.pluginInfo.title.3=Supported Versions:
andShow.pluginInfo.exportButton=Export Report
andShow.pluginInfo.closeButton=Close
andShow.pluginInfo.writer=The report has been saved to:
andShow.pluginInfo.writer.title=Export Successful
andShow.pluginInfo.writer.error=Export Failed:
andShow.pluginInfo.error.writer.title=Error
progressBarManager.title=Loading...
fridaWindow.title=Frida Injection Tool
fridaWindow.pidField=Enter Process PID
fridaWindow.browseButton=Select Process
fridaWindow.panel=Script Editor
fridaWindow.injectButton=Inject Script
fridaWindow.panel.log=Log Output
fridaWindow.processSelectionWindow=Select Process
fridaWindow.processSelectionWindow.search=Search Process
fridaWindow.processSelectionWindow.columns.1=Process Name
fridaWindow.processSelectionWindow.columns.2=Process ID
fridaWindow.processSelectionWindow.selectButton=Select
localWindow.newBtn=New Conversation
localWindow.saveBtn=Save Record
localWindow.cudaCheck=Enable CUDA
localWindow.searchBtn=Start Search
localWindow.searchBtn.1=Close Search
localWindow.searchBtn.appendMessage=Search functionality is enabled
localWindow.searchBtn.appendMessage.1=Search functionality is disabled
localWindow.sendButton=Send
localWindow.prompt.system=You are a helpful AI assistant. Please respond to user questions in a friendly and natural tone. Users may provide search results, and you should integrate those results into your answers.
localWindow.prompt.system.2=You are a search-focused assistant. Users will provide links, summaries, titles, and scraped content, and your job is to output the most relevant content to the user's question.
localWindow.prompt.name=[User]
settings.1.title=Plugins
settings.2.title=Basic Settings
settings.3.title=About
settings.4.title=Themes
settings.1.tip=Plugin Management
settings.2.tip=Appearance Settings
settings.3.tip=Version Information
settings.4.tip=Theme Management
settings.1.columns.1=Plugin Name
settings.1.columns.2=Supported Versions
settings.1.columns.3=Description
settings.1.scrollPane=Loaded Plugin List
settings.2.color=Interface Theme Color:
settings.2.colorBtn=Select Color
settings.2.colorBtn.color=Select Theme Color
settings.2.font=Interface Font:
settings.2.fontBtn=Select Font
settings.2.showConfirmDialog=Select Font
settings.2.cuda=Use CUDA for AI Inference:
settings.2.cudaCheckBox=Enable CUDA Acceleration
settings.2.cuda.error=Unable to reload AI inference library, please check the CUDA environment
settings.2.cuda.error.1=Error
settings.2.language=Interface Language:
settings.2.language.error=Unknown Language
settings.3.infoArea.1=Software Version:
settings.3.infoArea.2=Developer:
settings.4.no_theme=No available themes
settings.4.search=Search
settings.4.search_empty=Please enter search content!
settings.4.search_empty_title=Prompt
settings.4.search_not_found=No matching themes found!
settings.4.search_not_found_title=Prompt
settings.4.loading=This theme has already been loaded, no need to load again!
settings.4.loading_title=Prompt
settings.4.load=Load Theme
settings.4.info=Theme Class:
settings.4.info.1=Theme Name:
settings.4.info.2=Tip:
settings.4.info.3=Register Name:
settings.4.load_theme_success=Theme '
settings.4.load_theme_success.2=' loaded successfully!
settings.4.load_theme_success.3=Success
settings.4.load_theme_error=Failed to load theme:
settings.4.load_theme_error.title=Error

View File

@@ -0,0 +1,99 @@
default_theme.system.topicName=\u9ED8\u8BA4\u4E3B\u9898
default_theme.default.tip=\u9ED8\u8BA4\u7684\u4E3B\u9898
metal_theme.system.topicName=Metal\u98CE\u683C
metal_theme.default.tip=Metal\u98CE\u683C
motif_theme.system.topicName=Motif\u98CE\u683C
motif_theme.default.tip=Motif\u98CE\u683C
flatLightLaf_theme.system.topicName=flatLightLaf\u98CE\u683C
flatLightLaf_theme.default.tip=flatLightLaf\u98CE\u683C
mainWindow.title=\u8F74\u521B\u5DE5\u5177\u7BB1 v1.0
mainWindow.title.2=\u8F74\u521B\u5DE5\u5177\u7BB1
mainWindow.settings.title=\u7CFB\u7EDF\u8BBE\u7F6E
andShow.title=\u7A0B\u5E8F\u5D29\u6E83\u62A5\u544A
andShow.title.2=<html><h2 style='color: #D32F2F;'>\u7A0B\u5E8F\u53D1\u751F\u4E25\u91CD\u9519\u8BEF</h2></html>
andShow.title.3=<html><h3 style='color: #FF0000;'>\u8BF7\u5411\u6211\u4EEC\u53CD\u9988\uFF01</h3></html>
andShow.pluginInfo.title==== \u52A0\u8F7D\u7684\u63D2\u4EF6 ===
andShow.pluginInfo.title.1=\u63D2\u4EF6\u540D\u79F0:
andShow.pluginInfo.title.2=\u63D2\u4EF6\u63CF\u8FF0:
andShow.pluginInfo.title.3=\u652F\u6301\u7684\u7248\u672C:
andShow.pluginInfo.exportButton=\u5BFC\u51FA\u62A5\u544A
andShow.pluginInfo.closeButton=\u5173\u95ED
andShow.pluginInfo.writer=\u62A5\u544A\u5DF2\u4FDD\u5B58\u81F3:
andShow.pluginInfo.writer.title=\u5BFC\u51FA\u6210\u529F
andShow.pluginInfo.writer.error=\u5BFC\u51FA\u5931\u8D25:
andShow.pluginInfo.error.writer.title=\u9519\u8BEF
progressBarManager.title=\u52A0\u8F7D\u4E2D...
fridaWindow.title=Frida \u6CE8\u5165\u5DE5\u5177
fridaWindow.pidField=\u8BF7\u8F93\u5165\u8FDB\u7A0BPID
fridaWindow.browseButton=\u9009\u62E9\u8FDB\u7A0B
fridaWindow.panel=\u811A\u672C\u7F16\u8F91\u5668
fridaWindow.injectButton=\u6CE8\u5165\u811A\u672C
fridaWindow.panel.log=\u65E5\u5FD7\u8F93\u51FA
fridaWindow.processSelectionWindow=\u9009\u62E9\u8FDB\u7A0B
fridaWindow.processSelectionWindow.search=\u641C\u7D22\u8FDB\u7A0B
fridaWindow.processSelectionWindow.columns.1=\u8FDB\u7A0B\u540D\u79F0
fridaWindow.processSelectionWindow.columns.2=\u8FDB\u7A0BID
fridaWindow.processSelectionWindow.selectButton=\u9009\u62E9
localWindow.newBtn=\u65B0\u5BF9\u8BDD
localWindow.saveBtn=\u4FDD\u5B58\u8BB0\u5F55
localWindow.cudaCheck=\u542F\u7528CUDA
localWindow.searchBtn=\u5F00\u542F\u641C\u7D22
localWindow.searchBtn.1=\u5173\u95ED\u641C\u7D22
localWindow.searchBtn.appendMessage=\u641C\u7D22\u529F\u80FD\u5DF2\u5F00\u542F
localWindow.searchBtn.appendMessage.1=\u641C\u7D22\u529F\u80FD\u5DF2\u5173\u95ED
localWindow.sendButton=\u53D1\u9001
localWindow.prompt.system=\u4F60\u662F\u4E00\u4E2A\u4E50\u4E8E\u52A9\u4EBA\u7684AI\u52A9\u624B\uFF0C\u8BF7\u7528\u53CB\u597D\u81EA\u7136\u7684\u8BED\u6C14\u56DE\u7B54\u7528\u6237\u95EE\u9898,\u7528\u6237\u53EF\u80FD\u4F1A\u63D0\u4F9B\u4E00\u4E9B\u641C\u7D22\u7ED3\u679C\u8BF7\u4F60\u7ED3\u5408\u641C\u7D22\u7ED3\u679C\u6765\u56DE\u7B54\u7528\u6237\u3002
localWindow.prompt.system.2=\u4F60\u662F\u4E00\u4E2A\u4E13\u6CE8\u68C0\u7D22\u641C\u7D22\u4FE1\u606F\u7684\u52A9\u624B\uFF0C\u7528\u6237\u5C06\u63D0\u4F9B\u4E00\u4E9B\u94FE\u63A5\u3001\u6458\u8981\u3001\u6807\u9898\u3001\u722C\u53D6\u5230\u7684\u5185\u5BB9\uFF0C\u4F60\u7684\u4F5C\u7528\u5C31\u662F\u8F93\u51FA\u4E3B\u8981\u5185\u5BB9\u4E0E\u7528\u6237\u95EE\u9898\u76F8\u5173\u7684\u5185\u5BB9\u3002
localWindow.prompt.name=\u3010\u7528\u6237\u3011
settings.1.title=\u63D2\u4EF6
settings.2.title=\u57FA\u7840\u8BBE\u7F6E
settings.3.title=\u5173\u4E8E
settings.4.title=\u4E3B\u9898
settings.1.tip=\u63D2\u4EF6\u7BA1\u7406
settings.2.tip=\u5916\u89C2\u8BBE\u7F6E
settings.3.tip=\u7248\u672C\u4FE1\u606F
settings.4.tip=\u4E3B\u9898\u7BA1\u7406
settings.1.columns.1=\u63D2\u4EF6\u540D\u79F0
settings.1.columns.2=\u7248\u672C\u652F\u6301
settings.1.columns.3=\u63CF\u8FF0
settings.1.scrollPane=\u5DF2\u52A0\u8F7D\u63D2\u4EF6\u5217\u8868
settings.2.color=\u754C\u9762\u4E3B\u9898\u989C\u8272\uFF1A
settings.2.colorBtn=\u9009\u62E9\u989C\u8272
settings.2.colorBtn.color=\u9009\u62E9\u4E3B\u9898\u989C\u8272
settings.2.font=\u754C\u9762\u5B57\u4F53\uFF1A
settings.2.fontBtn=\u9009\u62E9\u5B57\u4F53
settings.2.showConfirmDialog=\u9009\u62E9\u5B57\u4F53
settings.2.cuda=AI\u63A8\u7406\u65F6\u4F7F\u7528CUDA\uFF1A
settings.2.cudaCheckBox=\u542F\u7528CUDA\u52A0\u901F
settings.2.cuda.error=\u65E0\u6CD5\u91CD\u65B0\u52A0\u8F7DAI\u63A8\u7406\u5E93\uFF0C\u8BF7\u68C0\u67E5CUDA\u73AF\u5883
settings.2.cuda.error.1=\u9519\u8BEF
settings.2.language=\u754C\u9762\u8BED\u8A00\uFF1A
settings.2.language.error=\u672A\u77E5\u8BED\u8A00
settings.3.infoArea.1=\u8F6F\u4EF6\u7248\u672C:
settings.3.infoArea.2=\u5F00\u53D1\u4F5C\u8005:
settings.4.no_theme=\u6CA1\u6709\u53EF\u7528\u7684\u4E3B\u9898
settings.4.search=\u641C\u7D22
settings.4.search_empty=\u8BF7\u8F93\u5165\u641C\u7D22\u5185\u5BB9\uFF01
settings.4.search_empty_title=\u63D0\u793A
settings.4.search_not_found=\u672A\u627E\u5230\u5339\u914D\u7684\u4E3B\u9898\uFF01
settings.4.search_not_found_title=\u63D0\u793A
settings.4.loading=\u8BE5\u4E3B\u9898\u5DF2\u52A0\u8F7D\uFF0C\u65E0\u9700\u91CD\u590D\u52A0\u8F7D\uFF01
settings.4.loading_title=\u63D0\u793A
settings.4.load=\u52A0\u8F7D\u4E3B\u9898
settings.4.info=\u4E3B\u9898\u7C7B:
settings.4.info.1=\u4E3B\u9898\u540D:
settings.4.info.2=\u63D0\u793A:
settings.4.info.3=\u6CE8\u518C\u540D:
settings.4.load_theme_success=\u4E3B\u9898 '
settings.4.load_theme_success.2=' \u5DF2\u6210\u529F\u52A0\u8F7D\uFF01
settings.4.load_theme_success.3=\u6210\u529F
settings.4.load_theme_error=\u52A0\u8F7D\u4E3B\u9898\u5931\u8D25:
settings.4.load_theme_error.title=\u9519\u8BEF

View File

@@ -0,0 +1,99 @@
default_theme.system.topicName=\u9810\u8A2D\u4E3B\u984C
default_theme.default.tip=\u9810\u8A2D\u7684\u4E3B\u984C
metal_theme.system.topicName=Metal\u98A8\u683C
metal_theme.default.tip=Metal\u98A8\u683C
motif_theme.system.topicName=Motif\u98A8\u683C
motif_theme.default.tip=Motif\u98A8\u683C
flatLightLaf_theme.system.topicName=flatLightLaf\u98A8\u683C
flatLightLaf_theme.default.tip=flatLightLaf\u98A8\u683C
mainWindow.title=\u8EF8\u5275\u5DE5\u5177\u7BB1 v1.0
mainWindow.title.2=\u8EF8\u5275\u5DE5\u5177\u7BB1
mainWindow.settings.title=\u7CFB\u7D71\u8A2D\u7F6E
andShow.title=\u7A0B\u5F0F\u5D29\u6F70\u5831\u544A
andShow.title.2=<html><h2 style='color: #D32F2F;'>\u7A0B\u5F0F\u767C\u751F\u56B4\u91CD\u932F\u8AA4</h2></html>
andShow.title.3=<html><h3 style='color: #FF0000;'>\u8ACB\u5411\u6211\u5011\u53CD\u994B\uFF01</h3></html>
andShow.pluginInfo.title==== \u8F09\u5165\u7684\u63D2\u4EF6 ===
andShow.pluginInfo.title.1=\u63D2\u4EF6\u540D\u7A31:
andShow.pluginInfo.title.2=\u63D2\u4EF6\u63CF\u8FF0:
andShow.pluginInfo.title.3=\u652F\u63F4\u7684\u7248\u672C:
andShow.pluginInfo.exportButton=\u532F\u51FA\u5831\u544A
andShow.pluginInfo.closeButton=\u95DC\u9589
andShow.pluginInfo.writer=\u5831\u544A\u5DF2\u5132\u5B58\u81F3:
andShow.pluginInfo.writer.title=\u532F\u51FA\u6210\u529F
andShow.pluginInfo.writer.error=\u532F\u51FA\u5931\u6557:
andShow.pluginInfo.error.writer.title=\u932F\u8AA4
progressBarManager.title=\u52A0\u8F09\u4E2D...
fridaWindow.title=Frida \u6CE8\u5165\u5DE5\u5177
fridaWindow.pidField=\u8F38\u5165\u9032\u7A0BPID
fridaWindow.browseButton=\u9078\u64C7\u9032\u7A0B
fridaWindow.panel=\u8173\u672C\u7DE8\u8F2F\u5668
fridaWindow.injectButton=\u6CE8\u5165\u8173\u672C
fridaWindow.panel.log=\u65E5\u8A8C\u8F38\u51FA
fridaWindow.processSelectionWindow=\u9078\u64C7\u9032\u7A0B
fridaWindow.processSelectionWindow.search=\u641C\u5C0B\u9032\u7A0B
fridaWindow.processSelectionWindow.columns.1=\u9032\u7A0B\u540D\u7A31
fridaWindow.processSelectionWindow.columns.2=\u9032\u7A0BID
fridaWindow.processSelectionWindow.selectButton=\u9078\u64C7
localWindow.newBtn=\u65B0\u5C0D\u8A71
localWindow.saveBtn=\u4FDD\u5B58\u8A18\u9304
localWindow.cudaCheck=\u555F\u7528CUDA
localWindow.searchBtn=\u958B\u555F\u641C\u5C0B
localWindow.searchBtn.1=\u95DC\u9589\u641C\u5C0B
localWindow.searchBtn.appendMessage=\u641C\u5C0B\u529F\u80FD\u5DF2\u958B\u555F
localWindow.searchBtn.appendMessage.1=\u641C\u5C0B\u529F\u80FD\u5DF2\u95DC\u9589
localWindow.sendButton=\u767C\u9001
localWindow.prompt.system=\u4F60\u662F\u4E00\u4E2A\u4E50\u4E8E\u52A9\u4EBA\u7684AI\u52A9\u624B\uFF0C\u8BF7\u7528\u53CB\u597D\u81EA\u7136\u7684\u8BED\u6C14\u56DE\u7B54\u7528\u6237\u95EE\u9898,\u7528\u6237\u53EF\u80FD\u4F1A\u63D0\u4F9B\u4E00\u4E9B\u641C\u7D22\u7ED3\u679C\u8BF7\u4F60\u7ED3\u5408\u641C\u7D22\u7ED3\u679C\u6765\u56DE\u7B54\u7528\u6237\u3002
localWindow.prompt.system.2=\u4F60\u662F\u4E00\u4E2A\u4E13\u6CE8\u68C0\u7D22\u641C\u7D22\u4FE1\u606F\u7684\u52A9\u624B\uFF0C\u7528\u6237\u5C06\u63D0\u4F9B\u4E00\u4E9B\u94FE\u63A5\u3001\u6458\u8981\u3001\u6807\u9898\u3001\u722C\u53D6\u5230\u7684\u5185\u5BB9\uFF0C\u4F60\u7684\u4F5C\u7528\u5C31\u662F\u8F93\u51FA\u4E3B\u8981\u5185\u5BB9\u4E0E\u7528\u6237\u95EE\u9898\u76F8\u5173\u7684\u5185\u5BB9\u3002
localWindow.prompt.name=[\u7528\u6236]
settings.1.title=\u63D2\u4EF6
settings.2.title=\u57FA\u672C\u8A2D\u7F6E
settings.3.title=\u95DC\u65BC
settings.4.title=\u4E3B\u984C
settings.1.tip=\u63D2\u4EF6\u7BA1\u7406
settings.2.tip=\u5916\u89C0\u8A2D\u7F6E
settings.3.tip=\u7248\u672C\u4FE1\u606F
settings.4.tip=\u4E3B\u984C\u7BA1\u7406
settings.1.columns.1=\u63D2\u4EF6\u540D\u7A31
settings.1.columns.2=\u7248\u672C\u652F\u6301
settings.1.columns.3=\u63CF\u8FF0
settings.1.scrollPane=\u5DF2\u8F09\u5165\u63D2\u4EF6\u5217\u8868
settings.2.color=\u4ECB\u9762\u4E3B\u984C\u984F\u8272\uFF1A
settings.2.colorBtn=\u9078\u64C7\u984F\u8272
settings.2.colorBtn.color=\u9078\u64C7\u4E3B\u984C\u984F\u8272
settings.2.font=\u4ECB\u9762\u5B57\u9AD4\uFF1A
settings.2.fontBtn=\u9078\u64C7\u5B57\u9AD4
settings.2.showConfirmDialog=\u9078\u64C7\u5B57\u9AD4
settings.2.cuda=AI\u63A8\u7406\u6642\u4F7F\u7528CUDA\uFF1A
settings.2.cudaCheckBox=\u555F\u7528CUDA\u52A0\u901F
settings.2.cuda.error=\u7121\u6CD5\u91CD\u65B0\u52A0\u8F09AI\u63A8\u7406\u5EAB\uFF0C\u8ACB\u6AA2\u67E5CUDA\u74B0\u5883
settings.2.cuda.error.1=\u932F\u8AA4
settings.2.language=\u4ECB\u9762\u8A9E\u8A00\uFF1A
settings.2.language.error=\u672A\u77E5\u8A9E\u8A00
settings.3.infoArea.1=\u8EDF\u9AD4\u7248\u672C:
settings.3.infoArea.2=\u958B\u767C\u4F5C\u8005:
settings.4.no_theme=\u6C92\u6709\u53EF\u7528\u7684\u4E3B\u984C
settings.4.search=\u641C\u5C0B
settings.4.search_empty=\u8ACB\u8F38\u5165\u641C\u5C0B\u5167\u5BB9\uFF01
settings.4.search_empty_title=\u63D0\u793A
settings.4.search_not_found=\u672A\u627E\u5230\u5339\u914D\u7684\u4E3B\u984C\uFF01
settings.4.search_not_found_title=\u63D0\u793A
settings.4.loading=\u8A72\u4E3B\u984C\u5DF2\u8F09\u5165\uFF0C\u7121\u9700\u91CD\u8907\u8F09\u5165\uFF01
settings.4.loading_title=\u63D0\u793A
settings.4.load=\u52A0\u8F09\u4E3B\u984C
settings.4.info=\u4E3B\u984C\u985E\u5225:
settings.4.info.1=\u4E3B\u984C\u540D\u7A31:
settings.4.info.2=\u63D0\u793A:
settings.4.info.3=\u8A3B\u518A\u540D\u7A31:
settings.4.load_theme_success=\u4E3B\u984C '
settings.4.load_theme_success.2=' \u5DF2\u6210\u529F\u52A0\u8F09\uFF01
settings.4.load_theme_success.3=\u6210\u529F
settings.4.load_theme_error=\u52A0\u8F09\u4E3B\u984C\u5931\u6557:
settings.4.load_theme_error.title=\u932F\u8AA4

View File

@@ -0,0 +1,3 @@
#Current Loaded Language
#Fri Feb 14 09:23:44 CST 2025
loadedLanguage=Zh

View File

@@ -0,0 +1,417 @@
package com.axis.innovators.box;
import com.axis.innovators.box.events.GlobalEventBus;
import com.axis.innovators.box.events.StartupEvent;
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.RegistrationSettingsItem;
import com.axis.innovators.box.register.RegistrationTool;
import com.axis.innovators.box.register.RegistrationTopic;
import com.axis.innovators.box.register.LanguageManager;
import com.axis.innovators.box.tools.LibraryLoad;
import com.axis.innovators.box.tools.StateManager;
import com.axis.innovators.box.tools.SystemInfoUtil;
import com.formdev.flatlaf.FlatLightLaf;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.tzd.lm.LM;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
/**
* 主类
* @author tzdwindows 7
*/
public class AxisInnovatorsBox {
private static final Logger logger = LogManager.getLogger(AxisInnovatorsBox.class);
private static final String VERSIONS = "0.0.1";
private static final String[] AUTHOR = new String[]{
"tzdwindows 7"
};
/** 我是总任务数 **/
public int totalTasks = 1;
/** 我是当前任务数 **/
private int completedTasks = 0;
public ProgressBarManager progressBarManager = new ProgressBarManager(
LanguageManager.getLoadedLanguages().getText("progressBarManager.title"),
totalTasks);
private static AxisInnovatorsBox main;
private MainWindow ex;
private Thread thread;
private final String[] args;
private boolean isWindow = false;
private RegistrationTool registrationTool = new RegistrationTool(this);
private final RegistrationTopic registrationTopic = new RegistrationTopic(this);
private final List<WindowsJDialog> windowsJDialogList = new ArrayList<>();
private final StateManager stateManager = new StateManager();
public AxisInnovatorsBox(String[] args){
this.args = args;
}
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);
}
}
/**
* 获取主类
* @return 主类
*/
public static AxisInnovatorsBox getMain() {
return main;
}
/**
* 获取主窗口
* @return 主窗口
*/
public MainWindow getMainWindow() {
return ex;
}
/**
* 退出程序
*/
public void quit() {
logger.info("Application is shutting down...");
thread.interrupt();
System.exit(0);
}
/**
* 组织崩溃报告
*/
public void organizingCrashReports(Exception e) {
String systemOut = Log4j2OutputStream.systemOutContent.toString();
String systemErr = Log4j2OutputStream.systemErrContent.toString();
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
String stackTrace = sw.toString();
String report = "========== 系统标准输出 ==========\n" + systemOut +
"\n========== 系统错误输出 ==========\n" + systemErr +
"\n========== 异常堆栈跟踪 ==========\n" + stackTrace;
SwingUtilities.invokeLater(() -> createAndShowGUI(report));
}
private void createAndShowGUI(String reportContent) {
JDialog dialog = new JDialog((Frame) null,
LanguageManager.getLoadedLanguages().getText("andShow.title"), true);
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
dialog.setLayout(new BorderLayout(10, 10));
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ignored) {}
JPanel topPanel = new JPanel(new BorderLayout(10, 10));
Icon errorIcon = UIManager.getIcon("OptionPane.errorIcon");
JLabel iconLabel = new JLabel(errorIcon);
JLabel titleLabel = new JLabel(LanguageManager.getLoadedLanguages().getText("andShow.title.2"));
JLabel feedbackLabel = new JLabel(LanguageManager.getLoadedLanguages().getText("andShow.title.3"));
feedbackLabel.setHorizontalAlignment(SwingConstants.CENTER);
JPanel titlePanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 10));
titlePanel.add(iconLabel);
titlePanel.add(titleLabel);
topPanel.add(titlePanel, BorderLayout.NORTH);
topPanel.add(feedbackLabel, BorderLayout.CENTER);
topPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
JTextArea contentArea = new JTextArea(reportContent);
contentArea.setEditable(false);
contentArea.setFont(new Font("Monospaced", Font.PLAIN, 12));
StringBuilder pluginInfo = new StringBuilder();
pluginInfo.append(
LanguageManager.getLoadedLanguages().getText("andShow.pluginInfo.title"))
.append("\n");
List<PluginDescriptor> corePluginList = new ArrayList<>();
for (PluginDescriptor plugin : PluginLoader.getLoadedPlugins()) {
pluginInfo.append(LanguageManager.getLoadedLanguages().getText("andShow.pluginInfo.title.1")).append(plugin.getName()).append("\n");
pluginInfo.append(LanguageManager.getLoadedLanguages().getText("andShow.pluginInfo.title.2")).append(plugin.getDescription()).append("\n");
pluginInfo.append(LanguageManager.getLoadedLanguages().getText("andShow.pluginInfo.title.3")).append(plugin.getSupportedVersions()).append("\n\n");
if (plugin.getTransformers() != null) {
corePluginList.add(plugin);
}
}
pluginInfo.append("=== 核心插件 ===\n");
for (PluginDescriptor corePlugin : corePluginList) {
pluginInfo.append("核心插件主类: ").append(corePlugin.getName()).append("\n");
pluginInfo.append("核心转换器位置: ").append(corePlugin.getTransformers()).append("\n");
}
contentArea.append("\n\n=== 插件信息 ===\n");
contentArea.append(pluginInfo.toString());
JScrollPane scrollPane = new JScrollPane(contentArea);
scrollPane.setBorder(BorderFactory.createTitledBorder("错误详细信息"));
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 10, 10));
JButton exportButton = new JButton(LanguageManager.getLoadedLanguages().getText("andShow.pluginInfo.exportButton"));
JButton closeButton = new JButton(LanguageManager.getLoadedLanguages().getText("andShow.pluginInfo.closeButton"));
exportButton.setForeground(Color.BLACK);
closeButton.setForeground(Color.BLACK);
exportButton.setBackground(new Color(0, 120, 215));
exportButton.setFocusPainted(false);
closeButton.setBackground(new Color(79, 79, 79));
closeButton.setFocusPainted(false);
exportButton.addActionListener((ActionEvent e) -> {
JFileChooser fileChooser = new JFileChooser();
fileChooser.setDialogTitle("保存崩溃报告");
fileChooser.setSelectedFile(new File("crash_report.txt"));
int userSelection = fileChooser.showSaveDialog(dialog);
if (userSelection == JFileChooser.APPROVE_OPTION) {
File fileToSave = fileChooser.getSelectedFile();
try (FileWriter writer = new FileWriter(fileToSave)) {
writer.write(reportContent + "\n" + pluginInfo);
JOptionPane.showMessageDialog(dialog,
LanguageManager.getLoadedLanguages().getText("andShow.pluginInfo.writer")
+ "\n" + fileToSave.getAbsolutePath(),
LanguageManager.getLoadedLanguages().getText("andShow.pluginInfo.writer.title"),
JOptionPane.INFORMATION_MESSAGE);
} catch (IOException ex) {
JOptionPane.showMessageDialog(dialog,
LanguageManager.getLoadedLanguages().getText("andShow.pluginInfo.writer.error")
+ "\n" + ex.getMessage(),
LanguageManager.getLoadedLanguages().getText("andShow.pluginInfo.error.writer.title"),
JOptionPane.ERROR_MESSAGE);
}
}
});
closeButton.addActionListener(e -> quit());
buttonPanel.add(exportButton);
buttonPanel.add(closeButton);
dialog.add(topPanel, BorderLayout.NORTH);
dialog.add(scrollPane, BorderLayout.CENTER);
dialog.add(buttonPanel, BorderLayout.SOUTH);
dialog.setSize(800, 600);
dialog.setLocationRelativeTo(null);
dialog.setVisible(true);
}
public void initLog4j2() {
Log4j2OutputStream.redirectSystemStreams();
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());
logger.info("Java Version: {}", System.getProperty("java.version"));
logger.info("Java Vendor: {}", System.getProperty("java.vendor"));
logger.info("Java Home: {}", System.getProperty("java.home"));
logger.info("Java Class Path: {}", System.getProperty("java.class.path"));
logger.info("ClassLoader.getSystemClassLoader(): {}", ClassLoader.getSystemClassLoader());
}
private void setTopic() {
try {
main.registrationTopic.addTopic(UIManager.getSystemLookAndFeelClassName(),
LanguageManager.getLoadedLanguages().getText("default_theme.system.topicName"),
LanguageManager.getLoadedLanguages().getText("default_theme.default.tip"),
LoadIcon.loadIcon(MainWindow.class, "logo.png", 64),
"system:default_theme");
main.registrationTopic.setLoading("system:default_theme");
main.registrationTopic.addTopic("javax.swing.plaf.metal.MetalLookAndFeel",
LanguageManager.getLoadedLanguages().getText("metal_theme.system.topicName"),
LanguageManager.getLoadedLanguages().getText("metal_theme.default.tip"),
LoadIcon.loadIcon(MainWindow.class, "logo.png", 64),
"system:metal_theme");
main.registrationTopic.addTopic("com.sun.java.swing.plaf.motif.MotifLookAndFeel",
LanguageManager.getLoadedLanguages().getText("motif_theme.system.topicName"),
LanguageManager.getLoadedLanguages().getText("motif_theme.default.tip"),
LoadIcon.loadIcon(MainWindow.class, "logo.png", 64),
"system:motif_theme");
main.registrationTopic.addTopic(new FlatLightLaf(),
LanguageManager.getLoadedLanguages().getText("flatLightLaf_theme.system.topicName"),
LanguageManager.getLoadedLanguages().getText("flatLightLaf_theme.default.tip"),
LoadIcon.loadIcon(MainWindow.class, "logo.png", 64),
"system:flatLightLaf_theme");
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
logger.warn("Failed to load the system facade class", e);
}
}
/**
* 弹出窗口
* @param windowsJDialog 窗口
*/
public void popupWindow(WindowsJDialog windowsJDialog) {
windowsJDialogList.add(windowsJDialog);
windowsJDialog.setVisible(true);
}
/**
* 判断窗口是否启动
* @param windowsJDialog 窗口
*/
public boolean isWindowStartup(WindowsJDialog windowsJDialog) {
return windowsJDialogList.contains(windowsJDialog);
}
/**
* 清除窗口
* @param windowsJDialog 窗口
*/
public void clearWindow(WindowsJDialog windowsJDialog){
windowsJDialogList.remove(windowsJDialog);
windowsJDialog.revalidate();
windowsJDialog.repaint();
}
/**
* 重新加载窗口
*/
public void reloadAllWindow() {
isWindow = false;
ex.getContentPane().removeAll();
ex.revalidate();
ex.repaint();
registrationTool = new RegistrationTool(this);
for (WindowsJDialog windowsJDialog : windowsJDialogList) {
windowsJDialog.getContentPane().removeAll();
windowsJDialog.initUI();
windowsJDialog.revalidate();
windowsJDialog.repaint();
}
ex.initUI();
ex.revalidate();
RegistrationSettingsItem.overloading();
isWindow = true;
}
public static void main(String[] args) {
main = new AxisInnovatorsBox(args);
main.initLog4j2();
main.setTopic();
main.thread = new Thread(() -> {
try {
// 主任务1加载插件
logger.info("Loaded plugins Started");
main.progressBarManager.updateMainProgress(++main.completedTasks);
PluginLoader.loadPlugins();
logger.info("Loaded plugins End");
main.progressBarManager.close();
SwingUtilities.invokeLater(() -> {
try {
main.ex = new MainWindow();
GlobalEventBus.EVENT_BUS.post(new StartupEvent(main));
main.runWindow();
} catch (Exception e) {
logger.error("There was a problem starting the main thread", e);
main.ex.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
main.organizingCrashReports(e);
throw new RuntimeException(e);
}
});
} catch (Exception e) {
logger.error("Failed to load plugins", e);
main.ex.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
main.organizingCrashReports(e);
throw new RuntimeException(e);
}
});
main.thread.setName("Main Thread");
main.thread.start();
}
public void runWindow() {
progressBarManager.updateMainProgress(++completedTasks);
if (!registrationTool.getToolCategories().isEmpty()) {
for (int i = 0; i < registrationTool.getToolCategories()
.size(); i++) {
ex.addToolCategory(registrationTool.getToolCategories()
.get(i));
progressBarManager.updateSubProgress(
"add tools", i,
registrationTool.getToolCategories().size());
}
}
ex.initUI();
isWindow = true;
ex.setVisible(true);
}
/**
* 获取注册工具
* @return 注册工具
*/
public RegistrationTool getRegistrationTool() {
return registrationTool;
}
/**
* 获取命令行参数
* @return 命令行参数
*/
public String[] getArgs() {
return args;
}
public boolean isWindow() {
return isWindow;
}
public static String getVersion() {
return VERSIONS;
}
public RegistrationTopic getRegistrationTopic() {
return registrationTopic;
}
public static String[] getAuthor() {
return AUTHOR;
}
/**
* 获取状态管理器
* @return 状态管理器
*/
public StateManager getStateManager() {
return stateManager;
}
}

View File

@@ -3,6 +3,7 @@ package com.axis.innovators.box;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.io.PrintStream;
@@ -12,14 +13,17 @@ import java.io.PrintStream;
*/
public class Log4j2OutputStream extends OutputStream {
private static final Logger logger = LogManager.getLogger();
public static final ByteArrayOutputStream systemOutContent = new ByteArrayOutputStream();
public static final ByteArrayOutputStream systemErrContent = new ByteArrayOutputStream();
@Override
public void write(int b) {
systemOutContent.write(b);
logger.info(String.valueOf((char) b));
}
@Override
public void write(byte[] b, int off, int len) {
systemOutContent.write(b, off, len);
String message = new String(b, off, len).trim();
logger.info(message);
}

View File

@@ -1,384 +1,16 @@
package com.axis.innovators.box;
import com.axis.innovators.box.events.GlobalEventBus;
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;
import com.axis.innovators.box.tools.FolderCleaner;
import com.axis.innovators.box.tools.FolderCreator;
import com.axis.innovators.box.register.LanguageManager;
/**
* 主类
* @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 int totalTasks = 1;
/** 我是当前任务数 **/
private int completedTasks = 0;
public ProgressBarManager progressBarManager = new ProgressBarManager("加载中...", totalTasks);
private static Main main;
private MainWindow ex;
private Thread thread;
private final String[] args;
private boolean isWindow = false;
private final RegistrationTool registrationTool = new RegistrationTool(this);
public Main(String[] args){
this.args = args;
}
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);
}
}
/**
* 获取主类
* @return 主类
*/
public static Main getMain() {
return main;
}
/**
* 获取主窗口
* @return 主窗口
*/
public MainWindow getMainWindow() {
return ex;
}
/**
* 退出程序
*/
public void quit() {
logger.info("Application is shutting down...");
thread.interrupt();
System.exit(0);
}
public void initLog4j2() {
Log4j2OutputStream.redirectSystemStreams();
// 输出版本和作者信息
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());
logger.info("Java Version: {}", System.getProperty("java.version"));
logger.info("Java Vendor: {}", System.getProperty("java.vendor"));
logger.info("Java Home: {}", System.getProperty("java.home"));
logger.info("Java Class Path: {}", System.getProperty("java.class.path"));
logger.info("ClassLoader.getSystemClassLoader(): {}", ClassLoader.getSystemClassLoader());
}
@SubscribeEvent
public void onSettingsLoad(SettingsLoadEvents event) {
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) {
main = new Main(args);
// 注册事件
GlobalEventBus.EVENT_BUS.register(main);
main.initLog4j2();
// 设置系统外观
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
logger.warn("Failed to load the system facade class", e);
}
main.thread = new Thread(() -> {
try {
// 主任务1加载插件
logger.info("Loaded plugins Started");
main.progressBarManager.updateMainProgress(++main.completedTasks);
PluginLoader.loadPlugins();
logger.info("Loaded plugins End");
main.progressBarManager.close();
SwingUtilities.invokeLater(() -> {
try {
main.ex = new MainWindow();
GlobalEventBus.EVENT_BUS.post(new StartupEvent(main));
main.runWindow();
} catch (Exception e) {
logger.error("There was a problem starting the main thread", e);
throw new RuntimeException(e);
}
});
} catch (Exception e) {
logger.error("Failed to load plugins", e);
throw new RuntimeException(e);
}
});
main.thread.setName("Main Thread");
main.thread.start();
FolderCleaner.cleanFolder(FolderCreator.getLogsFolder(), 10);
LanguageManager.loadSavedLanguage();
AxisInnovatorsBox.main(args);
}
public void runWindow() {
progressBarManager.updateMainProgress(++completedTasks);
if (!registrationTool.getToolCategories().isEmpty()) {
for (int i = 0; i < registrationTool.getToolCategories()
.size(); i++) {
ex.addToolCategory(registrationTool.getToolCategories()
.get(i));
progressBarManager.updateSubProgress(
"add tools", i,
registrationTool.getToolCategories().size());
}
}
ex.initUI();
isWindow = true;
ex.setVisible(true);
}
/**
* 获取注册工具
* @return 注册工具
*/
public RegistrationTool getRegistrationTool() {
return registrationTool;
}
/**
* 获取命令行参数
* @return 命令行参数
*/
public String[] getArgs() {
return args;
}
public boolean isWindow() {
return isWindow;
}
}
}

View File

@@ -1,5 +1,7 @@
package com.axis.innovators.box.events;
import com.axis.innovators.box.gui.WindowsJDialog;
import javax.swing.*;
/**
@@ -8,5 +10,5 @@ import javax.swing.*;
*
* @author tzdwindows 7
*/
public record SettingsLoadEvents(JDialog dialog, JPanel content) {
public record SettingsLoadEvents(WindowsJDialog dialog, JPanel content) {
}

View File

@@ -1,11 +1,11 @@
package com.axis.innovators.box.events;
import com.axis.innovators.box.Main;
import com.axis.innovators.box.AxisInnovatorsBox;
/**
* 当程序启动时触发
*
* @author tzdwindows 7
*/
public record StartupEvent(Main main) {
public record StartupEvent(AxisInnovatorsBox main) {
}

View File

@@ -1,5 +1,6 @@
package com.axis.innovators.box.gui;
import com.axis.innovators.box.register.LanguageManager;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.tzd.frida.windows.Frida;
@@ -21,7 +22,7 @@ import java.util.List;
* Frida注入工具窗口
* @author tzdwindows 7
*/
public class FridaWindow extends JDialog {
public class FridaWindow extends WindowsJDialog {
private static final Logger logger = LogManager.getLogger(FridaWindow.class);
private JTextArea scriptArea;
private JTextArea logArea;
@@ -29,11 +30,13 @@ public class FridaWindow extends JDialog {
private boolean isRepetition = false;
public FridaWindow(Window owner) {
super(owner, "Frida 注入工具", ModalityType.APPLICATION_MODAL);
initializeUI();
super(owner, language.getText("fridaWindow.title"), ModalityType.APPLICATION_MODAL);
initUI();
}
private void initializeUI() {
@Override
public void initUI() {
super.initUI();
setSize(800, 600);
setLocationRelativeTo(getOwner());
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
@@ -73,18 +76,15 @@ public class FridaWindow extends JDialog {
JPanel panel = new JPanel(new GridLayout(1, 3, 10, 10));
panel.setOpaque(false);
pidField = new JTextField("请输入进程PID");
pidField = new JTextField(language.getText("fridaWindow.pidField"));
pidField.setFont(new Font("微软雅黑", Font.PLAIN, 14));
pidField.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createLineBorder(new Color(57, 56, 56)),
BorderFactory.createEmptyBorder(5, 10, 5, 10)
));
//JButton attachButton = new JButton("附加进程");
//styleButton(attachButton, new Color(70, 130, 180));
//attachButton.setEnabled(false);
JButton browseButton = new JButton("选择进程");
JButton browseButton = new JButton(language.getText("fridaWindow.browseButton"));
styleButton(browseButton, new Color(60, 179, 113));
browseButton.addActionListener(this::openProcessSelectionWindow);
panel.add(pidField);
@@ -97,7 +97,7 @@ public class FridaWindow extends JDialog {
private JPanel createScriptPanel() {
JPanel panel = new JPanel(new BorderLayout());
panel.setOpaque(false);
panel.setBorder(BorderFactory.createTitledBorder("脚本编辑器"));
panel.setBorder(BorderFactory.createTitledBorder(language.getText("fridaWindow.panel")));
scriptArea = new JTextArea();
scriptArea.setFont(new Font("Consolas", Font.PLAIN, 14));
@@ -107,7 +107,7 @@ public class FridaWindow extends JDialog {
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 10, 5));
buttonPanel.setOpaque(false);
JButton injectButton = new JButton("注入脚本");
JButton injectButton = new JButton(language.getText("fridaWindow.injectButton"));
styleButton(injectButton, new Color(220, 20, 60));
injectButton.addActionListener(this::handleInject);
@@ -122,7 +122,7 @@ public class FridaWindow extends JDialog {
private JPanel createLogPanel() {
JPanel panel = new JPanel(new BorderLayout());
panel.setPreferredSize(new Dimension(0, 150));
panel.setBorder(BorderFactory.createTitledBorder("日志输出"));
panel.setBorder(BorderFactory.createTitledBorder(language.getText("fridaWindow.panel.log")));
panel.setOpaque(false);
logArea = new JTextArea();
@@ -187,7 +187,7 @@ public class FridaWindow extends JDialog {
private JTable table;
public ProcessSelectionWindow(Window owner) {
super(owner, "选择进程", ModalityType.APPLICATION_MODAL);
super(owner, language.getText("fridaWindow.processSelectionWindow"), ModalityType.APPLICATION_MODAL);
setSize(600, 400);
setLocationRelativeTo(owner);
initializeUI();
@@ -220,21 +220,22 @@ public class FridaWindow extends JDialog {
filterProcesses(searchField.getText());
}
});
searchPanel.add(new JLabel("搜索进程: "), BorderLayout.WEST);
searchPanel.add(new JLabel(language.getText("fridaWindow.processSelectionWindow.search")), BorderLayout.WEST);
searchPanel.add(searchField, BorderLayout.CENTER);
panel.add(searchPanel, BorderLayout.NORTH);
String[] columns = {"进程名称", "进程ID"};
String[] columns = {language.getText("fridaWindow.processSelectionWindow.columns.1"),
language.getText("fridaWindow.processSelectionWindow.columns.2")};
Object[][] data = getTableData(processList);
table = new JTable(data, columns);
JScrollPane scrollPane = new JScrollPane(table);
panel.add(scrollPane, BorderLayout.CENTER);
JButton selectButton = new JButton("选择");
JButton selectButton = new JButton(language.getText("fridaWindow.processSelectionWindow.selectButton"));
selectButton.addActionListener(e -> {
int selectedRow = table.getSelectedRow();
if (selectedRow >= 0) {
long selectedPid = (Long) table.getValueAt(selectedRow, 1); // 注意这里获取的是PID列
long selectedPid = (Long) table.getValueAt(selectedRow, 1);
((FridaWindow) getOwner()).pidField.setText(String.valueOf(selectedPid));
dispose();
}

View File

@@ -28,20 +28,6 @@ public class LoadIcon {
return loadIcon(LoadIcon.class, filename, size);
}
/**
* 专门留给插件的加载图片方法
* @param filename 图片在resources中的位置
* @param size 图片大小
* @return ImageIcon对象
*/
public static ImageIcon pluginsLoadIcon(String filename, int size) {
for (int i = 0; i < PluginLoader.getLoadedPlugins().size(); i++) {
PluginDescriptor plugin = PluginLoader.getLoadedPlugins().get(i);
return loadIcon(plugin.getInstance().getClass(), filename, size);
}
return null;
}
/**
* 加载图片
* @param clazz resources包所在的jar
@@ -51,6 +37,9 @@ public class LoadIcon {
*/
public static ImageIcon loadIcon(Class<?> clazz ,String filename, int size) {
try {
if (filename.isEmpty()){
return createPlaceholderIcon(size);
}
String fullPath = ICON_PATH + filename;
URL imgUrl = clazz.getResource(fullPath);
if (imgUrl == null) {
@@ -64,6 +53,30 @@ public class LoadIcon {
}
}
/**
* 加载图片,另一个版本
* @param clazz resources包所在的jar
* @param filename 图片名
* @param size 图片大小
* @return ImageIcon对象
*/
public static ImageIcon loadIcon0(Class<?> clazz ,String filename, int size) {
try {
if (filename.isEmpty()){
return createPlaceholderIcon(size);
}
URL imgUrl = clazz.getResource(filename);
if (imgUrl == null) {
return createPlaceholderIcon(size);
}
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);
}
}
private static ImageIcon createPlaceholderIcon(int size) {
BufferedImage img = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();

View File

@@ -1,21 +1,29 @@
package com.axis.innovators.box.gui;
import com.axis.innovators.box.register.LanguageManager;
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;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.LinkedList;
import java.util.List;
import java.io.IOException;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
/**
* 本地AI执行工具
* @author tzdwindows 7
*/
public class LocalWindow extends JDialog {
public class LocalWindow extends WindowsJDialog {
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);
@@ -31,14 +39,17 @@ public class LocalWindow extends JDialog {
private long currentModelHandle = -1;
private JSpinner tempSpinner;
private boolean searchEnabled = false;
public LocalWindow(Window owner) {
super(owner, "本地AI执行工具", ModalityType.APPLICATION_MODAL);
initializeUI();
initUI();
loadModelAsync();
}
private void initializeUI() {
@Override
public void initUI() {
super.initUI();
JPanel mainPanel = getjPanel();
// 聊天区域
@@ -97,17 +108,17 @@ public class LocalWindow extends JDialog {
toolBar.setBackground(bgColor);
// 新对话按钮
JButton newBtn = new JButton("新对话");
JButton newBtn = new JButton(language.getText("localWindow.newBtn"));
styleButton(newBtn);
newBtn.addActionListener(e -> createNewContext());
// 保存记录按钮
JButton saveBtn = new JButton("保存记录");
JButton saveBtn = new JButton(language.getText("localWindow.saveBtn"));
styleButton(saveBtn);
saveBtn.addActionListener(e -> saveConversation());
// CUDA切换
JCheckBox cudaCheck = new JCheckBox("启用CUDA", LM.CUDA);
JCheckBox cudaCheck = new JCheckBox(language.getText("localWindow.cudaCheck"), LM.CUDA);
cudaCheck.setFont(mainFont);
cudaCheck.setBackground(Color.lightGray);
cudaCheck.setForeground(Color.black);
@@ -118,13 +129,28 @@ public class LocalWindow extends JDialog {
contextBox.setBackground(bgColor);
contextBox.setForeground(textColor);
// 搜索功能按钮
JButton searchBtn = new JButton(language.getText("localWindow.searchBtn"));
styleButton(searchBtn);
searchBtn.addActionListener(e -> {
searchEnabled = !searchEnabled;
searchBtn.setText(searchEnabled ? language.getText("localWindow.searchBtn.1")
: language.getText("localWindow.searchBtn"));
if (searchEnabled) {
appendMessage(language.getText("localWindow.searchBtn.appendMessage"));
} else {
appendMessage(language.getText("localWindow.searchBtn.appendMessage.1"));
}
});
toolBar.add(newBtn);
toolBar.add(saveBtn);
toolBar.addSeparator();
toolBar.add(cudaCheck);
toolBar.addSeparator();
toolBar.add(contextBox);
toolBar.addSeparator();
toolBar.add(searchBtn);
return toolBar;
}
@@ -138,7 +164,7 @@ public class LocalWindow extends JDialog {
inputField.setForeground(Color.black);
inputField.setBackground(Color.white);
JButton sendButton = new JButton("发送");
JButton sendButton = new JButton(language.getText("localWindow.sendButton"));
styleButton(sendButton);
sendButton.addActionListener(this::handleSendMessage);
@@ -204,38 +230,155 @@ public class LocalWindow extends JDialog {
if (!prompt.isEmpty()) {
appendMessage(prompt);
inputField.setText("");
new SwingWorker<String, String>() {
@Override
protected String doInBackground() {
float temperature = ((Number) tempSpinner.getValue()).floatValue();
return LM.inference(
currentModelHandle,
contextHandles.getLast(),
temperature,
prompt,
"你是一个乐于助人的AI助手请用友好自然的语气回答用户问题。",
this::publish
);
}
@Override
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);
if (searchEnabled) {
// 如果搜索功能开启,先进行搜索
new SwingWorker<String, Void>() {
@Override
protected String doInBackground() {
return searchWeb(prompt);
}
}
}.execute();
@Override
protected void done() {
try {
String searchResult = get();
logger.info("Search result: {}", searchResult);
if (searchResult.isEmpty()) {
while (true){
searchResult = searchWeb(prompt);
if (!searchResult.isEmpty()) {
break;
}
}
seekAI(prompt, searchResult);
return;
}
seekAI(prompt, searchResult);
} catch (Exception ex) {
logger.error("Search failed: ", ex);
}
}
}.execute();
} else {
analyzeWithAI(prompt, null);
}
}
}
private static String searchWeb(String query) {
int maxRetries = 2;
int retry = 0;
while (true) {
try {
// 设置请求 URL
String url = "https://cn.bing.com/search?q=" + URLEncoder.encode(query, StandardCharsets.UTF_8);
// 设置请求头和 Cookies
Document doc = Jsoup.connect(url)
.userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36")
.header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8")
.header("Accept-Language", "zh-CN,zh;q=0.9")
.header("Accept-Encoding", "gzip, deflate, br")
.header("Connection", "keep-alive")
.cookie("MUID", "你的MUID值")
.cookie("SRCHD", "你的SRCHD值")
.timeout(10000)
.get();
StringBuilder result = new StringBuilder();
Elements items = doc.select("li.b_algo");
for (Element item : items) {
String title = item.select("h2").text();
String urlLink = item.select("a").attr("href");
String snippet = item.select("div.b_caption p").text();
String urlContent = "未爬取";
result.append("标题: ").append(title)
.append("\n链接: ").append(urlLink)
.append("\n摘要: ").append(snippet)
.append("\n爬取到的内容: ").append(urlContent)
.append("\n\n");
}
return result.toString();
} catch (IOException e) {
retry++;
if (retry > maxRetries) {
System.err.println("搜索失败(重试 " + maxRetries + " 次): " + e.getMessage());
return "搜索失败: " + e.getMessage();
}
}
}
}
private void analyzeWithAI(String prompt, String searchResult) {
new SwingWorker<String, String>() {
@Override
protected String doInBackground() {
float temperature = ((Number) tempSpinner.getValue()).floatValue();
String fullPrompt = searchResult != null ? ("\n\n搜索结果:\n" + searchResult + "") + prompt : prompt;
return LM.inference(
currentModelHandle,
contextHandles.getLast(),
temperature,
fullPrompt,
language.getText("localWindow.prompt.system"),
this::publish
);
}
@Override
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();
}
private void seekAI(String prompt, String searchResult) {
new SwingWorker<String, String>() {
@Override
protected String doInBackground() {
float temperature = ((Number) tempSpinner.getValue()).floatValue();
String fullPrompt = searchResult != null ? ("\n\n搜索结果:\n" + searchResult + "") + prompt : prompt;
return LM.inference(
currentModelHandle,
contextHandles.getLast(),
temperature,
fullPrompt,
language.getText("localWindow.prompt.system.2"),
this::publish
);
}
@Override
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 void appendAIMessage(String message) {
SwingUtilities.invokeLater(() -> {
@@ -256,7 +399,7 @@ public class LocalWindow extends JDialog {
private void appendMessage(String message) {
SwingUtilities.invokeLater(() -> {
logger.info("\n【用户】\n{}", message);
chatArea.append("\n【用户】\n" + message + "\n\n");
chatArea.append("\n"+ language.getText("localWindow.prompt.user")+"\n" + message + "\n\n");
chatArea.setCaretPosition(chatArea.getDocument().getLength());
});
}

View File

@@ -1,6 +1,9 @@
package com.axis.innovators.box.gui;
import com.axis.innovators.box.AxisInnovatorsBox;
import com.axis.innovators.box.events.*;
import com.axis.innovators.box.register.RegistrationSettingsItem;
import com.axis.innovators.box.register.LanguageManager;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -47,18 +50,26 @@ public class MainWindow extends JFrame {
categories.add(category);
}
public void initUI() {
setTitle("轴创工具箱 v1.0");
// 设置窗口属性
setTitle(LanguageManager.getLoadedLanguages().getText("mainWindow.title"));
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(1200, 800);
setLocationRelativeTo(null);
// 设置窗口和内容面板透明
//setBackground(new Color(0, 0, 0, 0));
getContentPane().setBackground(new Color(0, 0, 0, 0));
// 自定义面板
JPanel mainPanel = new JPanel() {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
Color color1 = new Color(235, 241, 250);
Color color2 = new Color(255, 255, 255);
GradientPaint gp = new GradientPaint(0, 0, color1, getWidth(), getHeight(), color2);
@@ -80,23 +91,29 @@ public class MainWindow extends JFrame {
int y = (getHeight() - backgroundImage.getIconHeight()) / 2;
g2d.drawImage(backgroundImage.getImage(), x, y, this);
}
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f));
} catch (Exception e) {
logger.error("Failed to load background image", e);
}
}
}
};
// 强制面板不透明
mainPanel.setOpaque(true);
mainPanel.putClientProperty("FlatLaf.style", "background: null;");
// 设置布局和边距
mainPanel.setLayout(new BorderLayout(20, 20));
mainPanel.setBorder(BorderFactory.createEmptyBorder(30, 30, 30, 30));
// 添加其他组件
mainPanel.add(createHeader(), BorderLayout.NORTH);
mainPanel.add(createCategoryTabs(), BorderLayout.CENTER);
GlobalEventBus.EVENT_BUS.post(new MainWindowEvents.initialize(this, mainPanel));
// 添加主面板到窗口
add(mainPanel);
}
@@ -243,7 +260,7 @@ public class MainWindow extends JFrame {
header.setBorder(BorderFactory.createEmptyBorder(15, 30, 15, 30));
// 创建标题
JLabel title = new JLabel("轴创工具箱");
JLabel title = new JLabel(LanguageManager.getLoadedLanguages().getText("mainWindow.title.2"));
title.setFont(new Font("微软雅黑", Font.BOLD, 28));
title.setForeground(new Color(44, 62, 80));
@@ -272,28 +289,50 @@ public class MainWindow extends JFrame {
super.update(g);
}
private void showSettings() {
JDialog dialog = new JDialog(this, "系统设置", true);
private WindowsJDialog dialog;
public void showSettings() {
if (dialog == null || !AxisInnovatorsBox.getMain().isWindowStartup(dialog)) {
dialog = new WindowsJDialog(this,
LanguageManager.getLoadedLanguages().getText("mainWindow.settings.title"), true);
}
dialog.setTitle(LanguageManager.getLoadedLanguages().getText("mainWindow.settings.title"));
dialog.setSize(600, 400);
dialog.setLocationRelativeTo(this);
JPanel content = new JPanel(new BorderLayout());
content.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
JTabbedPane tabbedPane = new JTabbedPane();
List<RegistrationSettingsItem> registrationSettingsItemList
= RegistrationSettingsItem.getRegistrationSettingsItemList();
for (RegistrationSettingsItem registrationSettingsItem : registrationSettingsItemList) {
registrationSettingsItem.registration(tabbedPane);
}
content.add(tabbedPane, BorderLayout.CENTER);
GlobalEventBus.EVENT_BUS.post(new SettingsLoadEvents(dialog, content));
dialog.add(content);
dialog.setVisible(true);
dialog.revalidate();
if (!AxisInnovatorsBox.getMain().isWindowStartup(dialog)) {
AxisInnovatorsBox.getMain().popupWindow(dialog);
}
}
private JPanel createToolCard(ToolItem tool) {
JPanel card = new JPanel() {
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// 毛玻璃效果
BufferedImage background = new BufferedImage(
getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
super.paintComponent(background.getGraphics());
BufferedImage blurred = applyGaussianBlur(background, 5);
g2d.drawImage(blurred, 0, 0, null);
// 绘制阴影
int elevation = cardElevations.getOrDefault(this, 2);

View File

@@ -9,7 +9,7 @@ import java.util.Map;
* 启动窗口的任务系统
* @author tzdwindows 7
*/
public class ProgressBarManager {
public class ProgressBarManager extends WindowsJDialog {
private JFrame loadingFrame;
private JProgressBar mainProgressBar;
private JProgressBar subProgressBar;

View File

@@ -0,0 +1,51 @@
package com.axis.innovators.box.gui;
import com.axis.innovators.box.AxisInnovatorsBox;
import com.axis.innovators.box.register.LanguageManager;
import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
* @author tzdwindows 7
*/
public class WindowsJDialog extends JDialog {
public static LanguageManager.Language language = LanguageManager.getLoadedLanguages();
public WindowsJDialog() {}
public WindowsJDialog(Window owner, String title, Dialog.ModalityType modalityType) {
super(owner, title, modalityType);
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
dispose();
}
});
}
public WindowsJDialog(Frame owner, String title, boolean modal) {
super(owner, title, modal);
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
dispose();
}
});
}
public void initUI() {
language = LanguageManager.getLoadedLanguages();
}
public void dispose_() {
super.dispose();
}
@Override
public void dispose() {
AxisInnovatorsBox.getMain().clearWindow(this);
super.dispose();
}
}

View File

@@ -2,6 +2,8 @@ package com.axis.innovators.box.plugins;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
@@ -32,14 +34,10 @@ public class BoxClassLoader extends URLClassLoader {
try {
PluginLoader.loadCorePlugin();
} catch (IOException e) {
throw new RuntimeException("Failed to load core plugin", e);
throw new RuntimeException(e);
}
}
public BoxClassLoader(URL[] urls, ClassLoader parent) {
super(urls, parent);
}
@Override
public void addURL(URL url) {
super.addURL(url);
@@ -49,7 +47,9 @@ public class BoxClassLoader extends URLClassLoader {
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
synchronized (getClassLoadingLock(name)) {
Class<?> loadedClass = findLoadedClass(name);
if (loadedClass != null) return loadedClass;
if (loadedClass != null) {
return loadedClass;
}
if (isBlacklisted(name)) {
return getParent().loadClass(name);
@@ -57,7 +57,9 @@ public class BoxClassLoader extends URLClassLoader {
try {
Class<?> c = findClass(name);
if (resolve) resolveClass(c);
if (resolve) {
resolveClass(c);
}
return c;
} catch (ClassNotFoundException e) {
return super.loadClass(name, resolve);
@@ -107,6 +109,10 @@ public class BoxClassLoader extends URLClassLoader {
CLASS_TRANSFORMS.add(transformer);
}
public static List<IClassTransformer> getClassTransforms() {
return CLASS_TRANSFORMS;
}
public static List<Class<?>> getClassList() {
return CLASS_LOADING_LIST_OBJECT;
}

View File

@@ -1,14 +1,19 @@
package com.axis.innovators.box.plugins;
import java.util.Map;
/**
* Core插件接口
* @author tzdwindows 7
*/
public interface LoadingCorePlugin {
String[] getLibraryRequestClass();
/**
* 获取主类
* @return 请返回插件主类
*/
String getMainClass();
/**
* 获取ASM转换器
* @return 请返回ASM转换器
*/
String[] getASMTransformerClass();
String getSetupClass();
void injectData(Map<String, Object> data);
}

View File

@@ -12,6 +12,7 @@ public class PluginDescriptor {
private String icon;
private String description;
private Object instance;
private String transformers;
// Getters and Setters
public String getId() { return id; }
@@ -26,4 +27,6 @@ public class PluginDescriptor {
public void setDescription(String description) { this.description = description; }
public Object getInstance() { return instance; }
public void setInstance(Object instance) { this.instance = instance; }
public String getTransformers() {return transformers;}
public void setTransformers(String transformers) {this.transformers = transformers;}
}

View File

@@ -1,6 +1,6 @@
package com.axis.innovators.box.plugins;
import com.axis.innovators.box.Main;
import com.axis.innovators.box.AxisInnovatorsBox;
import com.axis.innovators.box.tools.FolderCreator;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -19,6 +19,7 @@ public class PluginLoader {
public static final String PLUGIN_PATH = FolderCreator.getPluginFolder();
private static final List<PluginDescriptor> loadedPlugins = new ArrayList<>();
private static final List<IClassTransformer> transformers = new ArrayList<>();
private static final List<String> corePluginMainClass = new ArrayList<>();
public static void loadPlugins() throws IOException {
logger = LogManager.getLogger(PluginLoader.class);
File pluginDir = null;
@@ -35,7 +36,7 @@ public class PluginLoader {
}
for (int i = 0; i < jars.length; i++) {
processJarFile(jars[i],false);
Main.getMain().progressBarManager.updateSubProgress(
AxisInnovatorsBox.getMain().progressBarManager.updateSubProgress(
"Loading Plugin " + i,
i,
jars.length);
@@ -84,14 +85,14 @@ public class PluginLoader {
}
private static void processCorePlugin(File jarFile, String corePluginClass) {
try (URLClassLoader classLoader = new URLClassLoader(
try (URLClassLoader urlClassLoader = new URLClassLoader(
new URL[]{jarFile.toURI().toURL()},
PluginLoader.class.getClassLoader())
) {
Class<?> coreClass = classLoader.loadClass(corePluginClass);
Class<?> coreClass = urlClassLoader.loadClass(corePluginClass);
if (LoadingCorePlugin.class.isAssignableFrom(coreClass)) {
LoadingCorePlugin corePlugin = (LoadingCorePlugin) coreClass.getDeclaredConstructor().newInstance();
registerTransformers(corePlugin, classLoader);
registerTransformers(corePlugin, urlClassLoader);
}
} catch (Exception e) {
logger.error("Failed to load core plugin: {}", corePluginClass, e);
@@ -99,24 +100,29 @@ public class PluginLoader {
}
private static void registerTransformers(LoadingCorePlugin corePlugin, ClassLoader classLoader) {
String[] transformerClasses = corePlugin.getASMTransformerClass();
if (transformerClasses != null) {
for (String transformerClass : transformerClasses) {
try {
Class<?> transformerClazz = classLoader.loadClass(transformerClass);
if (IClassTransformer.class.isAssignableFrom(transformerClazz)) {
IClassTransformer transformer = (IClassTransformer) transformerClazz.getDeclaredConstructor().newInstance();
transformers.add(transformer);
BoxClassLoader.addClassTransformer(transformer);
//if (corePlugin.getMainClass() != null) {
corePluginMainClass.add(corePlugin.getMainClass());
String[] transformerClasses = corePlugin.getASMTransformerClass();
if (transformerClasses != null) {
for (String transformerClass : transformerClasses) {
try {
Class<?> transformerClazz = classLoader.loadClass(transformerClass);
if (IClassTransformer.class.isAssignableFrom(transformerClazz)) {
IClassTransformer transformer = (IClassTransformer) transformerClazz.getDeclaredConstructor().newInstance();
transformers.add(transformer);
BoxClassLoader.addClassTransformer(transformer);
}
} catch (Exception e) {
logger.error("Failed to register transformer: {}", transformerClass, e);
}
} catch (Exception e) {
logger.error("Failed to register transformer: {}", transformerClass, e);
}
}
}
//} else {
// logger.error("Failed to load core plugin: {}", corePlugin.getClass().getName());
//}
}
private static void processWithManifest(JarFile jar, JarEntry entry, File jarFile) {
private static void processWithManifest(JarFile jar, JarEntry entry, File jarFile) throws IOException {
Properties props = new Properties();
try (InputStream is = jar.getInputStream(entry)) {
props.load(is);
@@ -133,11 +139,12 @@ public class PluginLoader {
descriptor.setSupportedVersions(
Arrays.asList(props.getProperty("supportedVersions").split(","))
);
logger.info("Loaded plugin: {}", descriptor.getName());
loadMainClass(props.getProperty("mainClass"), jarFile, descriptor);
if (descriptor.getInstance() != null) {
loadedPlugins.add(descriptor);
}
Attributes attributes = jar.getManifest().getMainAttributes();
String corePluginClass = attributes.getValue("CorePlugin");
descriptor.setTransformers(corePluginClass);
}
private static void processWithAnnotations(JarFile jar, File jarFile) {
@@ -147,7 +154,7 @@ public class PluginLoader {
JarEntry entry = entries.nextElement();
if (entry.getName().endsWith(".class")) {
if (classLoader != null) {
processClassEntry(entry, classLoader);
processClassEntry(entry, jar,classLoader);
}
}
}
@@ -165,7 +172,7 @@ public class PluginLoader {
return null;
}
private static void processClassEntry(JarEntry entry, URLClassLoader classLoader) {
private static void processClassEntry(JarEntry entry,JarFile jar, URLClassLoader classLoader) {
String className = entry.getName()
.replace("/", ".")
.replace(".class", "");
@@ -185,6 +192,11 @@ public class PluginLoader {
Object instance = clazz.getDeclaredConstructor().newInstance();
descriptor.setInstance(instance);
loadedPlugins.add(descriptor);
Attributes attributes = jar.getManifest().getMainAttributes();
String corePluginClass = attributes.getValue("CorePlugin");
descriptor.setTransformers(corePluginClass);
logger.info("Loaded plugin: {}", descriptor.getName());
} catch (Exception e) {
logger.error("Failed to instantiate plugin class: {}", className, e);
}

View File

@@ -0,0 +1,176 @@
package com.axis.innovators.box.register;
import com.axis.innovators.box.tools.FolderCreator;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Properties;
/**
* 语言管理器
* @author tzdwindows 7
*/
public class LanguageManager {
private static Language loadedLanguages;
private static final String LANGUAGE_PATH = FolderCreator.getLanguageFolder();
private static final List<Language> LANGUAGES = new ArrayList<>();
private static final String SAVED_LANGUAGE_FILE = LANGUAGE_PATH + "\\saved_language.properties";
static {
LANGUAGES.add(new Language("简体中文", "Zh","SimplifiedChineseLanguage"));
LANGUAGES.add(new Language("繁體中文", "TC","TraditionalChineseLanguage"));
LANGUAGES.add(new Language("English", "En","EnglishLanguage"));
}
/**
* 添加语言
* @param language 语言
*/
public static void addLanguage(Language language) {
for (int i = 0; i < LANGUAGES.size(); i++) {
Language language1 = LANGUAGES.get(i);
if (Objects.equals(language1.getRegisteredName(), language.getRegisteredName())){
LANGUAGES.set(i, language);
return;
}
}
LANGUAGES.add(language);
}
/**
* 加载语言
* @param languageName 语言注册名
*/
public static void loadLanguage(String languageName) {
loadedLanguages = LanguageManager.getLanguage(languageName);
saveCurrentLanguageToFile();
}
/**
* 将当前加载的语言保存到配置文件中
*/
private static void saveCurrentLanguageToFile() {
Properties properties = new Properties();
properties.setProperty("loadedLanguage", loadedLanguages.getRegisteredName());
try (OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(SAVED_LANGUAGE_FILE), StandardCharsets.UTF_8)) {
properties.store(writer, "Current Loaded Language");
} catch (IOException e) {
System.err.println("Failed to save current language to file: " + SAVED_LANGUAGE_FILE);
e.printStackTrace();
}
}
/**
* 从配置文件中加载保存的语言
*/
public static void loadSavedLanguage() {
Properties properties = new Properties();
try (InputStreamReader reader = new InputStreamReader(new FileInputStream(SAVED_LANGUAGE_FILE), StandardCharsets.UTF_8)) {
properties.load(reader);
String loadedLanguageName = properties.getProperty("loadedLanguage");
if (loadedLanguageName != null) {
loadedLanguages = LanguageManager.getLanguage(loadedLanguageName);
}
} catch (IOException e) {
System.err.println("Failed to load saved language from file: " + SAVED_LANGUAGE_FILE);
e.printStackTrace();
}
}
/**
* 获取已加载的语言
* @return 已加载的语言
*/
public static Language getLoadedLanguages() {
return loadedLanguages;
}
/**
* 获取语言
* @param languageName 语言注册名,或者语言名称
* @return 语言对象
*/
public static Language getLanguage(String languageName) {
for (Language language : LANGUAGES) {
if (language.getRegisteredName().equals(languageName)) {
return language;
}
}
for (Language language : LANGUAGES) {
if (language.getLanguageName().equals(languageName)) {
return language;
}
}
return null;
}
/**
* 获取所有语言
* @return 所有语言
*/
public static List<Language> getLanguages() {
return LANGUAGES;
}
public static class Language {
private final String languageName;
private final String registeredName;
private final String languageFile;
private final Properties properties;
public Language(String languageName,
String registeredName,
String languageFileName) {
this.languageName = languageName;
this.registeredName = registeredName;
if (languageFileName == null) {
this.languageFile = LANGUAGE_PATH + "\\" + registeredName + ".properties";
} else {
this.languageFile = LANGUAGE_PATH + "\\" + languageFileName + ".properties";
}
this.properties = new Properties();
loadLanguageFile();
}
/**
* 加载语言文件
*/
private void loadLanguageFile() {
try (InputStreamReader reader = new InputStreamReader(new FileInputStream(this.languageFile),
StandardCharsets.UTF_8)) {
properties.load(reader);
} catch (IOException e) {
System.err.println("Failed to load language file: " + this.languageFile);
e.printStackTrace();
}
}
/**
* 获取指定键的文本
* @param key 键
* @return 对应的文本,如果键不存在则返回 null
*/
public String getText(String key) {
if (!properties.containsKey(key)) {
return key;
}
return properties.getProperty(key);
}
public String getLanguageName() {
return languageName;
}
public String getRegisteredName() {
return registeredName;
}
public File getLanguageFile() {
return new File(languageFile);
}
}
}

View File

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

View File

@@ -0,0 +1,679 @@
package com.axis.innovators.box.register;
import com.axis.innovators.box.AxisInnovatorsBox;
import com.axis.innovators.box.gui.LoadIcon;
import com.axis.innovators.box.gui.WindowsJDialog;
import com.axis.innovators.box.plugins.PluginDescriptor;
import com.axis.innovators.box.plugins.PluginLoader;
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.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.UUID;
/**
* 用于注册设置项的类
* @author tzdwindows 7
*/
public class RegistrationSettingsItem extends WindowsJDialog {
private static final List<RegistrationSettingsItem> registrationSettingsItemList = new ArrayList<>();
private static final Logger logger = LogManager.getLogger(RegistrationSettingsItem.class);
private static RegistrationTopic registrationTopic;
private final List<UUID> uuidList = new ArrayList<>();
private final List<String> registeredNameList = new ArrayList<>();
private final List<JPanel> tabbedPanesSettings = new ArrayList<>();
private final List<String> titleList = new ArrayList<>();
private final List<Icon> iconList = new ArrayList<>();
private final List<String> tipList = new ArrayList<>();
private boolean isEmpty = true;
private final AxisInnovatorsBox mainWindow;
static {
RegistrationSettingsItem registrationSettingsItem = new RegistrationSettingsItem();
JPanel pluginPanel = createPluginSettingsPanel();
JPanel generalPanel = createGeneralSettingsPanel();
JPanel aboutPanel = createAboutPanel();
JPanel themePanel = createThemePanel();
registrationSettingsItem.addSettings(
pluginPanel, language.getText("settings.1.title"),
null, language.getText("settings.1.tip"), "system:settings_plugins_item"
);
registrationSettingsItem.addSettings(
generalPanel, language.getText("settings.2.title"),
null, language.getText("settings.2.tip"), "system:settings_appearance_item"
);
registrationSettingsItem.addSettings(
aboutPanel, language.getText("settings.3.title"),
null, language.getText("settings.3.tip"), "system:settings_information_item"
);
registrationSettingsItem.addSettings(
themePanel, language.getText("settings.4.title"),
null, language.getText("settings.4.tip"), "system:settings_theme_item"
);
registrationSettingsItemList.add(
registrationSettingsItem
);
}
public static void overloading() {
language = LanguageManager.getLoadedLanguages();
registrationSettingsItemList.clear();
RegistrationSettingsItem registrationSettingsItem = new RegistrationSettingsItem();
JPanel pluginPanel = createPluginSettingsPanel();
JPanel generalPanel = createGeneralSettingsPanel();
JPanel aboutPanel = createAboutPanel();
JPanel themePanel = createThemePanel();
registrationSettingsItem.addSettings(
pluginPanel, language.getText("settings.1.title"),
null, language.getText("settings.1.tip"), "system:settings_plugins_item"
);
registrationSettingsItem.addSettings(
generalPanel, language.getText("settings.2.title"),
null, language.getText("settings.2.tip"), "system:settings_appearance_item"
);
registrationSettingsItem.addSettings(
aboutPanel, language.getText("settings.3.title"),
null, language.getText("settings.3.tip"), "system:settings_information_item"
);
registrationSettingsItem.addSettings(
themePanel, language.getText("settings.4.title"),
null, language.getText("settings.4.tip"), "system:settings_theme_item"
);
registrationSettingsItemList.add(
registrationSettingsItem
);
AxisInnovatorsBox.getMain().getMainWindow().showSettings();
}
private static JPanel createThemePanel() {
JPanel themePanel = new JPanel(new BorderLayout());
RegistrationTopic registrationTopic = getRegistrationTopic();
if (registrationTopic.isEmpty()) {
themePanel.add(new JLabel(language.getText("settings.4.no_theme"), SwingConstants.CENTER), BorderLayout.CENTER);
return themePanel;
}
// 创建搜索栏
JPanel searchPanel = new JPanel(new BorderLayout());
JTextField searchField = new JTextField();
JButton searchButton = new JButton(language.getText("settings.4.search"));
searchPanel.add(searchField, BorderLayout.CENTER);
searchPanel.add(searchButton, BorderLayout.EAST);
searchPanel.setVisible(false);
// 将搜索栏添加到主题面板的顶部
themePanel.add(searchPanel, BorderLayout.NORTH);
DefaultListModel<JPanel> listModel = new DefaultListModel<>();
JList<JPanel> themeList = new JList<>(listModel);
themeList.setCellRenderer(new DefaultListCellRenderer() {
@Override
public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
JPanel itemPanel = (JPanel) value;
if (registrationTopic.isLoading(registrationTopic.getRegisteredNameList().get(index))) {
itemPanel.setEnabled(false);
itemPanel.setBackground(Color.LIGHT_GRAY);
} else {
itemPanel.setEnabled(true);
itemPanel.setBackground(isSelected ? list.getSelectionBackground() : list.getBackground());
}
return itemPanel;
}
});
// 监听键盘事件
themeList.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if (e.isControlDown() && e.getKeyCode() == KeyEvent.VK_F) {
searchPanel.setVisible(true);
searchField.requestFocusInWindow();
}
}
});
searchButton.addActionListener(e -> {
String searchText = searchField.getText().trim().toLowerCase();
if (searchText.isEmpty()) {
JOptionPane.showMessageDialog(null,
language.getText("settings.4.search_empty"),
language.getText("settings.4.search_empty_title"), JOptionPane.INFORMATION_MESSAGE);
return;
}
for (int i = 0; i < registrationTopic.getTopicsClasses().size(); i++) {
String topicName = registrationTopic.getTopicsName().get(i).toLowerCase();
if (topicName.contains(searchText)) {
themeList.setSelectedIndex(i);
themeList.ensureIndexIsVisible(i);
return;
}
}
JOptionPane.showMessageDialog(null,
language.getText("settings.4.search_not_found"),
language.getText("settings.4.search_not_found_title"), JOptionPane.INFORMATION_MESSAGE);
});
themeList.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
int index = themeList.locationToIndex(e.getPoint());
if (index >= 0) {
if (registrationTopic.isLoading(registrationTopic.getRegisteredNameList().get(index))) {
JOptionPane.showMessageDialog(null, language.getText("settings.4.loading"),
language.getText("settings.4.loading_title"), JOptionPane.INFORMATION_MESSAGE);
return;
}
loadTheme(registrationTopic, index, themeList);
}
}
}
});
JPopupMenu popupMenu = new JPopupMenu();
JMenuItem loadMenuItem = new JMenuItem(language.getText("settings.4.load"));
loadMenuItem.addActionListener(e -> {
int index = themeList.getSelectedIndex();
if (index >= 0) {
if (registrationTopic.isLoading(registrationTopic.getRegisteredNameList().get(index))) {
JOptionPane.showMessageDialog(null, language.getText("settings.4.loading"),
language.getText("settings.4.loading_title"), JOptionPane.INFORMATION_MESSAGE);
return;
}
loadTheme(registrationTopic, index, themeList);
}
});
popupMenu.add(loadMenuItem);
themeList.setComponentPopupMenu(popupMenu);
for (int i = 0; i < registrationTopic.getTopicsClasses().size(); i++) {
JPanel itemPanel = new JPanel(new BorderLayout());
itemPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
JLabel iconLabel = new JLabel(registrationTopic.getIconList().get(i));
itemPanel.add(iconLabel, BorderLayout.WEST);
JPanel infoPanel = new JPanel(new GridLayout(0, 1));
String tip = registrationTopic.getTipList().get(i);
if (tip == null) {
tip = registrationTopic.getTopicsClassesLookAndFeel().get(i).getName();
}
infoPanel.add(new JLabel(language.getText("settings.4.info") + tip));
infoPanel.add(new JLabel(language.getText("settings.4.info.1") + registrationTopic.getTopicsName().get(i)));
infoPanel.add(new JLabel(language.getText("settings.4.info.2") + registrationTopic.getTipList().get(i)));
infoPanel.add(new JLabel(language.getText("settings.4.info.3") + registrationTopic.getRegisteredNameList().get(i)));
itemPanel.add(infoPanel, BorderLayout.CENTER);
listModel.addElement(itemPanel);
}
JScrollPane scrollPane = new JScrollPane(themeList);
themePanel.add(scrollPane, BorderLayout.CENTER);
return themePanel;
}
/**
* 加载主题
*/
private static void loadTheme(RegistrationTopic registrationTopic, int index, JList<JPanel> themeList) {
String themeClass = registrationTopic.getTopicsClasses().get(index);
String themeName = registrationTopic.getTopicsName().get(index);
String registeredName = registrationTopic.getRegisteredNameList().get(index);
try {
if (themeClass != null) {
UIManager.setLookAndFeel(themeClass);
} else {
LookAndFeel theme = registrationTopic.getTopicsClassesLookAndFeel().get(index);
UIManager.setLookAndFeel(theme);
}
JOptionPane.showMessageDialog(null, language.getText("settings.4.load_theme_success")
+ themeName + language.getText("settings.4.load_theme_success.2"),
language.getText("settings.4.load_theme_success.3"), JOptionPane.INFORMATION_MESSAGE);
registrationTopic.setLoading(registeredName);
themeList.repaint();
} catch (Exception e) {
JOptionPane.showMessageDialog(null, language.getText("settings.4.load_theme_error")
+ e.getMessage(),
language.getText("settings.4.load_theme_error.title"),
JOptionPane.ERROR_MESSAGE);
}
}
private static RegistrationTopic getRegistrationTopic() {
return registrationTopic;
}
private static 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(language.getText("settings.3.infoArea.1") + AxisInnovatorsBox.getVersion() + "\n\n");
infoArea.append(language.getText("settings.3.infoArea.2") + "\n");
for (String author : AxisInnovatorsBox.getAuthor()) {
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 static void applyThemeColor(Color color) {
UIManager.put("Panel.background", color);
UIManager.put("TabbedPane.background", color);
SwingUtilities.updateComponentTreeUI(AxisInnovatorsBox.getMain().getMainWindow());
}
private static JPanel createPluginSettingsPanel() {
JPanel panel = new JPanel(new BorderLayout());
String[] columns = {
language.getText("settings.1.columns.1"),
language.getText("settings.1.columns.2"),
language.getText("settings.1.columns.3")
};
DefaultTableModel model = new DefaultTableModel(columns, 0) {
@Override
public boolean isCellEditable(int row, int column) {
return false;
}
};
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));
table.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
int selectedRow = table.getSelectedRow();
if (selectedRow >= 0) {
PluginDescriptor selectedPlugin = plugins.get(selectedRow);
showPluginDetails(selectedPlugin);
}
}
}
});
JScrollPane scrollPane = new JScrollPane(table);
scrollPane.setBorder(BorderFactory.createTitledBorder(language.getText("settings.1.scrollPane")));
panel.add(scrollPane, BorderLayout.CENTER);
return panel;
}
private static void showPluginDetails(PluginDescriptor plugin) {
JDialog dialog = new JDialog(AxisInnovatorsBox.getMain().getMainWindow(), "插件详细信息", true);
dialog.setLayout(new BorderLayout());
dialog.setSize(500, 400);
dialog.setLocationRelativeTo(AxisInnovatorsBox.getMain().getMainWindow());
JPanel mainPanel = new JPanel(new BorderLayout(10, 10));
mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
JPanel iconPanel = new JPanel();
ImageIcon icon = LoadIcon.loadIcon(plugin.getInstance().getClass(), plugin.getIcon(), 64);
JLabel iconLabel = new JLabel(icon);
iconPanel.add(iconLabel);
mainPanel.add(iconPanel, BorderLayout.WEST);
JPanel infoPanel = new JPanel(new GridLayout(0, 1, 5, 5));
infoPanel.setBorder(BorderFactory.createTitledBorder("插件信息"));
infoPanel.add(new JLabel("插件名称: " + plugin.getName()));
String classFilePath = plugin.getClass().getResource(plugin.getClass().getSimpleName() + ".class").toString();
if (classFilePath.startsWith("jar:")) {
classFilePath = classFilePath.substring("jar:".length(), classFilePath.indexOf("!"));
} else if (classFilePath.startsWith("file:")) {
classFilePath = classFilePath.substring("file:".length(), classFilePath.indexOf(plugin.getClass().getSimpleName() + ".class"));
}
JTextArea locationTextArea = new JTextArea("插件位置: " + classFilePath);
locationTextArea.setLineWrap(true);
locationTextArea.setWrapStyleWord(true);
locationTextArea.setEditable(false);
locationTextArea.setBackground(infoPanel.getBackground());
infoPanel.add(new JScrollPane(locationTextArea));
infoPanel.add(new JLabel("主类: " + plugin.getInstance().getClass()));
if (plugin.getTransformers() != null) {
infoPanel.add(new JLabel("核心转换器: " + plugin.getTransformers()));
} else {
infoPanel.add(new JLabel("核心转换器: 无"));
}
infoPanel.add(new JLabel("描述: " + plugin.getDescription()));
mainPanel.add(infoPanel, BorderLayout.CENTER);
JButton closeButton = new JButton("关闭");
closeButton.addActionListener(e -> dialog.dispose());
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
buttonPanel.add(closeButton);
mainPanel.add(buttonPanel, BorderLayout.SOUTH);
dialog.add(mainPanel);
dialog.setVisible(true);
}
private static 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(language.getText("settings.2.color")), gbc);
JButton colorBtn = new JButton(language.getText("settings.2.colorBtn"));
colorBtn.addActionListener(e -> {
Color color = JColorChooser.showDialog(panel,
language.getText("settings.2.colorBtn.color"), Color.WHITE);
if (color != null) {
applyThemeColor(color);
}
});
gbc.gridx = 1;
panel.add(colorBtn, gbc);
// 界面字体设置
gbc.gridy++;
gbc.gridx = 0;
panel.add(new JLabel(language.getText("settings.2.font")), gbc);
JButton fontBtn = new JButton(language.getText("settings.2.fontBtn"));
fontBtn.addActionListener(e -> {
Font currentFont = UIManager.getFont("Label.font");
FontChooser fontChooser = new FontChooser(currentFont);
int result = JOptionPane.showConfirmDialog(
panel,
fontChooser,
language.getText("settings.2.showConfirmDialog"),
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(language.getText("settings.2.cuda")), gbc);
JCheckBox cudaCheckBox = new JCheckBox(language.getText("settings.2.cudaCheckBox"), 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, language.getText("settings.2.cuda.error"),
language.getText("settings.2.cuda.error.1"), JOptionPane.ERROR_MESSAGE);
}
});
gbc.gridx = 1;
panel.add(cudaCheckBox, gbc);
// 语言设置
gbc.gridy++;
gbc.gridx = 0;
panel.add(new JLabel(language.getText("settings.2.language")), gbc);
List<LanguageManager.Language> languages = LanguageManager.getLanguages();
String[] languageNames = languages.stream()
.map(LanguageManager.Language::getLanguageName)
.toArray(String[]::new);
JComboBox<String> languageComboBox = new JComboBox<>(languageNames);
if (LanguageManager.getLoadedLanguages() != null) {
languageComboBox.setSelectedItem(LanguageManager.getLoadedLanguages().getLanguageName());
} else {
languageComboBox.setSelectedItem(language.getText("settings.2.language.error"));
}
languageComboBox.addActionListener(e -> {
String selectedLanguageName = (String) languageComboBox.getSelectedItem();
LanguageManager.Language selectedLanguage = LanguageManager.getLanguage(selectedLanguageName);
if (selectedLanguage != null) {
LanguageManager.loadLanguage(selectedLanguage.getRegisteredName());
logger.info("语言已切换为: " + selectedLanguage.getLanguageName());
AxisInnovatorsBox.getMain().reloadAllWindow();
} else {
logger.error("无法切换语言: " + selectedLanguageName);
}
});
gbc.gridx = 1;
panel.add(languageComboBox, gbc);
return panel;
}
private static 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);
}
}
RegistrationSettingsItem() {
this.mainWindow = null;
registrationTopic = AxisInnovatorsBox.getMain().getRegistrationTopic();
}
public RegistrationSettingsItem(AxisInnovatorsBox main) {
this.mainWindow = main;
registrationTopic = main.getRegistrationTopic();
}
/**
* 注册设置项
* @param tabbedPanesSettings 设置页面
* @param title 标题
* @param icon 显示图标可为null
* @param tip 描述
* @param registeredName 注册名(必须是唯一的)
*/
public void addSettings(JPanel tabbedPanesSettings,
String title,
Icon icon,
String tip,
String registeredName) {
if (mainWindow != null) {
if (!mainWindow.isWindow()) {
registrationItem(tabbedPanesSettings, title, icon, tip, registeredName);
} else {
logger.warn("Wrong time to add tools");
}
} else {
registrationItem(tabbedPanesSettings, title, icon, tip, registeredName);
}
}
private void registrationItem(JPanel tabbedPanesSettings, String title, Icon icon, String tip, String registeredName) {
if (registeredNameList.contains(registeredName)) {
throw new RegistrationError(registeredName + " duplicate registered names");
}
this.isEmpty = false;
this.uuidList.add(UUID.randomUUID());
this.tabbedPanesSettings.add(tabbedPanesSettings);
this.titleList.add(title);
this.iconList.add(icon);
this.tipList.add(tip);
}
/**
* 获取设置项
* @param id id
* @return JPanel对象
*/
public JPanel getSettings(UUID id) {
for (int i = 0; i < uuidList.size(); i++) {
if (uuidList.get(i).equals(id)) {
return tabbedPanesSettings.get(i);
}
}
return null;
}
/**
* 通过注册名获取UUID
* @param registeredName 注册名
* @return UUID
*/
public UUID getUUID(String registeredName) {
for (int i = 0; i < registeredNameList.size(); i++) {
if (registeredNameList.get(i).equals(registeredName)) {
return uuidList.get(i);
}
}
return null;
}
/**
* 注册设置项
* @param registrationSettingsItem 注册设置项
*/
public void addRegistrationSettingsItem(RegistrationSettingsItem registrationSettingsItem) {
if (registrationSettingsItem.isEmpty()) {
logger.warn("Empty registration settings item");
return;
}
registrationSettingsItemList.add(registrationSettingsItem);
}
/**
* 注册设置项
* @param tabbedPane JTabbedPane
*/
public void registration(JTabbedPane tabbedPane) {
for (int i = 0; i < tabbedPanesSettings.size(); i++) {
tabbedPane.addTab(titleList.get(i), iconList.get(i), tabbedPanesSettings.get(i), tipList.get(i));
}
}
/**
* 获取所有注册设置项
* @return List<RegistrationSettingsItem>
*/
public static List<RegistrationSettingsItem> getRegistrationSettingsItemList() {
return registrationSettingsItemList;
}
public List<UUID> getUUIDList() {
return uuidList;
}
public List<String> getRegisteredNameList() {
return registeredNameList;
}
public List<JPanel> getTabbedPanesSettings() {
return tabbedPanesSettings;
}
public List<String> getTitleList() {
return titleList;
}
public List<Icon> getIconList() {
return iconList;
}
public List<String> getTipList() {
return tipList;
}
public boolean isEmpty() {
return isEmpty;
}
}

View File

@@ -1,6 +1,6 @@
package com.axis.innovators.box.register;
import com.axis.innovators.box.Main;
import com.axis.innovators.box.AxisInnovatorsBox;
import com.axis.innovators.box.gui.FridaWindow;
import com.axis.innovators.box.gui.LocalWindow;
import com.axis.innovators.box.gui.MainWindow;
@@ -21,12 +21,12 @@ import java.util.UUID;
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 AxisInnovatorsBox main;
private final List<UUID> uuidList = new ArrayList<>();
private final List<String> registeredNameList = new ArrayList<>();
public RegistrationTool(Main mainWindow) {
this.main = mainWindow;
public RegistrationTool(AxisInnovatorsBox main) {
this.main = main;
int id = 0;
MainWindow.ToolCategory debugCategory = new MainWindow.ToolCategory("调试工具",
"debug/debug.png",
@@ -39,7 +39,7 @@ public class RegistrationTool {
public void actionPerformed(ActionEvent e) {
Window owner = SwingUtilities.windowForComponent((Component) e.getSource());
FridaWindow fridaWindow = new FridaWindow(owner);
fridaWindow.setVisible(true);
main.popupWindow(fridaWindow);
}
}));
@@ -54,7 +54,7 @@ public class RegistrationTool {
public void actionPerformed(ActionEvent e) {
Window owner = SwingUtilities.windowForComponent((Component) e.getSource());
LocalWindow dialog = new LocalWindow(owner);
dialog.setVisible(true);
main.popupWindow(dialog);
}
}));
@@ -70,7 +70,7 @@ public class RegistrationTool {
String registeredName) {
if (!main.isWindow()) {
if (registeredNameList.contains(registeredName)) {
throw new ToolsRegistrationError(registeredName + " duplicate registered names");
throw new RegistrationError(registeredName + " duplicate registered names");
}
uuidList.add(toolCategory.getId());
registeredNameList.add(registeredName);

View File

@@ -0,0 +1,135 @@
package com.axis.innovators.box.register;
import com.axis.innovators.box.AxisInnovatorsBox;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import javax.swing.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* 注册主题
* @author tzdwindows 7
*/
public class RegistrationTopic {
private final Logger logger = LogManager.getLogger(RegistrationTopic.class);
private final List<String> topicsClasses = new ArrayList<>();
private final List<LookAndFeel> topicsClassesLookAndFeel = new ArrayList<>();
private final List<String> topicsName = new ArrayList<>();
private final List<String> registeredNameList = new ArrayList<>();
private final List<Icon> iconList = new ArrayList<>();
private final List<String> tipList = new ArrayList<>();
private final AxisInnovatorsBox axisInnovatorsBox;
private String loadTopics = "";
public RegistrationTopic(AxisInnovatorsBox axisInnovatorsBox) {
this.axisInnovatorsBox = axisInnovatorsBox;
}
/**
* 注册主题
* @param topicClass 主题类
* @param topicName 主题名
* @param icon 显示图标
* @param registeredName 注册名
*/
public void addTopic(String topicClass, String topicName, String tip ,Icon icon, String registeredName) {
if (!axisInnovatorsBox.isWindow()) {
if (registeredNameList.contains(registeredName)) {
throw new RegistrationError(registeredName + " duplicate registered names");
}
topicsClasses.add(topicClass);
topicsClassesLookAndFeel.add(null);
topicsName.add(topicName);
tipList.add(tip);
iconList.add(icon);
registeredNameList.add(registeredName);
} else {
logger.warn("Wrong time to add topics");
}
}
/**
* 注册主题
* @param topicClass 主题类
* @param topicName 主题名
* @param icon 显示图标
* @param registeredName 注册名
*/
public void addTopic(LookAndFeel topicClass, String topicName, String tip ,Icon icon, String registeredName) {
if (!axisInnovatorsBox.isWindow()) {
if (registeredNameList.contains(registeredName)) {
throw new RegistrationError(registeredName + " duplicate registered names");
}
topicsClasses.add(null);
topicsClassesLookAndFeel.add(topicClass);
topicsName.add(topicName);
tipList.add(tip);
iconList.add(icon);
registeredNameList.add(registeredName);
} else {
logger.warn("Wrong time to add topics");
}
}
/**
* 判断是否已经加载
* @return 是否已经加载
*/
public boolean isLoading(String loading) {
if (loadTopics.isEmpty()) {
return false;
}
return Objects.equals(loading, loadTopics);
}
/**
* 设置是否加载
* @param loading 是否加载
*/
public void setLoading(String loading) {
loadTopics = loading;
}
/**
* 判断是否为空
* @return 是否为空
*/
public boolean isEmpty() {
return registeredNameList.isEmpty();
}
/**
* 获取主题类
* @return 主题类
*/
public List<String> getTopicsClasses() {
return topicsClasses;
}
public AxisInnovatorsBox getAxisInnovatorsBox() {
return axisInnovatorsBox;
}
public List<LookAndFeel> getTopicsClassesLookAndFeel() {
return topicsClassesLookAndFeel;
}
public List<Icon> getIconList() {
return iconList;
}
public List<String> getRegisteredNameList() {
return registeredNameList;
}
public List<String> getTipList() {
return tipList;
}
public List<String> getTopicsName() {
return topicsName;
}
}

View File

@@ -0,0 +1,78 @@
package com.axis.innovators.box.tools;
import java.io.File;
import java.util.Arrays;
import java.util.Comparator;
public class FolderCleaner {
/**
* 清理文件夹中的文件
*
* @param folderPath 文件夹路径
* @param maxFiles 最大文件数量
*/
public static void cleanFolder(String folderPath, int maxFiles) {
File folder = new File(folderPath);
// 检查文件夹是否存在
if (!folder.exists() || !folder.isDirectory()) {
System.out.println("文件夹不存在或不是一个有效的文件夹: " + folderPath);
return;
}
// 获取文件夹中的文件列表
File[] files = folder.listFiles();
if (files == null) {
System.out.println("无法读取文件夹内容: " + folderPath);
return;
}
// 如果文件数量未超过最大值,直接返回
if (files.length <= maxFiles) {
System.out.println("文件数量未超过最大值,无需清理。");
return;
}
// 按文件最后修改时间排序(从旧到新)
Arrays.sort(files, Comparator.comparingLong(File::lastModified));
// 删除最旧的文件,直到文件数量不超过最大值
for (int i = 0; i < files.length - maxFiles; i++) {
File fileToDelete = files[i];
// 检查文件是否未被占用
if (isFileUnlocked(fileToDelete)) {
if (fileToDelete.delete()) {
System.out.println("已删除文件: " + fileToDelete.getName());
} else {
System.out.println("无法删除文件: " + fileToDelete.getName());
}
} else {
System.out.println("文件被占用,跳过删除: " + fileToDelete.getName());
}
}
}
/**
* 检查文件是否未被占用
*
* @param file 文件
* @return 如果文件未被占用返回 true否则返回 false
*/
private static boolean isFileUnlocked(File file) {
File tempFile = new File(file.getParentFile(), file.getName() + ".tmp");
if (file.renameTo(tempFile)) {
tempFile.renameTo(file);
return true;
}
return false;
}
public static void main(String[] args) {
String folderPath = "C:/path/to/your/folder";
int maxFiles = 10;
cleanFolder(folderPath, maxFiles);
}
}

View File

@@ -14,7 +14,25 @@ public class FolderCreator {
public static final String LIBRARY_NAME = "library";
public static final String MODEL_PATH = "model";
public static final String PLUGIN_PATH = "plug-in";
public static final String LOGS_PATH = "logs";
public static final String LANGUAGE_PATH = "language";
public static final String CONFIGURATION_PATH = "state";
public static String getConfigurationFolder() {
String folder = createFolder(CONFIGURATION_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 getLanguageFolder() {
String folder = createFolder(LANGUAGE_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 getPluginFolder() {
String folder = createFolder(PLUGIN_PATH);
if (folder == null) {
@@ -36,6 +54,18 @@ public class FolderCreator {
return folder;
}
public static String getLogsFolder() {
String folder = createFolder(LOGS_PATH);
if (folder == null) {
if (logger == null) {
logger = LogManager.getLogger();
}
logger.error("Library folder creation failed, please use administrator privileges to execute this procedure");
return null;
}
return folder;
}
public static String getLibraryFolder() {
String folder = createFolder(LIBRARY_NAME);
if (folder == null) {

View File

@@ -0,0 +1,163 @@
package com.axis.innovators.box.tools;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
/**
* 对状态进行管理
* @author tzdwindows 7
*/
public class StateManager {
private final String statusFile;
private final Map<String, String> configMap;
private final Properties properties;
/**
* 构造函数
* @param statusName 状态文件名
*/
public StateManager(String statusName) {
statusFile = FolderCreator.getConfigurationFolder() + statusName + ".properties";
configMap = new HashMap<>();
properties = new Properties();
loadConfiguration();
}
/**
* 默认构造函数
*/
public StateManager() {
statusFile = FolderCreator.getConfigurationFolder() + "state_management.properties";
configMap = new HashMap<>();
properties = new Properties();
loadConfiguration();
}
/**
* 加载配置文件内容到Map中
* 如果文件不存在,则创建该文件
*/
private void loadConfiguration() {
File configFile = new File(statusFile);
if (!configFile.exists()) {
try {
configFile.getParentFile().mkdirs();
configFile.createNewFile();
System.out.println("The configuration file does not exist, a new one has been created: " + statusFile);
} catch (IOException e) {
e.printStackTrace();
return;
}
}
try (FileInputStream fis = new FileInputStream(configFile)) {
properties.load(fis);
for (String key : properties.stringPropertyNames()) {
configMap.put(key, properties.getProperty(key));
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 保存状态到Map和配置文件中
* @param key 键
* @param value 值
*/
public void saveState(String key, String value) {
configMap.put(key, value);
properties.setProperty(key, value);
saveToFile();
}
public void saveState(String key, int value) {
saveState(key, String.valueOf(value));
}
public void saveState(String key, long value) {
saveState(key, String.valueOf(value));
}
public void saveState(String key, float value) {
saveState(key, String.valueOf(value));
}
public void saveState(String key, boolean value) {
saveState(key, String.valueOf(value));
}
public void saveState(String key, double value) {
saveState(key, String.valueOf(value));
}
public void saveState(String key, char value) {
saveState(key, String.valueOf(value));
}
public void saveState(String key, byte value) {
saveState(key, String.valueOf(value));
}
public void saveState(String key, short value) {
saveState(key, String.valueOf(value));
}
/**
* 将当前状态保存到配置文件中
*/
private void saveToFile() {
try (FileOutputStream fos = new FileOutputStream(statusFile)) {
properties.store(fos, "Updated configuration");
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 从Map中获取状态值
* @param key 键
* @return 值
*/
public String getState(String key) {
return configMap.get(key);
}
public int getStateAsInt(String key) {
return Integer.parseInt(configMap.get(key));
}
public long getStateAsLong(String key) {
return Long.parseLong(configMap.get(key));
}
public float getStateAsFloat(String key) {
return Float.parseFloat(configMap.get(key));
}
public boolean getStateAsBoolean(String key) {
return Boolean.parseBoolean(configMap.get(key));
}
public double getStateAsDouble(String key) {
return Double.parseDouble(configMap.get(key));
}
public char getStateAsChar(String key) {
return configMap.get(key).charAt(0);
}
public byte getStateAsByte(String key) {
return Byte.parseByte(configMap.get(key));
}
public short getStateAsShort(String key) {
return Short.parseShort(configMap.get(key));
}
}

View File

@@ -1,87 +0,0 @@
package org.tzd.frida;
import org.tzd.frida.windows.CallbackMessage;
import org.tzd.frida.windows.Frida;
import org.tzd.frida.windows.FridaRunnable;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* Main 类用于启动和执行 Frida 注入操作。
*
* <p>此类主要包含一个入口方法 <code>main</code>,用于加载必要的本地库并初始化 Frida 对象。</p>
* <p>它会通过调用 <code>getProcessPid</code> 方法获取指定进程的 PID并将 JavaScript 代码注入到目标进程中。</p>
*
* @author tzdwindows 7
*/
public class Main {
/**
* 程序入口方法。
*
* <p>此方法加载本地 DLL 库并创建一个 <code>Frida</code> 实例。接着通过 <code>run</code> 和 <code>execute</code> 方法执行指定的任务。</p>
* <p>执行期间,会将回调函数添加到 <code>Frida</code> 实例中,接收并打印消息。</p>
*
* @param args 命令行参数
*/
public static void main(String[] args) {
// 加载本地 DLL 文件
System.load("C:\\Users\\Administrator\\source\\repos\\FridaNative\\x64\\Release\\FridaNative.dll");
// 创建 Frida 实例并传入 JavaScript 代码及进程 PID
Frida frida = new Frida("console.log('Hello, Frida!');", getProcessPid("java.exe"));
// 执行 Frida 任务,注入代码并注册回调函数
frida.run(new Runnable() {
@Override
public void run() {
// 在此处添加要执行的代码
}
}).execute(new FridaRunnable() {
@Override
public void run(Frida frida) {
// 注册回调消息,接收到消息时打印
frida.addCallbackMessage(new CallbackMessage() {
@Override
public void onMessage(String message) {
System.out.println(message); // 打印收到的消息
}
});
}
}).start(); // 启动线程
}
/**
* 获取指定进程的 PID。
*
* <p>此方法通过运行 Windows 命令 <code>tasklist</code> 获取系统中所有正在运行的进程,并查找指定进程名。</p>
* <p>一旦找到匹配的进程,它将提取进程的 PID 并返回。</p>
*
* @param processName 要查找的进程名称。
* @return 目标进程的 PID如果未找到则返回 -1。
*/
public static long getProcessPid(String processName) {
long pid = -1;
try {
ProcessBuilder builder = new ProcessBuilder("tasklist");
builder.redirectErrorStream(true);
Process process = builder.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
if (line.contains(processName)) {
String[] parts = line.split("\\s+");
pid = Long.parseLong(parts[1]);
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
return pid;
}
}

View File

@@ -80,7 +80,7 @@ public class LM {
public static long createContext(long modelHandle){
return createContext(modelHandle,
4096,
100000,
0,
0,
0,

View File