update 2024-12-17 20:42:25

This commit is contained in:
kenzok8 2024-12-17 20:42:25 +08:00
parent a150e20c22
commit be18ab9d95
12 changed files with 313 additions and 166 deletions

View File

@ -32,6 +32,8 @@ $dash_link = $neko_cfg['ctrl_host'] . ':' . $neko_cfg['ctrl_port'] . '/ui/dashbo
<link href="./assets/theme/<?php echo $neko_theme ?>" rel="stylesheet">
<script type="text/javascript" src="./assets/js/feather.min.js"></script>
<script type="text/javascript" src="./assets/js/jquery-2.1.3.min.js"></script>
<script type="text/javascript" src="./assets/js/bootstrap.min.js"></script>
<?php include './ping.php'; ?>
</head>
<body>
<head>

View File

@ -233,6 +233,95 @@ if (isset($_POST['update'])) {
file_put_contents($subscriptionFile, json_encode($subscriptions));
}
?>
<?php
$shellScriptPath = '/etc/neko/core/update_mihomo.sh';
$LOG_FILE = '/tmp/update_subscription.log';
$JSON_FILE = '/etc/neko/proxy_provider/subscriptions.json';
$SAVE_DIR = '/etc/neko/proxy_provider';
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if (isset($_POST['createShellScript'])) {
$shellScriptContent = <<<EOL
#!/bin/bash
LOG_FILE="$LOG_FILE"
JSON_FILE="$JSON_FILE"
SAVE_DIR="$SAVE_DIR"
if [ ! -f "\$JSON_FILE" ]; then
echo "\$(date): 错误: JSON 文件不存在: \$JSON_FILE" >> "\$LOG_FILE"
exit 1
fi
echo "\$(date): 开始处理订阅链接..." >> "\$LOG_FILE"
jq -c '.[]' "\$JSON_FILE" | while read -r ITEM; do
URL=\$(echo "\$ITEM" | jq -r '.url')
FILE_NAME=\$(echo "\$ITEM" | jq -r '.file_name')
if [ -z "\$URL" ] || [ "\$URL" == "null" ]; then
echo "\$(date): 跳过空的 URL文件名: \$FILE_NAME" >> "\$LOG_FILE"
continue
fi
if [ -z "\$FILE_NAME" ] || [ "\$FILE_NAME" == "null" ]; then
echo "\$(date): 错误: 文件名为空,跳过此链接: \$URL" >> "\$LOG_FILE"
continue
fi
SAVE_PATH="\$SAVE_DIR/\$FILE_NAME"
TEMP_PATH="\$SAVE_PATH.temp"
echo "\$(date): 正在下载链接: \$URL 到临时文件: \$TEMP_PATH" >> "\$LOG_FILE"
wget -q -O "\$TEMP_PATH" "\$URL"
if [ \$? -eq 0 ]; then
echo "\$(date): 文件下载成功: \$TEMP_PATH" >> "\$LOG_FILE"
base64 -d "\$TEMP_PATH" > "\$SAVE_PATH"
if [ \$? -eq 0 ]; then
echo "\$(date): 文件解码成功: \$SAVE_PATH" >> "\$LOG_FILE"
else
echo "\$(date): 错误: 文件解码失败: \$SAVE_PATH" >> "\$LOG_FILE"
fi
rm -f "\$TEMP_PATH"
else
echo "\$(date): 错误: 文件下载失败: \$URL" >> "\$LOG_FILE"
fi
done
echo "\$(date): 所有订阅链接处理完成。" >> "\$LOG_FILE"
EOL;
if (file_put_contents($shellScriptPath, $shellScriptContent) !== false) {
chmod($shellScriptPath, 0755);
echo "<div class='alert alert-success'>Shell 脚本已创建成功!路径: $shellScriptPath</div>";
} else {
echo "<div class='alert alert-danger'>无法创建 Shell 脚本,请检查权限。</div>";
}
}
}
?>
<?php
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if (isset($_POST['createCronJob'])) {
$cronExpression = trim($_POST['cronExpression']);
if (empty($cronExpression)) {
echo "<div class='alert alert-warning'>Cron 表达式不能为空。</div>";
exit;
}
$cronJob = "$cronExpression /etc/neko/core/update_mihomo.sh > /dev/null 2>&1";
exec("crontab -l | grep -v '/etc/neko/core/update_mihomo.sh' | crontab -");
exec("(crontab -l; echo '$cronJob') | crontab -");
echo "<div class='alert alert-success'>Cron 任务已成功添加或更新!</div>";
}
}
?>
<!doctype html>
<html lang="en" data-bs-theme="<?php echo substr($neko_theme, 0, -4) ?>">
<head>
@ -509,7 +598,7 @@ function showUpdateAlert() {
</div>
<div class="container">
<h5 class="text-center">配置文件管理</h5>
<h5>配置文件管理</h5>
<div class="table-responsive">
<table class="table table-striped table-bordered text-center">
<thead class="thead-dark">
@ -912,7 +1001,6 @@ function initializeAceEditor() {
}
}
</script>
<h2 class="text-center mt-4 mb-4">Mihomo订阅管理</h2>
<?php if (isset($message) && $message): ?>
@ -958,6 +1046,56 @@ function initializeAceEditor() {
<?php else: ?>
<p>未找到订阅信息。</p>
<?php endif; ?>
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div class="container">
<h4 class="mt-4 mb-4 text-center">自动更新</h4>
<form method="post" class="text-center">
<button type="button" class="btn btn-primary mx-2" data-toggle="modal" data-target="#cronModal">
设置定时任务
</button>
<button type="submit" name="createShellScript" value="true" class="btn btn-success mx-2">
生成更新脚本
</button>
</form>
</div>
<form method="POST">
<div class="modal fade" id="cronModal" tabindex="-1" role="dialog" aria-labelledby="cronModalLabel" aria-hidden="true" data-backdrop="static" data-keyboard="false">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="cronModalLabel">设置 Cron 计划任务</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div class="form-group">
<label for="cronExpression">Cron 表达式</label>
<input type="text" class="form-control" id="cronExpression" name="cronExpression" placeholder="如: 0 2 * * *" required>
</div>
<div class="alert alert-info">
<strong>提示:</strong> Cron 表达式格式:
<ul>
<li><code>分钟 小时 星期</code></li>
<li>示例: 每天凌晨 2 : <code>0 2 * * *</code></li>
</ul>
</div>
</div>
<div class="modal-footer justify-content-center">
<button type="button" class="btn btn-secondary mr-3" data-dismiss="modal">取消</button>
<button type="submit" name="createCronJob" class="btn btn-primary">保存</button>
</div>
</div>
</div>
</div>
</form>
<script>
document.getElementById('pasteButton').onclick = function() {
window.open('https://paste.gg', '_blank');
@ -986,11 +1124,6 @@ function initializeAceEditor() {
}
</style>
<div class="help-text mb-3 text-start">
<strong>1. 对于首次使用 Sing-box 的用户,必须将核心更新至版本 v1.10.0 或更高版本。确保将出站和入站/转发防火墙规则都设置为“接受”并启用它们。
</div>
<div class="help-text mb-3 text-start">
<strong>2. 注意puernya订阅已合并至Mihomo订阅并确保使用 puernya 内核。
</div>
<footer class="text-center">
<p><?php echo $footer ?></p>

View File

@ -278,7 +278,6 @@ $lang = $_GET['lang'] ?? 'en';
.container-sm.container-bg.callout.border {
padding: 12px 15px;
min-height: 70px;
display: flex;
margin-bottom: 15px;
}

View File

@ -104,6 +104,16 @@ function getRazordVersion() {
return "未安装";
}
}
function getCliverVersion() {
$versionFile = '/etc/neko/tmp/nekobox_version';
if (file_exists($versionFile)) {
return trim(file_get_contents($versionFile));
} else {
return "未安装";
}
}
$singBoxVersionInfo = getSingboxVersion();
$singBoxVersion = $singBoxVersionInfo['version'];
$singBoxType = $singBoxVersionInfo['type'];
@ -113,6 +123,7 @@ $mihomoVersionInfo = getMihomoVersion();
$mihomoVersion = $mihomoVersionInfo['version'];
$mihomoType = $mihomoVersionInfo['type'];
$uiVersion = getUiVersion();
$cliverVersion = getCliverVersion();
$metaCubexdVersion = getMetaCubexdVersion();
$metaVersion = getMetaVersion();
$razordVersion = getRazordVersion();
@ -846,7 +857,7 @@ document.getElementById('checkUiButton').addEventListener('click', function () {
document.getElementById('checkCliverButton').addEventListener('click', function () {
const currentVersions = {
'客户端': document.getElementById('cliver').textContent,
'客户端': '<?php echo htmlspecialchars($cliverVersion); ?>',
};
const updateFiles = [{ name: '客户端', url: 'update_script.php' }];
checkVersion('NewCliver', updateFiles, currentVersions);

View File

@ -438,7 +438,7 @@ EOL;
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Personal - Neko</title>
<title>Sing-box - Neko</title>
<link rel="icon" href="./assets/img/nekobox.png">
<link href="./assets/css/bootstrap.min.css" rel="stylesheet">
<link href="./assets/css/custom.css" rel="stylesheet">
@ -762,6 +762,7 @@ EOL;
</div>
</div>
<div class="help mt-4">
<strong>1. 对于首次使用 Sing-box 的用户,必须将核心更新至版本 v1.10.0 或更高版本。确保将出站和入站/转发防火墙规则都设置为“接受”并启用它们。<p>
<p style="color: red;">注意:在线订阅转换存在隐私泄露风险,请确保使用 Sing-box 的通道一版本,通道二版本不支持此功能。同时,需要下载并配置 geoip geosite 文件以确保正常使用。</p>
<p>订阅转换由肥羊提供</p>
<a href="https://github.com/youshandefeiyang/sub-web-modify" target="_blank" class="btn btn-primary">

View File

@ -0,0 +1 @@
V1.5.9-cn

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -48,8 +48,8 @@
onload="this.media='all'"
href="https://unpkg.com/subsetted-fonts@latest/PingFangSC-Regular\PingFangSC-Regular.css"
/>
<script type="module" crossorigin src="./assets/index-D9NwuV-C.js"></script>
<link rel="stylesheet" crossorigin href="./assets/index-BYhhgJN7.css">
<script type="module" crossorigin src="./assets/index-C1iuVV9q.js"></script>
<link rel="stylesheet" crossorigin href="./assets/index-BxIFQ89r.css">
<link rel="manifest" href="./manifest.webmanifest"><script id="vite-plugin-pwa:register-sw" src="./registerSW.js"></script></head>
<body>
<div id="app"></div>

View File

@ -1 +1 @@
if(!self.define){let e,i={};const s=(s,n)=>(s=new URL(s+".js",n).href,i[s]||new Promise((i=>{if("document"in self){const e=document.createElement("script");e.src=s,e.onload=i,document.head.appendChild(e)}else e=s,importScripts(s),i()})).then((()=>{let e=i[s];if(!e)throw new Error(`Module ${s} didnt register its module`);return e})));self.define=(n,r)=>{const f=e||("document"in self?document.currentScript.src:"")||location.href;if(i[f])return;let d={};const o=e=>s(e,f),c={module:{uri:f},exports:d,require:o};i[f]=Promise.all(n.map((e=>c[e]||o(e)))).then((e=>(r(...e),d)))}}define(["./workbox-3e8df8c8"],(function(e){"use strict";self.skipWaiting(),e.clientsClaim(),e.precacheAndRoute([{url:"assets/index-BYhhgJN7.css",revision:null},{url:"assets/index-D9NwuV-C.js",revision:null},{url:"index.html",revision:"cfdf488d6346498f0e0c29ee500f6038"},{url:"registerSW.js",revision:"402b66900e731ca748771b6fc5e7a068"},{url:"favicon.svg",revision:"7f1c4521acc10694fefef8f72dd2ea5f"},{url:"pwa-192x192.png",revision:"021df52501f4357c03eebd808f40dc6a"},{url:"pwa-512x512.png",revision:"d2f759aaabcb2c44ff52b27fde3de6e0"},{url:"pwa-maskable-192x192.png",revision:"7cd11dc5f0490b349d23eef5591d10e5"},{url:"pwa-maskable-512x512.png",revision:"8c97dc367a85a5a1eba523b24f79d03b"},{url:"manifest.webmanifest",revision:"c452912633990899ffe790f985ad0db9"}],{}),e.cleanupOutdatedCaches(),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("index.html")))}));
if(!self.define){let e,i={};const s=(s,n)=>(s=new URL(s+".js",n).href,i[s]||new Promise((i=>{if("document"in self){const e=document.createElement("script");e.src=s,e.onload=i,document.head.appendChild(e)}else e=s,importScripts(s),i()})).then((()=>{let e=i[s];if(!e)throw new Error(`Module ${s} didnt register its module`);return e})));self.define=(n,r)=>{const f=e||("document"in self?document.currentScript.src:"")||location.href;if(i[f])return;let o={};const t=e=>s(e,f),c={module:{uri:f},exports:o,require:t};i[f]=Promise.all(n.map((e=>c[e]||t(e)))).then((e=>(r(...e),o)))}}define(["./workbox-3e8df8c8"],(function(e){"use strict";self.skipWaiting(),e.clientsClaim(),e.precacheAndRoute([{url:"assets/index-BxIFQ89r.css",revision:null},{url:"assets/index-C1iuVV9q.js",revision:null},{url:"index.html",revision:"28767b615484191159e70268009f21c7"},{url:"registerSW.js",revision:"402b66900e731ca748771b6fc5e7a068"},{url:"favicon.svg",revision:"7f1c4521acc10694fefef8f72dd2ea5f"},{url:"pwa-192x192.png",revision:"021df52501f4357c03eebd808f40dc6a"},{url:"pwa-512x512.png",revision:"d2f759aaabcb2c44ff52b27fde3de6e0"},{url:"pwa-maskable-192x192.png",revision:"7cd11dc5f0490b349d23eef5591d10e5"},{url:"pwa-maskable-512x512.png",revision:"8c97dc367a85a5a1eba523b24f79d03b"},{url:"manifest.webmanifest",revision:"c452912633990899ffe790f985ad0db9"}],{}),e.cleanupOutdatedCaches(),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("index.html")))}));

View File

@ -1 +1 @@
v1.29.0
v1.29.2