update 2024-12-10 16:28:20
This commit is contained in:
parent
90365f95f8
commit
18da74527c
|
@ -10,14 +10,14 @@
|
|||
var conf = 'dnsproxy';
|
||||
var instance = 'dnsproxy';
|
||||
|
||||
var callServiceList = rpc.declare({
|
||||
const callServiceList = rpc.declare({
|
||||
object: 'service',
|
||||
method: 'list',
|
||||
params: ['name'],
|
||||
expect: { '': {} }
|
||||
});
|
||||
|
||||
var callHostHints = rpc.declare({
|
||||
const callHostHints = rpc.declare({
|
||||
object: 'luci-rpc',
|
||||
method: 'getHostHints',
|
||||
expect: { '': {} }
|
||||
|
@ -60,7 +60,7 @@ return view.extend({
|
|||
var isRunning = res[0],
|
||||
hosts = res[1];
|
||||
|
||||
var m, s, o, ss, so;
|
||||
let m, s, o, ss, so;
|
||||
|
||||
m = new form.Map('dnsproxy', _('DNS Proxy'));
|
||||
|
||||
|
|
|
@ -352,7 +352,7 @@ return baseclass.extend({
|
|||
},
|
||||
|
||||
getFeatures: function() {
|
||||
var callGetFeatures = rpc.declare({
|
||||
const callGetFeatures = rpc.declare({
|
||||
object: 'luci.fchomo',
|
||||
method: 'get_features',
|
||||
expect: { '': {} }
|
||||
|
@ -363,7 +363,7 @@ return baseclass.extend({
|
|||
|
||||
getServiceStatus: function(instance) {
|
||||
var conf = 'fchomo';
|
||||
var callServiceList = rpc.declare({
|
||||
const callServiceList = rpc.declare({
|
||||
object: 'service',
|
||||
method: 'list',
|
||||
params: ['name'],
|
||||
|
@ -381,7 +381,7 @@ return baseclass.extend({
|
|||
},
|
||||
|
||||
getClashAPI: function(instance) {
|
||||
var callGetClashAPI = rpc.declare({
|
||||
const callGetClashAPI = rpc.declare({
|
||||
object: 'luci.fchomo',
|
||||
method: 'get_clash_api',
|
||||
params: ['instance'],
|
||||
|
@ -798,7 +798,7 @@ return baseclass.extend({
|
|||
},
|
||||
|
||||
lsDir: function(type) {
|
||||
var callLsDir = rpc.declare({
|
||||
const callLsDir = rpc.declare({
|
||||
object: 'luci.fchomo',
|
||||
method: 'dir_ls',
|
||||
params: ['type'],
|
||||
|
@ -814,7 +814,7 @@ return baseclass.extend({
|
|||
},
|
||||
|
||||
readFile: function(type, filename) {
|
||||
var callReadFile = rpc.declare({
|
||||
const callReadFile = rpc.declare({
|
||||
object: 'luci.fchomo',
|
||||
method: 'file_read',
|
||||
params: ['type', 'filename'],
|
||||
|
@ -830,7 +830,7 @@ return baseclass.extend({
|
|||
},
|
||||
|
||||
writeFile: function(type, filename, content) {
|
||||
var callWriteFile = rpc.declare({
|
||||
const callWriteFile = rpc.declare({
|
||||
object: 'luci.fchomo',
|
||||
method: 'file_write',
|
||||
params: ['type', 'filename', 'content'],
|
||||
|
@ -846,7 +846,7 @@ return baseclass.extend({
|
|||
},
|
||||
|
||||
downloadFile: function(type, filename, url, header) {
|
||||
var callDownloadFile = rpc.declare({
|
||||
const callDownloadFile = rpc.declare({
|
||||
object: 'luci.fchomo',
|
||||
method: 'file_download',
|
||||
params: ['type', 'filename', 'url', 'header'],
|
||||
|
@ -862,7 +862,7 @@ return baseclass.extend({
|
|||
},
|
||||
|
||||
removeFile: function(type, filename) {
|
||||
var callRemoveFile = rpc.declare({
|
||||
const callRemoveFile = rpc.declare({
|
||||
object: 'luci.fchomo',
|
||||
method: 'file_remove',
|
||||
params: ['type', 'filename'],
|
||||
|
@ -879,7 +879,7 @@ return baseclass.extend({
|
|||
|
||||
// thanks to homeproxy
|
||||
uploadCertificate: function(type, filename, ev) {
|
||||
var callWriteCertificate = rpc.declare({
|
||||
const callWriteCertificate = rpc.declare({
|
||||
object: 'luci.fchomo',
|
||||
method: 'certificate_write',
|
||||
params: ['filename'],
|
||||
|
@ -898,7 +898,7 @@ return baseclass.extend({
|
|||
.catch((e) => { ui.addNotification(null, E('p', e.message)) });
|
||||
},
|
||||
uploadInitialPack: function(ev, section_id) {
|
||||
var callWriteInitialPack = rpc.declare({
|
||||
const callWriteInitialPack = rpc.declare({
|
||||
object: 'luci.fchomo',
|
||||
method: 'initialpack_write',
|
||||
expect: { '': {} }
|
||||
|
|
|
@ -421,7 +421,7 @@ return view.extend({
|
|||
render: function(data) {
|
||||
var dashboard_repo = uci.get(data[0], 'api', 'dashboard_repo');
|
||||
|
||||
var m, s, o, ss, so;
|
||||
let m, s, o, ss, so;
|
||||
|
||||
m = new form.Map('fchomo', _('Mihomo client'));
|
||||
|
||||
|
|
|
@ -11,14 +11,14 @@
|
|||
'require tools.firewall as fwtool';
|
||||
'require tools.widgets as widgets';
|
||||
|
||||
var callResVersion = rpc.declare({
|
||||
const callResVersion = rpc.declare({
|
||||
object: 'luci.fchomo',
|
||||
method: 'resources_get_version',
|
||||
params: ['type', 'repo'],
|
||||
expect: { '': {} }
|
||||
});
|
||||
|
||||
var callCrondSet = rpc.declare({
|
||||
const callCrondSet = rpc.declare({
|
||||
object: 'luci.fchomo',
|
||||
method: 'crond_set',
|
||||
params: ['type', 'expr'],
|
||||
|
@ -26,7 +26,7 @@ var callCrondSet = rpc.declare({
|
|||
});
|
||||
|
||||
function handleResUpdate(type, repo) {
|
||||
var callResUpdate = rpc.declare({
|
||||
const callResUpdate = rpc.declare({
|
||||
object: 'luci.fchomo',
|
||||
method: 'resources_update',
|
||||
params: ['type', 'repo'],
|
||||
|
@ -122,7 +122,7 @@ return view.extend({
|
|||
|
||||
var dashboard_repo = uci.get(data[0], 'api', 'dashboard_repo');
|
||||
|
||||
var m, s, o, ss, so;
|
||||
let m, s, o, ss, so;
|
||||
|
||||
m = new form.Map('fchomo', _('FullCombo Mihomo'),
|
||||
'<img src="' + hm.sharktaikogif + '" title="Ciallo~(∠・ω< )⌒☆" height="52"></img>');
|
||||
|
@ -169,7 +169,7 @@ return view.extend({
|
|||
|
||||
so = ss.option(form.DummyValue, '_conn_check', _('Connection check'));
|
||||
so.cfgvalue = function() {
|
||||
var callConnStat = rpc.declare({
|
||||
const callConnStat = rpc.declare({
|
||||
object: 'luci.fchomo',
|
||||
method: 'connection_check',
|
||||
params: ['url'],
|
||||
|
|
|
@ -26,7 +26,7 @@ var css = ' \
|
|||
var hm_dir = '/var/run/fchomo';
|
||||
|
||||
function getRuntimeLog(name, filename) {
|
||||
var callLogClean = rpc.declare({
|
||||
const callLogClean = rpc.declare({
|
||||
object: 'luci.fchomo',
|
||||
method: 'log_clean',
|
||||
params: ['type'],
|
||||
|
@ -87,7 +87,7 @@ function getRuntimeLog(name, filename) {
|
|||
|
||||
return view.extend({
|
||||
render: function(data) {
|
||||
var m, s, o;
|
||||
let m, s, o;
|
||||
|
||||
m = new form.Map('fchomo');
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ return view.extend({
|
|||
},
|
||||
|
||||
render: function(data) {
|
||||
var m, s, o, ss, so;
|
||||
let m, s, o, ss, so;
|
||||
|
||||
m = new form.Map('fchomo', _('Edit node'));
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@ return view.extend({
|
|||
},
|
||||
|
||||
render: function(data) {
|
||||
var m, s, o;
|
||||
let m, s, o;
|
||||
|
||||
m = new form.Map('fchomo', _('Edit ruleset'));
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ return view.extend({
|
|||
var dashboard_repo = uci.get(data[0], 'api', 'dashboard_repo'),
|
||||
features = data[1];
|
||||
|
||||
var m, s, o;
|
||||
let m, s, o;
|
||||
|
||||
m = new form.Map('fchomo', _('Mihomo server'),
|
||||
_('When used as a server, HomeProxy is a better choice.'));
|
||||
|
|
|
@ -3,7 +3,7 @@ ob_start();
|
|||
include './cfg.php';
|
||||
date_default_timezone_set('Asia/Shanghai');
|
||||
|
||||
$dataFilePath = '/tmp/subscription_data.txt';
|
||||
$dataFilePath = '/etc/neko/subscription_data.txt';
|
||||
$lastSubscribeUrl = '';
|
||||
|
||||
if (file_exists($dataFilePath)) {
|
||||
|
@ -53,7 +53,7 @@ if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['setCron'])) {
|
|||
|
||||
<?php
|
||||
$shellScriptPath = '/etc/neko/core/update_subscription.sh';
|
||||
$DATA_FILE = '/tmp/subscription_data.txt';
|
||||
$DATA_FILE = '/etc/neko/subscription_data.txt';
|
||||
$LOG_FILE = '/tmp/update_subscription.log';
|
||||
$SUBSCRIBE_URL = '';
|
||||
|
||||
|
@ -73,7 +73,7 @@ if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
|||
$shellScriptContent = <<<EOL
|
||||
#!/bin/sh
|
||||
|
||||
DATA_FILE="/tmp/subscription_data.txt"
|
||||
DATA_FILE="/etc/neko/subscription_data.txt"
|
||||
CONFIG_DIR="/etc/neko/config"
|
||||
LOG_FILE="/tmp/update_subscription.log"
|
||||
TEMPLATE_URL="https://raw.githubusercontent.com/Thaolga/Rules/main/Clash/json/config_8.json"
|
||||
|
@ -266,7 +266,7 @@ EOL;
|
|||
</div>
|
||||
</div>
|
||||
<?php
|
||||
$dataFilePath = '/tmp/subscription_data.txt';
|
||||
$dataFilePath = '/etc/neko/subscription_data.txt';
|
||||
$configFilePath = '/etc/neko/config/sing-box.json';
|
||||
$downloadedContent = '';
|
||||
|
||||
|
@ -314,7 +314,7 @@ EOL;
|
|||
}
|
||||
|
||||
$completeSubscribeUrl = "https://sing-box-subscribe-doraemon.vercel.app/config/{$subscribeUrlEncoded}&file={$templateUrlEncoded}";
|
||||
$tempFilePath = '/tmp/' . $customFileName;
|
||||
$tempFilePath = '/etc/neko/' . $customFileName;
|
||||
$logMessages = [];
|
||||
$command = "wget -O " . escapeshellarg($tempFilePath) . " " . escapeshellarg($completeSubscribeUrl);
|
||||
exec($command, $output, $returnVar);
|
||||
|
|
|
@ -149,17 +149,14 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['editFile'], $_GET['file
|
|||
<?php
|
||||
$subscriptionPath = '/etc/neko/proxy_provider/';
|
||||
$subscriptionFile = $subscriptionPath . 'subscriptions.json';
|
||||
$clashFile = $subscriptionPath . 'subscription_6.yaml';
|
||||
$message = "";
|
||||
$decodedContent = "";
|
||||
$subscriptions = [];
|
||||
$updateCompleted = false;
|
||||
$updateCompleted = false;
|
||||
|
||||
function outputMessage($message) {
|
||||
if (!isset($_SESSION['update_messages'])) {
|
||||
$_SESSION['update_messages'] = array();
|
||||
$_SESSION['update_messages'] = [];
|
||||
}
|
||||
|
||||
$_SESSION['update_messages'][] = $message;
|
||||
}
|
||||
|
||||
|
@ -176,7 +173,7 @@ if (!$subscriptions) {
|
|||
for ($i = 0; $i < 6; $i++) {
|
||||
$subscriptions[$i] = [
|
||||
'url' => '',
|
||||
'file_name' => "subscription_{$i}.yaml",
|
||||
'file_name' => "subscription_" . ($i + 1) . ".yaml",
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -184,13 +181,14 @@ if (!$subscriptions) {
|
|||
if (isset($_POST['update'])) {
|
||||
$index = intval($_POST['index']);
|
||||
$url = $_POST['subscription_url'] ?? '';
|
||||
$customFileName = $_POST['custom_file_name'] ?? "subscription_{$index}.yaml";
|
||||
$customFileName = $_POST['custom_file_name'] ?? "subscription_" . ($index + 1) . ".yaml";
|
||||
|
||||
$subscriptions[$index]['url'] = $url;
|
||||
$subscriptions[$index]['file_name'] = $customFileName;
|
||||
|
||||
if (!empty($url)) {
|
||||
$finalPath = $subscriptionPath . $customFileName;
|
||||
|
||||
$command = "wget -q --show-progress -O {$finalPath} {$url}";
|
||||
exec($command . ' 2>&1', $output, $return_var);
|
||||
|
||||
|
@ -209,16 +207,25 @@ if (isset($_POST['update'])) {
|
|||
<li>该模板支持所有格式订阅链接,无需额外转换</li>
|
||||
</ul>
|
||||
</div>';
|
||||
$_SESSION['update_messages'][] = "订阅链接 {$url} 更新成功!文件已保存到: {$finalPath}";
|
||||
$message = '更新成功';
|
||||
$updateCompleted = true;
|
||||
|
||||
$fileContent = file_get_contents($finalPath);
|
||||
$decodedContent = base64_decode($fileContent);
|
||||
|
||||
if ($decodedContent === false) {
|
||||
$_SESSION['update_messages'][] = "Base64 解码失败,请检查下载的文件内容是否有效!";
|
||||
$message = "Base64 解码失败";
|
||||
} else {
|
||||
$clashFile = $subscriptionPath . $customFileName;
|
||||
file_put_contents($clashFile, "# Clash Meta Config\n\n" . $decodedContent);
|
||||
$_SESSION['update_messages'][] = "订阅链接 {$url} 更新成功,并解码内容保存到: {$clashFile}";
|
||||
$message = '更新成功';
|
||||
$updateCompleted = true;
|
||||
}
|
||||
} else {
|
||||
$_SESSION['update_messages'] = array();
|
||||
$_SESSION['update_messages'][] = "配置更新失败!错误信息: " . implode("\n", $output);
|
||||
$message = '更新失败';
|
||||
}
|
||||
} else {
|
||||
$_SESSION['update_messages'] = array();
|
||||
$_SESSION['update_messages'][] = "第" . ($index + 1) . "个订阅链接为空!";
|
||||
$message = '更新失败';
|
||||
}
|
||||
|
@ -230,14 +237,13 @@ if (isset($_POST['convert_base64'])) {
|
|||
$base64Content = $_POST['base64_content'] ?? '';
|
||||
|
||||
if (!empty($base64Content)) {
|
||||
$decodedContent = base64_decode($base64Content);
|
||||
$decodedContent = base64_decode($base64Content);
|
||||
|
||||
if ($decodedContent === false) {
|
||||
$message = "Base64 解码失败,请检查输入!";
|
||||
$message = "Base64 解码失败,请检查输入内容!";
|
||||
} else {
|
||||
$clashConfig = "# Clash Meta Config\n\n";
|
||||
$clashConfig .= $decodedContent;
|
||||
file_put_contents($clashFile, $clashConfig);
|
||||
$clashFile = $subscriptionPath . 'decoded_subscription.yaml';
|
||||
file_put_contents($clashFile, "# Clash Meta Config\n\n" . $decodedContent);
|
||||
$message = "Clash 配置文件已生成并保存到: {$clashFile}";
|
||||
}
|
||||
} else {
|
||||
|
@ -503,7 +509,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Mihomo - Neko</title>
|
||||
<title>Mihomo - NekoBox</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">
|
||||
|
@ -1188,30 +1194,36 @@ function initializeAceEditor() {
|
|||
|
||||
<?php if (isset($subscriptions) && is_array($subscriptions)): ?>
|
||||
<div class="row">
|
||||
<?php for ($i = 0; $i < 6; $i++): ?>
|
||||
<?php
|
||||
$maxSubscriptions = 6;
|
||||
for ($i = 0; $i < $maxSubscriptions; $i++):
|
||||
$displayIndex = $i + 1;
|
||||
$url = $subscriptions[$i]['url'] ?? '';
|
||||
$fileName = $subscriptions[$i]['file_name'] ?? "subscription_" . ($displayIndex) . ".yaml";
|
||||
?>
|
||||
<div class="col-md-4 mb-3">
|
||||
<form method="post" class="card">
|
||||
<div class="card-body">
|
||||
<div class="form-group">
|
||||
<h5 for="subscription_url_<?php echo $i; ?>" class="mb-2">订阅链接 <?php echo ($i + 1); ?></h5>
|
||||
<input type="text" name="subscription_url" id="subscription_url_<?php echo $i; ?>" value="<?php echo htmlspecialchars($subscriptions[$i]['url'] ?? ''); ?>" required class="form-control">
|
||||
<h5 for="subscription_url_<?php echo $displayIndex; ?>" class="mb-2">订阅链接 <?php echo $displayIndex; ?></h5>
|
||||
<input type="text" name="subscription_url" id="subscription_url_<?php echo $displayIndex; ?>" value="<?php echo htmlspecialchars($url); ?>" class="form-control">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="custom_file_name_<?php echo $i; ?>">自定义文件名</label>
|
||||
<input type="text" name="custom_file_name" id="custom_file_name_<?php echo $i; ?>" value="subscription_<?php echo ($i + 1); ?>.yaml" class="form-control">
|
||||
<label for="custom_file_name_<?php echo $displayIndex; ?>">自定义文件名</label>
|
||||
<input type="text" name="custom_file_name" id="custom_file_name_<?php echo $displayIndex; ?>" value="<?php echo htmlspecialchars($fileName); ?>" class="form-control">
|
||||
</div>
|
||||
<input type="hidden" name="index" value="<?php echo $i; ?>">
|
||||
<div class="text-center mt-3">
|
||||
<button type="submit" name="update" class="btn btn-info">🔄 更新订阅 <?php echo ($i + 1); ?></button>
|
||||
<button type="submit" name="update" class="btn btn-info">🔄 更新订阅 <?php echo $displayIndex; ?></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<?php if (($i + 1) % 3 == 0 && $i < 5): ?>
|
||||
<?php if (($displayIndex) % 3 == 0 && $displayIndex < $maxSubscriptions): ?>
|
||||
</div><div class="row">
|
||||
<?php endif; ?>
|
||||
|
||||
|
||||
<?php endfor; ?>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
proxies:
|
|
@ -2,13 +2,13 @@
|
|||
ob_start();
|
||||
include './cfg.php';
|
||||
date_default_timezone_set('Asia/Shanghai');
|
||||
$proxyDir = '/www/nekobox/proxy/';
|
||||
$uploadDir = '/etc/neko/proxy_provider/';
|
||||
$configDir = '/etc/neko/config/';
|
||||
|
||||
ini_set('memory_limit', '256M');
|
||||
|
||||
if (!is_dir($proxyDir)) {
|
||||
mkdir($proxyDir, 0755, true);
|
||||
if (!is_dir($uploadDir)) {
|
||||
mkdir($uploadDir, 0755, true);
|
||||
}
|
||||
|
||||
if (!is_dir($configDir)) {
|
||||
|
@ -18,7 +18,7 @@ if (!is_dir($configDir)) {
|
|||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
if (isset($_FILES['fileInput'])) {
|
||||
$file = $_FILES['fileInput'];
|
||||
$uploadFilePath = $proxyDir . basename($file['name']);
|
||||
$uploadFilePath = $uploadDir . basename($file['name']);
|
||||
|
||||
if ($file['error'] === UPLOAD_ERR_OK) {
|
||||
if (move_uploaded_file($file['tmp_name'], $uploadFilePath)) {
|
||||
|
@ -47,7 +47,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||
}
|
||||
|
||||
if (isset($_POST['deleteFile'])) {
|
||||
$fileToDelete = $proxyDir . basename($_POST['deleteFile']);
|
||||
$fileToDelete = $uploadDir . basename($_POST['deleteFile']);
|
||||
if (file_exists($fileToDelete) && unlink($fileToDelete)) {
|
||||
echo '文件删除成功:' . htmlspecialchars(basename($_POST['deleteFile']));
|
||||
} else {
|
||||
|
@ -64,21 +64,21 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||
}
|
||||
}
|
||||
|
||||
if (isset($_POST['oldFileName'], $_POST['newFileName'], $_POST['fileType'])) {
|
||||
$oldFileName = basename($_POST['oldFileName']);
|
||||
$newFileName = basename($_POST['newFileName']);
|
||||
$fileType = $_POST['fileType'];
|
||||
if (isset($_POST['oldFileName'], $_POST['newFileName'], $_POST['fileType'])) {
|
||||
$oldFileName = basename($_POST['oldFileName']);
|
||||
$newFileName = basename($_POST['newFileName']);
|
||||
$fileType = $_POST['fileType'];
|
||||
|
||||
if ($fileType === 'proxy') {
|
||||
$oldFilePath = $proxyDir . $oldFileName;
|
||||
$newFilePath = $proxyDir . $newFileName;
|
||||
} elseif ($fileType === 'config') {
|
||||
$oldFilePath = $configDir . $oldFileName;
|
||||
$newFilePath = $configDir . $newFileName;
|
||||
} else {
|
||||
echo '无效的文件类型';
|
||||
exit;
|
||||
}
|
||||
if ($fileType === 'proxy') {
|
||||
$oldFilePath = $uploadDir. $oldFileName;
|
||||
$newFilePath = $uploadDir. $newFileName;
|
||||
} elseif ($fileType === 'config') {
|
||||
$oldFilePath = $configDir . $oldFileName;
|
||||
$newFilePath = $configDir . $newFileName;
|
||||
} else {
|
||||
echo '无效的文件类型';
|
||||
exit;
|
||||
}
|
||||
|
||||
if (file_exists($oldFilePath) && !file_exists($newFilePath)) {
|
||||
if (rename($oldFilePath, $newFilePath)) {
|
||||
|
@ -88,16 +88,16 @@ if (isset($_POST['oldFileName'], $_POST['newFileName'], $_POST['fileType'])) {
|
|||
}
|
||||
} else {
|
||||
echo '文件重命名失败,文件不存在或新文件名已存在。';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_POST['saveContent'], $_POST['fileName'], $_POST['fileType'])) {
|
||||
$fileToSave = ($_POST['fileType'] === 'proxy') ? $proxyDir . basename($_POST['fileName']) : $configDir . basename($_POST['fileName']);
|
||||
$contentToSave = $_POST['saveContent'];
|
||||
file_put_contents($fileToSave, $contentToSave);
|
||||
echo '<p>文件内容已更新:' . htmlspecialchars(basename($fileToSave)) . '</p>';
|
||||
$fileToSave = ($_POST['fileType'] === 'proxy') ? $uploadDir . basename($_POST['fileName']) : $configDir . basename($_POST['fileName']);
|
||||
$contentToSave = $_POST['saveContent'];
|
||||
file_put_contents($fileToSave, $contentToSave);
|
||||
echo '<p>文件内容已更新:' . htmlspecialchars(basename($fileToSave)) . '</p>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function formatFileModificationTime($filePath) {
|
||||
if (file_exists($filePath)) {
|
||||
|
@ -108,7 +108,7 @@ function formatFileModificationTime($filePath) {
|
|||
}
|
||||
}
|
||||
|
||||
$proxyFiles = scandir($proxyDir);
|
||||
$proxyFiles = scandir($uploadDir);
|
||||
$configFiles = scandir($configDir);
|
||||
|
||||
if ($proxyFiles !== false) {
|
||||
|
@ -134,7 +134,7 @@ function formatSize($size) {
|
|||
}
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['editFile'], $_GET['fileType'])) {
|
||||
$filePath = ($_GET['fileType'] === 'proxy') ? $proxyDir . basename($_GET['editFile']) : $configDir . basename($_GET['editFile']);
|
||||
$filePath = ($_GET['fileType'] === 'proxy') ? $uploadDir. basename($_GET['editFile']) : $configDir . basename($_GET['editFile']);
|
||||
if (file_exists($filePath)) {
|
||||
header('Content-Type: text/plain');
|
||||
echo file_get_contents($filePath);
|
||||
|
@ -146,89 +146,6 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['editFile'], $_GET['file
|
|||
}
|
||||
?>
|
||||
|
||||
<?php
|
||||
$configPath = '/www/nekobox/proxy/';
|
||||
$configFile = $configPath . 'subscriptions.json';
|
||||
$subscriptionList = [];
|
||||
|
||||
while (ob_get_level() > 0) {
|
||||
ob_end_flush();
|
||||
}
|
||||
|
||||
function outputMessage($message) {
|
||||
if (!isset($_SESSION['notification_messages'])) {
|
||||
$_SESSION['notification_messages'] = [];
|
||||
}
|
||||
$_SESSION['notification_messages'][] = $message;
|
||||
}
|
||||
|
||||
if (!isset($_SESSION['help_message'])) {
|
||||
$_SESSION['help_message'] = '<div class="text-warning" style="margin-bottom: 8px;">
|
||||
<strong>⚠️ 注意:</strong> 当前配置文件必须配合 <strong>Puernya</strong> 内核使用,不支持其他内核!
|
||||
</div>';
|
||||
}
|
||||
|
||||
if (!file_exists($configPath)) {
|
||||
mkdir($configPath, 0755, true);
|
||||
}
|
||||
|
||||
if (!file_exists($configFile)) {
|
||||
file_put_contents($configFile, json_encode([]));
|
||||
}
|
||||
|
||||
$subscriptionList = json_decode(file_get_contents($configFile), true);
|
||||
if (!$subscriptionList || !is_array($subscriptionList)) {
|
||||
$subscriptionList = [];
|
||||
for ($i = 1; $i <= 3; $i++) {
|
||||
$subscriptionList[$i - 1] = [
|
||||
'url' => '',
|
||||
'file_name' => "subscription_{$i}.yaml",
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_POST['saveSubscription'])) {
|
||||
$index = intval($_POST['index']);
|
||||
if ($index >= 0 && $index < 3) {
|
||||
$url = $_POST['subscription_url'] ?? '';
|
||||
$customFileName = $_POST['custom_file_name'] ?? "subscription_{$index}.yaml";
|
||||
$subscriptionList[$index]['url'] = $url;
|
||||
$subscriptionList[$index]['file_name'] = $customFileName;
|
||||
|
||||
if (!empty($url)) {
|
||||
$finalPath = $configPath . $customFileName;
|
||||
$command = sprintf(
|
||||
"wget -q --show-progress -O %s %s",
|
||||
escapeshellarg($finalPath),
|
||||
escapeshellarg($url)
|
||||
);
|
||||
|
||||
exec($command . ' 2>&1', $output, $return_var);
|
||||
|
||||
if ($return_var !== 0) {
|
||||
$command = sprintf(
|
||||
"curl -s -o %s %s",
|
||||
escapeshellarg($finalPath),
|
||||
escapeshellarg($url)
|
||||
);
|
||||
exec($command . ' 2>&1', $output, $return_var);
|
||||
}
|
||||
|
||||
if ($return_var === 0) {
|
||||
outputMessage("订阅链接 {$url} 更新成功!文件已保存到: {$finalPath}");
|
||||
} else {
|
||||
outputMessage("配置更新失败!错误信息: " . implode("\n", $output));
|
||||
}
|
||||
} else {
|
||||
outputMessage("第" . ($index + 1) . "个订阅链接为空!");
|
||||
}
|
||||
|
||||
file_put_contents($configFile, json_encode($subscriptionList));
|
||||
}
|
||||
}
|
||||
$updateCompleted = isset($_POST['saveSubscription']);
|
||||
?>
|
||||
|
||||
<?php
|
||||
$subscriptionPath = '/etc/neko/config/';
|
||||
$dataFile = $subscriptionPath . 'subscription_data.json';
|
||||
|
@ -394,16 +311,6 @@ function isUtf8($string) {
|
|||
<script src="./assets/bootstrap/popper.min.js"></script>
|
||||
<script src="./assets/bootstrap/bootstrap.min.js"></script>
|
||||
</head>
|
||||
<?php if ($updateCompleted): ?>
|
||||
<script>
|
||||
if (!sessionStorage.getItem('refreshed')) {
|
||||
sessionStorage.setItem('refreshed', 'true');
|
||||
window.location.reload();
|
||||
} else {
|
||||
sessionStorage.removeItem('refreshed');
|
||||
}
|
||||
</script>
|
||||
<?php endif; ?>
|
||||
|
||||
<body>
|
||||
<div class="position-fixed w-100 d-flex justify-content-center" style="top: 20px; z-index: 1050">
|
||||
|
@ -602,7 +509,7 @@ td {
|
|||
<div class="card mb-4">
|
||||
<div class="card-body">
|
||||
<div class="container">
|
||||
<h5>代理文件管理 ➤ p核专用</h5>
|
||||
<h5>代理文件管理</h5>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-bordered text-center">
|
||||
<thead class="thead-dark">
|
||||
|
@ -615,7 +522,7 @@ td {
|
|||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($proxyFiles as $file): ?>
|
||||
<?php $filePath = $proxyDir . $file; ?>
|
||||
<?php $filePath = $uploadDir. $file; ?>
|
||||
<tr>
|
||||
<td class="align-middle"><a href="download.php?file=<?php echo urlencode($file); ?>"><?php echo htmlspecialchars($file); ?></a></td>
|
||||
<td class="align-middle"><?php echo file_exists($filePath) ? formatSize(filesize($filePath)) : '文件不存在'; ?></td>
|
||||
|
@ -1115,47 +1022,15 @@ function initializeAceEditor() {
|
|||
</div>
|
||||
</form>
|
||||
|
||||
<h2 class=" text-center mt-4 mb-4">订阅管理 ➤ p核专用</h2>
|
||||
<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. 注意:</strong> 通用模板(<code>puernya.json</code>)最多支持<strong>3 个</strong>订阅链接。请勿更改默认文件名称,并确保使用 puernya 内核。
|
||||
</div>
|
||||
<div class="help-text mb-3 text-start">
|
||||
<strong>3. 支持通用格式订阅,无需转换。
|
||||
</div>
|
||||
<div class="help-text mb-3 text-start">
|
||||
<strong>4. 保存与更新:</strong> 填写完毕后,请点击"更新配置"按钮进行保存。
|
||||
<strong>2. 注意:puernya订阅已合并至Mihomo订阅,并确保使用 puernya 内核。
|
||||
</div>
|
||||
<div class="help-text mb-3 text-start">
|
||||
<strong>5. 说明:</strong> 上述 Sing-box 订阅适用于原版 Sing-box 内核,仅支持后缀为 Sing-box 格式的机场订阅链接。对于通用订阅,请使用转换模板以确保兼容性。
|
||||
</div>
|
||||
<div class="row">
|
||||
<?php for ($i = 0; $i < 3; $i++): ?>
|
||||
<div class="col-md-4 mb-4">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">订阅链接 <?php echo ($i + 1); ?></h5>
|
||||
<form method="post">
|
||||
<div class="input-group mb-3">
|
||||
<input type="text" name="subscription_url" id="subscriptionurl<?php echo $i; ?>"
|
||||
value="<?php echo htmlspecialchars($subscriptionList[$i]['url']); ?>"
|
||||
required class="form-control" placeholder="输入链接">
|
||||
<input type="text" name="custom_file_name" id="custom_filename<?php echo $i; ?>"
|
||||
value="<?php echo htmlspecialchars($subscriptionList[$i]['file_name']); ?>"
|
||||
class="form-control" placeholder="自定义文件名">
|
||||
<input type="hidden" name="index" value="<?php echo $i; ?>">
|
||||
<button type="submit" name="saveSubscription" class="btn btn-success ml-2">
|
||||
<i>🔄</i> 更新
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endfor; ?>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -506,7 +506,7 @@
|
|||
"tag": "🛫 ",
|
||||
"type": "remote",
|
||||
"download_url": "https://example.com/xxx/xxx&flag=clash",
|
||||
"path": "./proxy/subscription_1.yaml",
|
||||
"path": "/etc/neko/proxy_provider/subscription_1.yaml",
|
||||
"download_interval": "24h",
|
||||
"download_ua": "clash.meta",
|
||||
"includes": [
|
||||
|
@ -520,7 +520,7 @@
|
|||
"tag": "🛫. ",
|
||||
"type": "remote",
|
||||
"download_url": "https://example.com/xxx/xxx&flag=clash",
|
||||
"path": "./proxy/subscription_2.yaml",
|
||||
"path": "/etc/neko/proxy_provider/subscription_2.yaml",
|
||||
"download_interval": "24h",
|
||||
"download_ua": "clash.meta",
|
||||
"includes": [
|
||||
|
@ -534,7 +534,7 @@
|
|||
"tag": "🛫.. ",
|
||||
"type": "remote",
|
||||
"download_url": "https://example.com/xxx/xxx&flag=clash",
|
||||
"path": "./proxy/subscription_3.yaml",
|
||||
"path": "/etc/neko/proxy_provider/subscription_3.yaml",
|
||||
"download_interval": "24h",
|
||||
"download_ua": "clash.meta",
|
||||
"includes": [
|
||||
|
|
|
@ -24,7 +24,7 @@ return view.extend({
|
|||
has_location = res[2].path,
|
||||
pkgversion = '2.6';
|
||||
|
||||
var m, s, o;
|
||||
let m, s, o;
|
||||
|
||||
m = new form.Map('tinyfilemanager');
|
||||
|
||||
|
|
Loading…
Reference in New Issue