feat(box): 升级版本号并优化代码执行功能

-将版本号从 0.0.2 修改为 0.1.2
- 移除了异常时抛出的 RuntimeException
- 新增了 C 语言和 Java代码的执行功能
- 优化了 Python 代码的执行方式- 添加了代码编辑器的前端界面
- 新增了 QQ音乐文件解密工具的 UI 界面
- 添加了 C++ 解密库的框架
This commit is contained in:
2025-05-24 09:36:48 +08:00
parent f632b9584d
commit e475e84851
53 changed files with 42629 additions and 9 deletions

View File

@@ -0,0 +1,96 @@
package org.QQdecryption;
import com.axis.innovators.box.tools.FolderCreator;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
public class QQMusicAutoDecryptor {
/**
* 解密QQ加密的文件
* @param inputPath 源文件路径
* @param outputDir 标准输出目录路径
*/
public static void decrypt(String inputPath, String outputDir) {
try {
// 构建UnlockQQ.exe路径
String unlockExe = FolderCreator.getLibraryFolder() + File.separator + "UnlockQQ.exe";
// 处理输出文件名和路径
File inputFile = new File(inputPath);
String originalName = inputFile.getName();
// 创建扩展名映射表(可根据需要扩展)
Map<String, String> formatMap = new HashMap<>() {{
put(".mflac", ".flac");
put(".mgg", ".ogg");
put(".qmc0", ".mp3");
put(".qmc3", ".mp3");
put(".qmcflac", ".flac");
put(".qmcogg", ".ogg");
put(".tkm", ".mp3");
put(".qmc2", ".mp3");
put(".bkcmp3", ".mp3");
put(".bkcflac", ".flac");
put(".ogg", ".ogg");
}};
// 自动识别并转换文件格式
String outputFileName = originalName;
int lastDotIndex = originalName.lastIndexOf('.');
if (lastDotIndex > 0) {
String ext = originalName.substring(lastDotIndex).toLowerCase();
if (formatMap.containsKey(ext)) {
outputFileName = originalName.substring(0, lastDotIndex)
+ formatMap.get(ext);
} else {
throw new RuntimeException("未知文件格式: " + ext);
}
}
File outputFile = new File(outputDir, outputFileName);
// 构建命令参数(处理带空格的路径)
String[] cmd = {
unlockExe,
"\"" + inputFile.getAbsolutePath() + "\"",
"\"" + outputFile.getAbsolutePath() + "\""
};
// 执行解密命令
Process process = Runtime.getRuntime().exec(cmd);
int exitCode = process.waitFor();
// 检查执行结果
if (exitCode == 0) {
System.out.println("解密成功: " + outputFile.getAbsolutePath());
} else {
System.err.println("解密失败,错误码: " + exitCode);
printProcessError(process);
}
} catch (IOException | InterruptedException e) {
System.err.println("解密过程中出现异常: ");
e.printStackTrace();
throw new RuntimeException("解密过程中出现异常: ", e);
}
}
// 添加错误流打印方法
private static void printProcessError(Process process) throws IOException {
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getErrorStream()))) {
String line;
while ((line = reader.readLine()) != null) {
System.err.println("[EXE ERROR] " + line);
throw new RuntimeException("解密失败: " + line);
}
}
}
}

View File

@@ -0,0 +1,167 @@
package org.QQdecryption.ui;
import org.QQdecryption.QQMusicAutoDecryptor;
import com.formdev.flatlaf.FlatIntelliJLaf;
import javax.swing.*;
import java.awt.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetAdapter;
import java.awt.dnd.DropTargetDropEvent;
import java.io.File;
import java.util.List;
public class DecryptionUI extends JFrame {
private JProgressBar progressBar;
private JTextArea logArea;
public DecryptionUI() {
initUI();
setupDnD();
}
private void initUI() {
setTitle("QQ音乐文件解锁工具 v2.1");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(800, 600);
setLocationRelativeTo(null);
setupModernLookAndFeel();
JPanel mainPanel = new JPanel(new BorderLayout(10, 10));
mainPanel.setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15));
// 拖放区域
JPanel dropZone = createDropZone();
mainPanel.add(dropZone, BorderLayout.CENTER);
// 控制面板
JPanel controlPanel = createControlPanel();
mainPanel.add(controlPanel, BorderLayout.SOUTH);
// 日志区域
logArea = new JTextArea();
logArea.setEditable(false);
JScrollPane scrollPane = new JScrollPane(logArea);
scrollPane.setPreferredSize(new Dimension(0, 150));
mainPanel.add(scrollPane, BorderLayout.SOUTH);
add(mainPanel);
}
private void setupModernLookAndFeel() {
try {
UIManager.setLookAndFeel(new FlatIntelliJLaf());
} catch (UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
}
private JPanel createDropZone() {
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createDashedBorder(null, 3, 5));
panel.setBackground(UIManager.getColor("Panel.background").darker());
JLabel dropLabel = new JLabel("拖放QQ音乐文件到此区域", SwingConstants.CENTER);
dropLabel.setFont(new Font("微软雅黑", Font.BOLD, 18));
dropLabel.setForeground(new Color(0x666666));
panel.add(dropLabel);
return panel;
}
private JPanel createControlPanel() {
JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 10));
// 进度条
progressBar = new JProgressBar();
progressBar.setPreferredSize(new Dimension(200, 20));
progressBar.setStringPainted(true);
panel.add(progressBar);
return panel;
}
private void setupDnD() {
new DropTarget(this, new DropTargetAdapter() {
@Override
public void drop(DropTargetDropEvent dtde) {
try {
dtde.acceptDrop(DnDConstants.ACTION_COPY);
List<File> files = (List<File>) dtde.getTransferable()
.getTransferData(DataFlavor.javaFileListFlavor);
processFiles(files);
} catch (Exception ex) {
logError("文件拖放错误: " + ex.getMessage());
}
}
});
}
private void processFiles(List<File> files) {
SwingWorker<Void, Void> worker = new SwingWorker<>() {
@Override
protected Void doInBackground() {
progressBar.setIndeterminate(true);
for (File file : files) {
decryptFile(file);
}
return null;
}
@Override
protected void done() {
progressBar.setIndeterminate(false);
JOptionPane.showMessageDialog(DecryptionUI.this,
"处理完成!",
"完成",
JOptionPane.INFORMATION_MESSAGE);
}
};
worker.execute();
}
private void decryptFile(File inputFile) {
try {
logMessage("开始处理: " + inputFile.getName());
// 自动获取源文件所在目录
File outputDir = inputFile.getParentFile();
QQMusicAutoDecryptor.decrypt(
inputFile.getAbsolutePath(),
outputDir.getAbsolutePath()
);
logMessage("✓ 成功解密保存到: " + outputDir.getAbsolutePath());
} catch (Exception ex) {
logError("解密失败: " + ex.getMessage());
}
}
private void logMessage(String message) {
SwingUtilities.invokeLater(() -> {
logArea.append("[INFO] " + message + "\n");
logArea.setCaretPosition(logArea.getDocument().getLength());
});
}
private void logError(String error) {
SwingUtilities.invokeLater(() -> {
logArea.append("[ERROR] " + error + "\n");
logArea.setCaretPosition(logArea.getDocument().getLength());
});
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
try {
UIManager.setLookAndFeel(new FlatIntelliJLaf());
} catch (UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
new DecryptionUI().setVisible(true);
});
}
}