mirror of
https://github.com/kenzok8/small-package
synced 2025-01-07 07:06:58 +08:00
update 2024-12-31 00:24:40
This commit is contained in:
parent
981a076945
commit
accb1bd370
@ -21,11 +21,15 @@ function index()
|
||||
entry({"admin", "services", "shadowsocksr", "subscribe"}, call("subscribe"))
|
||||
entry({"admin", "services", "shadowsocksr", "checkport"}, call("check_port"))
|
||||
entry({"admin", "services", "shadowsocksr", "log"}, form("shadowsocksr/log"), _("Log"), 80).leaf = true
|
||||
entry({"admin", "services", "shadowsocksr", "get_log"}, call("get_log")).leaf = true
|
||||
entry({"admin", "services", "shadowsocksr", "clear_log"}, call("clear_log")).leaf = true
|
||||
entry({"admin", "services", "shadowsocksr", "run"}, call("act_status"))
|
||||
entry({"admin", "services", "shadowsocksr", "ping"}, call("act_ping"))
|
||||
entry({"admin", "services", "shadowsocksr", "reset"}, call("act_reset"))
|
||||
entry({"admin", "services", "shadowsocksr", "restart"}, call("act_restart"))
|
||||
entry({"admin", "services", "shadowsocksr", "delete"}, call("act_delete"))
|
||||
--[[Backup]]
|
||||
entry({"admin", "services", "shadowsocksr", "backup"}, call("create_backup")).leaf = true
|
||||
end
|
||||
|
||||
function subscribe()
|
||||
@ -107,9 +111,9 @@ function check_port()
|
||||
ret = socket:connect(s.server, s.server_port)
|
||||
if tostring(ret) == "true" then
|
||||
socket:close()
|
||||
retstring = retstring .. "<font color = 'green'>[" .. server_name .. "] OK.</font><br />"
|
||||
retstring .. "<font><b style='color:green'>[" .. server_name .. "] OK.</b></font><br />"
|
||||
else
|
||||
retstring = retstring .. "<font color = 'red'>[" .. server_name .. "] Error.</font><br />"
|
||||
retstring = retstring .. "<font><b style='color:red'>[" .. server_name .. "] Error.</b></font><br />"
|
||||
end
|
||||
if iret == 0 then
|
||||
luci.sys.call("ipset del ss_spec_wan_ac " .. s.server)
|
||||
@ -120,7 +124,7 @@ function check_port()
|
||||
end
|
||||
|
||||
function act_reset()
|
||||
luci.sys.call("/etc/init.d/shadowsocksr reset &")
|
||||
luci.sys.call("/etc/init.d/shadowsocksr reset >/dev/null 2>&1")
|
||||
luci.http.redirect(luci.dispatcher.build_url("admin", "services", "shadowsocksr"))
|
||||
end
|
||||
|
||||
@ -133,3 +137,28 @@ function act_delete()
|
||||
luci.sys.call("/etc/init.d/shadowsocksr restart &")
|
||||
luci.http.redirect(luci.dispatcher.build_url("admin", "services", "shadowsocksr", "servers"))
|
||||
end
|
||||
|
||||
function get_log()
|
||||
luci.http.write(luci.sys.exec("[ -f '/var/log/ssrplus.log' ] && cat /var/log/ssrplus.log"))
|
||||
end
|
||||
|
||||
function clear_log()
|
||||
luci.sys.call("echo '' > /var/log/ssrplus.log")
|
||||
end
|
||||
|
||||
function create_backup()
|
||||
local backup_files = {
|
||||
"/etc/config/shadowsocksr",
|
||||
"/etc/ssrplus/*"
|
||||
}
|
||||
local date = os.date("%Y%m%d")
|
||||
local tar_file = "/tmp/shadowsocksr-" .. date .. "-backup.tar.gz"
|
||||
nixio.fs.remove(tar_file)
|
||||
local cmd = "tar -czf " .. tar_file .. " " .. table.concat(backup_files, " ")
|
||||
luci.sys.call(cmd)
|
||||
luci.http.header("Content-Disposition", "attachment; filename=shadowsocksr-" .. date .. "-backup.tar.gz")
|
||||
luci.http.header("X-Backup-Filename", "shadowsocksr-" .. date .. "-backup.tar.gz")
|
||||
luci.http.prepare_content("application/octet-stream")
|
||||
luci.http.write(nixio.fs.readfile(tar_file))
|
||||
nixio.fs.remove(tar_file)
|
||||
end
|
||||
|
@ -937,7 +937,7 @@ if is_finded("xray") then
|
||||
|
||||
-- [[ uTLS ]]--
|
||||
o = s:option(ListValue, "fingerprint", translate("Finger Print"))
|
||||
o.default = "chrome"
|
||||
o.default = ""
|
||||
o:value("chrome", translate("chrome"))
|
||||
o:value("firefox", translate("firefox"))
|
||||
o:value("safari", translate("safari"))
|
||||
@ -1016,7 +1016,7 @@ o:depends("mux", true)
|
||||
|
||||
|
||||
-- [[ MPTCP ]]--
|
||||
o = s:option(Flag, "mptcp", translate("MPTCP"))
|
||||
o = s:option(Flag, "mptcp", translate("MPTCP"), translate("Enabling MPTCP Requires Server Support."))
|
||||
o.rmempty = false
|
||||
o.default = false
|
||||
o:depends({type = "v2ray", v2ray_protocol = "vless"})
|
||||
|
@ -1,20 +1,102 @@
|
||||
require "luci.util"
|
||||
require "nixio.fs"
|
||||
require "luci.sys"
|
||||
require "luci.http"
|
||||
|
||||
f = SimpleForm("logview")
|
||||
f.reset = false
|
||||
f.submit = false
|
||||
t = f:field(TextValue, "conf")
|
||||
t.rmempty = true
|
||||
t.rows = 20
|
||||
function t.cfgvalue()
|
||||
if nixio.fs.access("/var/log/ssrplus.log") then
|
||||
local logs = luci.util.execi("cat /var/log/ssrplus.log")
|
||||
local s = ""
|
||||
for line in logs do
|
||||
s = line .. "\n" .. s
|
||||
end
|
||||
return s
|
||||
end
|
||||
f:append(Template("shadowsocksr/log"))
|
||||
|
||||
-- 自定义 log 函数
|
||||
function log(...)
|
||||
local result = os.date("%Y-%m-%d %H:%M:%S: ") .. table.concat({...}, " ")
|
||||
local f, err = io.open("/var/log/ssrplus.log", "a")
|
||||
if f and err == nil then
|
||||
f:write(result .. "\n")
|
||||
f:close()
|
||||
end
|
||||
end
|
||||
t.readonly = "readonly"
|
||||
return f
|
||||
|
||||
-- 创建备份与恢复表单
|
||||
fb = SimpleForm('backup-restore')
|
||||
fb.reset = false
|
||||
fb.submit = false
|
||||
s = fb:section(SimpleSection, translate("Backup and Restore"), translate("Backup or Restore Client and Server Configurations.") ..
|
||||
"<br><font style='color:red'><b>" ..
|
||||
translate("Note: Restoring configurations across different versions may cause compatibility issues.") ..
|
||||
"</b></font>")
|
||||
o = s:option(DummyValue, '', nil)
|
||||
o.template = "shadowsocksr/backup_restore"
|
||||
|
||||
-- 定义备份目标文件和目录
|
||||
local backup_targets = {
|
||||
files = {
|
||||
"/etc/config/shadowsocksr"
|
||||
},
|
||||
dirs = {
|
||||
"/etc/ssrplus"
|
||||
}
|
||||
}
|
||||
|
||||
local file_path = '/tmp/shadowsocksr_upload.tar.gz'
|
||||
local temp_dir = '/tmp/shadowsocksr_bak'
|
||||
local fd
|
||||
|
||||
-- 处理文件上传
|
||||
luci.http.setfilehandler(function(meta, chunk, eof)
|
||||
if not fd and meta and meta.name == "ulfile" and chunk then
|
||||
-- 初始化上传处理
|
||||
luci.sys.call("rm -rf " .. temp_dir)
|
||||
nixio.fs.remove(file_path)
|
||||
fd = nixio.open(file_path, "w")
|
||||
luci.sys.call("echo '' > /var/log/ssrplus.log")
|
||||
end
|
||||
|
||||
if fd and chunk then
|
||||
fd:write(chunk)
|
||||
end
|
||||
|
||||
if eof and fd then
|
||||
fd:close()
|
||||
fd = nil
|
||||
if nixio.fs.access(file_path) then
|
||||
log(" * shadowsocksr 配置文件上传成功…") -- 使用自定义的 log 函数
|
||||
luci.sys.call("mkdir -p " .. temp_dir)
|
||||
|
||||
if luci.sys.call("tar -xzf " .. file_path .. " -C " .. temp_dir) == 0 then
|
||||
-- 处理文件还原
|
||||
for _, target in ipairs(backup_targets.files) do
|
||||
local temp_file = temp_dir .. target
|
||||
if nixio.fs.access(temp_file) then
|
||||
luci.sys.call(string.format("cp -f '%s' '%s'", temp_file, target))
|
||||
log(" * 文件 " .. target .. " 还原成功…") -- 使用自定义的 log 函数
|
||||
end
|
||||
end
|
||||
|
||||
-- 处理目录还原
|
||||
for _, target in ipairs(backup_targets.dirs) do
|
||||
local temp_dir_path = temp_dir .. target
|
||||
if nixio.fs.access(temp_dir_path) then
|
||||
luci.sys.call(string.format("cp -rf '%s'/* '%s/'", temp_dir_path, target))
|
||||
log(" * 目录 " .. target .. " 还原成功…") -- 使用自定义的 log 函数
|
||||
end
|
||||
end
|
||||
|
||||
log(" * shadowsocksr 配置还原成功…") -- 使用自定义的 log 函数
|
||||
log(" * 重启 shadowsocksr 服务中…\n") -- 使用自定义的 log 函数
|
||||
luci.sys.call('/etc/init.d/shadowsocksr restart > /dev/null 2>&1 &')
|
||||
else
|
||||
log(" * shadowsocksr 配置文件解压失败,请重试!") -- 使用自定义的 log 函数
|
||||
end
|
||||
else
|
||||
log(" * shadowsocksr 配置文件上传失败,请重试!") -- 使用自定义的 log 函数
|
||||
end
|
||||
|
||||
-- 清理临时文件
|
||||
luci.sys.call("rm -rf " .. temp_dir)
|
||||
nixio.fs.remove(file_path)
|
||||
end
|
||||
end)
|
||||
|
||||
return f, fb
|
||||
|
@ -155,6 +155,14 @@ if nixio.fs.access("/usr/bin/kcptun-client") then
|
||||
end
|
||||
end
|
||||
|
||||
s = m:field(Button, "Restart", translate("Restart ShadowSocksR Plus+"))
|
||||
s.inputtitle = translate("Restart Service")
|
||||
s.inputstyle = "reload"
|
||||
s.write = function()
|
||||
luci.sys.call("/etc/init.d/shadowsocksr restart >/dev/null 2>&1 &")
|
||||
luci.http.redirect(luci.dispatcher.build_url("admin", "services", "shadowsocksr", "client"))
|
||||
end
|
||||
|
||||
s = m:field(DummyValue, "google", translate("Google Connectivity"))
|
||||
s.value = translate("No Check")
|
||||
s.template = "shadowsocksr/check"
|
||||
@ -181,10 +189,10 @@ if uci:get_first("shadowsocksr", 'global', 'apple_optimization', '0') ~= '0' the
|
||||
end
|
||||
|
||||
if uci:get_first("shadowsocksr", 'global', 'netflix_enable', '0') ~= '0' then
|
||||
s = m:field(DummyValue, "nfip_data", translate("Netflix IP Data"))
|
||||
s.rawhtml = true
|
||||
s.template = "shadowsocksr/refresh"
|
||||
s.value = nfip_count .. " " .. translate("Records")
|
||||
s = m:field(DummyValue, "nfip_data", translate("Netflix IP Data"))
|
||||
s.rawhtml = true
|
||||
s.template = "shadowsocksr/refresh"
|
||||
s.value = nfip_count .. " " .. translate("Records")
|
||||
end
|
||||
|
||||
if uci:get_first("shadowsocksr", 'global', 'adblock', '0') == '1' then
|
||||
|
154
luci-app-ssr-plus/luasrc/view/shadowsocksr/backup_restore.htm
Normal file
154
luci-app-ssr-plus/luasrc/view/shadowsocksr/backup_restore.htm
Normal file
@ -0,0 +1,154 @@
|
||||
<%+cbi/valueheader%>
|
||||
<div class="cbi-value" id="_backup_div">
|
||||
<label class="cbi-value-title"><%:Create Backup File%></label>
|
||||
<div class="cbi-value-field">
|
||||
<input type="button" class="btn cbi-button cbi-input-apply" onclick="dl_backup()" value="<%:DL Backup%>" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="cbi-value" id="_upload_div">
|
||||
<label class="cbi-value-title"><%:Restore Backup File%></label>
|
||||
<div class="cbi-value-field">
|
||||
<input type="button" class="btn cbi-button cbi-input-apply" id="upload-btn" value="<%:RST Backup%>" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="cbi-value" id="_reset_div">
|
||||
<label class="cbi-value-title"><%:Restore to default configuration%></label>
|
||||
<div class="cbi-value-field">
|
||||
<input type="button" class="btn cbi-button cbi-button-remove" onclick="do_reset()" value="<%:Do Reset%>" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="upload-modal" class="up-modal" style="display:none;">
|
||||
<div class="up-modal-content">
|
||||
<h3><%:Restore Backup File%></h3>
|
||||
<div class="cbi-value" id="_upload_div">
|
||||
<div class="up-cbi-value-field">
|
||||
<input class="cbi-input-file" type="file" id="ulfile" name="ulfile" accept=".tar.gz" required />
|
||||
<br />
|
||||
<div class="up-button-container">
|
||||
<input type="submit" class="btn cbi-button cbi-input-apply" value="<%:UL Restore%>" />
|
||||
<button class="btn cbi-button cbi-button-remove" id="upload-close"><%:CLOSE WIN%></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.up-modal {
|
||||
position: fixed;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
background: white;
|
||||
padding: 20px;
|
||||
border: 2px solid #ccc;
|
||||
box-shadow: 0 0 10px rgba(0,0,0,0.5);
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.up-modal-content {
|
||||
width: 100%;
|
||||
max-width: 400px;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.up-button-container {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
max-width: 250px;
|
||||
}
|
||||
|
||||
.up-cbi-value-field {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
// JavaScript 版本的 url 函数
|
||||
function url(...args) {
|
||||
let url = "/cgi-bin/luci/admin/services/shadowsocksr";
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
if (args[i] !== "") {
|
||||
url += "/" + args[i];
|
||||
}
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
// 上传按钮点击事件
|
||||
document.getElementById("upload-btn").addEventListener("click", function() {
|
||||
document.getElementById("upload-modal").style.display = "block";
|
||||
});
|
||||
|
||||
// 关闭上传模态框
|
||||
document.getElementById("upload-close").addEventListener("click", function() {
|
||||
document.getElementById("upload-modal").style.display = "none";
|
||||
});
|
||||
|
||||
// 备份下载函数
|
||||
function dl_backup(btn) {
|
||||
fetch(url("backup"), { // 使用 JavaScript 版本的 url 函数
|
||||
method: 'POST',
|
||||
credentials: 'same-origin'
|
||||
})
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
throw new Error("备份失败!");
|
||||
}
|
||||
const filename = response.headers.get("X-Backup-Filename");
|
||||
if (!filename) {
|
||||
return;
|
||||
}
|
||||
return response.blob().then(blob => ({ blob, filename }));
|
||||
})
|
||||
.then(result => {
|
||||
if (!result) return;
|
||||
const { blob, filename } = result;
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const a = document.createElement("a");
|
||||
a.href = url;
|
||||
a.download = filename;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
a.remove();
|
||||
window.URL.revokeObjectURL(url);
|
||||
})
|
||||
.catch(error => alert(error.message));
|
||||
}
|
||||
|
||||
// 恢复出厂设置
|
||||
function do_reset(btn) {
|
||||
if (confirm("<%: Do you want to restore the client to default settings?%>")) {
|
||||
setTimeout(function () {
|
||||
if (confirm("<%: Are you sure you want to restore the client to default settings?%>")) {
|
||||
// 清理日志
|
||||
var xhr1 = new XMLHttpRequest();
|
||||
xhr1.open("GET", url("clear_log"), true); // 使用 JavaScript 版本的 url 函数
|
||||
xhr1.send();
|
||||
// 恢复出厂
|
||||
var xhr2 = new XMLHttpRequest();
|
||||
xhr2.open("GET", url("reset"), true); // 使用 JavaScript 版本的 url 函数
|
||||
xhr2.send();
|
||||
// 处理响应
|
||||
xhr2.onload = function() {
|
||||
if (xhr2.status === 200) {
|
||||
window.location.href = url("reset");
|
||||
}
|
||||
};
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<%+cbi/valuefooter%>
|
37
luci-app-ssr-plus/luasrc/view/shadowsocksr/log.htm
Normal file
37
luci-app-ssr-plus/luasrc/view/shadowsocksr/log.htm
Normal file
@ -0,0 +1,37 @@
|
||||
<%
|
||||
local dsp = require "luci.dispatcher"
|
||||
-%>
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
function clearlog(btn) {
|
||||
XHR.get('<%=dsp.build_url("admin/services/shadowsocksr/clear_log")%>', null,
|
||||
function(x, data) {
|
||||
if (x && x.status == 200) {
|
||||
var log_textarea = document.getElementById('log_textarea');
|
||||
log_textarea.innerHTML = "";
|
||||
log_textarea.scrollTop = log_textarea.scrollHeight;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
XHR.poll(5, '<%=dsp.build_url("admin/services/shadowsocksr/get_log")%>', null,
|
||||
function(x, data) {
|
||||
if (x && x.status == 200) {
|
||||
var log_textarea = document.getElementById('log_textarea');
|
||||
// 将日志分行处理,移除最后一行空行但保留中间空行
|
||||
var logs = x.responseText.split("\n");
|
||||
if (logs[logs.length - 1].trim() === "") {
|
||||
logs.pop(); // 删除最后的空行
|
||||
}
|
||||
logs = logs.reverse().join("\n"); // 倒序排列
|
||||
log_textarea.innerHTML = logs;
|
||||
}
|
||||
}
|
||||
);
|
||||
//]]>
|
||||
</script>
|
||||
<fieldset class="cbi-section" id="_log_fieldset">
|
||||
<input class="btn cbi-button cbi-button-remove" type="button" onclick="clearlog()" value="<%:Clear logs%>" />
|
||||
<textarea id="log_textarea" class="cbi-input-textarea" style="width: 100%;margin-top: 10px;" data-update="change" rows="20" wrap="off" readonly="readonly"></textarea>
|
||||
</fieldset>
|
@ -217,8 +217,9 @@ function import_ssr_url(btn, urlname, sid) {
|
||||
case "trojan":
|
||||
try {
|
||||
var url = new URL("http://" + ssu[1]);
|
||||
var params = url.searchParams;
|
||||
} catch(e) {
|
||||
alert(e)
|
||||
alert(e);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -232,7 +233,65 @@ function import_ssr_url(btn, urlname, sid) {
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.password')[0].value = decodeURIComponent(url.username);
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls')[0].checked = true;
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls')[0].dispatchEvent(event);
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls_host')[0].value = url.searchParams.get("sni");
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.fingerprint')[0].value = params.get("fp") || "";
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls_host')[0].value = params.get("sni");
|
||||
if (params.get("allowInsecure") === "1") {
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.insecure')[0].checked = true; // 设置 insecure 为 true
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.insecure')[0].dispatchEvent(event); // 触发事件
|
||||
}
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.transport')[0].value =
|
||||
params.get("type") == "http" ? "h2" :
|
||||
(["tcp", "raw"].includes(params.get("type")) ? "raw" :
|
||||
(params.get("type") || "raw"));
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.transport')[0].dispatchEvent(event);
|
||||
switch (params.get("type")) {
|
||||
case "ws":
|
||||
if (params.get("security") !== "tls") {
|
||||
setElementValue('cbid.shadowsocksr.' + sid + '.ws_host', params.get("host") ? decodeURIComponent(params.get("host")) : "");
|
||||
}
|
||||
setElementValue('cbid.shadowsocksr.' + sid + '.ws_path', params.get("path") ? decodeURIComponent(params.get("path")) : "/");
|
||||
break;
|
||||
case "httpupgrade":
|
||||
if (params.get("security") !== "tls") {
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.httpupgrade_host')[0].value = params.get("host") ? decodeURIComponent(params.get("host")) : "";
|
||||
}
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.httpupgrade_path')[0].value = params.get("path") ? decodeURIComponent(params.get("path")) : "/";
|
||||
break;
|
||||
case "splithttp":
|
||||
if (params.get("security") !== "tls") {
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.splithttp_host')[0].value = params.get("host") ? decodeURIComponent(params.get("host")) : "";
|
||||
}
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.splithttp_path')[0].value = params.get("path") ? decodeURIComponent(params.get("path")) : "/";
|
||||
break;
|
||||
case "kcp":
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.kcp_guise')[0].value = params.get("headerType") || "none";
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.seed')[0].value = params.get("seed") || "";
|
||||
break;
|
||||
case "http":
|
||||
/* this is non-standard, bullshit */
|
||||
case "h2":
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.h2_host')[0].value = params.get("host") ? decodeURIComponent(params.get("host")) : "";
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.h2_path')[0].value = params.get("path") ? decodeURIComponent(params.get("path")) : "";
|
||||
break;
|
||||
case "quic":
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.quic_guise')[0].value = params.get("headerType") || "none";
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.quic_security')[0].value = params.get("quicSecurity") || "none";
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.quic_key')[0].value = params.get("key") || "";
|
||||
break;
|
||||
case "grpc":
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.serviceName')[0].value = params.get("serviceName") || "";
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.grpc_mode')[0].value = params.get("mode") || "gun";
|
||||
break;
|
||||
case "raw":
|
||||
case "tcp":
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tcp_guise')[0].value = params.get("headerType") || "none";
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tcp_guise')[0].dispatchEvent(event);
|
||||
if (params.get("headerType") === "http") {
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.http_host')[0].value = params.get("host") ? decodeURIComponent(params.get("host")) : "";
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.http_path')[0].value = params.get("path") ? decodeURIComponent(params.get("path")) : "";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
s.innerHTML = "<font style=\'color:green\'><%:Import configuration information successfully.%></font>";
|
||||
return false;
|
||||
@ -306,7 +365,7 @@ function import_ssr_url(btn, urlname, sid) {
|
||||
var url = new URL("http://" + ssu[1]);
|
||||
var params = url.searchParams;
|
||||
} catch(e) {
|
||||
alert(e)
|
||||
alert(e);
|
||||
return false;
|
||||
}
|
||||
// Check if the elements exist before trying to modify them
|
||||
@ -336,7 +395,7 @@ function import_ssr_url(btn, urlname, sid) {
|
||||
setElementValue('cbid.shadowsocksr.' + sid + '.vmess_id', url.username);
|
||||
setElementValue('cbid.shadowsocksr.' + sid + '.transport',
|
||||
params.get("type") === "http" ? "h2" :
|
||||
(["tcp", "raw"].includes(params.get("type")) ? "raw" :
|
||||
(["tcp", "raw"].includes(params.get("type")) ? "raw" :
|
||||
(params.get("type") || "tcp"))
|
||||
);
|
||||
dispatchEventIfExists('cbid.shadowsocksr.' + sid + '.transport', event);
|
||||
|
@ -91,6 +91,8 @@ msgstr "TLS 主机名"
|
||||
msgid "allowInsecure"
|
||||
msgstr "允许不安全连接"
|
||||
|
||||
msgid "Enabling MPTCP Requires Server Support."
|
||||
msgstr "启用 MPTCP 需服务端支持。"
|
||||
|
||||
msgid "concurrency"
|
||||
msgstr "TCP 最大并发连接数"
|
||||
@ -377,6 +379,12 @@ msgstr "强制走代理"
|
||||
msgid "UDP Relay"
|
||||
msgstr "UDP 中继"
|
||||
|
||||
msgid "Restart ShadowSocksR Plus+"
|
||||
msgstr "重启 ShadowSocksR Plus+"
|
||||
|
||||
msgid "Restart Service"
|
||||
msgstr "重启服务"
|
||||
|
||||
msgid "Google Connectivity"
|
||||
msgstr "【谷歌】连通性检查"
|
||||
|
||||
@ -1168,3 +1176,45 @@ msgstr "socks5 服务器可以从外部接收的最大数据包大小(单位
|
||||
|
||||
msgid "Disable ChinaDNS-NG"
|
||||
msgstr "直通模式(禁用 ChinaDNS-NG)"
|
||||
|
||||
msgid "Clear logs"
|
||||
msgstr "清空日志"
|
||||
|
||||
msgid "Backup and Restore"
|
||||
msgstr "备份还原"
|
||||
|
||||
msgid "Backup or Restore Client and Server Configurations."
|
||||
msgstr "备份或还原客户端及服务端配置。"
|
||||
|
||||
msgid "Note: Restoring configurations across different versions may cause compatibility issues."
|
||||
msgstr "注意:不同版本间的配置恢复可能会导致兼容性问题。"
|
||||
|
||||
msgid "Create Backup File"
|
||||
msgstr "创建备份文件"
|
||||
|
||||
msgid "Restore Backup File"
|
||||
msgstr "恢复备份文件"
|
||||
|
||||
msgid "DL Backup"
|
||||
msgstr "下载备份"
|
||||
|
||||
msgid "RST Backup"
|
||||
msgstr "恢复备份"
|
||||
|
||||
msgid "UL Restore"
|
||||
msgstr "上传恢复"
|
||||
|
||||
msgid "CLOSE WIN"
|
||||
msgstr "关闭窗口"
|
||||
|
||||
msgid "Restore to default configuration"
|
||||
msgstr "恢复默认配置"
|
||||
|
||||
msgid "Do Reset"
|
||||
msgstr "执行重置"
|
||||
|
||||
msgid "Do you want to restore the client to default settings?"
|
||||
msgstr "是否要恢复客户端默认配置?"
|
||||
|
||||
msgid "Are you sure you want to restore the client to default settings?"
|
||||
msgstr "是否真的要恢复客户端默认配置?"
|
||||
|
@ -283,8 +283,9 @@ end
|
||||
initial_windows_size = tonumber(server.initial_windows_size) or nil
|
||||
} or nil,
|
||||
sockopt = {
|
||||
tcpMptcp = (server.mptcp == "1") and true or false, -- MPTCP
|
||||
tcpNoDelay = (server.mptcp == "1") and true or false, -- MPTCP
|
||||
mark = 250,
|
||||
tcpMptcp = (server.mptcp == "1") and true or nil, -- MPTCP
|
||||
tcpNoDelay = (server.mptcp == "1") and true or nil, -- MPTCP
|
||||
tcpcongestion = server.custom_tcpcongestion, -- 连接服务器节点的 TCP 拥塞控制算法
|
||||
dialerProxy = (xray_fragment.fragment == "1" or xray_fragment.noise == "1") and "dialerproxy" or nil
|
||||
}
|
||||
@ -321,8 +322,10 @@ if xray_fragment.fragment ~= "0" or (xray_fragment.noise ~= "0" and xray_noise.e
|
||||
},
|
||||
streamSettings = {
|
||||
sockopt = {
|
||||
tcpMptcp = (server.mptcp == "1") and true or false, -- MPTCP
|
||||
tcpNoDelay = (server.mptcp == "1") and true or false -- MPTCP
|
||||
mark = 250,
|
||||
tcpMptcp = (server.mptcp == "1") and true or nil, -- MPTCP
|
||||
tcpNoDelay = (server.mptcp == "1") and true or nil, -- MPTCP
|
||||
tcpcongestion = server.custom_tcpcongestion -- 连接服务器节点的 TCP 拥塞控制算法
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -319,6 +319,7 @@ local function processData(szType, content)
|
||||
result.server = nil
|
||||
end
|
||||
elseif szType == "trojan" then
|
||||
local params = {}
|
||||
local idx_sp = 0
|
||||
local alias = ""
|
||||
if content:find("#") then
|
||||
@ -327,20 +328,27 @@ local function processData(szType, content)
|
||||
end
|
||||
local info = content:sub(1, idx_sp - 1)
|
||||
local hostInfo = split(info, "@")
|
||||
local host = split(hostInfo[2], ":")
|
||||
local userinfo = hostInfo[1]
|
||||
local password = userinfo
|
||||
|
||||
-- 分离服务器地址和端口
|
||||
local host = split(hostInfo[2], ":")
|
||||
local server = host[1]
|
||||
local port = host[2]
|
||||
|
||||
result.alias = UrlDecode(alias)
|
||||
result.type = v2_tj
|
||||
result.v2ray_protocol = "trojan"
|
||||
result.server = host[1]
|
||||
result.server = server
|
||||
result.password = password
|
||||
|
||||
-- 按照官方的建议 默认验证ssl证书
|
||||
result.insecure = "0"
|
||||
result.tls = "1"
|
||||
if host[2]:find("?") then
|
||||
local query = split(host[2], "?")
|
||||
|
||||
if port:find("?") then
|
||||
local query = split(port, "?")
|
||||
result.server_port = query[1]
|
||||
local params = {}
|
||||
for _, v in pairs(split(query[2], '&')) do
|
||||
local t = split(v, '=')
|
||||
params[t[1]] = t[2]
|
||||
@ -349,10 +357,62 @@ local function processData(szType, content)
|
||||
-- 未指定peer(sni)默认使用remote addr
|
||||
result.tls_host = params.sni
|
||||
end
|
||||
|
||||
if params.allowInsecure then
|
||||
-- 处理 insecure 参数
|
||||
result.insecure = params.allowInsecure
|
||||
end
|
||||
else
|
||||
result.server_port = host[2]
|
||||
result.server_port = port
|
||||
end
|
||||
|
||||
if v2_tj ~= "trojan" then
|
||||
if params.fp then
|
||||
-- 处理 fingerprint 参数
|
||||
result.fingerprint = params.fp
|
||||
end
|
||||
-- 处理传输协议
|
||||
result.transport = params.type or "tcp" -- 默认传输协议为 tcp
|
||||
if result.transport == "tcp" then
|
||||
result.transport = "raw"
|
||||
end
|
||||
if result.transport == "ws" then
|
||||
result.ws_host = (result.tls ~= "1") and (params.host and UrlDecode(params.host)) or nil
|
||||
result.ws_path = params.path and UrlDecode(params.path) or "/"
|
||||
elseif result.transport == "httpupgrade" then
|
||||
result.httpupgrade_host = (result.tls ~= "1") and (params.host and UrlDecode(params.host)) or nil
|
||||
result.httpupgrade_path = params.path and UrlDecode(params.path) or "/"
|
||||
elseif result.transport == "splithttp" then
|
||||
result.splithttp_host = (result.tls ~= "1") and (params.host and UrlDecode(params.host)) or nil
|
||||
result.splithttp_path = params.path and UrlDecode(params.path) or "/"
|
||||
elseif result.transport == "http" or result.transport == "h2" then
|
||||
result.transport = "h2"
|
||||
result.h2_host = params.host and UrlDecode(params.host) or nil
|
||||
result.h2_path = params.path and UrlDecode(params.path) or nil
|
||||
elseif result.transport == "kcp" then
|
||||
result.kcp_guise = params.headerType or "none"
|
||||
result.seed = params.seed
|
||||
result.mtu = 1350
|
||||
result.tti = 50
|
||||
result.uplink_capacity = 5
|
||||
result.downlink_capacity = 20
|
||||
result.read_buffer_size = 2
|
||||
result.write_buffer_size = 2
|
||||
elseif result.transport == "quic" then
|
||||
result.quic_guise = params.headerType or "none"
|
||||
result.quic_security = params.quicSecurity or "none"
|
||||
result.quic_key = params.key
|
||||
elseif result.transport == "grpc" then
|
||||
result.serviceName = params.serviceName
|
||||
result.grpc_mode = params.mode or "gun"
|
||||
elseif result.transport == "tcp" or result.transport == "raw" then
|
||||
result.tcp_guise = params.headerType and params.headerType ~= "" and params.headerType or "none"
|
||||
if result.tcp_guise == "http" then
|
||||
result.tcp_host = params.host and UrlDecode(params.host) or nil
|
||||
result.tcp_path = params.path and UrlDecode(params.path) or nil
|
||||
end
|
||||
end
|
||||
end
|
||||
result.password = password
|
||||
elseif szType == "vless" then
|
||||
local url = URL.parse("http://" .. content)
|
||||
local params = url.query
|
||||
|
Loading…
Reference in New Issue
Block a user