diff --git a/.htaccess b/.htaccess new file mode 100755 index 0000000..0519ecb --- /dev/null +++ b/.htaccess @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/404.html b/404.html new file mode 100755 index 0000000..829e029 --- /dev/null +++ b/404.html @@ -0,0 +1,69 @@ + + + + + + 网站已封禁 + + + +
+ +

此页面已被管理员封禁

+

您尝试访问的网站已被学校管理员封禁,如需了解更多详情,请联系学校网络管理部门。

+
+ + \ No newline at end of file diff --git a/a.html b/a.html new file mode 100755 index 0000000..7a9b0e5 --- /dev/null +++ b/a.html @@ -0,0 +1,949 @@ + + + + + + 成绩追踪应用 + + + + + + + + + + + + + +
+ +
+

+ 成绩追踪 +

+

+ 记录、分析和可视化你的预估成绩与实际成绩,帮助你更好地掌握学习情况 +

+
+ +
+ +
+
+

+ 添加成绩 +

+ +
+
+ +
+ +
+ +
+
+ +
+ + + +
+ + +
+ +
+ + +
+ +
+ + +
+ + +
+ + +
+
+

平均预估

+

--

+
+
+

平均实际

+

--

+
+
+

预估偏差

+

--

+
+
+

成绩总数

+

0

+
+
+
+
+ + +
+ +
+
+

+ 成绩趋势 +

+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+
+ + +
+
+

+ 成绩记录 +

+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + +
+ 课程 + + 预估 + + 实际 + + 偏差 + + 备注 + + 操作 +
+
+ +

暂无成绩记录

+
+
+
+ + +
+
+ 显示 0-0 条,共 0 条 +
+
+ + 1 + +
+
+
+
+
+ + + +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/api.php b/api.php new file mode 100755 index 0000000..8d2fe9f --- /dev/null +++ b/api.php @@ -0,0 +1,291 @@ +host = $host; + $this->port = $port; + $this->timeout = $timeout; + } + + public function connect() { + // 记录开始时间计算延迟 + $start = microtime(true); + + // 创建 socket 连接 + $this->socket = @fsockopen($this->host, $this->port, $errno, $errstr, $this->timeout); + + if (!$this->socket) { + return false; + } + + // 设置超时 + stream_set_timeout($this->socket, $this->timeout); + + // 发送握手包 + $this->sendHandshake(); + + // 发送状态请求 + $this->sendStatusRequest(); + + // 读取状态响应 + $this->readStatusResponse(); + + // 计算延迟 + $this->ping = round((microtime(true) - $start) * 1000); + + // 关闭连接 + fclose($this->socket); + + return true; + } + + private function sendHandshake() { + $packet = pack('c', 0x00); // 包ID (Handshake) + $packet .= pack('c', 0x04); // 协议版本 (4 for 1.7.2+) + $packet .= pack('c', strlen($this->host)) . $this->host; // 服务器地址 + $packet .= pack('n', $this->port); // 服务器端口 + $packet .= pack('c', 0x01); // 下一步状态 (1 for Status) + + $packet = pack('c', strlen($packet)) . $packet; // 添加包长度前缀 + fwrite($this->socket, $packet); + } + + private function sendStatusRequest() { + $packet = pack('c', 0x00); // 包ID (Status Request) + $packet = pack('c', strlen($packet)) . $packet; + fwrite($this->socket, $packet); + } + + private function readStatusResponse() { + // 读取包长度 + $length = $this->readVarInt(); + + // 读取包ID + $packetID = $this->readVarInt(); + + if ($packetID !== 0x00) { + return false; // 不是状态响应包 + } + + // 读取JSON数据长度 + $jsonLength = $this->readVarInt(); + + // 读取JSON数据 + $json = ''; + $bytesRead = 0; + + while ($bytesRead < $jsonLength) { + $chunk = fread($this->socket, $jsonLength - $bytesRead); + if ($chunk === false) break; + $json .= $chunk; + $bytesRead += strlen($chunk); + } + + $this->info = json_decode($json, true); + return true; + } + + private function readVarInt() { + $value = 0; + $size = 0; + $b; + + do { + $b = ord(fgetc($this->socket)); + $value |= ($b & 0x7F) << ($size++ * 7); + if ($size > 5) { + throw new Exception('VarInt too big'); + } + } while (($b & 0x80) == 0x80); + + return $value; + } + + public function getInfo() { + return $this->info; + } + + public function getPing() { + return $this->ping; + } + + public function formatMotd($motd) { + // 颜色代码映射 + $colors = [ + '0' => '#000000', '1' => '#0000AA', '2' => '#00AA00', '3' => '#00AAAA', + '4' => '#AA0000', '5' => '#AA00AA', '6' => '#FFAA00', '7' => '#AAAAAA', + '8' => '#555555', '9' => '#5555FF', 'a' => '#55FF55', 'b' => '#55FFFF', + 'c' => '#FF5555', 'd' => '#FF55FF', 'e' => '#FFFF55', 'f' => '#FFFFFF' + ]; + + // 格式化代码映射 + $formats = [ + 'l' => 'font-weight:bold', // 粗体 + 'm' => 'text-decoration:line-through', // 删除线 + 'n' => 'text-decoration:underline', // 下划线 + 'o' => 'font-style:italic', // 斜体 + 'r' => '' // 重置 + ]; + + $html = ''; + $currentStyles = []; + $buffer = ''; + $chars = preg_split('//u', $motd, -1, PREG_SPLIT_NO_EMPTY); + + for ($i = 0; $i < count($chars); $i++) { + $char = $chars[$i]; + + if ($char === '§' && isset($chars[$i + 1])) { + $code = $chars[$i + 1]; + $i++; + + // 处理颜色代码 + if (isset($colors[strtolower($code)])) { + if ($buffer !== '') { + $html .= $this->wrapWithStyles($buffer, $currentStyles); + $buffer = ''; + } + $currentStyles['color'] = $colors[strtolower($code)]; + } + // 处理格式代码 + elseif (isset($formats[strtolower($code)])) { + if ($buffer !== '') { + $html .= $this->wrapWithStyles($buffer, $currentStyles); + $buffer = ''; + } + + if (strtolower($code) === 'r') { + $currentStyles = []; // 重置所有样式 + } else { + $currentStyles[] = $formats[strtolower($code)]; + } + } + // 忽略未知代码 + else { + $buffer .= $char . $code; + } + } else { + $buffer .= $char; + } + } + + if ($buffer !== '') { + $html .= $this->wrapWithStyles($buffer, $currentStyles); + } + + // 处理换行符 + $html = str_replace("\n", "
", $html); + + return $html; + } + + private function wrapWithStyles($text, $styles) { + if (empty($styles)) { + return htmlspecialchars($text); + } + + $styleString = ''; + foreach ($styles as $key => $value) { + if (is_numeric($key)) { + $styleString .= $value . ';'; + } else { + $styleString .= $key . ':' . $value . ';'; + } + } + + return '' . htmlspecialchars($text) . ''; + } +} + +// 处理API请求 +if ($_SERVER['REQUEST_METHOD'] === 'GET') { + // 获取查询参数 + $host = isset($_GET['host']) ? $_GET['host'] : ''; + $port = isset($_GET['port']) ? (int)$_GET['port'] : 25565; + + // 验证输入 + if (empty($host)) { + http_response_code(400); + echo json_encode(['error' => 'Missing host parameter']); + exit; + } + + // 创建服务器查询实例 + $server = new MinecraftServerQuery($host, $port); + + try { + // 尝试连接并获取信息 + $connected = $server->connect(); + + if ($connected) { + $info = $server->getInfo(); + $ping = $server->getPing(); + + // 处理玩家列表 + $players = []; + if (isset($info['players']['sample'])) { + foreach ($info['players']['sample'] as $player) { + $players[] = $player['name']; + } + } + + // 格式化MOTD + $motd = ''; + $formattedMotd = ''; + + if (isset($info['description'])) { + if (is_string($info['description'])) { + $motd = $info['description']; + $formattedMotd = $server->formatMotd($motd); + } elseif (is_array($info['description']) && isset($info['description']['text'])) { + $motd = $info['description']['text']; + $formattedMotd = $server->formatMotd($motd); + } + } + + // 构建响应数据 + $response = [ + 'online' => true, + 'host' => $host, + 'port' => $port, + 'ping' => $ping, + 'version' => $info['version']['name'] ?? 'Unknown', + 'protocol' => $info['version']['protocol'] ?? -1, + 'online_players' => $info['players']['online'] ?? 0, + 'max_players' => $info['players']['max'] ?? 0, + 'motd' => $motd, + 'formatted_motd' => $formattedMotd, + 'players' => $players + ]; + + echo json_encode($response); + } else { + http_response_code(500); + echo json_encode([ + 'online' => false, + 'error' => '无法连接到服务器', + 'host' => $host, + 'port' => $port + ]); + } + } catch (Exception $e) { + http_response_code(500); + echo json_encode([ + 'online' => false, + 'error' => $e->getMessage(), + 'host' => $host, + 'port' => $port + ]); + } +} else { + http_response_code(405); + echo json_encode(['error' => 'Method not allowed']); +} +?> \ No newline at end of file diff --git a/auth/index.php b/auth/index.php index a6bca7b..62ecb64 100755 --- a/auth/index.php +++ b/auth/index.php @@ -237,24 +237,25 @@ if ($token) {
-
- - - - - - - - - - --> + + + + + + + + + + + + + + + + +
-
+ @@ -368,7 +374,8 @@ $conn->close(); Cookie政策
- 版本 2.4.1(Alpha) + Copyright © 2023-2025 CCSIT Network.All rights reserved. +© 圆周云境信息技术 保留所有权利。| 版本:2.8.9(submitID:NULL(未开源))
@@ -526,6 +533,7 @@ $conn->close(); 积分 邮箱 注册时间 + QQ号码 操作 @@ -547,6 +555,7 @@ $conn->close(); + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/console/ins_beta/js/api.js b/console/ins_beta/js/api.js new file mode 100755 index 0000000..2875c8e --- /dev/null +++ b/console/ins_beta/js/api.js @@ -0,0 +1,668 @@ +// 解析URL参数 +function getQueryParams() { + const urlParams = new URLSearchParams(window.location.search); + return { + serverUUID: urlParams.get('serverUUID'), + nodeUUID: urlParams.get('nodeUUID') + }; +} + +// 检查是否包含必要的URL参数 +function checkParams() { + const { serverUUID, nodeUUID } = getQueryParams(); + + if (!serverUUID || !nodeUUID) { + alert('URL中缺少必要的参数: serverUUID 和 nodeUUID'); + return false; + } + + return true; +} + +// 显示加载模态框 +function showLoadingModal() { + document.getElementById('loadingModal').classList.remove('hidden'); +} + +// 隐藏加载模态框 +function hideLoadingModal() { + document.getElementById('loadingModal').classList.add('hidden'); +} + +// 加载实例信息 +function loadInstanceInfo() { + showLoadingModal(); + + const { serverUUID, nodeUUID } = getQueryParams(); + + fetch(`php/api.php?action=getInstanceInfo&serverUUID=${serverUUID}&nodeUUID=${nodeUUID}`) + .then(response => response.json()) + .then(data => { + hideLoadingModal(); + + if (data.status !== 200) { + alert(`获取实例信息失败: ${data.message || '未知错误'}`); + return; + } + + const instanceInfo = data.data; + let html = ` +
+
+

基础信息

+

实例名称: ${instanceInfo.name || '未命名'}

+

实例ID: ${instanceInfo.id}

+

实例UUID: ${serverUUID}

+

节点UUID: ${nodeUUID}

+

状态: ${instanceInfo.running ? '运行中' : '已停止'}

+
+ +
+

运行状态

+ ${instanceInfo.running ? ` +

CPU使用率: ${instanceInfo.cpuUsage}%

+

内存使用: ${(instanceInfo.memoryUsage / 1024 / 1024).toFixed(2)} MB / ${(instanceInfo.totalMemory / 1024 / 1024).toFixed(2)} MB

+

运行时间: ${formatUptime(instanceInfo.uptime)}

+ ` : ` +

实例未运行

+ `} +
+
+ +
+ + +
+ `; + + document.getElementById('instanceInfo').innerHTML = html; + + // 绑定按钮事件 + document.getElementById('startInstance')?.addEventListener('click', startInstance); + document.getElementById('stopInstance')?.addEventListener('click', stopInstance); + + // 显示模态框 + document.getElementById('instanceModal').classList.remove('hidden'); + }) + .catch(error => { + hideLoadingModal(); + console.error('获取实例信息失败:', error); + alert('获取实例信息失败,请检查网络连接或参数是否正确'); + }); +} + +// 格式化运行时间 +function formatUptime(uptime) { + const hours = Math.floor(uptime / 3600); + const minutes = Math.floor((uptime % 3600) / 60); + const seconds = uptime % 60; + + return `${hours}小时 ${minutes}分钟 ${seconds}秒`; +} + +// 启动实例 +function startInstance() { + const { serverUUID, nodeUUID } = getQueryParams(); + + if (!confirm('确定要启动实例吗?')) return; + + showLoadingModal(); + + fetch(`php/api.php?action=startInstance&serverUUID=${serverUUID}&nodeUUID=${nodeUUID}`) + .then(response => response.json()) + .then(data => { + hideLoadingModal(); + + if (data.status !== 200) { + alert(`启动实例失败: ${data.message || '未知错误'}`); + return; + } + + alert('实例启动成功'); + // 刷新实例信息 + loadInstanceInfo(); + }) + .catch(error => { + hideLoadingModal(); + console.error('启动实例失败:', error); + alert('启动实例失败,请检查网络连接或参数是否正确'); + }); +} + +// 停止实例 +function stopInstance() { + const { serverUUID, nodeUUID } = getQueryParams(); + + if (!confirm('确定要停止实例吗?')) return; + + showLoadingModal(); + + fetch(`php/api.php?action=stopInstance&serverUUID=${serverUUID}&nodeUUID=${nodeUUID}`) + .then(response => response.json()) + .then(data => { + hideLoadingModal(); + + if (data.status !== 200) { + alert(`停止实例失败: ${data.message || '未知错误'}`); + return; + } + + alert('实例停止成功'); + // 刷新实例信息 + loadInstanceInfo(); + }) + .catch(error => { + hideLoadingModal(); + console.error('停止实例失败:', error); + alert('停止实例失败,请检查网络连接或参数是否正确'); + }); +} + +// 加载控制台 +function loadConsole() { + showLoadingModal(); + + const { serverUUID, nodeUUID } = getQueryParams(); + + fetch(`php/api.php?action=getConsole&serverUUID=${serverUUID}&nodeUUID=${nodeUUID}`) + .then(response => response.json()) + .then(data => { + hideLoadingModal(); + + if (data.status !== 200) { + alert(`获取控制台失败: ${data.message || '未知错误'}`); + return; + } + + // 清空控制台输出 + document.getElementById('consoleOutput').innerHTML = ''; + + // 显示模态框 + document.getElementById('consoleModal').classList.remove('hidden'); + + // 绑定发送命令事件 + document.getElementById('sendConsoleCommand').addEventListener('click', sendConsoleCommand); + + // 监听输入框回车事件 + document.getElementById('consoleInput').addEventListener('keypress', function(e) { + if (e.key === 'Enter') { + sendConsoleCommand(); + } + }); + + // 开始轮询控制台输出 + startConsolePolling(); + }) + .catch(error => { + hideLoadingModal(); + console.error('获取控制台失败:', error); + alert('获取控制台失败,请检查网络连接或参数是否正确'); + }); +} + +// 发送控制台命令 +function sendConsoleCommand() { + const { serverUUID, nodeUUID } = getQueryParams(); + const command = document.getElementById('consoleInput').value.trim(); + + if (!command) return; + + showLoadingModal(); + + fetch(`php/api.php?action=sendConsoleCommand&serverUUID=${serverUUID}&nodeUUID=${nodeUUID}&command=${encodeURIComponent(command)}`) + .then(response => response.json()) + .then(data => { + hideLoadingModal(); + + if (data.status !== 200) { + alert(`发送命令失败: ${data.message || '未知错误'}`); + return; + } + + // 添加命令到输出 + addConsoleOutput(`> ${command}\n`); + + // 清空输入框 + document.getElementById('consoleInput').value = ''; + }) + .catch(error => { + hideLoadingModal(); + console.error('发送命令失败:', error); + alert('发送命令失败,请检查网络连接或参数是否正确'); + }); +} + +// 添加控制台输出 +function addConsoleOutput(text) { + const output = document.getElementById('consoleOutput'); + output.innerHTML += text; + output.scrollTop = output.scrollHeight; +} + +// 开始控制台轮询 +function startConsolePolling() { + const { serverUUID, nodeUUID } = getQueryParams(); + + // 清除之前的轮询 + if (window.consolePollingInterval) { + clearInterval(window.consolePollingInterval); + } + + // 开始新的轮询 + window.consolePollingInterval = setInterval(() => { + fetch(`php/api.php?action=getConsoleOutput&serverUUID=${serverUUID}&nodeUUID=${nodeUUID}`) + .then(response => response.json()) + .then(data => { + if (data.status === 200) { + addConsoleOutput(data.data); + } + }) + .catch(error => { + console.error('轮询控制台输出失败:', error); + }); + }, 1000); // 每秒轮询一次 +} + +// 停止控制台轮询 +function stopConsolePolling() { + if (window.consolePollingInterval) { + clearInterval(window.consolePollingInterval); + window.consolePollingInterval = null; + } +} + +// 加载文件管理 +function loadFiles() { + showLoadingModal(); + + const { serverUUID, nodeUUID } = getQueryParams(); + + fetch(`php/api.php?action=getFiles&serverUUID=${serverUUID}&nodeUUID=${nodeUUID}`) + .then(response => response.json()) + .then(data => { + hideLoadingModal(); + + if (data.status !== 200) { + alert(`获取文件列表失败: ${data.message || '未知错误'}`); + return; + } + + const files = data.data; + + let html = ` +
+

文件管理

+
+ + +
+
+ +
+ + + + + + + + + + + + `; + + files.forEach(file => { + html += ` + + + + + + + + `; + }); + + html += ` + +
名称类型大小修改时间操作
${file.name}${file.type}${formatFileSize(file.size)}${new Date(file.modifiedTime).toLocaleString()} + + + ${file.type === 'file' ? ` + + ` : ''} + +
+
+ `; + + document.getElementById('fileContent').innerHTML = html; + + // 显示模态框 + document.getElementById('filesModal').classList.remove('hidden'); + + // 绑定事件 + document.getElementById('refreshFiles').addEventListener('click', loadFiles); + document.getElementById('uploadFile').addEventListener('click', showUploadFileDialog); + + // 绑定文件操作事件 + document.querySelectorAll('.view-file').forEach(button => { + button.addEventListener('click', function() { + viewFile(this.dataset.path); + }); + }); + + document.querySelectorAll('.download-file').forEach(button => { + button.addEventListener('click', function() { + downloadFile(this.dataset.path); + }); + }); + + document.querySelectorAll('.edit-file').forEach(button => { + button.addEventListener('click', function() { + editFile(this.dataset.path); + }); + }); + + document.querySelectorAll('.delete-file').forEach(button => { + button.addEventListener('click', function() { + deleteFile(this.dataset.path); + }); + }); + }) + .catch(error => { + hideLoadingModal(); + console.error('获取文件列表失败:', error); + alert('获取文件列表失败,请检查网络连接或参数是否正确'); + }); +} + +// 格式化文件大小 +function formatFileSize(size) { + if (size < 1024) { + return `${size} B`; + } else if (size < 1024 * 1024) { + return `${(size / 1024).toFixed(2)} KB`; + } else if (size < 1024 * 1024 * 1024) { + return `${(size / 1024 / 1024).toFixed(2)} MB`; + } else { + return `${(size / 1024 / 1024 / 1024).toFixed(2)} GB`; + } +} + +// 显示上传文件对话框 +function showUploadFileDialog() { + const { serverUUID, nodeUUID } = getQueryParams(); + + const input = document.createElement('input'); + input.type = 'file'; + input.onchange = function() { + if (this.files && this.files[0]) { + uploadFile(this.files[0], serverUUID, nodeUUID); + } + }; + input.click(); +} + +// 上传文件 +function uploadFile(file, serverUUID, nodeUUID) { + const formData = new FormData(); + formData.append('file', file); + formData.append('serverUUID', serverUUID); + formData.append('nodeUUID', nodeUUID); + formData.append('path', '/'); // 默认上传到根目录 + + showLoadingModal(); + + fetch('php/api.php?action=uploadFile', { + method: 'POST', + body: formData + }) + .then(response => response.json()) + .then(data => { + hideLoadingModal(); + + if (data.status !== 200) { + alert(`上传文件失败: ${data.message || '未知错误'}`); + return; + } + + alert('文件上传成功'); + loadFiles(); // 刷新文件列表 + }) + .catch(error => { + hideLoadingModal(); + console.error('上传文件失败:', error); + alert('上传文件失败,请检查网络连接或参数是否正确'); + }); +} + +// 查看文件 +function viewFile(path) { + const { serverUUID, nodeUUID } = getQueryParams(); + + showLoadingModal(); + + fetch(`php/api.php?action=viewFile&serverUUID=${serverUUID}&nodeUUID=${nodeUUID}&path=${encodeURIComponent(path)}`) + .then(response => response.json()) + .then(data => { + hideLoadingModal(); + + if (data.status !== 200) { + alert(`查看文件失败: ${data.message || '未知错误'}`); + return; + } + + alert(`文件内容:\n${data.data}`); + }) + .catch(error => { + hideLoadingModal(); + console.error('查看文件失败:', error); + alert('查看文件失败,请检查网络连接或参数是否正确'); + }); +} + +// 下载文件 +function downloadFile(path) { + const { serverUUID, nodeUUID } = getQueryParams(); + + window.location.href = `php/api.php?action=downloadFile&serverUUID=${serverUUID}&nodeUUID=${nodeUUID}&path=${encodeURIComponent(path)}`; +} + +// 编辑文件 +function editFile(path) { + const { serverUUID, nodeUUID } = getQueryParams(); + + showLoadingModal(); + + fetch(`php/api.php?action=viewFile&serverUUID=${serverUUID}&nodeUUID=${nodeUUID}&path=${encodeURIComponent(path)}`) + .then(response => response.json()) + .then(data => { + hideLoadingModal(); + + if (data.status !== 200) { + alert(`编辑文件失败: ${data.message || '未知错误'}`); + return; + } + + // 显示编辑模态框 + const modalHtml = ` +
+
+

编辑文件: ${path.split('/').pop()}

+ +
+ + +
+
+
+ `; + + document.body.insertAdjacentHTML('beforeend', modalHtml); + + // 绑定保存按钮事件 + document.getElementById('saveEditFile').addEventListener('click', function() { + const content = document.getElementById('editFileContent').value; + saveEditFile(path, content); + }); + + // 绑定取消按钮事件 + document.getElementById('cancelEditFile').addEventListener('click', function() { + document.getElementById('editFileModal').remove(); + }); + }) + .catch(error => { + hideLoadingModal(); + console.error('编辑文件失败:', error); + alert('编辑文件失败,请检查网络连接或参数是否正确'); + }); +} + +// 保存编辑的文件 +function saveEditFile(path, content) { + const { serverUUID, nodeUUID } = getQueryParams(); + + const formData = new FormData(); + formData.append('content', content); + formData.append('serverUUID', serverUUID); + formData.append('nodeUUID', nodeUUID); + formData.append('path', path); + + showLoadingModal(); + + fetch('php/api.php?action=saveEditFile', { + method: 'POST', + body: formData + }) + .then(response => response.json()) + .then(data => { + hideLoadingModal(); + + if (data.status !== 200) { + alert(`保存文件失败: ${data.message || '未知错误'}`); + return; + } + + alert('文件保存成功'); + document.getElementById('editFileModal').remove(); + loadFiles(); // 刷新文件列表 + }) + .catch(error => { + hideLoadingModal(); + console.error('保存文件失败:', error); + alert('保存文件失败,请检查网络连接或参数是否正确'); + }); +} + +// 删除文件 +function deleteFile(path) { + const { serverUUID, nodeUUID } = getQueryParams(); + + if (!confirm('确定要删除此文件/文件夹吗?此操作不可撤销')) return; + + showLoadingModal(); + + fetch(`php/api.php?action=deleteFile&serverUUID=${serverUUID}&nodeUUID=${nodeUUID}&path=${encodeURIComponent(path)}`) + .then(response => response.json()) + .then(data => { + hideLoadingModal(); + + if (data.status !== 200) { + alert(`删除文件失败: ${data.message || '未知错误'}`); + return; + } + + alert('文件删除成功'); + loadFiles(); // 刷新文件列表 + }) + .catch(error => { + hideLoadingModal(); + console.error('删除文件失败:', error); + alert('删除文件失败,请检查网络连接或参数是否正确'); + }); +} + +// 初始化页面 +function initPage() { + // 检查URL参数 + if (!checkParams()) return; + + // 绑定菜单点击事件 + document.getElementById('dashboardLink').addEventListener('click', function() { + document.getElementById('contentArea').innerHTML = ` +

仪表盘

+

+ 这里将显示实例的概览信息。 +

+ + `; + + // 绑定按钮事件 + document.getElementById('viewInstanceInfo').addEventListener('click', loadInstanceInfo); + }); + + document.getElementById('instancesLink').addEventListener('click', function() { + document.getElementById('contentArea').innerHTML = ` +

实例信息

+ +
+ `; + + // 加载实例信息 + loadInstanceInfo(); + + // 绑定刷新按钮事件 + document.getElementById('refreshInstanceInfo').addEventListener('click', loadInstanceInfo); + }); + + document.getElementById('filesLink').addEventListener('click', function() { + document.getElementById('contentArea').innerHTML = ` +

文件管理

+ + `; + + // 绑定按钮事件 + document.getElementById('openFilesModal').addEventListener('click', loadFiles); + }); + + document.getElementById('consoleLink').addEventListener('click', function() { + document.getElementById('contentArea').innerHTML = ` +

控制台

+ + `; + + // 绑定按钮事件 + document.getElementById('openConsoleModal').addEventListener('click', loadConsole); + }); + + // 绑定模态框关闭事件 + document.getElementById('closeInstanceModal')?.addEventListener('click', function() { + document.getElementById('instanceModal').classList.add('hidden'); + }); + + document.getElementById('closeConsoleModal')?.addEventListener('click', function() { + document.getElementById('consoleModal').classList.add('hidden'); + stopConsolePolling(); // 停止轮询 + }); + + document.getElementById('closeFilesModal')?.addEventListener('click', function() { + document.getElementById('filesModal').classList.add('hidden'); + }); +} + +// 页面加载完成后初始化 +document.addEventListener('DOMContentLoaded', initPage); \ No newline at end of file diff --git a/console/ins_beta/js/util.js b/console/ins_beta/js/util.js new file mode 100755 index 0000000..0965d6e --- /dev/null +++ b/console/ins_beta/js/util.js @@ -0,0 +1,445 @@ +// 通用工具函数 + +// 显示通知消息 +function showToast(message, type = 'info') { + // 创建通知元素 + const toast = document.createElement('div'); + toast.className = `toast fixed top-4 right-4 p-3 rounded-lg shadow-lg ${type === 'success' ? 'bg-green-500 text-white' : type === 'error' ? 'bg-red-500 text-white' : 'bg-blue-500 text-white'}`; + toast.innerHTML = message; + + // 添加到页面 + document.body.appendChild(toast); + + // 3秒后自动消失 + setTimeout(() => { + toast.style.opacity = '0'; + toast.style.transition = 'opacity 0.5s ease'; + setTimeout(() => { + document.body.removeChild(toast); + }, 500); + }, 3000); +} + +// 格式化日期 +function formatDate(date) { + return new Date(date).toLocaleString(); +} + +// 转换字节为可读格式 +function formatBytes(bytes) { + if (bytes === 0) return '0 Bytes'; + + const k = 1024; + const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']; + const i = Math.floor(Math.log(bytes) / Math.log(k)); + + return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i]; +} + +// 检查响应是否成功 +function checkResponse(response) { + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + return response; +} + +// 生成随机字符串 +function generateRandomString(length = 16) { + const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + let result = ''; + for (let i = 0; i < length; i++) { + result += chars.charAt(Math.floor(Math.random() * chars.length)); + } + return result; +} + +// 检查是否为有效的UUID +function isValidUUID(uuid) { + const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i; + return uuidRegex.test(uuid); +} + +// URL编码特殊字符 +function urlEncodeParams(params) { + const encodedParams = {}; + for (const key in params) { + encodedParams[key] = encodeURIComponent(params[key]); + } + return encodedParams; +} + +// 将对象转换为查询字符串 +function objectToQueryString(obj) { + return new URLSearchParams(obj).toString(); +} + +// 获取元素的DOM节点 +function $(selector) { + return document.querySelector(selector); +} + +// 显示元素 +function showElement(element) { + element.style.display = 'block'; +} + +// 隐藏元素 +function hideElement(element) { + element.style.display = 'none'; +} + +// 设置元素文本内容 +function setTextContent(element, text) { + element.textContent = text; +} + +// 获取元素文本内容 +function getTextContent(element) { + return element.textContent; +} + +// 添加事件监听器 +function addEventListener(element, event, handler) { + element.addEventListener(event, handler); +} + +// 移除事件监听器 +function removeEventListener(element, event, handler) { + element.removeEventListener(event, handler); +} + +// 滚动到页面顶部 +function scrollToTop() { + window.scrollTo({ + top: 0, + behavior: 'smooth' + }); +} + +// 滚动到元素 +function scrollToElement(element) { + element.scrollIntoView({ + behavior: 'smooth', + block: 'start' + }); +} + +// 创建DOM元素 +function createElement(tagName, className = '', innerHTML = '') { + const element = document.createElement(tagName); + if (className) { + element.className = className; + } + if (innerHTML) { + element.innerHTML = innerHTML; + } + return element; +} + +// 克隆DOM元素 +function cloneElement(element) { + return element.cloneNode(true); +} + +// 移除DOM元素 +function removeElement(element) { + if (element && element.parentNode) { + element.parentNode.removeChild(element); + } +} + +// 插入到DOM元素之前 +function insertBefore(referenceNode, newNode) { + referenceNode.parentNode.insertBefore(newNode, referenceNode); +} + +// 插入到DOM元素之后 +function insertAfter(referenceNode, newNode) { + referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling); +} + +// 替换DOM元素 +function replaceElement(oldNode, newNode) { + if (oldNode.parentNode) { + oldNode.parentNode.replaceChild(newNode, oldNode); + } +} + +// 添加CSS类 +function addClass(element, className) { + element.classList.add(className); +} + +// 移除CSS类 +function removeClass(element, className) { + element.classList.remove(className); +} + +// 切换CSS类 +function toggleClass(element, className) { + element.classList.toggle(className); +} + +// 检查CSS类是否存在 +function hasClass(element, className) { + return element.classList.contains(className); +} + +// 设置CSS样式 +function setStyle(element, style) { + for (const key in style) { + element.style[key] = style[key]; + } +} + +// 获取CSS样式 +function getStyle(element, property) { + return window.getComputedStyle(element).getPropertyValue(property); +} + +// 设置数据属性 +function setData(element, key, value) { + element.dataset[key] = value; +} + +// 获取数据属性 +function getData(element, key) { + return element.dataset[key]; +} + +// 移除数据属性 +function removeData(element, key) { + delete element.dataset[key]; +} + +// 获取或设置表单字段值 +function getFieldValue(element) { + const type = element.type; + if (type === 'checkbox' || type === 'radio') { + return element.checked; + } + return element.value; +} + +function setFieldValue(element, value) { + const type = element.type; + if (type === 'checkbox' || type === 'radio') { + element.checked = value; + } else { + element.value = value; + } +} + +// 阻止事件冒泡 +function stopEventPropagation(event) { + event.stopPropagation(); +} + +// 阻止事件默认行为 +function preventEventDefault(event) { + event.preventDefault(); +} + +// 检查元素是否在视口中 +function isInViewport(element) { + const rect = element.getBoundingClientRect(); + return ( + rect.top >= 0 && + rect.left >= 0 && + rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && + rect.right <= (window.innerWidth || document.documentElement.clientWidth) + ); +} + +// 观察元素变化 +function observeElement(element, callback) { + const observer = new MutationObserver(callback); + observer.observe(element, { + attributes: true, + childList: true, + characterData: true, + subtree: true + }); + + return observer; +} + +// 取消观察元素 +function disconnectObserver(observer) { + if (observer) { + observer.disconnect(); + } +} + +// 加载外部CSS文件 +function loadCSS(url) { + const link = document.createElement('link'); + link.rel = 'stylesheet'; + link.href = url; + document.head.appendChild(link); +} + +// 加载外部JS文件 +function loadJS(url, callback) { + const script = document.createElement('script'); + script.src = url; + script.onload = callback; + document.head.appendChild(script); +} + +// 获取浏览器窗口大小 +function getWindowSize() { + return { + width: window.innerWidth, + height: window.innerHeight + }; +} + +// 监听窗口大小变化 +function watchWindowSize(callback) { + window.addEventListener('resize', callback); +} + +// 取消监听窗口大小变化 +function unwatchWindowSize(callback) { + window.removeEventListener('resize', callback); +} + +// 模拟点击 +function simulateClick(element) { + const event = new MouseEvent('click', { + view: window, + bubbles: true, + cancelable: true + }); + element.dispatchEvent(event); +} + +// 创建并下载文件 +function downloadFileBlob(blob, fileName) { + const url = window.URL.createObjectURL(blob); + const a = document.createElement('a'); + a.style.display = 'none'; + a.href = url; + a.download = fileName; + document.body.appendChild(a); + a.click(); + window.URL.revokeObjectURL(url); + document.body.removeChild(a); +} + +// 复制文本到剪贴板 +async function copyToClipboard(text) { + try { + await navigator.clipboard.writeText(text); + return true; + } catch (err) { + console.error('无法复制文本: ', err); + return false; + } +} + +// 加载更多内容 +function loadMoreContent(element, loadFn, params = {}) { + const loadMoreBtn = document.createElement('button'); + loadMoreBtn.className = 'btn btn-primary w-full mt-4'; + loadMoreBtn.textContent = '加载更多'; + + element.appendChild(loadMoreBtn); + + loadMoreBtn.addEventListener('click', function() { + showLoadingModal(); + loadFn(params) + .then(data => { + hideLoadingModal(); + if (data.status === 200) { + element.removeChild(loadMoreBtn); + // 处理加载的数据 + // 这里需要根据具体需求实现 + } else { + alert(`加载失败: ${data.message || '未知错误'}`); + } + }) + .catch(error => { + hideLoadingModal(); + console.error('加载失败:', error); + alert('加载失败,请检查网络连接'); + }); + }); +} + +// 创建模态框 +function createModal(title, content, footer = '') { + const modal = document.createElement('div'); + modal.className = 'fixed top-0 left-0 w-full h-full bg-gray-900 bg-opacity-50 flex items-center justify-center'; + modal.innerHTML = ` +
+

${title}

+
${content}
+ ${footer} +
+ `; + + document.body.appendChild(modal); + + return modal; +} + +// 关闭模态框 +function closeModal(modal) { + if (modal && modal.parentNode) { + modal.parentNode.removeChild(modal); + } +} + +// 创建确认框 +function createConfirmModal(message, onConfirm, onCancel = null, title = '确认') { + const modal = createModal(title, message, ` +
+ + +
+ `); + + document.getElementById('confirmBtn').addEventListener('click', function() { + closeModal(modal); + if (typeof onConfirm === 'function') { + onConfirm(); + } + }); + + document.getElementById('cancelBtn').addEventListener('click', function() { + closeModal(modal); + if (typeof onCancel === 'function') { + onCancel(); + } + }); + + return modal; +} + +// 创建加载提示 +function createLoadingTip(message = '加载中...') { + const tip = document.createElement('div'); + tip.className = 'fixed top-0 left-0 w-full h-full bg-gray-900 bg-opacity-50 flex items-center justify-center'; + tip.innerHTML = ` +
+
+ +
+

${message}

+
+ `; + + document.body.appendChild(tip); + + return tip; +} + +// 移除加载提示 +function removeLoadingTip(tip) { + if (tip && tip.parentNode) { + tip.parentNode.removeChild(tip); + } +} \ No newline at end of file diff --git a/console/ins_beta/php/api.php b/console/ins_beta/php/api.php new file mode 100755 index 0000000..bc26970 --- /dev/null +++ b/console/ins_beta/php/api.php @@ -0,0 +1,385 @@ + CONFIG_API_BAD_REQUEST, + 'message' => '缺少必要的参数: serverUUID 或 nodeUUID' + ]); + exit; +} + +// 根据不同的操作执行不同的API请求 +switch ($action) { + case 'getInstanceInfo': + $response = getInstanceInfo($serverUUID, $nodeUUID); + break; + case 'startInstance': + $response = startInstance($serverUUID, $nodeUUID); + break; + case 'stopInstance': + $response = stopInstance($serverUUID, $nodeUUID); + break; + case 'getConsole': + $response = getConsole($serverUUID, $nodeUUID); + break; + case 'sendConsoleCommand': + $command = isset($_GET['command']) ? $_GET['command'] : null; + $response = sendConsoleCommand($serverUUID, $nodeUUID, $command); + break; + case 'getConsoleOutput': + $response = getConsoleOutput($serverUUID, $nodeUUID); + break; + case 'getFiles': + $response = getFiles($serverUUID, $nodeUUID); + break; + case 'viewFile': + $path = isset($_GET['path']) ? $_GET['path'] : null; + $response = viewFile($serverUUID, $nodeUUID, $path); + break; + case 'downloadFile': + $path = isset($_GET['path']) ? $_GET['path'] : null; + downloadFile($serverUUID, $nodeUUID, $path); + exit; + case 'uploadFile': + if ($_SERVER['REQUEST_METHOD'] !== 'POST') { + echo json_encode([ + 'status' => CONFIG_API_BAD_REQUEST, + 'message' => '无效的请求方法' + ]); + exit; + } + $file = $_FILES['file'] ?? null; + $path = isset($_POST['path']) ? $_POST['path'] : '/'; + $response = uploadFile($serverUUID, $nodeUUID, $file, $path); + break; + case 'saveEditFile': + if ($_SERVER['REQUEST_METHOD'] !== 'POST') { + echo json_encode([ + 'status' => CONFIG_API_BAD_REQUEST, + 'message' => '无效的请求方法' + ]); + exit; + } + $content = isset($_POST['content']) ? $_POST['content'] : null; + $path = isset($_POST['path']) ? $_POST['path'] : null; + $response = saveEditFile($serverUUID, $nodeUUID, $content, $path); + break; + case 'deleteFile': + $path = isset($_GET['path']) ? $_GET['path'] : null; + $response = deleteFile($serverUUID, $nodeUUID, $path); + break; + default: + echo json_encode([ + 'status' => CONFIG_API_BAD_REQUEST, + 'message' => '无效的操作' + ]); + exit; +} + +// 输出响应 +echo json_encode($response); + +// 获取实例信息 +function getInstanceInfo($serverUUID, $nodeUUID) { + $url = CONFIG_MCSM_API_URL . "/api/service/remote_services_system?nodeUUID=" . urlencode($nodeUUID) . "&serverUUID=" . urlencode($serverUUID); + + return sendRequest($url, 'GET'); +} + +// 启动实例 +function startInstance($serverUUID, $nodeUUID) { + $url = CONFIG_MCSM_API_URL . "/api/service/start_server?nodeUUID=" . urlencode($nodeUUID) . "&serverUUID=" . urlencode($serverUUID); + + return sendRequest($url, 'GET'); +} + +// 停止实例 +function stopInstance($serverUUID, $nodeUUID) { + $url = CONFIG_MCSM_API_URL . "/api/service/stop_server?nodeUUID=" . urlencode($nodeUUID) . "&serverUUID=" . urlencode($serverUUID); + + return sendRequest($url, 'GET'); +} + +// 获取控制台 +function getConsole($serverUUID, $nodeUUID) { + $url = CONFIG_MCSM_API_URL . "/api/service/console?nodeUUID=" . urlencode($nodeUUID) . "&serverUUID=" . urlencode($serverUUID); + + return sendRequest($url, 'GET'); +} + +// 发送控制台命令 +function sendConsoleCommand($serverUUID, $nodeUUID, $command) { + if (!$command) { + return [ + 'status' => CONFIG_API_BAD_REQUEST, + 'message' => '命令不能为空' + ]; + } + + $url = CONFIG_MCSM_API_URL . "/api/service/console?nodeUUID=" . urlencode($nodeUUID) . "&serverUUID=" . urlencode($serverUUID); + + return sendRequest($url, 'POST', json_encode(['command' => $command])); +} + +// 获取控制台输出 +function getConsoleOutput($serverUUID, $nodeUUID) { + $url = CONFIG_MCSM_API_URL . "/api/service/console?nodeUUID=" . urlencode($nodeUUID) . "&serverUUID=" . urlencode($serverUUID); + + return sendRequest($url, 'GET'); +} + +// 获取文件列表 +function getFiles($serverUUID, $nodeUUID) { + $url = CONFIG_MCSM_API_URL . "/api/service/files?nodeUUID=" . urlencode($nodeUUID) . "&serverUUID=" . urlencode($serverUUID); + + return sendRequest($url, 'GET'); +} + +// 查看文件内容 +function viewFile($serverUUID, $nodeUUID, $path) { + if (!$path) { + return [ + 'status' => CONFIG_API_BAD_REQUEST, + 'message' => '文件路径不能为空' + ]; + } + + $url = CONFIG_MCSM_API_URL . "/api/service/file_content?nodeUUID=" . urlencode($nodeUUID) . "&serverUUID=" . urlencode($serverUUID); + + return sendRequest($url, 'POST', json_encode(['path' => $path])); +} + +// 下载文件 +function downloadFile($serverUUID, $nodeUUID, $path) { + if (!$path) { + echo json_encode([ + 'status' => CONFIG_API_BAD_REQUEST, + 'message' => '文件路径不能为空' + ]); + exit; + } + + $url = CONFIG_MCSM_API_URL . "/api/service/file_download?nodeUUID=" . urlencode($nodeUUID) . "&serverUUID=" . urlencode($serverUUID); + + try { + // 发送请求到MCSManager API + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(['path' => $path])); + curl_setopt($ch, CURLOPT_HTTPHEADER, [ + 'Content-Type: application/json; charset=utf-8', + 'X-Requested-With: XMLHttpRequest' + ]); + curl_setopt($ch, CURLOPT_TIMEOUT, CONFIG_API_TIMEOUT); + + $response = curl_exec($ch); + $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); + curl_close($ch); + + // 检查API响应状态码 + if ($httpCode !== CONFIG_API_SUCCESS) { + echo json_encode([ + 'status' => $httpCode, + 'message' => 'API请求失败' + ]); + exit; + } + + // 解析响应 + $data = json_decode($response, true); + + if ($data['status'] !== CONFIG_API_SUCCESS) { + echo json_encode([ + 'status' => $data['status'], + 'message' => $data['message'] ?? '未知错误' + ]); + exit; + } + + // 设置下载响应头 + header('Content-Type: application/octet-stream'); + header('Content-Disposition: attachment; filename="' . basename($path) . '"'); + header('Content-Length: ' . strlen($data['data'])); + + // 输出文件内容 + echo $data['data']; + } catch (Exception $e) { + echo json_encode([ + 'status' => CONFIG_API_INTERNAL_ERROR, + 'message' => '下载文件失败: ' . $e->getMessage() + ]); + } +} + +// 上传文件 +function uploadFile($serverUUID, $nodeUUID, $file, $path) { + if (!$file || !is_uploaded_file($file['tmp_name'])) { + return [ + 'status' => CONFIG_API_BAD_REQUEST, + 'message' => '未上传有效的文件' + ]; + } + + $url = CONFIG_MCSM_API_URL . "/api/service/file_upload?nodeUUID=" . urlencode($nodeUUID) . "&serverUUID=" . urlencode($serverUUID); + + try { + // 打开文件 + $fileData = file_get_contents($file['tmp_name']); + + // 发送请求到MCSManager API + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, [ + 'path' => $path, + 'file' => base64_encode($fileData) + ]); + curl_setopt($ch, CURLOPT_HTTPHEADER, [ + 'Content-Type: application/x-www-form-urlencoded; charset=utf-8', + 'X-Requested-With: XMLHttpRequest' + ]); + curl_setopt($ch, CURLOPT_TIMEOUT, CONFIG_API_TIMEOUT); + + $response = curl_exec($ch); + $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); + curl_close($ch); + + // 检查API响应状态码 + if ($httpCode !== CONFIG_API_SUCCESS) { + return [ + 'status' => $httpCode, + 'message' => 'API请求失败' + ]; + } + + // 解析响应 + $data = json_decode($response, true); + + if ($data['status'] !== CONFIG_API_SUCCESS) { + return [ + 'status' => $data['status'], + 'message' => $data['message'] ?? '未知错误' + ]; + } + + return [ + 'status' => CONFIG_API_SUCCESS, + 'message' => '文件上传成功' + ]; + } catch (Exception $e) { + return [ + 'status' => CONFIG_API_INTERNAL_ERROR, + 'message' => '上传文件失败: ' . $e->getMessage() + ]; + } +} + +// 保存编辑的文件 +function saveEditFile($serverUUID, $nodeUUID, $content, $path) { + if (!$content || !$path) { + return [ + 'status' => CONFIG_API_BAD_REQUEST, + 'message' => '内容或路径不能为空' + ]; + } + + $url = CONFIG_MCSM_API_URL . "/api/service/file_content?nodeUUID=" . urlencode($nodeUUID) . "&serverUUID=" . urlencode($serverUUID); + + return sendRequest($url, 'PUT', json_encode(['path' => $path, 'content' => $content])); +} + +// 删除文件 +function deleteFile($serverUUID, $nodeUUID, $path) { + if (!$path) { + return [ + 'status' => CONFIG_API_BAD_REQUEST, + 'message' => '文件路径不能为空' + ]; + } + + $url = CONFIG_MCSM_API_URL . "/api/service/file_delete?nodeUUID=" . urlencode($nodeUUID) . "&serverUUID=" . urlencode($serverUUID); + + return sendRequest($url, 'DELETE', json_encode(['path' => $path])); +} + +// 发送API请求 +function sendRequest($url, $method = 'GET', $data = null) { + try { + // 发送请求到MCSManager API + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // 设置请求方法 + switch ($method) { + case 'POST': + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $data); + break; + case 'PUT': + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT'); + curl_setopt($ch, CURLOPT_POSTFIELDS, $data); + break; + case 'DELETE': + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE'); + curl_setopt($ch, CURLOPT_POSTFIELDS, $data); + break; + } + + // 设置请求头 + curl_setopt($ch, CURLOPT_HTTPHEADER, [ + 'Content-Type: application/json; charset=utf-8', + 'X-Requested-With: XMLHttpRequest' + ]); + + // 设置超时时间 + curl_setopt($ch, CURLOPT_TIMEOUT, CONFIG_API_TIMEOUT); + + $response = curl_exec($ch); + $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); + curl_close($ch); + + // 检查API响应状态码 + if ($httpCode !== CONFIG_API_SUCCESS) { + return [ + 'status' => $httpCode, + 'message' => 'API请求失败' + ]; + } + + // 解析响应 + $data = json_decode($response, true); + + if ($data['status'] !== CONFIG_API_SUCCESS) { + return [ + 'status' => $data['status'], + 'message' => $data['message'] ?? '未知错误' + ]; + } + + return [ + 'status' => CONFIG_API_SUCCESS, + 'data' => $data['data'] ?? [] + ]; + } catch (Exception $e) { + return [ + 'status' => CONFIG_API_INTERNAL_ERROR, + 'message' => '请求失败: ' . $e->getMessage() + ]; + } +} \ No newline at end of file diff --git a/console/ins_beta/php/config.php b/console/ins_beta/php/config.php new file mode 100755 index 0000000..188c66c --- /dev/null +++ b/console/ins_beta/php/config.php @@ -0,0 +1,21 @@ + + + + + + CCS | Minecraft服务器在线状态查询 + + + + + + + + + +
+ +
+ +
+

+ Minecraft(JE)状态查询 +

+

+ CCSNetwork | 圆周云境技术部门 +

+ +
+ 20秒后自动刷新 +
+
+ + +
+ +
+
+
+

正在刷新服务器状态...

+
+
+ + +
+
+
+ +
+ + + + +
+
+ +
+ +
+ + + + +
+
+ +
+ +
+
+
+ + + + + + +
+ + +
+ + + + \ No newline at end of file diff --git a/console/tools.html b/console/tools.html new file mode 100755 index 0000000..c5c84bf --- /dev/null +++ b/console/tools.html @@ -0,0 +1,309 @@ + + + + + + 实用工具导航 + + + + + + +
+
+
+ +

实用工具导航

+
+
+ + +
+
+
+ +
+ +
+

+ + 开发工具 +

+ +
+ + +
+

+ + 安全工具 +

+ +
+ + +
+

+ + 设计工具 +

+ +
+ + +
+

+ + 效率工具 +

+ +
+
+ + + + + + + \ No newline at end of file diff --git a/get_server_status.php b/get_server_status.php new file mode 100755 index 0000000..a37d3a5 --- /dev/null +++ b/get_server_status.php @@ -0,0 +1,28 @@ + "Failed to fetch server status"]); + exit; +} + +// 返回JSON数据 +header('Content-Type: application/json'); +echo $response; +?> \ No newline at end of file diff --git a/haresworld.html b/haresworld.html new file mode 100755 index 0000000..0191fde --- /dev/null +++ b/haresworld.html @@ -0,0 +1,494 @@ + + + + + + CCSIT | Hare's World服务器 + + + + + + + + + + + +
+ +
+
+
+ +
+
+
+ +
+

+ Hare's +

+

+ 探索无限可能 +

+ +
+
+ +
+
当前在线
+
加载中...
+
+
+ +
+ +
+
服务器运行时间
+
24/7 不间断
+
+
+
+ + +
+
+ +
+ + + +
+
+ + +
+
+
+
+

+ 特色系统 +

+

+ 我们的服务器整合了多种独特功能,打造沉浸式游戏体验 +

+
+ +
+ + + + + + + + +
+
+
+ + +
+ +
+
+

+ +

+

+ 通过游戏成就解锁独特称号,展现你的实力与地位 +

+
+ +
+ + + + + + + + +
+ + +
+

进入服务器步骤

+ +
+ + + + + + + + + + + +
+
+
+
+ +
+ + + + + + + \ No newline at end of file diff --git a/img/Hare'sWorld.png b/img/Hare'sWorld.png new file mode 100755 index 0000000..7415d02 Binary files /dev/null and b/img/Hare'sWorld.png differ diff --git a/back.jpeg b/img/back.jpeg similarity index 100% rename from back.jpeg rename to img/back.jpeg diff --git a/rainyun.jpg b/img/rainyun.jpg similarity index 100% rename from rainyun.jpg rename to img/rainyun.jpg diff --git a/img/web.png b/img/web.png new file mode 100755 index 0000000..8736297 Binary files /dev/null and b/img/web.png differ diff --git a/index.html b/index.html index 90e3c26..18ebec2 100755 --- a/index.html +++ b/index.html @@ -2,410 +2,1085 @@ - - 维护通知 - - - - + + + - - -
- - - + + +
+ + +
+
-
-
-
-

服务正在维护

-

请耐心等待恢复

- -
- - 服务维护中 -
- -
- -
- -
-

- 通知 -

-

- 我们非常遗憾地通知您,我们已于 2025年06月14日 停止服务。 -

-

- 请注意,所有账户数据将继续储存在我们的数据库中,不会丢失数据 -

-
-
-

服务维护时间线

-
-
-
2025-05-30
-
提交备案申请完毕
-
-
-
-
2025-06-14
-
服务停止,运行备案流程
-
-
-
-
2025-06-XX
-
等待备案下发
-
-
-
-
- -
-

- - 常见问题 -

-
-
-

为什么维护?

-

国内云产品使用带域名的 HTTP/HTTPS 服务或使用80,443端口时,需确保域名完成备案才能正常使用,备案期间完全无法使用服务,此外,服务器项目源文件因失误遭到损坏,正在迁移备份!

-
-
-

为什么之前能访问?

-

之前本工作室采用香港计算节点运行网站服务,现迁移至境内服务器,并注册新域名ccsnetwork.cn用于备案。

-
-
-
- -
- -

© 2025 CCSIT圆周云境技术部门 -

+ +