feat(box): 升级版本号并优化代码执行功能
-将版本号从 0.0.2 修改为 0.1.2 - 移除了异常时抛出的 RuntimeException - 新增了 C 语言和 Java代码的执行功能 - 优化了 Python 代码的执行方式- 添加了代码编辑器的前端界面 - 新增了 QQ音乐文件解密工具的 UI 界面 - 添加了 C++ 解密库的框架
This commit is contained in:
364
javascript/CCodeEditor.html
Normal file
364
javascript/CCodeEditor.html
Normal file
@@ -0,0 +1,364 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>C语言编辑器</title>
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
height: 100vh;
|
||||
background: #2B2B2B;
|
||||
font-family: 'JetBrains Mono', 'Consolas', monospace;
|
||||
}
|
||||
#editor {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
}
|
||||
.mtk5.keyword { color: #CC7832; font-weight: bold; }
|
||||
.mtk5.function { color: #FFC66D; }
|
||||
.mtk5.variable { color: #9876AA; }
|
||||
.mtk5.comment { color: #808080; }
|
||||
.mtk5.string { color: #6A8759; }
|
||||
.mtk5.number { color: #6897BB; }
|
||||
.doxygen-tag { color: #CC7832; }
|
||||
.doxygen-param { color: #9876AA; }
|
||||
.monaco-editor.vs-dark .monaco-editor-background { background: #2B2B2B !important; }
|
||||
.monaco-editor .margin { background: #313335 !important; }
|
||||
|
||||
#container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
#toolbar {
|
||||
background: #1E1E1E;
|
||||
padding: 8px;
|
||||
border-bottom: 1px solid #333;
|
||||
}
|
||||
|
||||
#executeBtn {
|
||||
background: #3276B1;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 8px 16px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-family: 'JetBrains Mono';
|
||||
}
|
||||
|
||||
#console {
|
||||
height: 200px;
|
||||
background: #1E1E1E;
|
||||
border-top: 1px solid #333;
|
||||
padding: 10px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
#output {
|
||||
color: #B5B5B5;
|
||||
margin: 0;
|
||||
font-family: 'JetBrains Mono';
|
||||
font-size: 14px;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
</style>
|
||||
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono&display=swap" rel="stylesheet">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="toolbar">
|
||||
<button id="executeBtn">▶ 执行</button>
|
||||
</div>
|
||||
<div id="editor"></div>
|
||||
<div id="console">
|
||||
<pre id="output"></pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.49.0/min/vs/loader.min.js"></script>
|
||||
<script>
|
||||
require.config({
|
||||
paths: { vs: 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.49.0/min/vs' },
|
||||
'vs/nls': {
|
||||
availableLanguages: { '*': 'zh-cn' }
|
||||
}
|
||||
});
|
||||
|
||||
require(['vs/editor/editor.main'], function() {
|
||||
|
||||
// 输出内容到控制台
|
||||
function appendOutput(text, isError = false) {
|
||||
const output = document.getElementById('output');
|
||||
const div = document.createElement('div');
|
||||
div.style.color = isError ? '#FF6666' : '#B5B5B5';
|
||||
div.textContent = text;
|
||||
output.appendChild(div);
|
||||
output.scrollTop = output.scrollHeight;
|
||||
}
|
||||
|
||||
// 清空控制台
|
||||
function clearOutput() {
|
||||
document.getElementById('output').innerHTML = '';
|
||||
}
|
||||
|
||||
document.getElementById('executeBtn').addEventListener('click', () => {
|
||||
const code = editor.getValue();
|
||||
|
||||
// 发送执行请求到Java后端
|
||||
window.cefQuery({
|
||||
request: JSON.stringify({
|
||||
type: "executeCode",
|
||||
code: code,
|
||||
language: "c"
|
||||
}),
|
||||
onSuccess: (response) => {
|
||||
const result = JSON.parse(response);
|
||||
appendOutput(result.output);
|
||||
},
|
||||
onFailure: (errorCode, errorMsg) => {
|
||||
appendOutput(`执行错误 (${errorCode}): ${errorMsg}`, true);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
monaco.languages.register({ id: 'c' });
|
||||
|
||||
// C语言关键字配置
|
||||
const cKeywords = [
|
||||
'auto', 'break', 'case', 'char', 'const', 'continue',
|
||||
'default', 'do', 'double', 'else', 'enum', 'extern',
|
||||
'float', 'for', 'goto', 'if', 'inline', 'int', 'long',
|
||||
'register', 'return', 'short', 'signed', 'sizeof', 'static',
|
||||
'struct', 'switch', 'typedef', 'union', 'unsigned', 'void',
|
||||
'volatile', 'while', '_Alignas', '_Alignof', '_Atomic',
|
||||
'_Bool', '_Complex', '_Generic', '_Imaginary', '_Noreturn',
|
||||
'_Static_assert', '_Thread_local',"#include","#define"
|
||||
];
|
||||
|
||||
// 语法高亮配置
|
||||
monaco.languages.setMonarchTokensProvider('c', {
|
||||
keywords: cKeywords,
|
||||
tokenizer: {
|
||||
root: [
|
||||
[/for\s*\(/, {
|
||||
cases: {
|
||||
'@keywords': 'keyword',
|
||||
'@default': 'keyword'
|
||||
}
|
||||
}],
|
||||
[/if\s*\(/, 'keyword'],
|
||||
[/\/\*\*/, 'comment.doxygen', '@doxygen'],
|
||||
[/\/\*/, 'comment', '@comment'],
|
||||
[/[a-zA-Z_]\w*(?=\s*\()/, 'function'],
|
||||
[/[a-zA-Z_]\w*/, {
|
||||
cases: {
|
||||
'@keywords': 'keyword',
|
||||
'@default': 'variable'
|
||||
}
|
||||
}],
|
||||
{ include: '@whitespace' },
|
||||
[/[{}()\[\]]/, '@brackets'],
|
||||
[/[0-9]+/, 'number'],
|
||||
[/"/, 'string', '@string'],
|
||||
[/\/\/.*$/, 'comment'],
|
||||
],
|
||||
doxygen: [
|
||||
[/\*\//, 'comment.doxygen', '@pop'],
|
||||
[/@\w+/, 'doxygen-tag'],
|
||||
[/\\[\w]+/, 'doxygen-param'],
|
||||
[/[\s\S]/, 'comment.doxygen']
|
||||
],
|
||||
comment: [
|
||||
[/\*\//, 'comment', '@pop'],
|
||||
[/[\s\S]/, 'comment']
|
||||
],
|
||||
string: [
|
||||
[/[^\\"]+/, 'string'],
|
||||
[/\\["\\nrt]/, 'string.escape'],
|
||||
[/"/, 'string', '@pop']
|
||||
],
|
||||
whitespace: [
|
||||
[/[ \t\r\n]+/, 'white'],
|
||||
],
|
||||
}
|
||||
});
|
||||
|
||||
// 定义跳转功能
|
||||
monaco.languages.registerDefinitionProvider('c', {
|
||||
provideDefinition: (model, position) => {
|
||||
const word = model.getWordAtPosition(position);
|
||||
if (!word) return [];
|
||||
const funcMatches = model.findMatches(
|
||||
`\\b(\\w+)\\s+${word.word}\\s*\\([^)]*\\)\\s*[;{]`,
|
||||
true, true, false, null, true
|
||||
);
|
||||
const varMatches = model.findMatches(
|
||||
`\\b(int|float|double|char|void|short|long|unsigned)\\s+${word.word}\\b`,
|
||||
true, true, false, null, true
|
||||
);
|
||||
return [...funcMatches, ...varMatches].map(match => ({
|
||||
uri: model.uri,
|
||||
range: match.range
|
||||
}));
|
||||
}
|
||||
});
|
||||
|
||||
// 自动补全配置
|
||||
const systemFunctions = [
|
||||
{
|
||||
label: 'printf',
|
||||
kind: monaco.languages.CompletionItemKind.Function,
|
||||
insertText: 'printf("${1:format}", ${2:args});',
|
||||
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
documentation: {
|
||||
value: '**格式化输出函数**\n\n参数:\n- `format`: 格式字符串 (例: "%d")\n- `...`: 可变参数列表'
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'main',
|
||||
kind: monaco.languages.CompletionItemKind.Function,
|
||||
insertText: 'int main(int ${1:argc}, char* ${2:argv[]}){\n ${3://is code}\n}',
|
||||
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
documentation: {
|
||||
value: '**主函数**'
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'scanf',
|
||||
kind: monaco.languages.CompletionItemKind.Function,
|
||||
insertText: 'scanf("${1:format}", ${2:&var});',
|
||||
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
documentation: {
|
||||
value: '**格式化输入函数**\n\n参数:\n- `format`: 格式字符串\n- `...`: 变量地址列表'
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
const codeSnippets = [
|
||||
{
|
||||
label: 'if',
|
||||
kind: monaco.languages.CompletionItemKind.Snippet,
|
||||
insertText: 'if (${1:condition}) {\n\t${2:// code}\n}',
|
||||
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
documentation: 'if条件语句'
|
||||
},
|
||||
{
|
||||
label: 'for',
|
||||
kind: monaco.languages.CompletionItemKind.Snippet,
|
||||
insertText: 'for (int ${1:i} = 0; ${1:i} < ${2:count}; ${1:i}++) {\n\t${3:// code}\n}',
|
||||
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
documentation: 'for循环语句'
|
||||
},
|
||||
{
|
||||
label: 'while',
|
||||
kind: monaco.languages.CompletionItemKind.Snippet,
|
||||
insertText: 'while (${1:condition}) {\n\t${2:// code}\n}',
|
||||
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
documentation: 'while循环语句'
|
||||
},
|
||||
{
|
||||
label: 'switch',
|
||||
kind: monaco.languages.CompletionItemKind.Snippet,
|
||||
insertText: 'switch (${1:expression}) {\n\tcase ${2:value}:\n\t\t${3:// code}\n\t\tbreak;\n\tdefault:\n\t\t${4:// code}\n}',
|
||||
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
documentation: 'switch语句'
|
||||
}
|
||||
];
|
||||
|
||||
monaco.languages.registerCompletionItemProvider('c', {
|
||||
triggerCharacters: ['.', ':', '$', '/', '@', '*'],
|
||||
provideCompletionItems: (model, position) => {
|
||||
const word = model.getWordUntilPosition(position);
|
||||
const range = new monaco.Range(
|
||||
position.lineNumber,
|
||||
word.startColumn,
|
||||
position.lineNumber,
|
||||
word.endColumn
|
||||
);
|
||||
|
||||
return {
|
||||
suggestions: [
|
||||
...cKeywords.map(keyword => ({
|
||||
label: keyword,
|
||||
kind: monaco.languages.CompletionItemKind.Keyword,
|
||||
insertText: keyword,
|
||||
range: range
|
||||
})),
|
||||
...codeSnippets.map(snippet => ({
|
||||
...snippet,
|
||||
range: range
|
||||
})),
|
||||
...systemFunctions.map(func => ({
|
||||
...func,
|
||||
range: range
|
||||
})),
|
||||
...getCurrentVariables(model).map(v => ({
|
||||
label: v.name,
|
||||
kind: monaco.languages.CompletionItemKind.Variable,
|
||||
detail: `类型: ${v.type}`,
|
||||
insertText: v.name,
|
||||
range: range
|
||||
})),
|
||||
...getCurrentFunctions(model).map(f => ({
|
||||
label: f,
|
||||
kind: monaco.languages.CompletionItemKind.Function,
|
||||
detail: '用户定义函数',
|
||||
insertText: f,
|
||||
range: range
|
||||
}))
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
// 创建编辑器实例
|
||||
const editor = monaco.editor.create(document.getElementById('editor'), {
|
||||
value: `#include <stdio.h>\n\nint main() {\n printf("Hello World\\n");\n return 0;\n}`,
|
||||
language: 'c',
|
||||
theme: 'vs-dark',
|
||||
minimap: { enabled: true },
|
||||
fontSize: 16,
|
||||
lineNumbers: 'on',
|
||||
roundedSelection: false,
|
||||
scrollBeyondLastLine: false,
|
||||
automaticLayout: true,
|
||||
tabSize: 4,
|
||||
suggest: {
|
||||
showKeywords: true,
|
||||
showSnippets: true
|
||||
},
|
||||
glyphMargin: true,
|
||||
lightbulb: { enabled: true }
|
||||
});
|
||||
|
||||
// 辅助函数
|
||||
function getCurrentVariables(model) {
|
||||
const varRegex = /\b(int|float|double|char|void|short|long|unsigned)\s+([a-zA-Z_][\w,\s*]*)/g;
|
||||
const variables = [];
|
||||
let match;
|
||||
while ((match = varRegex.exec(model.getValue()))) {
|
||||
const type = match[1];
|
||||
const names = match[2].split(',').map(s => s.trim());
|
||||
names.forEach(name => {
|
||||
variables.push({
|
||||
name: name.replace(/\*+/g, '').trim(),
|
||||
type: type
|
||||
});
|
||||
});
|
||||
}
|
||||
return variables;
|
||||
}
|
||||
|
||||
function getCurrentFunctions(model) {
|
||||
const funcRegex = /(\w+)\s*\([^)]*\)\s*\{/g;
|
||||
return Array.from(model.getValue().matchAll(funcRegex))
|
||||
.map(m => m[1])
|
||||
.filter(f => !['if','while','for','switch'].includes(f));
|
||||
}
|
||||
|
||||
window.addEventListener('resize', () => editor.layout());
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user