vmess批量编辑器
This commit is contained in:
@@ -0,0 +1,521 @@
|
|||||||
|
<?php
|
||||||
|
// 设置默认时区(可选,防止警告)
|
||||||
|
date_default_timezone_set('Asia/Shanghai');
|
||||||
|
|
||||||
|
// ===== 辅助函数:vmess 解析与构建 =====
|
||||||
|
|
||||||
|
// 解析一行 vmess 链接,返回 [bool 成功, array 数据]
|
||||||
|
function parse_vmess_line(string $line): array {
|
||||||
|
$line = trim($line);
|
||||||
|
if ($line === '' || stripos($line, 'vmess://') !== 0) {
|
||||||
|
return [false, null];
|
||||||
|
}
|
||||||
|
|
||||||
|
$b64 = substr($line, strlen('vmess://'));
|
||||||
|
$b64 = trim($b64);
|
||||||
|
if ($b64 === '') {
|
||||||
|
return [false, null];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 补齐 Base64 的 '=' 填充
|
||||||
|
$mod = strlen($b64) % 4;
|
||||||
|
if ($mod > 0) {
|
||||||
|
$b64 .= str_repeat('=', 4 - $mod);
|
||||||
|
}
|
||||||
|
|
||||||
|
$json_str = base64_decode($b64, true);
|
||||||
|
if ($json_str === false) {
|
||||||
|
return [false, null];
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = json_decode($json_str, true);
|
||||||
|
if (!is_array($data)) {
|
||||||
|
return [false, null];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [true, $data];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将配置重新编码为 vmess 行
|
||||||
|
function build_vmess_line(array $data): string {
|
||||||
|
$json = json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||||
|
$b64 = base64_encode($json);
|
||||||
|
return 'vmess://' . $b64;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 标准 vmess 字段定义(显示顺序 + 中文说明)
|
||||||
|
$vmess_fields = [
|
||||||
|
'ps' => '备注(ps)',
|
||||||
|
'add' => '地址(add)',
|
||||||
|
'port' => '端口(port)',
|
||||||
|
'id' => 'UUID(id)',
|
||||||
|
'aid' => '额外ID(aid)',
|
||||||
|
'scy' => '加密方式(scy)',
|
||||||
|
'net' => '网络(net)',
|
||||||
|
'type' => '伪装类型(type)',
|
||||||
|
'host' => 'Host(host)',
|
||||||
|
'path' => '路径(path)',
|
||||||
|
'tls' => 'TLS(tls)',
|
||||||
|
'sni' => 'SNI(sni)',
|
||||||
|
'alpn' => 'ALPN(alpn)',
|
||||||
|
'insecure' => 'insecure',
|
||||||
|
];
|
||||||
|
|
||||||
|
// ===== 控制流程变量 =====
|
||||||
|
$mode = 'input'; // input | edit | result
|
||||||
|
$original_text = '';
|
||||||
|
$result_text = '';
|
||||||
|
$gost_text = '';
|
||||||
|
$vmess_rows = []; // 仅合法 vmess 行的解析结果
|
||||||
|
$other_lines = []; // 非 vmess 行或解析失败的行
|
||||||
|
$target_ip = '';
|
||||||
|
$batch_from = '';
|
||||||
|
$batch_to = '';
|
||||||
|
$batch_ip_from = '';
|
||||||
|
$batch_ip_to = '';
|
||||||
|
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
|
$step = $_POST['step'] ?? 'input';
|
||||||
|
$target_ip = trim($_POST['target_ip'] ?? '');
|
||||||
|
$batch_from = trim($_POST['batch_from'] ?? '');
|
||||||
|
$batch_to = trim($_POST['batch_to'] ?? '');
|
||||||
|
$batch_ip_from = trim($_POST['batch_ip_from'] ?? '');
|
||||||
|
$batch_ip_to = trim($_POST['batch_ip_to'] ?? '');
|
||||||
|
|
||||||
|
if ($step === 'upload') {
|
||||||
|
// 第一步:用户粘贴 vmess 列表,进入“表格编辑模式”
|
||||||
|
$original_text = trim($_POST['content'] ?? '');
|
||||||
|
if ($original_text !== '') {
|
||||||
|
$lines = preg_split("/\r\n|\n|\r/", $original_text);
|
||||||
|
foreach ($lines as $line) {
|
||||||
|
$raw = trim($line);
|
||||||
|
if ($raw === '') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
[$ok, $data] = parse_vmess_line($raw);
|
||||||
|
if (!$ok) {
|
||||||
|
$other_lines[] = $raw;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 拆分成标准字段 + 额外字段
|
||||||
|
$fields = [];
|
||||||
|
foreach ($vmess_fields as $key => $_label) {
|
||||||
|
$fields[$key] = isset($data[$key]) ? (string)$data[$key] : '';
|
||||||
|
}
|
||||||
|
$extra = array_diff_key($data, $vmess_fields);
|
||||||
|
|
||||||
|
$vmess_rows[] = [
|
||||||
|
'fields' => $fields,
|
||||||
|
'extra' => !empty($extra)
|
||||||
|
? json_encode($extra, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)
|
||||||
|
: '',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$mode = 'edit';
|
||||||
|
} elseif ($step === 'save') {
|
||||||
|
// 第二步:从表格接收编辑后的数据,生成最终 vmess 列表
|
||||||
|
$rows_post = $_POST['rows'] ?? [];
|
||||||
|
$other_lines = [];
|
||||||
|
$other_raw = trim($_POST['other_lines'] ?? '');
|
||||||
|
if ($other_raw !== '') {
|
||||||
|
$other_lines = preg_split("/\r\n|\n|\r/", $other_raw);
|
||||||
|
}
|
||||||
|
|
||||||
|
$lines_out = [];
|
||||||
|
$gost_lines_out = [];
|
||||||
|
|
||||||
|
// 从表格重建 JSON
|
||||||
|
foreach ($rows_post as $row) {
|
||||||
|
$fields = $row['fields'] ?? [];
|
||||||
|
$extra_json = $row['extra'] ?? '';
|
||||||
|
|
||||||
|
$data = [];
|
||||||
|
foreach ($vmess_fields as $key => $_label) {
|
||||||
|
if (isset($fields[$key]) && $fields[$key] !== '') {
|
||||||
|
$data[$key] = $fields[$key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($extra_json !== '') {
|
||||||
|
$extra = json_decode($extra_json, true);
|
||||||
|
if (is_array($extra)) {
|
||||||
|
$data = array_merge($data, $extra);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 批量替换(提交阶段再兜底跑一遍)
|
||||||
|
if ($target_ip !== '') {
|
||||||
|
$data['add'] = $target_ip;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($batch_from !== '' && $batch_to !== '') {
|
||||||
|
array_walk_recursive($data, function (&$value) use ($batch_from, $batch_to) {
|
||||||
|
if (is_string($value) && $value !== '') {
|
||||||
|
$value = str_replace($batch_from, $batch_to, $value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($batch_ip_from !== '' && $batch_ip_to !== '' && isset($data['add'])) {
|
||||||
|
$data['add'] = str_replace($batch_ip_from, $batch_ip_to, (string)$data['add']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建 vmess 行
|
||||||
|
$lines_out[] = build_vmess_line($data);
|
||||||
|
|
||||||
|
// 构建对应的 Gost 配置行(端口使用当前记录的 port 字段)
|
||||||
|
$ip_for_gost = isset($data['add']) ? (string)$data['add'] : '';
|
||||||
|
$port_for_gost = isset($data['port']) ? (string)$data['port'] : '';
|
||||||
|
if ($ip_for_gost !== '' && $port_for_gost !== '') {
|
||||||
|
if (strpos($ip_for_gost, ':') === false) {
|
||||||
|
// IPv4
|
||||||
|
$gost_lines_out[] = 'nonencrypt/' . $port_for_gost . '#' . $ip_for_gost . '#' . $port_for_gost;
|
||||||
|
} else {
|
||||||
|
// IPv6,添加方括号
|
||||||
|
$ip = $ip_for_gost;
|
||||||
|
if ($ip[0] !== '[') {
|
||||||
|
$ip = '[' . $ip . ']';
|
||||||
|
}
|
||||||
|
$gost_lines_out[] = 'nonencrypt/' . $port_for_gost . '#' . $ip . '#' . $port_for_gost;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$gost_lines_out[] = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 把无法解析的其它行也保留在结果中
|
||||||
|
foreach ($other_lines as $raw) {
|
||||||
|
$raw = trim($raw);
|
||||||
|
if ($raw !== '') {
|
||||||
|
$lines_out[] = $raw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$result_text = implode(PHP_EOL, $lines_out);
|
||||||
|
$gost_text = implode(PHP_EOL, $gost_lines_out);
|
||||||
|
$mode = 'result';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 默认示例文本
|
||||||
|
$original_text = "vmess://ew0KICAidiI6ICIyIiwNCiAgInBzIjogIkFsaVBDLUdHWS1TaGFyZS1CZXN0dm0tU0ciLA0KICAiYWRkIjogIjEuMS4xLjEiLA0KICAicG9ydCI6ICIzMzg4OCIsDQogICJpZCI6ICI3N2MwYWFmZC03MTNhLTQwZDUtYmI2MS1mZWMyN2JiMTI0MTEiLA0KICAiYWlkIjogIjAiLA0KICAic2N5IjogImF1dG8iLA0KICAibmV0IjogInRjcCIsDQogICJ0eXBlIjogIm5vbmUiLA0KICAiaG9zdCI6ICIiLA0KICAicGF0aCI6ICIiLA0KICAidGxzIjogIiIsDQogICJzbmkiOiAiIiwNCiAgImFscG4iOiAiIiwNCiAgImZwIjogIiIsDQogICJpbnNlY3VyZSI6ICIwIg0KfQ==";
|
||||||
|
$mode = 'input';
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>vmess 批量编辑与替换工具</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
background-color: #f4f6f9;
|
||||||
|
color: #333;
|
||||||
|
margin: 0;
|
||||||
|
padding: 20px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.container {
|
||||||
|
background-color: #fff;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 1100px;
|
||||||
|
padding: 24px 28px 32px;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 4px 15px rgba(0,0,0,0.08);
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
text-align: center;
|
||||||
|
color: #2c3e50;
|
||||||
|
margin: 0 0 20px;
|
||||||
|
font-size: 22px;
|
||||||
|
}
|
||||||
|
h2 {
|
||||||
|
font-size: 16px;
|
||||||
|
margin: 18px 0 10px;
|
||||||
|
color: #2c3e50;
|
||||||
|
}
|
||||||
|
.form-group {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #555;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
input[type="text"] {
|
||||||
|
width: 100%;
|
||||||
|
padding: 7px 10px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 13px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
textarea {
|
||||||
|
width: 100%;
|
||||||
|
height: 260px;
|
||||||
|
padding: 8px 10px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-family: monospace;
|
||||||
|
resize: vertical;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background-color: #fafafa;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
.btn-primary {
|
||||||
|
background-color: #007bff;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 10px 20px;
|
||||||
|
font-size: 14px;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.25s;
|
||||||
|
}
|
||||||
|
.btn-primary:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
}
|
||||||
|
.btn-secondary {
|
||||||
|
background-color: #6c757d;
|
||||||
|
color: #fff;
|
||||||
|
border: none;
|
||||||
|
padding: 6px 10px;
|
||||||
|
font-size: 12px;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
margin-right: 6px;
|
||||||
|
}
|
||||||
|
.btn-secondary:hover {
|
||||||
|
background-color: #5a6268;
|
||||||
|
}
|
||||||
|
.grid-layout {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 16px;
|
||||||
|
margin-top: 12px;
|
||||||
|
}
|
||||||
|
@media (max-width: 900px) {
|
||||||
|
.grid-layout {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.table-wrapper {
|
||||||
|
max-height: 460px;
|
||||||
|
overflow: auto;
|
||||||
|
border: 1px solid #e0e0e0;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: #fafafa;
|
||||||
|
}
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
thead {
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
background-color: #f0f2f5;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
th, td {
|
||||||
|
border: 1px solid #e1e1e1;
|
||||||
|
padding: 4px 6px;
|
||||||
|
text-align: left;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
th {
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 11px;
|
||||||
|
}
|
||||||
|
td input[type="text"] {
|
||||||
|
width: 140px;
|
||||||
|
padding: 3px 5px;
|
||||||
|
font-size: 11px;
|
||||||
|
}
|
||||||
|
td input.cell-short {
|
||||||
|
width: 80px;
|
||||||
|
}
|
||||||
|
td input.cell-long {
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
.small-hint {
|
||||||
|
font-size: 11px;
|
||||||
|
color: #888;
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
.section {
|
||||||
|
margin-bottom: 18px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h1>vmess 批量编辑与替换工具</h1>
|
||||||
|
|
||||||
|
<?php if ($mode === 'input'): ?>
|
||||||
|
<form method="post" action="">
|
||||||
|
<input type="hidden" name="step" value="upload">
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<h2>① 粘贴 vmess 分享地址(每行一条)</h2>
|
||||||
|
<textarea name="content" placeholder="在此粘贴 vmess:// 开头的分享地址,每行一条"><?php echo htmlspecialchars($original_text); ?></textarea>
|
||||||
|
<div class="small-hint">提交后会进入类似 Excel 的表格界面,可以逐行编辑字段。</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="submit" class="btn-primary">下一步:进入表格编辑</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<?php elseif ($mode === 'edit'): ?>
|
||||||
|
<form method="post" action="">
|
||||||
|
<input type="hidden" name="step" value="save">
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<h2>② 全局批量替换设置(可选)</h2>
|
||||||
|
<div class="grid-layout">
|
||||||
|
<div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="target_ip">统一替换为的新 IP(写入 add 字段)</label>
|
||||||
|
<input type="text" id="target_ip" name="target_ip" value="<?php echo htmlspecialchars($target_ip); ?>" placeholder="例如:192.168.1.1">
|
||||||
|
<div class="small-hint">留空则不修改 IP。</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>字符批量替换(作用于所有字段,如备注、路径等)</label>
|
||||||
|
<input type="text" id="batch_from" name="batch_from" value="<?php echo htmlspecialchars($batch_from); ?>" placeholder="原始字符,如 AliPC-GGY">
|
||||||
|
<div style="height:4px;"></div>
|
||||||
|
<input type="text" id="batch_to" name="batch_to" value="<?php echo htmlspecialchars($batch_to); ?>" placeholder="目标字符,如 TX-Haha">
|
||||||
|
<div class="small-hint">
|
||||||
|
点击下方按钮可在当前表格中直接替换,不提交到服务器。
|
||||||
|
</div>
|
||||||
|
<button type="button" class="btn-secondary" onclick="applyBatchReplaceAll()">在表格中应用字符替换</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>IP 批量替换(仅作用于地址 add 字段)</label>
|
||||||
|
<input type="text" id="batch_ip_from" name="batch_ip_from" value="<?php echo htmlspecialchars($batch_ip_from); ?>" placeholder="原始 IP 片段,例如 1.1.1.1">
|
||||||
|
<div style="height:4px;"></div>
|
||||||
|
<input type="text" id="batch_ip_to" name="batch_ip_to" value="<?php echo htmlspecialchars($batch_ip_to); ?>" placeholder="目标 IP 片段,例如 8.8.8.8">
|
||||||
|
<div class="small-hint">
|
||||||
|
点击按钮仅在 IP 列(add)中替换,方便从一台机器迁移到另一台。
|
||||||
|
</div>
|
||||||
|
<button type="button" class="btn-secondary" onclick="applyBatchReplaceIP()">在表格中应用 IP 替换</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<h2>③ 表格编辑(类似 Excel,可逐行修改任意字段)</h2>
|
||||||
|
<div class="table-wrapper">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>#</th>
|
||||||
|
<?php foreach ($vmess_fields as $key => $label): ?>
|
||||||
|
<th><?php echo htmlspecialchars($label); ?></th>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php foreach ($vmess_rows as $idx => $row): ?>
|
||||||
|
<tr>
|
||||||
|
<td><?php echo $idx + 1; ?></td>
|
||||||
|
<?php foreach ($vmess_fields as $key => $label): ?>
|
||||||
|
<?php
|
||||||
|
$value = $row['fields'][$key] ?? '';
|
||||||
|
$classes = 'cell-string';
|
||||||
|
if (in_array($key, ['port', 'aid'], true)) {
|
||||||
|
$classes .= ' cell-short';
|
||||||
|
} elseif (in_array($key, ['ps', 'host', 'path', 'id'], true)) {
|
||||||
|
$classes .= ' cell-long';
|
||||||
|
}
|
||||||
|
if ($key === 'add') {
|
||||||
|
$classes .= ' cell-add';
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<td>
|
||||||
|
<input type="text" name="rows[<?php echo $idx; ?>][fields][<?php echo htmlspecialchars($key); ?>]"
|
||||||
|
value="<?php echo htmlspecialchars($value); ?>"
|
||||||
|
class="<?php echo $classes; ?>">
|
||||||
|
</td>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
<input type="hidden" name="rows[<?php echo $idx; ?>][extra]" value="<?php echo htmlspecialchars($row['extra']); ?>">
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<?php if (!empty($other_lines)): ?>
|
||||||
|
<div class="small-hint" style="margin-top:6px;">
|
||||||
|
下列行无法识别为 vmess,将原样保留在结果中(如需要可自行编辑后粘贴回上一步):
|
||||||
|
</div>
|
||||||
|
<textarea readonly><?php echo htmlspecialchars(implode("\n", $other_lines)); ?></textarea>
|
||||||
|
<input type="hidden" name="other_lines" value="<?php echo htmlspecialchars(implode("\n", $other_lines)); ?>">
|
||||||
|
<?php else: ?>
|
||||||
|
<input type="hidden" name="other_lines" value="">
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section" style="margin-top: 16px;">
|
||||||
|
<button type="submit" class="btn-primary">确认提交并生成 vmess 结果</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function applyBatchReplaceAll() {
|
||||||
|
var from = document.getElementById('batch_from').value;
|
||||||
|
var to = document.getElementById('batch_to').value;
|
||||||
|
if (!from) return;
|
||||||
|
var inputs = document.querySelectorAll('input.cell-string');
|
||||||
|
inputs.forEach(function (input) {
|
||||||
|
if (input.value) {
|
||||||
|
input.value = input.value.split(from).join(to);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function applyBatchReplaceIP() {
|
||||||
|
var from = document.getElementById('batch_ip_from').value;
|
||||||
|
var to = document.getElementById('batch_ip_to').value;
|
||||||
|
if (!from || !to) return;
|
||||||
|
var inputs = document.querySelectorAll('input.cell-add');
|
||||||
|
inputs.forEach(function (input) {
|
||||||
|
if (input.value) {
|
||||||
|
input.value = input.value.split(from).join(to);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<?php elseif ($mode === 'result'): ?>
|
||||||
|
<div class="section">
|
||||||
|
<h2>④ 生成结果</h2>
|
||||||
|
<div class="grid-layout">
|
||||||
|
<div>
|
||||||
|
<label>生成后的 vmess 链接(每行一条,可直接复制使用)</label>
|
||||||
|
<textarea readonly onclick="this.select()" placeholder="结果会显示在这里"><?php echo htmlspecialchars($result_text); ?></textarea>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label>对应的 Gost 配置(每条记录一行,端口使用当前记录的 port 值)</label>
|
||||||
|
<textarea readonly onclick="this.select()" placeholder="Gost 配置会显示在这里"><?php echo htmlspecialchars($gost_text); ?></textarea>
|
||||||
|
<div class="small-hint">示例:IPv4 => nonencrypt/33888#1.1.1.1#33888;IPv6 => nonencrypt/22777#[2403:2c80::1]#22777(端口都取自各自 vmess 的 port)。</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="section" style="margin-top: 16px;">
|
||||||
|
<form method="post" action="">
|
||||||
|
<input type="hidden" name="step" value="input">
|
||||||
|
<button type="submit" class="btn-primary">返回第①步继续处理其他链接</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user