2024-10-26 10:38:22 +08:00
|
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
include './cfg.php';
|
|
|
|
|
|
|
|
|
|
$themeDir = "$neko_www/assets/theme";
|
|
|
|
|
$tmpPath = "$neko_www/lib/selected_config.txt";
|
|
|
|
|
$arrFiles = array();
|
|
|
|
|
$arrFiles = glob("$themeDir/*.css");
|
|
|
|
|
|
|
|
|
|
for($x=0;$x<count($arrFiles);$x++) $arrFiles[$x] = substr($arrFiles[$x], strlen($themeDir)+1);
|
|
|
|
|
|
|
|
|
|
if(isset($_POST['themechange'])){
|
|
|
|
|
$dt = $_POST['themechange'];
|
|
|
|
|
shell_exec("echo $dt > $neko_www/lib/theme.txt");
|
|
|
|
|
$neko_theme = $dt;
|
|
|
|
|
}
|
|
|
|
|
if(isset($_POST['fw'])){
|
|
|
|
|
$dt = $_POST['fw'];
|
|
|
|
|
if ($dt == 'enable') shell_exec("uci set neko.cfg.new_interface='1' && uci commit neko");
|
|
|
|
|
if ($dt == 'disable') shell_exec("uci set neko.cfg.new_interface='0' && uci commit neko");
|
|
|
|
|
}
|
|
|
|
|
$fwstatus=shell_exec("uci get neko.cfg.new_interface");
|
2025-01-26 00:23:38 +08:00
|
|
|
|
$enableSnow = false;
|
2024-10-26 10:38:22 +08:00
|
|
|
|
?>
|
|
|
|
|
<?php
|
|
|
|
|
function getSingboxVersion() {
|
|
|
|
|
$singBoxPath = '/usr/bin/sing-box';
|
|
|
|
|
$command = "$singBoxPath version 2>&1";
|
|
|
|
|
exec($command, $output, $returnVar);
|
|
|
|
|
|
|
|
|
|
if ($returnVar === 0) {
|
|
|
|
|
foreach ($output as $line) {
|
|
|
|
|
if (strpos($line, 'version') !== false) {
|
|
|
|
|
$parts = explode(' ', $line);
|
2024-12-07 09:40:48 +08:00
|
|
|
|
$version = end($parts);
|
|
|
|
|
|
|
|
|
|
if (strpos($version, 'alpha') !== false || strpos($version, 'beta') !== false) {
|
|
|
|
|
if (strpos($version, '1.10.0-alpha.29-067c81a7') !== false) {
|
|
|
|
|
return ['version' => $version, 'type' => 'Puernya 预览版'];
|
|
|
|
|
}
|
|
|
|
|
return ['version' => $version, 'type' => 'Singbox 预览版'];
|
|
|
|
|
} else {
|
2024-12-29 16:23:13 +08:00
|
|
|
|
if (strpos($version, 'v') !== false) {
|
|
|
|
|
return ['version' => $version, 'type' => 'Singbox 编译版'];
|
|
|
|
|
}
|
2024-12-07 09:40:48 +08:00
|
|
|
|
return ['version' => $version, 'type' => 'Singbox 正式版'];
|
|
|
|
|
}
|
2024-10-26 10:38:22 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-07 09:40:48 +08:00
|
|
|
|
return ['version' => '未安装', 'type' => '未知'];
|
2024-10-26 10:38:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-12-07 09:40:48 +08:00
|
|
|
|
function getMihomoVersion() {
|
2024-12-22 20:34:43 +08:00
|
|
|
|
$mihomoPath = '/usr/bin/mihomo';
|
|
|
|
|
$command = "$mihomoPath -v 2>&1";
|
|
|
|
|
exec($command, $output, $returnVar);
|
2024-12-07 09:40:48 +08:00
|
|
|
|
|
2024-12-22 20:34:43 +08:00
|
|
|
|
if ($returnVar === 0) {
|
|
|
|
|
foreach ($output as $line) {
|
|
|
|
|
if (strpos($line, 'Mihomo') !== false) {
|
|
|
|
|
preg_match('/alpha-[a-z0-9]+/', $line, $matches);
|
|
|
|
|
if (!empty($matches)) {
|
|
|
|
|
$version = $matches[0];
|
|
|
|
|
return ['version' => $version, 'type' => '预览版'];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
preg_match('/([0-9]+(\.[0-9]+)+)/', $line, $matches);
|
|
|
|
|
if (!empty($matches)) {
|
|
|
|
|
$version = $matches[0];
|
2025-01-10 09:28:17 +08:00
|
|
|
|
if (preg_match('/^\d/', $version)) {
|
|
|
|
|
$version = 'v' . $version;
|
|
|
|
|
}
|
2024-12-22 20:34:43 +08:00
|
|
|
|
return ['version' => $version, 'type' => '正式版'];
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-12-07 09:40:48 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2024-12-22 20:34:43 +08:00
|
|
|
|
|
|
|
|
|
return ['version' => '未安装', 'type' => '未知'];
|
2024-12-07 09:40:48 +08:00
|
|
|
|
}
|
2024-10-26 16:23:41 +08:00
|
|
|
|
|
|
|
|
|
function getUiVersion() {
|
2024-12-04 09:43:01 +08:00
|
|
|
|
$versionFile = '/etc/neko/ui/zashboard/version.txt';
|
2024-10-26 16:23:41 +08:00
|
|
|
|
|
|
|
|
|
if (file_exists($versionFile)) {
|
|
|
|
|
return trim(file_get_contents($versionFile));
|
|
|
|
|
} else {
|
2024-12-07 00:25:43 +08:00
|
|
|
|
return "未安装";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getMetaCubexdVersion() {
|
|
|
|
|
$versionFile = '/etc/neko/ui/metacubexd/version.txt';
|
|
|
|
|
|
|
|
|
|
if (file_exists($versionFile)) {
|
|
|
|
|
return trim(file_get_contents($versionFile));
|
|
|
|
|
} else {
|
|
|
|
|
return "未安装";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getMetaVersion() {
|
|
|
|
|
$versionFile = '/etc/neko/ui/meta/version.txt';
|
|
|
|
|
|
|
|
|
|
if (file_exists($versionFile)) {
|
|
|
|
|
return trim(file_get_contents($versionFile));
|
|
|
|
|
} else {
|
|
|
|
|
return "未安装";
|
2024-10-26 16:23:41 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-07 09:40:48 +08:00
|
|
|
|
function getRazordVersion() {
|
|
|
|
|
$versionFile = '/etc/neko/ui/dashboard/version.txt';
|
|
|
|
|
|
|
|
|
|
if (file_exists($versionFile)) {
|
|
|
|
|
return trim(file_get_contents($versionFile));
|
|
|
|
|
} else {
|
|
|
|
|
return "未安装";
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-12-17 20:42:25 +08:00
|
|
|
|
|
|
|
|
|
function getCliverVersion() {
|
|
|
|
|
$versionFile = '/etc/neko/tmp/nekobox_version';
|
|
|
|
|
|
|
|
|
|
if (file_exists($versionFile)) {
|
2024-12-19 09:38:38 +08:00
|
|
|
|
$version = trim(file_get_contents($versionFile));
|
|
|
|
|
|
|
|
|
|
if (preg_match('/-cn$|en$/', $version)) {
|
|
|
|
|
return ['version' => $version, 'type' => '正式版'];
|
|
|
|
|
} elseif (preg_match('/-preview$|beta$/', $version)) {
|
|
|
|
|
return ['version' => $version, 'type' => '预览版'];
|
|
|
|
|
} else {
|
|
|
|
|
return ['version' => $version, 'type' => '未知'];
|
|
|
|
|
}
|
2024-12-17 20:42:25 +08:00
|
|
|
|
} else {
|
2024-12-19 09:38:38 +08:00
|
|
|
|
return ['version' => '未安装', 'type' => '未知'];
|
2024-12-17 20:42:25 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2024-12-19 09:38:38 +08:00
|
|
|
|
|
|
|
|
|
$cliverData = getCliverVersion();
|
|
|
|
|
$cliverVersion = $cliverData['version'];
|
|
|
|
|
$cliverType = $cliverData['type'];
|
2024-12-07 09:40:48 +08:00
|
|
|
|
$singBoxVersionInfo = getSingboxVersion();
|
|
|
|
|
$singBoxVersion = $singBoxVersionInfo['version'];
|
|
|
|
|
$singBoxType = $singBoxVersionInfo['type'];
|
|
|
|
|
$puernyaVersion = ($singBoxType === 'Puernya 预览版') ? $singBoxVersion : '未安装';
|
|
|
|
|
$singboxPreviewVersion = ($singBoxType === 'Singbox 预览版') ? $singBoxVersion : '未安装';
|
2024-12-29 16:23:13 +08:00
|
|
|
|
$singboxCompileVersion = ($singBoxType === 'Singbox 编译版') ? $singBoxVersion : '未安装';
|
2024-12-07 09:40:48 +08:00
|
|
|
|
$mihomoVersionInfo = getMihomoVersion();
|
|
|
|
|
$mihomoVersion = $mihomoVersionInfo['version'];
|
|
|
|
|
$mihomoType = $mihomoVersionInfo['type'];
|
2024-10-26 16:23:41 +08:00
|
|
|
|
$uiVersion = getUiVersion();
|
2024-12-07 00:25:43 +08:00
|
|
|
|
$metaCubexdVersion = getMetaCubexdVersion();
|
|
|
|
|
$metaVersion = getMetaVersion();
|
2024-12-07 09:40:48 +08:00
|
|
|
|
$razordVersion = getRazordVersion();
|
2024-12-07 00:25:43 +08:00
|
|
|
|
|
2024-10-26 16:23:41 +08:00
|
|
|
|
?>
|
|
|
|
|
|
2024-10-26 10:38:22 +08:00
|
|
|
|
<!doctype html>
|
|
|
|
|
<html lang="en" data-bs-theme="<?php echo substr($neko_theme,0,-4) ?>">
|
|
|
|
|
<head>
|
|
|
|
|
<meta charset="utf-8">
|
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
2024-12-22 20:34:43 +08:00
|
|
|
|
<title>Settings - Nekobox</title>
|
2024-10-26 10:38:22 +08:00
|
|
|
|
<link rel="icon" href="./assets/img/nekobox.png">
|
|
|
|
|
<link href="./assets/css/bootstrap.min.css" rel="stylesheet">
|
|
|
|
|
<link href="./assets/theme/<?php echo $neko_theme ?>" rel="stylesheet">
|
|
|
|
|
<link href="./assets/css/custom.css" rel="stylesheet">
|
2025-01-10 00:26:22 +08:00
|
|
|
|
<link href="./assets/bootstrap/bootstrap-icons.css" rel="stylesheet">
|
2025-01-24 16:24:40 +08:00
|
|
|
|
<link rel="stylesheet" href="styles.css?v=<?php echo time(); ?>" />
|
|
|
|
|
<script src="script.js?v=<?php echo time(); ?>"></script>
|
2024-10-26 10:38:22 +08:00
|
|
|
|
<script type="text/javascript" src="./assets/js/bootstrap.min.js"></script>
|
|
|
|
|
<script type="text/javascript" src="./assets/js/feather.min.js"></script>
|
2024-10-26 16:23:41 +08:00
|
|
|
|
<script type="text/javascript" src="./assets/bootstrap/bootstrap.bundle.min.js"></script>
|
2024-10-26 10:38:22 +08:00
|
|
|
|
<script type="text/javascript" src="./assets/js/jquery-2.1.3.min.js"></script>
|
|
|
|
|
<script type="text/javascript" src="./assets/js/neko.js"></script>
|
2024-11-03 20:36:08 +08:00
|
|
|
|
<?php include './ping.php'; ?>
|
2024-10-26 10:38:22 +08:00
|
|
|
|
</head>
|
2024-12-22 20:34:43 +08:00
|
|
|
|
<style>
|
|
|
|
|
.form-select {
|
|
|
|
|
margin-left: 10px;
|
|
|
|
|
margin-right: 16px;
|
|
|
|
|
}
|
2025-01-10 09:28:17 +08:00
|
|
|
|
|
|
|
|
|
@media (max-width: 576px) {
|
|
|
|
|
.btn-custom {
|
2025-01-12 00:22:09 +08:00
|
|
|
|
width: 30%;
|
2025-01-10 09:28:17 +08:00
|
|
|
|
margin: 0 auto;
|
|
|
|
|
display: block;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.btn-fw {
|
|
|
|
|
width: 100%;
|
|
|
|
|
margin-right: 0;
|
|
|
|
|
margin-bottom: 10px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.container .form-select {
|
|
|
|
|
margin-right: 6ch;
|
|
|
|
|
width: calc(100% - 1.8ch);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-22 20:34:43 +08:00
|
|
|
|
</style>
|
2024-10-26 10:38:22 +08:00
|
|
|
|
<body>
|
|
|
|
|
<div class="container-sm container-bg text-center callout border border-3 rounded-4 col-11">
|
|
|
|
|
<div class="row">
|
2025-01-10 00:26:22 +08:00
|
|
|
|
<a href="./index.php" class="col btn btn-lg"><i class="bi bi-house-door"></i> 首页</a>
|
|
|
|
|
<a href="./dashboard.php" class="col btn btn-lg"><i class="bi bi-bar-chart"></i> 面板</a>
|
|
|
|
|
<a href="./singbox.php" class="col btn btn-lg"><i class="bi bi-box"></i> 订阅</a>
|
|
|
|
|
<a href="./settings.php" class="col btn btn-lg"><i class="bi bi-gear"></i> 设定</a>
|
2024-12-24 14:16:36 +08:00
|
|
|
|
<div class="container px-4">
|
|
|
|
|
<h2 class="text-center p-2 mb-4">主题设定</h2>
|
|
|
|
|
<form action="settings.php" method="post">
|
|
|
|
|
<div class="row justify-content-center">
|
|
|
|
|
<div class="col-12 col-md-6 mb-3">
|
|
|
|
|
<select class="form-select" name="themechange" aria-label="themex">
|
|
|
|
|
<option selected>Change Theme (<?php echo $neko_theme ?>)</option>
|
|
|
|
|
<?php foreach ($arrFiles as $file) echo "<option value=\"".$file.'">'.$file."</option>" ?>
|
|
|
|
|
</select>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="col-12 col-md-6 mb-3" style="padding-right: 1.3rem;" >
|
2025-01-14 12:22:26 +08:00
|
|
|
|
<div class="d-flex justify-content-between gap-2">
|
2025-01-24 16:24:40 +08:00
|
|
|
|
<button class="btn btn-info btn-custom" type="submit">
|
|
|
|
|
<i class="bi bi-paint-bucket"></i> 更改主题
|
|
|
|
|
</button>
|
2025-01-14 12:22:26 +08:00
|
|
|
|
|
|
|
|
|
<button type="button" class="btn btn-success" data-bs-toggle="modal" data-bs-target="#colorModal">
|
2025-01-24 16:24:40 +08:00
|
|
|
|
<i class="bi-palette"></i> 主题编辑器
|
2025-01-14 12:22:26 +08:00
|
|
|
|
</button>
|
|
|
|
|
|
|
|
|
|
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#filesModal">
|
2025-01-24 16:24:40 +08:00
|
|
|
|
<i class="bi-upload"></i> 上传并管理背景图片
|
2025-01-14 12:22:26 +08:00
|
|
|
|
</button>
|
2024-10-26 10:38:22 +08:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2024-12-24 14:16:36 +08:00
|
|
|
|
</div>
|
|
|
|
|
</form>
|
2025-01-14 12:22:26 +08:00
|
|
|
|
|
2024-11-06 09:24:05 +08:00
|
|
|
|
<table class="table table-borderless mb-3">
|
|
|
|
|
<tbody>
|
|
|
|
|
<tr>
|
|
|
|
|
<td colspan="2">
|
|
|
|
|
<h2 class="text-center mb-3">自动重载防火墙</h2>
|
|
|
|
|
<form action="settings.php" method="post">
|
|
|
|
|
<div class="btn-group d-flex justify-content-center">
|
2025-01-10 09:28:17 +08:00
|
|
|
|
<button type="submit" name="fw" value="enable" class="btn btn<?php if($fwstatus==1) echo "-outline" ?>-success <?php if($fwstatus==1) echo "disabled" ?> btn-fw" style="margin-right: 20px;">启用</button>
|
2024-11-06 09:24:05 +08:00
|
|
|
|
<button type="submit" name="fw" value="disable" class="btn btn<?php if($fwstatus==0) echo "-outline" ?>-danger <?php if($fwstatus==0) echo "disabled" ?>">停用</button>
|
2024-12-24 14:16:36 +08:00
|
|
|
|
</div>
|
|
|
|
|
</form>
|
|
|
|
|
</td>
|
|
|
|
|
</tr>
|
|
|
|
|
<tr>
|
|
|
|
|
<tr>
|
|
|
|
|
<td>
|
|
|
|
|
<table class="table">
|
|
|
|
|
<thead>
|
|
|
|
|
<tr>
|
|
|
|
|
<th>客户端版本</th>
|
|
|
|
|
</tr>
|
|
|
|
|
</thead>
|
|
|
|
|
<tbody>
|
|
|
|
|
<tr>
|
|
|
|
|
<td class="text-center" style="font-family: monospace;">
|
|
|
|
|
<span id="cliver"></span><span id="NewCliver"> </span>
|
|
|
|
|
</td>
|
|
|
|
|
</tr>
|
|
|
|
|
<tr>
|
|
|
|
|
<td class="text-center">
|
2025-01-15 09:24:24 +08:00
|
|
|
|
<button class="btn btn-pink me-1" id="checkCliverButton">🔍 检测版本</button>
|
2024-12-24 14:16:36 +08:00
|
|
|
|
<button class="btn btn-info" id="updateButton" title="更新到最新版本" onclick="showVersionTypeModal()">🔄 更新版本</button>
|
|
|
|
|
</td>
|
|
|
|
|
</tr>
|
|
|
|
|
</tbody>
|
|
|
|
|
</table>
|
|
|
|
|
</td>
|
|
|
|
|
<td>
|
|
|
|
|
<table class="table">
|
|
|
|
|
<thead>
|
|
|
|
|
<tr>
|
|
|
|
|
<th>UI 控制面板</th>
|
|
|
|
|
</tr>
|
|
|
|
|
</thead>
|
|
|
|
|
<tbody>
|
|
|
|
|
<tr>
|
|
|
|
|
<td class="text-center">
|
|
|
|
|
<?php echo htmlspecialchars($uiVersion); ?><span id="NewUi"> </span>
|
|
|
|
|
</td>
|
|
|
|
|
</tr>
|
|
|
|
|
<tr>
|
|
|
|
|
<td class="text-center">
|
2025-01-15 09:24:24 +08:00
|
|
|
|
<button class="btn btn-pink me-1" id="checkUiButton">🔍 检测版本</button>
|
2024-12-24 14:16:36 +08:00
|
|
|
|
<button class="btn btn-info" id="updateUiButton" title="更新面板" onclick="showPanelSelector()">🔄 更新版本</button>
|
|
|
|
|
</td>
|
|
|
|
|
</tr>
|
|
|
|
|
</tbody>
|
|
|
|
|
</table>
|
|
|
|
|
</td>
|
|
|
|
|
</tr>
|
|
|
|
|
<tr>
|
|
|
|
|
<td>
|
|
|
|
|
<table class="table">
|
|
|
|
|
<thead>
|
|
|
|
|
<tr>
|
|
|
|
|
<th>Sing-box 核心版本</th>
|
|
|
|
|
</tr>
|
|
|
|
|
</thead>
|
|
|
|
|
<tbody>
|
|
|
|
|
<tr>
|
|
|
|
|
<td class="text-center">
|
|
|
|
|
<div id="singBoxCorever">
|
|
|
|
|
<?php echo htmlspecialchars($singBoxVersion); ?><span id="NewSingbox"></span>
|
2024-11-06 09:24:05 +08:00
|
|
|
|
</div>
|
2024-12-24 14:16:36 +08:00
|
|
|
|
</td>
|
|
|
|
|
</tr>
|
|
|
|
|
<tr>
|
|
|
|
|
<td class="text-center">
|
2025-01-15 09:24:24 +08:00
|
|
|
|
<button class="btn btn-pink me-1" id="checkSingboxButton">🔍 检测版本</button>
|
2024-12-24 14:16:36 +08:00
|
|
|
|
<button class="btn btn-info" id="singboxOptionsButton" title="Singbox 相关操作">🔄 更新版本</button>
|
|
|
|
|
</td>
|
|
|
|
|
</tr>
|
|
|
|
|
</tbody>
|
|
|
|
|
</table>
|
|
|
|
|
</td>
|
|
|
|
|
<td>
|
|
|
|
|
<table class="table">
|
|
|
|
|
<thead>
|
|
|
|
|
<tr>
|
|
|
|
|
<th>Mihomo 核心版本</th>
|
|
|
|
|
</tr>
|
|
|
|
|
</thead>
|
|
|
|
|
<tbody>
|
|
|
|
|
<tr>
|
|
|
|
|
<td class="text-center">
|
2025-01-10 09:28:17 +08:00
|
|
|
|
<?php echo htmlspecialchars($mihomoVersion); ?><span id="NewMihomo"> </span>
|
2024-12-24 14:16:36 +08:00
|
|
|
|
</td>
|
|
|
|
|
</tr>
|
|
|
|
|
<tr>
|
|
|
|
|
<td class="text-center">
|
2025-01-15 09:24:24 +08:00
|
|
|
|
<button class="btn btn-pink me-1" id="checkMihomoButton">🔍 检测版本</button>
|
2024-12-24 14:16:36 +08:00
|
|
|
|
<button class="btn btn-info" id="updateCoreButton" title="更新 Mihomo 内核" onclick="showMihomoVersionSelector()">🔄 更新版本</button>
|
|
|
|
|
</td>
|
|
|
|
|
</tr>
|
|
|
|
|
</tbody>
|
|
|
|
|
</table>
|
|
|
|
|
</td>
|
|
|
|
|
</tr>
|
|
|
|
|
</tbody>
|
|
|
|
|
</table>
|
2024-12-17 12:26:43 +08:00
|
|
|
|
<div class="modal fade" id="updateVersionTypeModal" tabindex="-1" aria-labelledby="updateVersionTypeModalLabel" aria-hidden="true" data-bs-backdrop="static" data-bs-keyboard="false">
|
2024-11-24 12:24:44 +08:00
|
|
|
|
<div class="modal-dialog modal-lg">
|
|
|
|
|
<div class="modal-content">
|
|
|
|
|
<div class="modal-header">
|
2024-12-17 12:26:43 +08:00
|
|
|
|
<h5 class="modal-title" id="updateVersionTypeModalLabel">选择更新版本类型</h5>
|
2025-01-04 09:25:09 +08:00
|
|
|
|
<button type="button" class="close" data-bs-dismiss="modal" aria-label="Close">
|
|
|
|
|
<span aria-hidden="true">×</span>
|
|
|
|
|
</button>
|
2024-12-17 12:26:43 +08:00
|
|
|
|
</div>
|
|
|
|
|
<div class="modal-body">
|
|
|
|
|
<div class="form-group text-center">
|
|
|
|
|
<button id="stableBtn" class="btn btn-success btn-lg" style="margin: 10px;" onclick="selectVersionType('stable')">正式版</button>
|
|
|
|
|
<button id="previewBtn" class="btn btn-warning btn-lg" style="margin: 10px;" onclick="selectVersionType('preview')">预览版</button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="modal fade" id="updateLanguageModal" tabindex="-1" aria-labelledby="updateLanguageModalLabel" aria-hidden="true" data-bs-backdrop="static" data-bs-keyboard="false">
|
|
|
|
|
<div class="modal-dialog modal-lg">
|
|
|
|
|
<div class="modal-content">
|
|
|
|
|
<div class="modal-header">
|
|
|
|
|
<h5 class="modal-title" id="updateLanguageModalLabel">选择语言</h5>
|
2025-01-04 09:25:09 +08:00
|
|
|
|
<button type="button" class="close" data-bs-dismiss="modal" aria-label="Close">
|
|
|
|
|
<span aria-hidden="true">×</span>
|
|
|
|
|
</button>
|
2024-11-24 12:24:44 +08:00
|
|
|
|
</div>
|
|
|
|
|
<div class="modal-body">
|
|
|
|
|
<div class="form-group">
|
|
|
|
|
<label for="languageSelect">选择语言</label>
|
|
|
|
|
<select id="languageSelect" class="form-select">
|
|
|
|
|
<option value="cn">中文版</option>
|
2024-12-17 12:26:43 +08:00
|
|
|
|
<option value="en">英文版</option>
|
2024-11-24 12:24:44 +08:00
|
|
|
|
</select>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="modal-footer">
|
|
|
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
|
2024-12-17 12:26:43 +08:00
|
|
|
|
<button type="button" class="btn btn-primary" onclick="confirmLanguageSelection()">确认</button>
|
2024-11-24 12:24:44 +08:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2024-12-22 20:34:43 +08:00
|
|
|
|
<div class="modal fade" id="previewLanguageModal" tabindex="-1" aria-labelledby="previewLanguageModalLabel" aria-hidden="true" data-bs-backdrop="static" data-bs-keyboard="false">
|
|
|
|
|
<div class="modal-dialog modal-lg">
|
|
|
|
|
<div class="modal-content">
|
|
|
|
|
<div class="modal-header">
|
|
|
|
|
<h5 class="modal-title" id="previewLanguageModalLabel">选择预览版语言</h5>
|
2025-01-04 09:25:09 +08:00
|
|
|
|
<button type="button" class="close" data-bs-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
2024-12-22 20:34:43 +08:00
|
|
|
|
</div>
|
|
|
|
|
<div class="modal-body">
|
|
|
|
|
<div class="form-group">
|
|
|
|
|
<label for="previewLanguageSelect">选择语言</label>
|
|
|
|
|
<select id="previewLanguageSelect" class="form-select">
|
|
|
|
|
<option value="cn">中文预览版</option>
|
|
|
|
|
<option value="en">英文预览版</option>
|
|
|
|
|
</select>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="modal-footer">
|
|
|
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
|
|
|
|
|
<button type="button" class="btn btn-primary" onclick="confirmPreviewLanguageSelection()">确认</button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2024-11-24 11:00:22 +08:00
|
|
|
|
<div class="modal fade" id="mihomoVersionSelectionModal" tabindex="-1" aria-labelledby="mihomoVersionSelectionModalLabel" aria-hidden="true" data-bs-backdrop="static" data-bs-keyboard="false">
|
|
|
|
|
<div class="modal-dialog modal-lg">
|
|
|
|
|
<div class="modal-content">
|
|
|
|
|
<div class="modal-header">
|
|
|
|
|
<h5 class="modal-title" id="mihomoVersionSelectionModalLabel">选择 Mihomo 内核版本</h5>
|
|
|
|
|
<button type="button" class="close" data-bs-dismiss="modal" aria-label="Close">
|
|
|
|
|
<span aria-hidden="true">×</span>
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="modal-body">
|
|
|
|
|
<select id="mihomoVersionSelect" class="form-select">
|
2024-12-19 09:38:38 +08:00
|
|
|
|
<option value="stable">正式版</option>
|
2024-11-24 11:00:22 +08:00
|
|
|
|
<option value="preview">预览版</option>
|
|
|
|
|
</select>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="modal-footer">
|
|
|
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
|
|
|
|
|
<button type="button" class="btn btn-primary" onclick="confirmMihomoVersion()">确认</button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2024-12-03 16:28:37 +08:00
|
|
|
|
|
2024-11-06 09:24:05 +08:00
|
|
|
|
<div class="modal fade" id="optionsModal" tabindex="-1" aria-labelledby="optionsModalLabel" aria-hidden="true" data-bs-backdrop="static" data-bs-keyboard="false">
|
|
|
|
|
<div class="modal-dialog modal-lg">
|
|
|
|
|
<div class="modal-content">
|
|
|
|
|
<div class="modal-header">
|
|
|
|
|
<h5 class="modal-title" id="optionsModalLabel">选择操作</h5>
|
|
|
|
|
<button type="button" class="close" data-bs-dismiss="modal" aria-label="Close">
|
|
|
|
|
<span aria-hidden="true">×</span>
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="modal-body">
|
2024-12-16 14:18:39 +08:00
|
|
|
|
<p class="text-warning">
|
2024-12-24 14:16:36 +08:00
|
|
|
|
<strong>说明:</strong> 请优先选择通道一编译版本进行更新,以确保兼容性。系统会先检测并动态生成最新版本号供选择下载。 如果通道一更新不可用,可以尝试通道二版本。
|
2024-12-16 14:18:39 +08:00
|
|
|
|
</p>
|
2024-11-06 09:24:05 +08:00
|
|
|
|
<div class="d-grid gap-2">
|
2024-11-24 11:00:22 +08:00
|
|
|
|
<button class="btn btn-info" onclick="showSingboxVersionSelector()">更新 Singbox 内核(通道一)</button>
|
2024-11-26 10:55:19 +08:00
|
|
|
|
<button class="btn btn-success" onclick="showSingboxVersionSelectorForChannelTwo()">更新 Singbox 内核(通道二)</button>
|
2024-12-27 16:25:03 +08:00
|
|
|
|
<button type="button" class="btn btn-warning" id="operationOptionsButton">其他操作</button>
|
|
|
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">关闭</button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="modal fade" id="operationModal" tabindex="-1" aria-labelledby="operationModalLabel" aria-hidden="true" data-bs-backdrop="static" data-bs-keyboard="false">
|
|
|
|
|
<div class="modal-dialog modal-lg">
|
|
|
|
|
<div class="modal-content">
|
|
|
|
|
<div class="modal-header">
|
|
|
|
|
<h5 class="modal-title" id="operationModalLabel">选择操作</h5>
|
|
|
|
|
<button type="button" class="close" data-bs-dismiss="modal" aria-label="Close">
|
|
|
|
|
<span aria-hidden="true">×</span>
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="modal-body">
|
|
|
|
|
<p class="text-warning">
|
|
|
|
|
<strong>说明:</strong> 请根据需求选择操作。
|
|
|
|
|
</p>
|
|
|
|
|
<div class="d-grid gap-2">
|
2024-11-06 09:24:05 +08:00
|
|
|
|
<button class="btn btn-success" onclick="selectOperation('puernya')">切换 Puernya 内核</button>
|
2024-12-24 14:16:36 +08:00
|
|
|
|
<button class="btn btn-primary" onclick="selectOperation('rule')">更新 P核 规则集</button>
|
|
|
|
|
<button class="btn btn-primary" onclick="selectOperation('config')">更新配置文件(备用)</button>
|
2024-12-16 14:18:39 +08:00
|
|
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">关闭</button>
|
2024-11-06 09:24:05 +08:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2024-11-08 10:44:50 +08:00
|
|
|
|
<div class="modal fade" id="versionSelectionModal" tabindex="-1" aria-labelledby="versionSelectionModalLabel" aria-hidden="true" data-bs-backdrop="static" data-bs-keyboard="false">
|
2024-11-13 00:25:36 +08:00
|
|
|
|
<div class="modal-dialog modal-lg">
|
2024-11-08 10:44:50 +08:00
|
|
|
|
<div class="modal-content">
|
|
|
|
|
<div class="modal-header">
|
2024-12-24 14:16:36 +08:00
|
|
|
|
<h5 class="modal-title" id="versionSelectionModalLabel">选择 Singbox 内核版本 (编译通道一)</h5>
|
2024-11-08 10:44:50 +08:00
|
|
|
|
<button type="button" class="close" data-bs-dismiss="modal" aria-label="Close">
|
|
|
|
|
<span aria-hidden="true">×</span>
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="modal-body">
|
2024-12-22 20:34:43 +08:00
|
|
|
|
<div class="mb-3">
|
|
|
|
|
<select id="singboxVersionSelect" class="form-select w-100" style="transform: translateX(-10px);">
|
|
|
|
|
<option value="v1.11.0-alpha.10">v1.11.0-alpha.10</option>
|
|
|
|
|
<option value="v1.11.0-alpha.15">v1.11.0-alpha.15</option>
|
|
|
|
|
<option value="v1.11.0-alpha.20">v1.11.0-alpha.20</option>
|
|
|
|
|
<option value="v1.11.0-beta.5">v1.11.0-beta.5</option>
|
|
|
|
|
<option value="v1.11.0-beta.10">v1.11.0-beta.10</option>
|
2025-01-10 09:28:17 +08:00
|
|
|
|
<option value="v1.11.0-beta.15">v1.11.0-beta.15</option>
|
|
|
|
|
<option value="v1.11.0-beta.20">v1.11.0-beta.20</option>
|
2025-01-27 20:37:55 +08:00
|
|
|
|
<option value="v1.11.0-rc.1">v1.11.0-rc.1</option>
|
2024-12-22 20:34:43 +08:00
|
|
|
|
</select>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="mb-3">
|
|
|
|
|
<label for="manualVersionInput" class="form-label">输入自定义版本</label>
|
2025-01-27 20:37:55 +08:00
|
|
|
|
<input type="text" id="manualVersionInput" class="form-control w-100" value="v1.11.0-rc.1">
|
2024-12-22 20:34:43 +08:00
|
|
|
|
</div>
|
|
|
|
|
<button type="button" class="btn btn-secondary mt-2" onclick="addManualVersion()">添加版本</button>
|
2024-11-08 10:44:50 +08:00
|
|
|
|
</div>
|
|
|
|
|
<div class="modal-footer">
|
|
|
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
|
|
|
|
|
<button type="button" class="btn btn-primary" onclick="confirmSingboxVersion()">确认</button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2024-11-26 10:55:19 +08:00
|
|
|
|
<div class="modal fade" id="singboxVersionModal" tabindex="-1" aria-labelledby="singboxVersionModalLabel" aria-hidden="true" data-bs-backdrop="static" data-bs-keyboard="false">
|
|
|
|
|
<div class="modal-dialog modal-lg">
|
|
|
|
|
<div class="modal-content">
|
|
|
|
|
<div class="modal-header">
|
2024-12-24 14:16:36 +08:00
|
|
|
|
<h5 class="modal-title" id="singboxVersionModalLabel">选择 Singbox 核心版本(官方通道二)</h5>
|
2025-01-04 09:25:09 +08:00
|
|
|
|
<button type="button" class="close" data-bs-dismiss="modal" aria-label="Close">
|
|
|
|
|
<span aria-hidden="true">×</span>
|
|
|
|
|
</button>
|
2024-11-26 10:55:19 +08:00
|
|
|
|
</div>
|
|
|
|
|
<div class="modal-body">
|
|
|
|
|
<div class="form-group">
|
|
|
|
|
<label for="singboxVersionSelectForChannelTwo">选择版本</label>
|
2024-12-26 20:37:57 +08:00
|
|
|
|
<select id="singboxVersionSelectForChannelTwo" class="form-select">
|
2024-11-26 10:55:19 +08:00
|
|
|
|
<option value="preview" selected>预览版</option>
|
2024-12-19 09:38:38 +08:00
|
|
|
|
<option value="stable">正式版</option>
|
2024-11-26 10:55:19 +08:00
|
|
|
|
</select>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="modal-footer">
|
|
|
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">关闭</button>
|
|
|
|
|
<button type="button" class="btn btn-primary" onclick="confirmSingboxVersionForChannelTwo()">确认</button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2024-12-03 16:28:37 +08:00
|
|
|
|
<div id="panelSelectionModal" class="modal fade" tabindex="-1" aria-labelledby="panelSelectionModalLabel" aria-hidden="true" data-bs-backdrop="static" data-bs-keyboard="false">
|
|
|
|
|
<div class="modal-dialog modal-lg">
|
|
|
|
|
<div class="modal-content">
|
|
|
|
|
<div class="modal-header">
|
|
|
|
|
<h5 class="modal-title" id="panelSelectionModalLabel">选择面板</h5>
|
2025-01-04 09:25:09 +08:00
|
|
|
|
<button type="button" class="close" data-bs-dismiss="modal" aria-label="Close">
|
|
|
|
|
<span aria-hidden="true">×</span>
|
|
|
|
|
</button>
|
2024-12-03 16:28:37 +08:00
|
|
|
|
</div>
|
|
|
|
|
<div class="modal-body">
|
|
|
|
|
<div class="form-group">
|
|
|
|
|
<label for="panelSelect">选择一个面板</label>
|
|
|
|
|
<select id="panelSelect" class="form-select">
|
2025-01-07 20:39:04 +08:00
|
|
|
|
<option value="zashboard">Zashboard 面板 【小内存】</option>
|
2025-01-10 09:28:17 +08:00
|
|
|
|
<option value="Zashboard">Zashboard 面板 【大内存】</option>
|
2024-12-04 09:43:01 +08:00
|
|
|
|
<option value="metacubexd">Metacubexd 面板</option>
|
2024-12-05 00:27:49 +08:00
|
|
|
|
<option value="yacd-meat">Yacd-Meat 面板</option>
|
2024-12-07 09:40:48 +08:00
|
|
|
|
<option value="dashboard">Dashboard 面板</option>
|
2024-12-03 16:28:37 +08:00
|
|
|
|
</select>
|
|
|
|
|
</div>
|
2025-01-10 09:28:17 +08:00
|
|
|
|
</div>
|
2024-12-03 16:28:37 +08:00
|
|
|
|
<div class="modal-footer">
|
|
|
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
|
|
|
|
|
<button type="button" class="btn btn-primary" onclick="confirmPanelSelection()">确认</button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2024-12-04 13:29:55 +08:00
|
|
|
|
<div class="modal fade" id="versionModal" tabindex="-1" aria-labelledby="versionModalLabel" aria-hidden="true" data-bs-backdrop="static" data-bs-keyboard="false">
|
|
|
|
|
<div class="modal-dialog modal-lg">
|
|
|
|
|
<div class="modal-content">
|
|
|
|
|
<div class="modal-header">
|
|
|
|
|
<h5 class="modal-title" id="versionModalLabel">版本检测结果</h5>
|
2025-01-04 09:25:09 +08:00
|
|
|
|
<button type="button" class="close" data-bs-dismiss="modal" aria-label="Close">
|
|
|
|
|
<span aria-hidden="true">×</span>
|
|
|
|
|
</button>
|
2024-12-04 13:29:55 +08:00
|
|
|
|
</div>
|
|
|
|
|
<div class="modal-body">
|
|
|
|
|
<div id="modalContent">
|
|
|
|
|
<p>正在加载...</p>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="modal-footer">
|
|
|
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">关闭</button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2024-11-06 09:24:05 +08:00
|
|
|
|
<div class="modal fade" id="updateModal" tabindex="-1" aria-labelledby="updateModalLabel" aria-hidden="true" data-bs-backdrop="static" data-bs-keyboard="false">
|
|
|
|
|
<div class="modal-dialog modal-lg">
|
|
|
|
|
<div class="modal-content">
|
|
|
|
|
<div class="modal-header">
|
|
|
|
|
<h5 class="modal-title" id="updateModalLabel">更新状态</h5>
|
|
|
|
|
<button type="button" class="close" data-bs-dismiss="modal" aria-label="Close">
|
|
|
|
|
<span aria-hidden="true">×</span>
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="modal-body text-center">
|
|
|
|
|
<div id="updateDescription" class="alert alert-info mb-3"></div>
|
|
|
|
|
<pre id="logOutput" style="white-space: pre-wrap; word-wrap: break-word; text-align: left; display: inline-block;">等待操作开始...</pre>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2024-11-03 20:36:08 +08:00
|
|
|
|
</div>
|
2025-01-14 09:22:34 +08:00
|
|
|
|
|
2025-01-15 09:24:24 +08:00
|
|
|
|
<div class="modal fade" id="colorModal" tabindex="-1" aria-labelledby="colorModalLabel" aria-hidden="true" data-bs-backdrop="static" data-bs-keyboard="false">
|
|
|
|
|
<div class="modal-dialog modal-xl">
|
|
|
|
|
<div class="modal-content">
|
|
|
|
|
<div class="modal-header">
|
|
|
|
|
<h5 class="modal-title" id="colorModalLabel">选择主题颜色</h5>
|
|
|
|
|
<button type="button" class="close" data-bs-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="modal-body">
|
|
|
|
|
<form method="POST" action="theme.php" id="themeForm" enctype="multipart/form-data">
|
|
|
|
|
<div class="row">
|
|
|
|
|
<div class="col-md-6 mb-3">
|
2025-01-24 16:24:40 +08:00
|
|
|
|
<label for="primaryColor" class="form-label">导航栏文本色</label>
|
2025-01-23 20:38:43 +08:00
|
|
|
|
<input type="color" class="form-control" name="primaryColor" id="primaryColor" value="#0ceda2">
|
2025-01-15 09:24:24 +08:00
|
|
|
|
</div>
|
|
|
|
|
<div class="col-md-6 mb-3">
|
2025-01-24 16:24:40 +08:00
|
|
|
|
<label for="secondaryColor" class="form-label">导航栏悬停文本色</label>
|
2025-01-15 09:24:24 +08:00
|
|
|
|
<input type="color" class="form-control" name="secondaryColor" id="secondaryColor" value="#00ffff">
|
|
|
|
|
</div>
|
|
|
|
|
<div class="col-md-6 mb-3">
|
|
|
|
|
<label for="bodyBgColor" class="form-label">主背景色</label>
|
2025-01-26 00:23:38 +08:00
|
|
|
|
<input type="color" class="form-control" name="bodyBgColor" id="bodyBgColor" value="#23407e">
|
2025-01-15 09:24:24 +08:00
|
|
|
|
</div>
|
|
|
|
|
<div class="col-md-6 mb-3">
|
|
|
|
|
<label for="infoBgSubtle" class="form-label">信息背景色</label>
|
2025-01-26 00:23:38 +08:00
|
|
|
|
<input type="color" class="form-control" name="infoBgSubtle" id="infoBgSubtle" value="#23407e">
|
2025-01-15 09:24:24 +08:00
|
|
|
|
</div>
|
|
|
|
|
<div class="col-md-6 mb-3">
|
2025-01-24 16:24:40 +08:00
|
|
|
|
<label for="backgroundColor" class="form-label">表格背景色</label>
|
2025-01-23 20:38:43 +08:00
|
|
|
|
<input type="color" class="form-control" name="backgroundColor" id="backgroundColor" value="#20cdd9">
|
|
|
|
|
</div>
|
|
|
|
|
<div class="col-md-6 mb-3">
|
2025-01-24 16:24:40 +08:00
|
|
|
|
<label for="primaryBorderSubtle" class="form-label">表格文本色</label>
|
2025-01-23 20:38:43 +08:00
|
|
|
|
<input type="color" class="form-control" name="primaryBorderSubtle" id="primaryBorderSubtle" value="#1815d1">
|
|
|
|
|
</div>
|
|
|
|
|
<div class="col-md-6 mb-3">
|
2025-01-24 16:24:40 +08:00
|
|
|
|
<label for="placeholderColor" class="form-label">输入框文本色</label>
|
|
|
|
|
<input type="color" class="form-control" name="placeholderColor" id="placeholderColor" value="#f82af2">
|
|
|
|
|
</div>
|
|
|
|
|
<div class="col-md-6 mb-3">
|
|
|
|
|
<label for="logTextColor" class="form-label">日志文本色</label>
|
|
|
|
|
<input type="color" class="form-control" name="logTextColor" id="logTextColor" value="#f8f9fa">
|
|
|
|
|
</div>
|
|
|
|
|
<div class="col-md-6 mb-3">
|
|
|
|
|
<label for="selectColor" class="form-label">主边框背景色</label>
|
2025-01-26 00:23:38 +08:00
|
|
|
|
<input type="color" class="form-control" name="selectColor" id="selectColor" value="#23407e">
|
2025-01-15 09:24:24 +08:00
|
|
|
|
</div>
|
|
|
|
|
<div class="col-md-6 mb-3">
|
2025-01-24 16:24:40 +08:00
|
|
|
|
<label for="bodyColor" class="form-label">表格文本色 1</label>
|
2025-01-26 00:23:38 +08:00
|
|
|
|
<input type="color" class="form-control" name="bodyColor" id="bodyColor" value="#04f153">
|
2025-01-15 09:24:24 +08:00
|
|
|
|
</div>
|
|
|
|
|
<div class="col-md-6 mb-3">
|
2025-01-24 16:24:40 +08:00
|
|
|
|
<label for="tertiaryColor" class="form-label">表格文本色 2</label>
|
2025-01-26 00:23:38 +08:00
|
|
|
|
<input type="color" class="form-control" name="tertiaryColor" id="tertiaryColor" value="#46e1ec">
|
2025-01-15 09:24:24 +08:00
|
|
|
|
</div>
|
|
|
|
|
<div class="col-md-6 mb-3">
|
2025-01-24 16:24:40 +08:00
|
|
|
|
<label for="tertiaryRgbColor" class="form-label">表格文本色 3</label>
|
2025-01-15 09:24:24 +08:00
|
|
|
|
<input type="color" class="form-control" name="tertiaryRgbColor" id="tertiaryRgbColor" value="#1e90ff">
|
|
|
|
|
</div>
|
2025-01-24 20:38:04 +08:00
|
|
|
|
<div class="col-md-6 mb-3">
|
|
|
|
|
<label for="outlineColor" class="form-label">按键色(青色)</label>
|
|
|
|
|
<input type="color" class="form-control" name="outlineColor" id="outlineColor" value="#0dcaf0">
|
|
|
|
|
</div>
|
|
|
|
|
<div class="col-md-6 mb-3">
|
|
|
|
|
<label for="successColor" class="form-label">按键色(绿色)</label>
|
|
|
|
|
<input type="color" class="form-control" name="successColor" id="successColor" value="#28a745">
|
|
|
|
|
</div>
|
|
|
|
|
<div class="col-md-6 mb-3">
|
|
|
|
|
<label for="infoColor" class="form-label">按键色(蓝色)</label>
|
|
|
|
|
<input type="color" class="form-control" name="infoColor" id="infoColor" value="#0ca2ed">
|
|
|
|
|
</div>
|
|
|
|
|
<div class="col-md-6 mb-3">
|
|
|
|
|
<label for="warningColor" class="form-label">按键色(黄色)</label>
|
|
|
|
|
<input type="color" class="form-control" name="warningColor" id="warningColor" value="#ffc107">
|
|
|
|
|
</div>
|
|
|
|
|
<div class="col-md-6 mb-3">
|
|
|
|
|
<label for="pinkColor" class="form-label">按键色(粉红色)</label>
|
|
|
|
|
<input type="color" class="form-control" name="pinkColor" id="pinkColor" value="#f82af2">
|
|
|
|
|
</div>
|
|
|
|
|
<div class="col-md-6 mb-3">
|
|
|
|
|
<label for="dangerColor" class="form-label">按键色(红色)</label>
|
|
|
|
|
<input type="color" class="form-control" name="dangerColor" id="dangerColor" value="#dc3545">
|
|
|
|
|
</div>
|
2025-01-15 09:24:24 +08:00
|
|
|
|
<div class="col-md-6 mb-3">
|
2025-01-24 16:24:40 +08:00
|
|
|
|
<label for="heading1Color" class="form-label">标题色 1</label>
|
|
|
|
|
<input type="color" class="form-control" name="heading1Color" id="heading1Color" value="#21e4f2">
|
2025-01-15 09:24:24 +08:00
|
|
|
|
</div>
|
|
|
|
|
<div class="col-md-6 mb-3">
|
2025-01-24 16:24:40 +08:00
|
|
|
|
<label for="heading2Color" class="form-label">标题色 2</label>
|
|
|
|
|
<input type="color" class="form-control" name="heading2Color" id="heading2Color" value="#65f1fb">
|
2025-01-15 09:24:24 +08:00
|
|
|
|
</div>
|
|
|
|
|
<div class="col-md-6 mb-3">
|
2025-01-24 16:24:40 +08:00
|
|
|
|
<label for="heading3Color" class="form-label">标题色 3</label>
|
2025-01-15 09:24:24 +08:00
|
|
|
|
<input type="color" class="form-control" name="heading3Color" id="heading3Color" value="#ffcc00">
|
|
|
|
|
</div>
|
|
|
|
|
<div class="col-md-6 mb-3">
|
2025-01-24 16:24:40 +08:00
|
|
|
|
<label for="heading4Color" class="form-label">标题色 4</label>
|
2025-01-26 09:27:31 +08:00
|
|
|
|
<input type="color" class="form-control" name="heading4Color" id="heading4Color" value="#00fbff">
|
2025-01-15 09:24:24 +08:00
|
|
|
|
</div>
|
|
|
|
|
<div class="col-md-6 mb-3">
|
2025-01-24 16:24:40 +08:00
|
|
|
|
<label for="heading5Color" class="form-label">标题色 5</label>
|
|
|
|
|
<input type="color" class="form-control" name="heading5Color" id="heading5Color" value="#ba13f6">
|
2025-01-15 09:24:24 +08:00
|
|
|
|
</div>
|
|
|
|
|
<div class="col-md-6 mb-3">
|
2025-01-24 16:24:40 +08:00
|
|
|
|
<label for="heading6Color" class="form-label">标题色 6</label>
|
2025-01-15 09:24:24 +08:00
|
|
|
|
<input type="color" class="form-control" name="heading6Color" id="heading6Color" value="#00ffff">
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2025-01-26 00:23:38 +08:00
|
|
|
|
<div class="mb-3 form-check">
|
|
|
|
|
<input type="checkbox" class="form-check-input" id="enableSnowEffect" name="enableSnowEffect" <?php echo $enableSnow ? 'checked' : ''; ?>>
|
2025-01-27 16:26:57 +08:00
|
|
|
|
<label class="form-check-label" for="enableSnowEffect">启用雪花动画(Ctrl + F6快捷键启用/禁用)</label>
|
2025-01-26 00:23:38 +08:00
|
|
|
|
</div>
|
2025-01-15 09:24:24 +08:00
|
|
|
|
<div class="mb-3 form-check">
|
|
|
|
|
<input type="checkbox" class="form-check-input" id="useBackgroundImage" name="useBackgroundImage">
|
|
|
|
|
<label class="form-check-label" for="useBackgroundImage">使用自定义背景图片</label>
|
2025-01-14 09:22:34 +08:00
|
|
|
|
</div>
|
2025-01-15 10:41:13 +08:00
|
|
|
|
<div class="mb-3" id="backgroundImageContainer" style="display:none; position: relative; left: -1ch;">
|
2025-01-15 09:24:24 +08:00
|
|
|
|
<select class="form-select" id="backgroundImage" name="backgroundImage">
|
|
|
|
|
<option value="">请选择图片</option>
|
|
|
|
|
<?php
|
|
|
|
|
$dir = $_SERVER['DOCUMENT_ROOT'] . '/nekobox/assets/Pictures/';
|
|
|
|
|
$files = array_diff(scandir($dir), array('..', '.'));
|
|
|
|
|
foreach ($files as $file) {
|
|
|
|
|
if (in_array(strtolower(pathinfo($file, PATHINFO_EXTENSION)), ['jpg', 'jpeg', 'png'])) {
|
|
|
|
|
echo "<option value='/nekobox/assets/Pictures/$file'>$file</option>";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
?>
|
|
|
|
|
</select>
|
2025-01-14 09:22:34 +08:00
|
|
|
|
</div>
|
2025-01-23 20:38:43 +08:00
|
|
|
|
<div class="d-flex flex-wrap justify-content-center align-items-center mb-3 gap-2">
|
|
|
|
|
<button type="submit" class="btn btn-primary">保存主题</button>
|
|
|
|
|
<button type="button" class="btn btn-success" id="resetButton">恢复默认值</button>
|
|
|
|
|
<button type="button" class="btn btn-info" id="exportButton">立即备份</button>
|
|
|
|
|
<button type="button" class="btn btn-warning" id="restoreButton">恢复备份</button>
|
|
|
|
|
<input type="file" id="importButton" class="form-control" accept="application/json" style="display: none;">
|
|
|
|
|
<button type="button" class="btn btn-pink" data-bs-dismiss="modal">取消</button>
|
|
|
|
|
</div>
|
2025-01-15 09:24:24 +08:00
|
|
|
|
</form>
|
2025-01-14 09:22:34 +08:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2025-01-15 09:24:24 +08:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
document.getElementById('useBackgroundImage').addEventListener('change', function() {
|
|
|
|
|
const container = document.getElementById('backgroundImageContainer');
|
|
|
|
|
container.style.display = this.checked ? 'block' : 'none';
|
|
|
|
|
});
|
|
|
|
|
</script>
|
2025-01-14 09:22:34 +08:00
|
|
|
|
|
2025-01-23 20:38:43 +08:00
|
|
|
|
<script>
|
|
|
|
|
document.getElementById('restoreButton').addEventListener('click', () => {
|
|
|
|
|
document.getElementById('importButton').click();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
document.getElementById('importButton').addEventListener('change', (event) => {
|
|
|
|
|
const file = event.target.files[0];
|
|
|
|
|
if (file) {
|
|
|
|
|
const reader = new FileReader();
|
|
|
|
|
reader.onload = (e) => {
|
|
|
|
|
const content = e.target.result;
|
|
|
|
|
try {
|
|
|
|
|
const jsonData = JSON.parse(content);
|
|
|
|
|
console.log('恢复的备份数据:', jsonData);
|
|
|
|
|
alert('备份已成功上传并解析!');
|
|
|
|
|
} catch (error) {
|
|
|
|
|
alert('文件格式错误,请上传正确的 JSON 文件!');
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
reader.readAsText(file);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
</script>
|
|
|
|
|
|
2025-01-26 00:23:38 +08:00
|
|
|
|
<script>
|
2025-01-26 20:34:25 +08:00
|
|
|
|
const tooltip = document.createElement('div');
|
|
|
|
|
tooltip.style.position = 'fixed';
|
|
|
|
|
tooltip.style.top = '10px';
|
|
|
|
|
tooltip.style.left = '10px';
|
|
|
|
|
tooltip.style.backgroundColor = 'rgba(0, 128, 0, 0.7)';
|
|
|
|
|
tooltip.style.color = 'white';
|
|
|
|
|
tooltip.style.padding = '10px';
|
|
|
|
|
tooltip.style.borderRadius = '5px';
|
|
|
|
|
tooltip.style.zIndex = '9999';
|
|
|
|
|
tooltip.style.display = 'none';
|
|
|
|
|
document.body.appendChild(tooltip);
|
|
|
|
|
|
|
|
|
|
function showTooltip(message) {
|
|
|
|
|
tooltip.textContent = message;
|
|
|
|
|
tooltip.style.display = 'block';
|
|
|
|
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
tooltip.style.display = 'none';
|
|
|
|
|
}, 5000);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
window.onload = function() {
|
|
|
|
|
const lastShownTime = localStorage.getItem('lastTooltipShownTime');
|
|
|
|
|
const currentTime = new Date().getTime();
|
2025-01-26 00:23:38 +08:00
|
|
|
|
|
2025-01-26 20:34:25 +08:00
|
|
|
|
if (!lastShownTime || (currentTime - lastShownTime) > 4 * 60 * 60 * 1000) {
|
|
|
|
|
showTooltip('双击左键打开播放器,F8键开启网站连通性检测');
|
|
|
|
|
|
|
|
|
|
localStorage.setItem('lastTooltipShownTime', currentTime);
|
|
|
|
|
}
|
|
|
|
|
};
|
2025-01-26 00:23:38 +08:00
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
document.getElementById('enableSnowEffect').addEventListener('change', function() {
|
2025-01-27 16:26:57 +08:00
|
|
|
|
toggleSnowEffect(this.checked);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
document.addEventListener('keydown', function(event) {
|
|
|
|
|
if (event.ctrlKey && event.code === 'F6') {
|
|
|
|
|
var checkbox = document.getElementById('enableSnowEffect');
|
|
|
|
|
checkbox.checked = !checkbox.checked;
|
|
|
|
|
toggleSnowEffect(checkbox.checked);
|
|
|
|
|
|
|
|
|
|
var message = checkbox.checked ? '已启用雪花效果' : '已禁用雪花效果';
|
|
|
|
|
showNotification(message);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
function toggleSnowEffect(isChecked) {
|
2025-01-26 00:23:38 +08:00
|
|
|
|
var xhr = new XMLHttpRequest();
|
|
|
|
|
xhr.open('POST', 'save_snow_status.php', true);
|
|
|
|
|
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
|
|
|
|
|
xhr.send('enableSnowEffect=' + (isChecked ? '1' : '0'));
|
2025-01-26 20:34:25 +08:00
|
|
|
|
var message = isChecked ? '已启用' : '已禁用';
|
|
|
|
|
console.log(message);
|
2025-01-27 16:26:57 +08:00
|
|
|
|
showNotification(message);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function showNotification(message) {
|
2025-01-26 20:34:25 +08:00
|
|
|
|
var notification = document.createElement('div');
|
|
|
|
|
notification.style.position = 'fixed';
|
|
|
|
|
notification.style.top = '10px';
|
|
|
|
|
notification.style.right = '30px';
|
|
|
|
|
notification.style.backgroundColor = '#4CAF50';
|
|
|
|
|
notification.style.color = '#fff';
|
|
|
|
|
notification.style.padding = '10px';
|
|
|
|
|
notification.style.borderRadius = '5px';
|
|
|
|
|
notification.style.zIndex = '9999';
|
|
|
|
|
notification.innerText = message;
|
|
|
|
|
document.body.appendChild(notification);
|
|
|
|
|
setTimeout(function() {
|
|
|
|
|
notification.style.display = 'none';
|
2025-01-27 16:26:57 +08:00
|
|
|
|
}, 5000);
|
|
|
|
|
}
|
2025-01-26 00:23:38 +08:00
|
|
|
|
</script>
|
|
|
|
|
|
2025-01-14 12:22:26 +08:00
|
|
|
|
<div class="modal fade" id="filesModal" tabindex="-1" aria-labelledby="filesModalLabel" aria-hidden="true" data-bs-backdrop="static" data-bs-keyboard="false">
|
|
|
|
|
<div class="modal-dialog modal-xl">
|
|
|
|
|
<div class="modal-content">
|
|
|
|
|
<div class="modal-header">
|
|
|
|
|
<h5 class="modal-title" id="filesModalLabel">上传并管理背景图片</h5>
|
|
|
|
|
<button type="button" class="close" data-bs-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="modal-body">
|
|
|
|
|
<div class="mb-4">
|
|
|
|
|
<h2 class="mb-3">上传背景图片</h2>
|
|
|
|
|
<form method="POST" action="theme.php" enctype="multipart/form-data">
|
|
|
|
|
<input type="file" class="form-control mb-3" name="imageFile" id="imageFile">
|
|
|
|
|
<button type="submit" class="btn btn-success" id="submitBtn">上传图片</button>
|
|
|
|
|
</form>
|
|
|
|
|
</div>
|
2025-01-14 09:22:34 +08:00
|
|
|
|
|
2025-01-14 12:22:26 +08:00
|
|
|
|
<h2 class="mb-3">上传的图片文件</h2>
|
|
|
|
|
<table class="table table-bordered text-center">
|
|
|
|
|
<thead>
|
|
|
|
|
<tr>
|
|
|
|
|
<th>文件名</th>
|
|
|
|
|
<th>文件大小</th>
|
|
|
|
|
<th>预览</th>
|
|
|
|
|
<th>操作</th>
|
|
|
|
|
</tr>
|
|
|
|
|
</thead>
|
|
|
|
|
<tbody>
|
|
|
|
|
<?php
|
|
|
|
|
$picturesDir = $_SERVER['DOCUMENT_ROOT'] . '/nekobox/assets/Pictures/';
|
|
|
|
|
if (is_dir($picturesDir)) {
|
|
|
|
|
$files = array_diff(scandir($picturesDir), array('..', '.'));
|
|
|
|
|
foreach ($files as $file) {
|
|
|
|
|
$filePath = $picturesDir . $file;
|
|
|
|
|
if (is_file($filePath)) {
|
|
|
|
|
$fileSize = filesize($filePath);
|
|
|
|
|
$fileUrl = '/nekobox/assets/Pictures/' . $file;
|
|
|
|
|
echo "<tr>
|
|
|
|
|
<td class='align-middle'>$file</td>
|
|
|
|
|
<td class='align-middle'>" . formatSize($fileSize) . "</td>
|
|
|
|
|
<td class='align-middle'><img src='$fileUrl' alt='$file' style='width: 100px; height: auto;'></td>
|
|
|
|
|
<td class='align-middle'>
|
|
|
|
|
<a href='?delete=$file' class='btn btn-danger btn-sm'>删除</a>
|
|
|
|
|
</td>
|
|
|
|
|
</tr>";
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-01-14 09:22:34 +08:00
|
|
|
|
}
|
2025-01-14 12:22:26 +08:00
|
|
|
|
?>
|
|
|
|
|
</tbody>
|
|
|
|
|
</table>
|
|
|
|
|
</div>
|
2025-01-15 09:24:24 +08:00
|
|
|
|
<div class="modal-footer">
|
|
|
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
|
|
|
|
|
</div>
|
2025-01-14 12:22:26 +08:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2025-01-14 09:22:34 +08:00
|
|
|
|
<?php
|
|
|
|
|
if (isset($_GET['delete'])) {
|
|
|
|
|
$fileToDelete = $_GET['delete'];
|
|
|
|
|
$filePath = $picturesDir . $fileToDelete;
|
|
|
|
|
if (file_exists($filePath)) {
|
|
|
|
|
unlink($filePath);
|
|
|
|
|
echo '<script>window.location.href = "settings.php";</script>';
|
|
|
|
|
exit;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function formatSize($size) {
|
|
|
|
|
if ($size >= 1073741824) {
|
|
|
|
|
return number_format($size / 1073741824, 2) . ' GB';
|
|
|
|
|
} elseif ($size >= 1048576) {
|
|
|
|
|
return number_format($size / 1048576, 2) . ' MB';
|
|
|
|
|
} elseif ($size >= 1024) {
|
|
|
|
|
return number_format($size / 1024, 2) . ' KB';
|
|
|
|
|
} else {
|
|
|
|
|
return $size . ' bytes';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
?>
|
|
|
|
|
</tbody>
|
|
|
|
|
</table>
|
|
|
|
|
<script>
|
|
|
|
|
document.addEventListener("DOMContentLoaded", function() {
|
|
|
|
|
const colorInputs = document.querySelectorAll('input[type="color"]');
|
|
|
|
|
|
|
|
|
|
colorInputs.forEach(input => {
|
|
|
|
|
if (localStorage.getItem(input.name)) {
|
|
|
|
|
input.value = localStorage.getItem(input.name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
input.addEventListener('input', function() {
|
|
|
|
|
localStorage.setItem(input.name, input.value);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2025-01-15 09:24:24 +08:00
|
|
|
|
const useBackgroundImageCheckbox = document.getElementById('useBackgroundImage');
|
|
|
|
|
const backgroundImageContainer = document.getElementById('backgroundImageContainer');
|
|
|
|
|
|
|
|
|
|
const savedBackgroundImageState = localStorage.getItem('useBackgroundImage');
|
|
|
|
|
if (savedBackgroundImageState === 'true') {
|
|
|
|
|
useBackgroundImageCheckbox.checked = true;
|
|
|
|
|
backgroundImageContainer.style.display = 'block';
|
|
|
|
|
} else {
|
|
|
|
|
useBackgroundImageCheckbox.checked = false;
|
|
|
|
|
backgroundImageContainer.style.display = 'none';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
useBackgroundImageCheckbox.addEventListener('change', function() {
|
|
|
|
|
if (useBackgroundImageCheckbox.checked) {
|
|
|
|
|
backgroundImageContainer.style.display = 'block';
|
|
|
|
|
} else {
|
|
|
|
|
backgroundImageContainer.style.display = 'none';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
localStorage.setItem('useBackgroundImage', useBackgroundImageCheckbox.checked);
|
|
|
|
|
});
|
|
|
|
|
|
2025-01-14 09:22:34 +08:00
|
|
|
|
document.getElementById('resetButton').addEventListener('click', function() {
|
2025-01-23 20:38:43 +08:00
|
|
|
|
document.getElementById('primaryColor').value = '#0ceda2';
|
2025-01-14 09:22:34 +08:00
|
|
|
|
document.getElementById('secondaryColor').value = '#00ffff';
|
2025-01-26 00:23:38 +08:00
|
|
|
|
document.getElementById('bodyBgColor').value = '#23407e';
|
|
|
|
|
document.getElementById('bodyColor').value = '#04f153';
|
|
|
|
|
document.getElementById('infoBgSubtle').value = '#23407e';
|
|
|
|
|
document.getElementById('selectColor').value = '#23407e';
|
|
|
|
|
document.getElementById('tertiaryColor').value = '#46e1ec';
|
2025-01-14 09:22:34 +08:00
|
|
|
|
document.getElementById('tertiaryRgbColor').value = '#1e90ff';
|
2025-01-24 16:24:40 +08:00
|
|
|
|
document.getElementById('heading1Color').value = '#21e4f2';
|
|
|
|
|
document.getElementById('heading2Color').value = '#65f1fb';
|
2025-01-14 09:22:34 +08:00
|
|
|
|
document.getElementById('heading3Color').value = '#ffcc00';
|
2025-01-26 09:27:31 +08:00
|
|
|
|
document.getElementById('heading4Color').value = '#00fbff';
|
2025-01-24 16:24:40 +08:00
|
|
|
|
document.getElementById('heading5Color').value = '#ba13f6';
|
2025-01-14 09:22:34 +08:00
|
|
|
|
document.getElementById('heading6Color').value = '#00ffff';
|
2025-01-23 20:38:43 +08:00
|
|
|
|
document.getElementById('primaryBorderSubtle').value = '#1815d1';
|
|
|
|
|
document.getElementById('backgroundColor').value = '#20cdd9';
|
2025-01-24 16:24:40 +08:00
|
|
|
|
document.getElementById('placeholderColor').value = '#f82af2';
|
|
|
|
|
document.getElementById('logTextColor').value = '#f8f9fa';
|
2025-01-24 20:38:04 +08:00
|
|
|
|
document.getElementById('outlineColor').value = '#0dcaf0';
|
|
|
|
|
document.getElementById('successColor').value = '#28a745';
|
|
|
|
|
document.getElementById('infoColor').value = '#0ca2ed';
|
|
|
|
|
document.getElementById('warningColor').value = '#ffc107';
|
|
|
|
|
document.getElementById('pinkColor').value = '#f82af2';
|
|
|
|
|
document.getElementById('dangerColor').value = '#dc3545';
|
2025-01-15 09:24:24 +08:00
|
|
|
|
|
2025-01-14 09:22:34 +08:00
|
|
|
|
localStorage.clear();
|
|
|
|
|
});
|
2025-01-15 10:41:13 +08:00
|
|
|
|
|
|
|
|
|
document.getElementById('exportButton').addEventListener('click', function() {
|
|
|
|
|
const settings = {
|
|
|
|
|
primaryColor: document.getElementById('primaryColor').value,
|
|
|
|
|
secondaryColor: document.getElementById('secondaryColor').value,
|
|
|
|
|
bodyBgColor: document.getElementById('bodyBgColor').value,
|
|
|
|
|
infoBgSubtle: document.getElementById('infoBgSubtle').value,
|
2025-01-23 20:38:43 +08:00
|
|
|
|
selectColor: document.getElementById('selectColor').value,
|
2025-01-15 10:41:13 +08:00
|
|
|
|
bodyColor: document.getElementById('bodyColor').value,
|
|
|
|
|
tertiaryColor: document.getElementById('tertiaryColor').value,
|
|
|
|
|
tertiaryRgbColor: document.getElementById('tertiaryRgbColor').value,
|
|
|
|
|
heading1Color: document.getElementById('heading1Color').value,
|
|
|
|
|
heading2Color: document.getElementById('heading2Color').value,
|
|
|
|
|
heading3Color: document.getElementById('heading3Color').value,
|
|
|
|
|
heading4Color: document.getElementById('heading4Color').value,
|
|
|
|
|
heading5Color: document.getElementById('heading5Color').value,
|
|
|
|
|
heading6Color: document.getElementById('heading6Color').value,
|
2025-01-24 20:38:04 +08:00
|
|
|
|
|
|
|
|
|
outlineColor: document.getElementById('outlineColor').value,
|
|
|
|
|
successColor: document.getElementById('successColor').value,
|
|
|
|
|
infoColor: document.getElementById('infoColor').value,
|
|
|
|
|
warningColor: document.getElementById('warningColor').value,
|
|
|
|
|
pinkColor: document.getElementById('pinkColor').value,
|
|
|
|
|
dangerColor: document.getElementById('dangerColor').value,
|
2025-01-23 20:38:43 +08:00
|
|
|
|
primaryBorderSubtle: document.getElementById('primaryBorderSubtle').value,
|
|
|
|
|
backgroundColor: document.getElementById('backgroundColor').value,
|
2025-01-24 16:24:40 +08:00
|
|
|
|
placeholderColor: document.getElementById('placeholderColor').value,
|
|
|
|
|
logTextColor: document.getElementById('logTextColor').value,
|
2025-01-15 10:41:13 +08:00
|
|
|
|
useBackgroundImage: document.getElementById('useBackgroundImage').checked,
|
|
|
|
|
backgroundImage: document.getElementById('backgroundImage').value
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const blob = new Blob([JSON.stringify(settings)], { type: 'application/json' });
|
|
|
|
|
const link = document.createElement('a');
|
|
|
|
|
link.href = URL.createObjectURL(blob);
|
|
|
|
|
link.download = 'theme-settings.json';
|
|
|
|
|
link.click();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
document.getElementById('importButton').addEventListener('change', function(event) {
|
|
|
|
|
const file = event.target.files[0];
|
|
|
|
|
if (file && file.type === 'application/json') {
|
|
|
|
|
const reader = new FileReader();
|
|
|
|
|
reader.onload = function(e) {
|
|
|
|
|
const settings = JSON.parse(e.target.result);
|
|
|
|
|
|
|
|
|
|
document.getElementById('primaryColor').value = settings.primaryColor;
|
|
|
|
|
document.getElementById('secondaryColor').value = settings.secondaryColor;
|
|
|
|
|
document.getElementById('bodyBgColor').value = settings.bodyBgColor;
|
|
|
|
|
document.getElementById('infoBgSubtle').value = settings.infoBgSubtle;
|
2025-01-23 20:38:43 +08:00
|
|
|
|
document.getElementById('selectColor').value = settings.selectColor;
|
2025-01-15 10:41:13 +08:00
|
|
|
|
document.getElementById('bodyColor').value = settings.bodyColor;
|
|
|
|
|
document.getElementById('tertiaryColor').value = settings.tertiaryColor;
|
|
|
|
|
document.getElementById('tertiaryRgbColor').value = settings.tertiaryRgbColor;
|
|
|
|
|
document.getElementById('heading1Color').value = settings.heading1Color;
|
|
|
|
|
document.getElementById('heading2Color').value = settings.heading2Color;
|
|
|
|
|
document.getElementById('heading3Color').value = settings.heading3Color;
|
|
|
|
|
document.getElementById('heading4Color').value = settings.heading4Color;
|
|
|
|
|
document.getElementById('heading5Color').value = settings.heading5Color;
|
|
|
|
|
document.getElementById('heading6Color').value = settings.heading6Color;
|
2025-01-24 20:38:04 +08:00
|
|
|
|
document.getElementById('outlineColor').value = settings.outlineColor;
|
|
|
|
|
document.getElementById('successColor').value = settings.successColor;
|
|
|
|
|
document.getElementById('infoColor').value = settings.infoColor;
|
|
|
|
|
document.getElementById('warningColor').value = settings.warningColor;
|
|
|
|
|
document.getElementById('pinkColor').value = settings.pinkColor;
|
|
|
|
|
document.getElementById('dangerColor').value = settings.dangerColor;
|
2025-01-23 20:38:43 +08:00
|
|
|
|
document.getElementById('primaryBorderSubtle').value = settings.primaryBorderSubtle;
|
|
|
|
|
document.getElementById('backgroundColor').value = settings.backgroundColor;
|
2025-01-24 16:24:40 +08:00
|
|
|
|
document.getElementById('placeholderColor').value = settings.placeholderColor;
|
|
|
|
|
document.getElementById('logTextColor').value = settings.logTextColor;
|
2025-01-15 10:41:13 +08:00
|
|
|
|
document.getElementById('useBackgroundImage').checked = settings.useBackgroundImage;
|
|
|
|
|
|
|
|
|
|
const backgroundImageContainer = document.getElementById('backgroundImageContainer');
|
|
|
|
|
backgroundImageContainer.style.display = settings.useBackgroundImage ? 'block' : 'none';
|
|
|
|
|
document.getElementById('backgroundImage').value = settings.backgroundImage || '';
|
|
|
|
|
|
|
|
|
|
localStorage.setItem('primaryColor', settings.primaryColor);
|
|
|
|
|
localStorage.setItem('secondaryColor', settings.secondaryColor);
|
|
|
|
|
localStorage.setItem('bodyBgColor', settings.bodyBgColor);
|
|
|
|
|
localStorage.setItem('infoBgSubtle', settings.infoBgSubtle);
|
2025-01-23 20:38:43 +08:00
|
|
|
|
localStorage.setItem('selectColor', settings.selectColor);
|
2025-01-15 10:41:13 +08:00
|
|
|
|
localStorage.setItem('bodyColor', settings.bodyColor);
|
|
|
|
|
localStorage.setItem('tertiaryColor', settings.tertiaryColor);
|
|
|
|
|
localStorage.setItem('tertiaryRgbColor', settings.tertiaryRgbColor);
|
|
|
|
|
localStorage.setItem('heading1Color', settings.heading1Color);
|
|
|
|
|
localStorage.setItem('heading2Color', settings.heading2Color);
|
|
|
|
|
localStorage.setItem('heading3Color', settings.heading3Color);
|
|
|
|
|
localStorage.setItem('heading4Color', settings.heading4Color);
|
|
|
|
|
localStorage.setItem('heading5Color', settings.heading5Color);
|
|
|
|
|
localStorage.setItem('heading6Color', settings.heading6Color);
|
2025-01-24 20:38:04 +08:00
|
|
|
|
|
|
|
|
|
localStorage.setItem('outlineColor', settings.outlineColor);
|
|
|
|
|
localStorage.setItem('successColor', settings.successColor);
|
|
|
|
|
localStorage.setItem('infoColor', settings.infoColor);
|
|
|
|
|
localStorage.setItem('warningColor', settings.warningColor);
|
|
|
|
|
localStorage.setItem('pinkColor', settings.pinkColor);
|
|
|
|
|
localStorage.setItem('dangerColor', settings.dangerColor);
|
2025-01-23 20:38:43 +08:00
|
|
|
|
localStorage.setItem('primaryBorderSubtle', settings.primaryBorderSubtle);
|
|
|
|
|
localStorage.setItem('backgroundColor', settings.backgroundColor);
|
2025-01-24 16:24:40 +08:00
|
|
|
|
localStorage.setItem('placeholderColor', settings.placeholderColor);
|
|
|
|
|
localStorage.setItem('logTextColor', settings.logTextColor);
|
2025-01-15 10:41:13 +08:00
|
|
|
|
localStorage.setItem('useBackgroundImage', settings.useBackgroundImage);
|
|
|
|
|
localStorage.setItem('backgroundImage', settings.backgroundImage);
|
|
|
|
|
};
|
|
|
|
|
reader.readAsText(file);
|
|
|
|
|
}
|
|
|
|
|
});
|
2025-01-14 09:22:34 +08:00
|
|
|
|
});
|
|
|
|
|
</script>
|
2024-10-26 16:23:41 +08:00
|
|
|
|
<style>
|
|
|
|
|
@media (max-width: 767px) {
|
|
|
|
|
.table td {
|
|
|
|
|
display: block;
|
|
|
|
|
width: 100%;
|
|
|
|
|
}
|
|
|
|
|
.form-control {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
}
|
|
|
|
|
.btn-group {
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</style>
|
2024-10-26 10:38:22 +08:00
|
|
|
|
<script>
|
2024-12-07 09:40:48 +08:00
|
|
|
|
let selectedSingboxVersion = 'v1.11.0-alpha.10';
|
2024-11-24 11:00:22 +08:00
|
|
|
|
let selectedMihomoVersion = 'stable';
|
2024-11-24 12:24:44 +08:00
|
|
|
|
let selectedLanguage = 'cn';
|
2024-11-26 10:55:19 +08:00
|
|
|
|
let selectedSingboxVersionForChannelTwo = 'preview';
|
2024-12-04 09:43:01 +08:00
|
|
|
|
let selectedPanel = 'zashboard';
|
2024-12-17 12:26:43 +08:00
|
|
|
|
let selectedVersionType = 'stable';
|
2024-12-03 16:28:37 +08:00
|
|
|
|
|
|
|
|
|
function showPanelSelector() {
|
|
|
|
|
$('#panelSelectionModal').modal('show');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function confirmPanelSelection() {
|
|
|
|
|
selectedPanel = document.getElementById('panelSelect').value;
|
|
|
|
|
$('#panelSelectionModal').modal('hide');
|
|
|
|
|
selectOperation('panel');
|
|
|
|
|
}
|
2024-11-24 12:24:44 +08:00
|
|
|
|
|
2024-12-17 12:26:43 +08:00
|
|
|
|
function showVersionTypeModal() {
|
|
|
|
|
$('#updateVersionTypeModal').modal('show');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function confirmVersionTypeSelection() {
|
|
|
|
|
selectedVersionType = document.getElementById('versionTypeSelect').value;
|
|
|
|
|
$('#updateVersionTypeModal').modal('hide');
|
|
|
|
|
|
|
|
|
|
if (selectedVersionType === 'stable') {
|
|
|
|
|
$('#updateLanguageModal').modal('show');
|
|
|
|
|
} else {
|
|
|
|
|
selectOperation('client');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function selectVersionType(type) {
|
|
|
|
|
selectedVersionType = type;
|
|
|
|
|
|
|
|
|
|
if (type === 'stable') {
|
|
|
|
|
document.getElementById('stableBtn').classList.add('btn-success');
|
|
|
|
|
document.getElementById('previewBtn').classList.remove('btn-warning');
|
|
|
|
|
document.getElementById('previewBtn').classList.add('btn-light');
|
|
|
|
|
} else {
|
|
|
|
|
document.getElementById('previewBtn').classList.add('btn-warning');
|
|
|
|
|
document.getElementById('stableBtn').classList.remove('btn-success');
|
|
|
|
|
document.getElementById('stableBtn').classList.add('btn-light');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
handleVersionSelection();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function handleVersionSelection() {
|
|
|
|
|
$('#updateVersionTypeModal').modal('hide');
|
|
|
|
|
|
|
|
|
|
if (selectedVersionType === 'stable') {
|
|
|
|
|
$('#updateLanguageModal').modal('show');
|
|
|
|
|
} else {
|
2024-12-22 20:34:43 +08:00
|
|
|
|
$('#previewLanguageModal').modal('show');
|
2024-12-17 12:26:43 +08:00
|
|
|
|
}
|
2024-11-24 12:24:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-12-17 12:26:43 +08:00
|
|
|
|
function confirmLanguageSelection() {
|
|
|
|
|
selectedLanguage = document.getElementById('languageSelect').value;
|
|
|
|
|
$('#updateLanguageModal').modal('hide');
|
|
|
|
|
selectOperation('client');
|
2024-11-24 12:24:44 +08:00
|
|
|
|
}
|
2024-11-24 11:00:22 +08:00
|
|
|
|
|
2024-12-22 20:34:43 +08:00
|
|
|
|
function confirmPreviewLanguageSelection() {
|
|
|
|
|
selectedLanguage = document.getElementById('previewLanguageSelect').value;
|
|
|
|
|
$('#previewLanguageModal').modal('hide');
|
|
|
|
|
selectOperation('client');
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-08 10:44:50 +08:00
|
|
|
|
function showSingboxVersionSelector() {
|
|
|
|
|
$('#optionsModal').modal('hide');
|
|
|
|
|
$('#versionSelectionModal').modal('show');
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-26 10:55:19 +08:00
|
|
|
|
function showSingboxVersionSelectorForChannelTwo() {
|
|
|
|
|
$('#optionsModal').modal('hide');
|
|
|
|
|
$('#singboxVersionModal').modal('show');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function confirmSingboxVersionForChannelTwo() {
|
|
|
|
|
selectedSingboxVersionForChannelTwo = document.getElementById('singboxVersionSelectForChannelTwo').value;
|
|
|
|
|
$('#singboxVersionModal').modal('hide');
|
|
|
|
|
selectOperation('sing-box');
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-24 11:00:22 +08:00
|
|
|
|
function showMihomoVersionSelector() {
|
|
|
|
|
$('#mihomoVersionSelectionModal').modal('show');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function confirmMihomoVersion() {
|
|
|
|
|
selectedMihomoVersion = document.getElementById('mihomoVersionSelect').value;
|
|
|
|
|
$('#mihomoVersionSelectionModal').modal('hide');
|
|
|
|
|
selectOperation('mihomo');
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-22 20:34:43 +08:00
|
|
|
|
function addManualVersion() {
|
|
|
|
|
var manualVersion = document.getElementById('manualVersionInput').value;
|
|
|
|
|
|
|
|
|
|
if (manualVersion.trim() === "") {
|
|
|
|
|
alert("请输入版本号!");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var select = document.getElementById('singboxVersionSelect');
|
|
|
|
|
|
|
|
|
|
var versionExists = Array.from(select.options).some(function(option) {
|
|
|
|
|
return option.value === manualVersion;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (versionExists) {
|
|
|
|
|
alert("该版本已存在!");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var newOption = document.createElement("option");
|
|
|
|
|
newOption.value = manualVersion;
|
|
|
|
|
newOption.textContent = manualVersion;
|
|
|
|
|
|
|
|
|
|
select.innerHTML = '';
|
|
|
|
|
|
|
|
|
|
select.appendChild(newOption);
|
|
|
|
|
|
|
|
|
|
var options = [
|
|
|
|
|
"v1.11.0-alpha.10",
|
|
|
|
|
"v1.11.0-alpha.15",
|
|
|
|
|
"v1.11.0-alpha.20",
|
|
|
|
|
"v1.11.0-beta.5",
|
|
|
|
|
"v1.11.0-beta.10"
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
options.forEach(function(version) {
|
|
|
|
|
var option = document.createElement("option");
|
|
|
|
|
option.value = version;
|
|
|
|
|
option.textContent = version;
|
|
|
|
|
select.appendChild(option);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
document.getElementById('manualVersionInput').value = '';
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-08 10:44:50 +08:00
|
|
|
|
function confirmSingboxVersion() {
|
|
|
|
|
selectedSingboxVersion = document.getElementById('singboxVersionSelect').value;
|
|
|
|
|
$('#versionSelectionModal').modal('hide');
|
|
|
|
|
|
|
|
|
|
selectOperation('singbox');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
document.getElementById('singboxOptionsButton').addEventListener('click', function() {
|
|
|
|
|
$('#optionsModal').modal('show');
|
2024-11-06 09:24:05 +08:00
|
|
|
|
});
|
2024-10-26 10:38:22 +08:00
|
|
|
|
|
2024-11-06 09:24:05 +08:00
|
|
|
|
function selectOperation(type) {
|
2024-11-08 10:44:50 +08:00
|
|
|
|
$('#optionsModal').modal('hide');
|
|
|
|
|
|
2024-11-06 09:24:05 +08:00
|
|
|
|
const operations = {
|
|
|
|
|
'singbox': {
|
2024-11-08 10:44:50 +08:00
|
|
|
|
url: 'update_singbox_core.php?version=' + selectedSingboxVersion,
|
2024-11-06 09:24:05 +08:00
|
|
|
|
message: '开始下载 Singbox 核心更新...',
|
|
|
|
|
description: '正在更新 Singbox 核心到最新版本'
|
|
|
|
|
},
|
|
|
|
|
'sing-box': {
|
2024-11-26 10:55:19 +08:00
|
|
|
|
url: selectedSingboxVersionForChannelTwo === 'stable'
|
|
|
|
|
? 'update_singbox_stable.php'
|
|
|
|
|
: 'update_singbox_preview.php',
|
2024-11-06 09:24:05 +08:00
|
|
|
|
message: '开始下载 Singbox 核心更新...',
|
2024-11-26 10:55:19 +08:00
|
|
|
|
description: '正在更新 Singbox 核心到 ' + selectedSingboxVersionForChannelTwo + ' 版本'
|
2024-11-06 09:24:05 +08:00
|
|
|
|
},
|
|
|
|
|
'puernya': {
|
|
|
|
|
url: 'puernya.php',
|
|
|
|
|
message: '开始切换 Puernya 核心...',
|
|
|
|
|
description: '正在切换到 Puernya 内核,此操作将替换当前的 Singbox 核心'
|
|
|
|
|
},
|
|
|
|
|
'rule': {
|
|
|
|
|
url: 'update_rule.php',
|
|
|
|
|
message: '开始下载 Singbox 规则集...',
|
|
|
|
|
description: '正在更新 Singbox 规则集,配合 Puernya 内核可以使用 Singbox 的配置文件和本地规则集'
|
|
|
|
|
},
|
|
|
|
|
'config': {
|
|
|
|
|
url: 'update_config.php',
|
|
|
|
|
message: '开始下载 Mihomo 配置文件...',
|
|
|
|
|
description: '正在更新 Mihomo 配置文件到最新版本'
|
2024-11-24 11:00:22 +08:00
|
|
|
|
},
|
|
|
|
|
'mihomo': {
|
|
|
|
|
url: selectedMihomoVersion === 'stable'
|
|
|
|
|
? 'update_mihomo_stable.php'
|
|
|
|
|
: 'update_mihomo_preview.php',
|
|
|
|
|
message: '开始下载 Mihomo 内核更新...',
|
|
|
|
|
description: '正在更新 Mihomo 内核到最新版本 (' + selectedMihomoVersion + ')'
|
2024-11-24 12:24:44 +08:00
|
|
|
|
},
|
|
|
|
|
'client': {
|
2024-12-17 12:26:43 +08:00
|
|
|
|
url: selectedVersionType === 'stable'
|
|
|
|
|
? 'update_script.php?lang=' + selectedLanguage
|
2024-12-22 20:34:43 +08:00
|
|
|
|
: 'update_preview.php?lang=' + selectedLanguage,
|
2024-12-17 12:26:43 +08:00
|
|
|
|
message: selectedVersionType === 'stable'
|
|
|
|
|
? '开始下载客户端更新...'
|
|
|
|
|
: '开始下载客户端预览版更新...',
|
|
|
|
|
description: selectedVersionType === 'stable'
|
|
|
|
|
? '正在更新客户端到最新正式版'
|
|
|
|
|
: '正在更新客户端到最新预览版'
|
2024-12-03 16:28:37 +08:00
|
|
|
|
},
|
|
|
|
|
'panel': {
|
2024-12-04 09:43:01 +08:00
|
|
|
|
url: selectedPanel === 'zashboard'
|
2025-01-07 20:39:04 +08:00
|
|
|
|
? 'update_zashboard.php?panel=zashboard&update_type=dist'
|
2025-01-10 09:28:17 +08:00
|
|
|
|
: selectedPanel === 'Zashboard'
|
2025-01-07 20:39:04 +08:00
|
|
|
|
? 'update_zashboard.php?panel=zashboard1&update_type=fonts'
|
2024-12-05 00:27:49 +08:00
|
|
|
|
: selectedPanel === 'yacd-meat'
|
|
|
|
|
? 'update_meta.php'
|
|
|
|
|
: selectedPanel === 'metacubexd'
|
|
|
|
|
? 'update_metacubexd.php'
|
2024-12-07 09:40:48 +08:00
|
|
|
|
: selectedPanel === 'dashboard'
|
|
|
|
|
? 'update_dashboard.php'
|
|
|
|
|
: 'unknown_panel.php',
|
2024-12-04 09:43:01 +08:00
|
|
|
|
message: selectedPanel === 'zashboard'
|
2025-01-10 09:28:17 +08:00
|
|
|
|
? '开始下载 Zashboard 面板更新(dist-cdn-fonts.zip)...'
|
|
|
|
|
: selectedPanel === 'Zashboard'
|
|
|
|
|
? '开始下载 Zashboard 面板 更新(dist.zip)...'
|
2024-12-05 00:27:49 +08:00
|
|
|
|
: selectedPanel === 'yacd-meat'
|
|
|
|
|
? '开始下载 Yacd-Meat 面板更新...'
|
|
|
|
|
: selectedPanel === 'metacubexd'
|
|
|
|
|
? '开始下载 Metacubexd 面板更新...'
|
2024-12-07 09:40:48 +08:00
|
|
|
|
: selectedPanel === 'dashboard'
|
|
|
|
|
? '开始下载 Dashboard 面板更新...'
|
|
|
|
|
: '未知面板更新类型...',
|
2024-12-04 09:43:01 +08:00
|
|
|
|
description: selectedPanel === 'zashboard'
|
2025-01-24 16:24:40 +08:00
|
|
|
|
? '正在更新 Zashboard 面板到最新版本(dist-cdn-fonts.zip)'
|
2025-01-10 09:28:17 +08:00
|
|
|
|
: selectedPanel === 'Zashboard'
|
2025-01-24 16:24:40 +08:00
|
|
|
|
? '正在更新 Zashboard 面板到最新版本(dist.zip)'
|
2024-12-05 00:27:49 +08:00
|
|
|
|
: selectedPanel === 'yacd-meat'
|
2025-01-24 16:24:40 +08:00
|
|
|
|
? '正在更新 Yacd-Meat 面板到最新版本'
|
2024-12-05 00:27:49 +08:00
|
|
|
|
: selectedPanel === 'metacubexd'
|
|
|
|
|
? '正在更新 Metacubexd 面板到最新版本'
|
2024-12-07 09:40:48 +08:00
|
|
|
|
: selectedPanel === 'dashboard'
|
|
|
|
|
? '正在更新 Dashboard 面板到最新版本'
|
|
|
|
|
: '无法识别的面板类型,无法更新。'
|
2024-11-06 09:24:05 +08:00
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
const operation = operations[type];
|
|
|
|
|
if (operation) {
|
|
|
|
|
setTimeout(function() {
|
|
|
|
|
initiateUpdate(operation.url, operation.message, operation.description);
|
|
|
|
|
}, 500);
|
2024-10-26 16:23:41 +08:00
|
|
|
|
}
|
2024-11-06 09:24:05 +08:00
|
|
|
|
}
|
2024-10-26 16:23:41 +08:00
|
|
|
|
|
2024-11-06 09:24:05 +08:00
|
|
|
|
function initiateUpdate(url, logMessage, description) {
|
|
|
|
|
const xhr = new XMLHttpRequest();
|
|
|
|
|
xhr.open('POST', url, true);
|
|
|
|
|
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
|
|
|
|
|
$('#updateModal').modal('show');
|
|
|
|
|
document.getElementById('updateDescription').textContent = description;
|
|
|
|
|
document.getElementById('logOutput').textContent = logMessage;
|
|
|
|
|
xhr.onload = function() {
|
|
|
|
|
if (xhr.status === 200) {
|
|
|
|
|
document.getElementById('logOutput').textContent += '\n更新完成!';
|
|
|
|
|
document.getElementById('logOutput').textContent += '\n' + xhr.responseText;
|
|
|
|
|
setTimeout(function() {
|
|
|
|
|
$('#updateModal').modal('hide');
|
|
|
|
|
setTimeout(function() {
|
|
|
|
|
location.reload();
|
|
|
|
|
}, 500);
|
|
|
|
|
}, 10000);
|
|
|
|
|
} else {
|
|
|
|
|
document.getElementById('logOutput').textContent += '\n发生错误:' + xhr.statusText;
|
2024-11-08 10:44:50 +08:00
|
|
|
|
}
|
2024-11-06 09:24:05 +08:00
|
|
|
|
};
|
2024-10-26 10:38:22 +08:00
|
|
|
|
|
2024-11-06 09:24:05 +08:00
|
|
|
|
xhr.onerror = function() {
|
|
|
|
|
document.getElementById('logOutput').textContent += '\n网络错误,请稍后再试。';
|
|
|
|
|
};
|
2024-10-27 12:23:17 +08:00
|
|
|
|
|
2024-11-06 09:24:05 +08:00
|
|
|
|
xhr.send();
|
|
|
|
|
}
|
2024-11-09 20:34:05 +08:00
|
|
|
|
|
|
|
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
|
|
|
document.getElementById('singboxOptionsButton').addEventListener('click', function() {
|
2024-12-27 16:25:03 +08:00
|
|
|
|
$('#optionsModal').modal('hide');
|
|
|
|
|
|
2024-11-09 20:34:05 +08:00
|
|
|
|
$('#optionsModal').modal('show');
|
|
|
|
|
});
|
|
|
|
|
|
2024-12-27 16:25:03 +08:00
|
|
|
|
document.getElementById('operationOptionsButton').addEventListener('click', function() {
|
|
|
|
|
$('#optionsModal').modal('hide');
|
|
|
|
|
|
|
|
|
|
$('#operationModal').modal('show');
|
|
|
|
|
});
|
|
|
|
|
|
2024-11-09 20:34:05 +08:00
|
|
|
|
document.getElementById('updateUiButton').addEventListener('click', function() {
|
2024-12-03 16:28:37 +08:00
|
|
|
|
showPanelSelector();
|
2024-11-09 20:34:05 +08:00
|
|
|
|
});
|
|
|
|
|
});
|
2024-10-26 10:38:22 +08:00
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<script>
|
2024-12-07 00:25:43 +08:00
|
|
|
|
function checkVersion(outputId, updateFiles, currentVersions) {
|
2024-12-04 13:29:55 +08:00
|
|
|
|
const modalContent = document.getElementById('modalContent');
|
|
|
|
|
const versionModal = new bootstrap.Modal(document.getElementById('versionModal'));
|
|
|
|
|
modalContent.innerHTML = '<p>正在检查新版本...</p>';
|
2024-12-04 09:43:01 +08:00
|
|
|
|
let results = [];
|
|
|
|
|
|
2024-12-04 13:29:55 +08:00
|
|
|
|
const requests = updateFiles.map((file) => {
|
|
|
|
|
return fetch(file.url + '?check_version=true')
|
|
|
|
|
.then(response => {
|
|
|
|
|
if (!response.ok) {
|
|
|
|
|
throw new Error(`请求失败: ${file.name}`);
|
|
|
|
|
}
|
|
|
|
|
return response.text();
|
|
|
|
|
})
|
|
|
|
|
.then(responseText => {
|
|
|
|
|
const versionMatch = responseText.trim().match(/最新版本:\s*([^\s]+)/);
|
2024-12-04 09:43:01 +08:00
|
|
|
|
if (versionMatch && versionMatch[1]) {
|
|
|
|
|
const newVersion = versionMatch[1];
|
2024-12-04 13:29:55 +08:00
|
|
|
|
results.push(`
|
|
|
|
|
<tr class="table-success">
|
|
|
|
|
<td>${file.name}</td>
|
2024-12-07 00:25:43 +08:00
|
|
|
|
<td>${currentVersions[file.name] || '未知'}</td>
|
2024-12-04 13:29:55 +08:00
|
|
|
|
<td>${newVersion}</td>
|
|
|
|
|
</tr>
|
|
|
|
|
`);
|
2024-12-04 09:43:01 +08:00
|
|
|
|
|
2024-12-26 16:25:03 +08:00
|
|
|
|
if (file.url === 'update_singbox_core.php') {
|
2024-12-04 09:43:01 +08:00
|
|
|
|
const select = document.getElementById('singboxVersionSelect');
|
|
|
|
|
let versionExists = Array.from(select.options).some(option => option.value === newVersion);
|
|
|
|
|
|
|
|
|
|
if (!versionExists) {
|
|
|
|
|
const newOption = document.createElement('option');
|
|
|
|
|
newOption.value = newVersion;
|
|
|
|
|
newOption.textContent = newVersion;
|
|
|
|
|
select.appendChild(newOption);
|
|
|
|
|
}
|
2024-11-13 00:25:36 +08:00
|
|
|
|
}
|
2024-12-04 09:43:01 +08:00
|
|
|
|
} else {
|
2024-12-04 13:29:55 +08:00
|
|
|
|
results.push(`
|
|
|
|
|
<tr class="table-warning">
|
|
|
|
|
<td>${file.name}</td>
|
2024-12-07 00:25:43 +08:00
|
|
|
|
<td>${currentVersions[file.name] || '未知'}</td>
|
2024-12-04 13:29:55 +08:00
|
|
|
|
<td>无法解析版本信息</td>
|
2024-12-04 09:43:01 +08:00
|
|
|
|
</tr>
|
2024-12-04 13:29:55 +08:00
|
|
|
|
`);
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.catch(error => {
|
|
|
|
|
results.push(`
|
|
|
|
|
<tr class="table-danger">
|
|
|
|
|
<td>${file.name}</td>
|
2024-12-07 00:25:43 +08:00
|
|
|
|
<td>${currentVersions[file.name] || '未知'}</td>
|
2024-12-04 13:29:55 +08:00
|
|
|
|
<td>网络错误</td>
|
|
|
|
|
</tr>
|
|
|
|
|
`);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
Promise.all(requests).then(() => {
|
|
|
|
|
modalContent.innerHTML = `
|
|
|
|
|
<table class="table table-striped table-bordered">
|
|
|
|
|
<thead>
|
|
|
|
|
<tr>
|
|
|
|
|
<th class="text-center">组件名称</th>
|
2024-12-07 00:25:43 +08:00
|
|
|
|
<th class="text-center">当前版本</th>
|
2024-12-04 13:29:55 +08:00
|
|
|
|
<th class="text-center">最新版本</th>
|
|
|
|
|
</tr>
|
|
|
|
|
</thead>
|
|
|
|
|
<tbody>
|
|
|
|
|
${results.join('')}
|
|
|
|
|
</tbody>
|
|
|
|
|
</table>
|
|
|
|
|
`;
|
2024-12-07 00:25:43 +08:00
|
|
|
|
versionModal.show();
|
2024-12-04 09:43:01 +08:00
|
|
|
|
});
|
2024-11-13 00:25:36 +08:00
|
|
|
|
}
|
2024-10-26 16:23:41 +08:00
|
|
|
|
|
2024-12-04 09:43:01 +08:00
|
|
|
|
document.getElementById('checkSingboxButton').addEventListener('click', function () {
|
2024-12-29 16:23:13 +08:00
|
|
|
|
const singBoxVersion = "<?php echo htmlspecialchars(trim($singBoxVersion)); ?>";
|
2024-12-07 09:40:48 +08:00
|
|
|
|
const singBoxType = "<?php echo htmlspecialchars($singBoxType); ?>";
|
|
|
|
|
const puernyaVersion = "<?php echo htmlspecialchars($puernyaVersion); ?>";
|
|
|
|
|
const singboxPreviewVersion = "<?php echo htmlspecialchars($singboxPreviewVersion); ?>";
|
2024-12-29 16:23:13 +08:00
|
|
|
|
const singboxCompileVersion = "<?php echo htmlspecialchars($singboxCompileVersion); ?>";
|
|
|
|
|
|
|
|
|
|
let finalPreviewVersion = '未安装';
|
|
|
|
|
let finalCompileVersion = '未安装';
|
|
|
|
|
let finalOfficialVersion = '未安装';
|
|
|
|
|
let finalPuernyaVersion = '未安装';
|
|
|
|
|
|
|
|
|
|
if (puernyaVersion === '1.10.0-alpha.29-067c81a7') {
|
|
|
|
|
finalPuernyaVersion = puernyaVersion;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-27 20:37:55 +08:00
|
|
|
|
if (singBoxVersion && /^v/.test(singBoxVersion) && /-.+/.test(singBoxVersion)) {
|
2024-12-29 16:23:13 +08:00
|
|
|
|
finalCompileVersion = singBoxVersion;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-27 20:37:55 +08:00
|
|
|
|
if (singBoxVersion && /-.+/.test(singBoxVersion) && puernyaVersion !== '1.10.0-alpha.29-067c81a7' && !/^v/.test(singBoxVersion)) {
|
2024-12-29 16:23:13 +08:00
|
|
|
|
finalPreviewVersion = singBoxVersion;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (singBoxVersion && !/[a-zA-Z]/.test(singBoxVersion)) {
|
|
|
|
|
finalOfficialVersion = singBoxVersion;
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-07 00:25:43 +08:00
|
|
|
|
const currentVersions = {
|
2024-12-29 16:23:13 +08:00
|
|
|
|
'Singbox [ 正式版 ]': finalOfficialVersion,
|
|
|
|
|
'Singbox [ 预览版 ]': finalPreviewVersion,
|
|
|
|
|
'Singbox [ 编译版 ]': finalCompileVersion,
|
|
|
|
|
'Puernya [ 预览版 ]': finalPuernyaVersion
|
2024-12-07 00:25:43 +08:00
|
|
|
|
};
|
2024-12-29 16:23:13 +08:00
|
|
|
|
|
2024-12-04 09:43:01 +08:00
|
|
|
|
const updateFiles = [
|
2024-12-19 09:38:38 +08:00
|
|
|
|
{ name: 'Singbox [ 正式版 ]', url: 'update_singbox_stable.php' },
|
|
|
|
|
{ name: 'Singbox [ 预览版 ]', url: 'update_singbox_preview.php' },
|
2024-12-22 20:34:43 +08:00
|
|
|
|
{ name: 'Singbox [ 编译版 ]', url: 'update_singbox_core.php' },
|
2024-12-19 09:38:38 +08:00
|
|
|
|
{ name: 'Puernya [ 预览版 ]', url: 'puernya.php' }
|
2024-12-04 09:43:01 +08:00
|
|
|
|
];
|
2024-12-29 16:23:13 +08:00
|
|
|
|
|
2024-12-07 00:25:43 +08:00
|
|
|
|
checkVersion('NewSingbox', updateFiles, currentVersions);
|
2024-11-13 00:25:36 +08:00
|
|
|
|
});
|
2024-10-26 10:38:22 +08:00
|
|
|
|
|
2024-12-04 09:43:01 +08:00
|
|
|
|
document.getElementById('checkMihomoButton').addEventListener('click', function () {
|
2024-12-07 09:40:48 +08:00
|
|
|
|
const mihomoVersion = "<?php echo htmlspecialchars($mihomoVersion); ?>";
|
|
|
|
|
const mihomoType = "<?php echo htmlspecialchars($mihomoType); ?>";
|
|
|
|
|
|
2024-12-22 20:34:43 +08:00
|
|
|
|
console.log('Mihomo Version:', mihomoVersion);
|
|
|
|
|
console.log('Mihomo Type:', mihomoType);
|
|
|
|
|
|
2024-12-07 00:25:43 +08:00
|
|
|
|
const currentVersions = {
|
2024-12-19 09:38:38 +08:00
|
|
|
|
'Mihomo [ 正式版 ]': mihomoType === '正式版' ? mihomoVersion : '未安装',
|
|
|
|
|
'Mihomo [ 预览版 ]': mihomoType === '预览版' ? mihomoVersion : '未安装',
|
2024-12-07 00:25:43 +08:00
|
|
|
|
};
|
2024-12-07 09:40:48 +08:00
|
|
|
|
|
2024-12-04 09:43:01 +08:00
|
|
|
|
const updateFiles = [
|
2024-12-19 09:38:38 +08:00
|
|
|
|
{ name: 'Mihomo [ 正式版 ]', url: 'update_mihomo_stable.php' },
|
|
|
|
|
{ name: 'Mihomo [ 预览版 ]', url: 'update_mihomo_preview.php' }
|
2024-12-04 09:43:01 +08:00
|
|
|
|
];
|
2024-12-07 09:40:48 +08:00
|
|
|
|
|
2024-12-07 00:25:43 +08:00
|
|
|
|
checkVersion('NewMihomo', updateFiles, currentVersions);
|
2024-11-13 00:25:36 +08:00
|
|
|
|
});
|
2024-10-26 10:38:22 +08:00
|
|
|
|
|
2024-12-22 20:34:43 +08:00
|
|
|
|
|
2024-12-04 09:43:01 +08:00
|
|
|
|
document.getElementById('checkUiButton').addEventListener('click', function () {
|
2024-12-07 00:25:43 +08:00
|
|
|
|
const currentVersions = {
|
|
|
|
|
'MetaCube': '<?php echo htmlspecialchars($metaCubexdVersion); ?>',
|
|
|
|
|
'Zashboard': '<?php echo htmlspecialchars($uiVersion); ?>',
|
|
|
|
|
'Yacd-Meat': '<?php echo htmlspecialchars($metaVersion); ?>',
|
2024-12-07 09:40:48 +08:00
|
|
|
|
'Dashboard': '<?php echo htmlspecialchars($razordVersion); ?>',
|
2024-12-07 00:25:43 +08:00
|
|
|
|
};
|
2024-12-04 09:43:01 +08:00
|
|
|
|
const updateFiles = [
|
|
|
|
|
{ name: 'MetaCube', url: 'update_metacubexd.php' },
|
2024-12-05 00:27:49 +08:00
|
|
|
|
{ name: 'Zashboard', url: 'update_zashboard.php' },
|
2024-12-07 09:40:48 +08:00
|
|
|
|
{ name: 'Yacd-Meat', url: 'update_meta.php' },
|
|
|
|
|
{ name: 'Dashboard', url: 'update_dashboard.php' }
|
2024-12-04 09:43:01 +08:00
|
|
|
|
];
|
2024-12-07 00:25:43 +08:00
|
|
|
|
checkVersion('NewUi', updateFiles, currentVersions);
|
2024-11-13 00:25:36 +08:00
|
|
|
|
});
|
2024-10-26 16:23:41 +08:00
|
|
|
|
|
2024-12-04 13:29:55 +08:00
|
|
|
|
document.getElementById('checkCliverButton').addEventListener('click', function () {
|
2024-12-19 09:38:38 +08:00
|
|
|
|
const cliverVersion = "<?php echo htmlspecialchars($cliverVersion); ?>";
|
|
|
|
|
const cliverType = "<?php echo htmlspecialchars($cliverType); ?>";
|
|
|
|
|
|
2024-12-07 00:25:43 +08:00
|
|
|
|
const currentVersions = {
|
2024-12-19 09:38:38 +08:00
|
|
|
|
'客户端 [ 正式版 ]': cliverType === '正式版' ? cliverVersion : '未安装',
|
|
|
|
|
'客户端 [ 预览版 ]': cliverType === '预览版' ? cliverVersion : '未安装',
|
2024-12-07 00:25:43 +08:00
|
|
|
|
};
|
2024-12-19 09:38:38 +08:00
|
|
|
|
|
|
|
|
|
const updateFiles = [
|
|
|
|
|
{ name: '客户端 [ 正式版 ]', url: 'update_script.php' },
|
|
|
|
|
{ name: '客户端 [ 预览版 ]', url: 'update_preview.php' }
|
|
|
|
|
];
|
|
|
|
|
|
2024-12-07 00:25:43 +08:00
|
|
|
|
checkVersion('NewCliver', updateFiles, currentVersions);
|
2024-11-13 00:25:36 +08:00
|
|
|
|
});
|
2024-12-07 09:40:48 +08:00
|
|
|
|
|
2024-10-26 10:38:22 +08:00
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<script>
|
2024-10-26 16:23:41 +08:00
|
|
|
|
function compareVersions(v1, v2) {
|
2024-11-06 09:24:05 +08:00
|
|
|
|
const v1parts = v1.split(/[-.]/).filter(x => !isNaN(x));
|
|
|
|
|
const v2parts = v2.split(/[-.]/).filter(x => !isNaN(x));
|
2024-10-26 16:23:41 +08:00
|
|
|
|
|
|
|
|
|
for (let i = 0; i < Math.max(v1parts.length, v2parts.length); ++i) {
|
2024-11-06 09:24:05 +08:00
|
|
|
|
const v1part = parseInt(v1parts[i]) || 0;
|
|
|
|
|
const v2part = parseInt(v2parts[i]) || 0;
|
2024-10-26 16:23:41 +08:00
|
|
|
|
|
|
|
|
|
if (v1part > v2part) return 1;
|
|
|
|
|
if (v1part < v2part) return -1;
|
|
|
|
|
}
|
2024-10-26 10:38:22 +08:00
|
|
|
|
|
2024-11-06 09:24:05 +08:00
|
|
|
|
return 0;
|
2024-10-26 10:38:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-10-26 16:23:41 +08:00
|
|
|
|
function checkSingboxVersion() {
|
2024-12-12 13:24:47 +08:00
|
|
|
|
var currentVersion = '<?php echo $singBoxVersion; ?>';
|
2024-11-06 09:24:05 +08:00
|
|
|
|
var minVersion = '1.10.0';
|
2024-10-26 16:23:41 +08:00
|
|
|
|
|
2024-12-12 13:24:47 +08:00
|
|
|
|
if (currentVersion === '未安装') {
|
|
|
|
|
alert('未检测到 Sing-box 安装,请检查系统配置。');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2024-10-26 16:23:41 +08:00
|
|
|
|
if (compareVersions(currentVersion, minVersion) >= 0) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2024-10-26 10:38:22 +08:00
|
|
|
|
|
2024-10-26 16:23:41 +08:00
|
|
|
|
var modalHtml = `
|
|
|
|
|
<div class="modal fade" id="versionWarningModal" tabindex="-1" aria-labelledby="versionWarningModalLabel" aria-hidden="true">
|
|
|
|
|
<div class="modal-dialog">
|
|
|
|
|
<div class="modal-content">
|
|
|
|
|
<div class="modal-header">
|
|
|
|
|
<h5 class="modal-title" id="versionWarningModalLabel">版本警告</h5>
|
|
|
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="modal-body">
|
|
|
|
|
<p>您的 Sing-box 版本 (${currentVersion}) 低于推荐的最低版本 (v1.10.0)。</p>
|
|
|
|
|
<p>请考虑升级到更高版本以获得最佳性能。</p>
|
|
|
|
|
</div>
|
2024-10-26 10:38:22 +08:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2024-10-26 16:23:41 +08:00
|
|
|
|
`;
|
2024-12-12 13:24:47 +08:00
|
|
|
|
|
|
|
|
|
if (!document.getElementById('versionWarningModal')) {
|
|
|
|
|
document.body.insertAdjacentHTML('beforeend', modalHtml);
|
|
|
|
|
}
|
|
|
|
|
|
2024-10-26 16:23:41 +08:00
|
|
|
|
var modal = new bootstrap.Modal(document.getElementById('versionWarningModal'));
|
|
|
|
|
modal.show();
|
|
|
|
|
|
|
|
|
|
setTimeout(function() {
|
|
|
|
|
modal.hide();
|
|
|
|
|
}, 5000);
|
|
|
|
|
}
|
2024-10-26 10:38:22 +08:00
|
|
|
|
|
2024-10-26 16:23:41 +08:00
|
|
|
|
document.addEventListener('DOMContentLoaded', checkSingboxVersion);
|
2024-10-26 10:38:22 +08:00
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<!DOCTYPE html>
|
|
|
|
|
<html lang="zh">
|
|
|
|
|
<head>
|
|
|
|
|
<meta charset="UTF-8">
|
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
|
|
<title>NekoBox</title>
|
|
|
|
|
<style>
|
|
|
|
|
body {
|
|
|
|
|
margin: 0;
|
|
|
|
|
padding: 0;
|
|
|
|
|
font-family: Arial, sans-serif;
|
|
|
|
|
}
|
|
|
|
|
.feature-box {
|
|
|
|
|
padding: 15px;
|
|
|
|
|
margin-bottom: 20px;
|
|
|
|
|
border: 1px solid #000000;
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
}
|
|
|
|
|
.feature-box h6 {
|
|
|
|
|
margin-bottom: 15px;
|
|
|
|
|
}
|
|
|
|
|
.table-container {
|
|
|
|
|
padding: 15px;
|
|
|
|
|
margin-bottom: 20px;
|
|
|
|
|
border: 1px solid #000000;
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
}
|
|
|
|
|
.table {
|
|
|
|
|
table-layout: fixed;
|
|
|
|
|
width: 100%;
|
|
|
|
|
}
|
|
|
|
|
.table td, .table th {
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
}
|
|
|
|
|
.table thead th {
|
|
|
|
|
background-color: transparent;
|
|
|
|
|
color: #000000;
|
|
|
|
|
}
|
|
|
|
|
.btn-outline-secondary {
|
|
|
|
|
border-color: transparent;
|
|
|
|
|
color: #000000;
|
|
|
|
|
}
|
|
|
|
|
.btn-outline-secondary:hover {
|
|
|
|
|
background-color: transparent;
|
|
|
|
|
color: #000000;
|
|
|
|
|
}
|
|
|
|
|
.footer {
|
|
|
|
|
padding: 15px 0;
|
|
|
|
|
background-color: transparent;
|
|
|
|
|
color: #000000;
|
|
|
|
|
}
|
|
|
|
|
.footer p {
|
|
|
|
|
margin: 0;
|
|
|
|
|
}
|
|
|
|
|
.link-box {
|
|
|
|
|
border: 1px solid #000000;
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
padding: 10px;
|
|
|
|
|
display: block;
|
|
|
|
|
text-align: center;
|
|
|
|
|
width: 100%;
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
transition: background-color 0.3s ease;
|
|
|
|
|
}
|
|
|
|
|
.link-box a {
|
|
|
|
|
display: block;
|
|
|
|
|
padding: 10px;
|
|
|
|
|
text-decoration: none;
|
|
|
|
|
color: #000000;
|
|
|
|
|
}
|
|
|
|
|
</style>
|
|
|
|
|
</head>
|
|
|
|
|
<body>
|
|
|
|
|
<div class="container mt-4">
|
|
|
|
|
<h2 class="text-center mb-4">关于 NekoBox</h2>
|
|
|
|
|
<div class="feature-box text-center">
|
|
|
|
|
<h5>NekoBox</h5>
|
|
|
|
|
<p>NekoBox是一款精心设计的 Sing-box 代理工具,专为家庭用户打造,旨在提供简洁而强大的代理解决方案。基于 PHP 和 BASH 技术,NekoBox 将复杂的代理配置简化为直观的操作体验,让每个用户都能轻松享受高效、安全的网络环境。</p>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<h5 class="text-center mb-4">核心特点</h5>
|
|
|
|
|
<div class="row">
|
|
|
|
|
<div class="col-md-4 mb-4 d-flex">
|
|
|
|
|
<div class="feature-box text-center flex-fill">
|
|
|
|
|
<h6>简化配置</h6>
|
|
|
|
|
<p>采用用户友好的界面和智能配置功能,轻松实现 Sing-box 代理的设置与管理。</p>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="col-md-4 mb-4 d-flex">
|
|
|
|
|
<div class="feature-box text-center flex-fill">
|
|
|
|
|
<h6>优化性能</h6>
|
|
|
|
|
<p>通过高效的脚本和自动化处理,确保最佳的代理性能和稳定性。</p>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="col-md-4 mb-4 d-flex">
|
|
|
|
|
<div class="feature-box text-center flex-fill">
|
|
|
|
|
<h6>无缝体验</h6>
|
|
|
|
|
<p>专为家庭用户设计,兼顾易用性与功能性,确保每个家庭成员都能便捷地使用代理服务。</p>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<h5 class="text-center mb-4">工具信息</h5>
|
|
|
|
|
<div class="d-flex justify-content-center">
|
|
|
|
|
<div class="table-container">
|
|
|
|
|
<table class="table table-borderless mb-5">
|
|
|
|
|
<tbody>
|
|
|
|
|
<tr class="text-center">
|
|
|
|
|
<td>SagerNet</td>
|
|
|
|
|
<td>MetaCubeX</td>
|
|
|
|
|
</tr>
|
|
|
|
|
<tr class="text-center">
|
|
|
|
|
<td>
|
|
|
|
|
<div class="link-box">
|
|
|
|
|
<a href="https://github.com/SagerNet/sing-box" target="_blank">Sing-box</a>
|
|
|
|
|
</div>
|
|
|
|
|
</td>
|
|
|
|
|
<td>
|
|
|
|
|
<div class="link-box">
|
|
|
|
|
<a href="https://github.com/MetaCubeX/mihomo" target="_blank">Mihomo</a>
|
|
|
|
|
</div>
|
|
|
|
|
</td>
|
|
|
|
|
</tr>
|
|
|
|
|
</tbody>
|
|
|
|
|
</table>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<h5 class="text-center mb-4">外部链接</h5>
|
|
|
|
|
<div class="table-container">
|
|
|
|
|
<table class="table table-borderless mb-5">
|
|
|
|
|
<tbody>
|
|
|
|
|
<tr class="text-center">
|
|
|
|
|
<td>Github</td>
|
2025-01-07 20:39:04 +08:00
|
|
|
|
<td>Thaolga</td>
|
2024-10-26 10:38:22 +08:00
|
|
|
|
</tr>
|
|
|
|
|
<tr class="text-center">
|
|
|
|
|
<td>
|
|
|
|
|
<div class="link-box">
|
|
|
|
|
<a href="https://github.com/Thaolga/openwrt-nekobox/issues" target="_blank">Issues</a>
|
|
|
|
|
</div>
|
|
|
|
|
</td>
|
|
|
|
|
<td>
|
|
|
|
|
<div class="link-box">
|
2025-01-07 20:39:04 +08:00
|
|
|
|
<a href="https://github.com/Thaolga/openwrt-nekobox" target="_blank">NEKOBOX</a>
|
2024-10-26 10:38:22 +08:00
|
|
|
|
</div>
|
|
|
|
|
</td>
|
|
|
|
|
</tr>
|
|
|
|
|
<tr class="text-center">
|
|
|
|
|
<td>Telegram</td>
|
2025-01-07 20:39:04 +08:00
|
|
|
|
<td>Zephyruso</td>
|
2024-10-26 10:38:22 +08:00
|
|
|
|
</tr>
|
|
|
|
|
<tr class="text-center">
|
|
|
|
|
<td>
|
|
|
|
|
<div class="link-box">
|
|
|
|
|
<a href="https://t.me/+J55MUupktxFmMDgx" target="_blank">Telegram</a>
|
|
|
|
|
</div>
|
|
|
|
|
</td>
|
|
|
|
|
<td>
|
|
|
|
|
<div class="link-box">
|
2025-01-07 20:39:04 +08:00
|
|
|
|
<a href="https://github.com/Zephyruso/zashboard" target="_blank">ZASHBOARD</a>
|
2024-10-26 10:38:22 +08:00
|
|
|
|
</div>
|
|
|
|
|
</td>
|
|
|
|
|
</tr>
|
|
|
|
|
</tbody>
|
|
|
|
|
</table>
|
|
|
|
|
</div>
|
|
|
|
|
<footer class="text-center">
|
|
|
|
|
<p><?php echo $footer ?></p>
|
|
|
|
|
</footer>
|
|
|
|
|
</div>
|
|
|
|
|
</body>
|
|
|
|
|
</html>
|
2025-01-26 00:23:38 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|