diff --git a/luci-app-openclawmgr/Makefile b/luci-app-openclawmgr/Makefile
index b51829eb5..66d9dba65 100644
--- a/luci-app-openclawmgr/Makefile
+++ b/luci-app-openclawmgr/Makefile
@@ -1,8 +1,8 @@
include $(TOPDIR)/rules.mk
-PKG_VERSION:=0.1.6
-PKG_RELEASE:=7
+PKG_VERSION:=0.1.7
+PKG_RELEASE:=8
LUCI_TITLE:=LuCI support for OpenClaw Launcher
LUCI_PKGARCH:=all
diff --git a/luci-app-openclawmgr/htdocs/luci-static/resources/openclawmgr/app.css b/luci-app-openclawmgr/htdocs/luci-static/resources/openclawmgr/app.css
index 826a8540c..da0ffdc57 100644
--- a/luci-app-openclawmgr/htdocs/luci-static/resources/openclawmgr/app.css
+++ b/luci-app-openclawmgr/htdocs/luci-static/resources/openclawmgr/app.css
@@ -282,6 +282,19 @@
filter: brightness(1.03);
}
+.oclm-button-community {
+ background: linear-gradient(180deg, #8b5cf6, #7c3aed);
+ color: #fff;
+ border-color: transparent;
+ box-shadow: 0 8px 18px rgba(124, 58, 237, 0.24);
+}
+
+.oclm-button-community:hover {
+ color: #fff;
+ filter: brightness(1.05);
+ box-shadow: 0 10px 22px rgba(124, 58, 237, 0.3);
+}
+
.oclm-button-danger {
color: #fff;
background: linear-gradient(180deg, #ff5d6d, #ef4444);
diff --git a/luci-app-openclawmgr/htdocs/luci-static/resources/openclawmgr/app.js b/luci-app-openclawmgr/htdocs/luci-static/resources/openclawmgr/app.js
index 60b256313..ee8cc459a 100644
--- a/luci-app-openclawmgr/htdocs/luci-static/resources/openclawmgr/app.js
+++ b/luci-app-openclawmgr/htdocs/luci-static/resources/openclawmgr/app.js
@@ -39,7 +39,16 @@
lastTaskRunning: false,
taskLogOpenTs: 0,
consoleReady: false,
- consoleCheckTimer: null
+ consoleCheckTimer: null,
+ updateCheck: {
+ checking: false,
+ checked: false,
+ hasUpdate: false,
+ upgrading: false,
+ localVersion: "",
+ remoteVersion: "",
+ error: ""
+ }
};
var styleText = "";
@@ -127,7 +136,7 @@
}
function statusText(status) {
- if (status.installing) return "安装中";
+ if (status.installing) return status.task_op === "upgrade" ? "更新中" : "安装中";
if (!status || !status.installed) return "未安装";
if (status.running) return "运行中";
if (status.reachable) return "运行中(未托管)";
@@ -164,6 +173,52 @@
});
}
+ function getUpdateCheck() {
+ state.updateCheck = state.updateCheck || {
+ checking: false,
+ checked: false,
+ hasUpdate: false,
+ upgrading: false,
+ localVersion: "",
+ remoteVersion: "",
+ error: ""
+ };
+ return state.updateCheck;
+ }
+
+ function updateActionLabel(status) {
+ var updateCheck = getUpdateCheck();
+ if (updateCheck.upgrading || (status && status.installing && status.task_op === "upgrade")) return "更新中";
+ if (updateCheck.checking) return "检测中…";
+ if (updateCheck.hasUpdate) return "更新 OpenClaw";
+ return "检测更新";
+ }
+
+ function statusNoteText(status) {
+ var updateCheck = getUpdateCheck();
+ if (status && status.installing) {
+ return status.task_op === "upgrade"
+ ? "更新任务正在后台运行,可打开任务日志查看进度。"
+ : "安装任务正在后台运行,可打开任务日志查看进度。";
+ }
+ if (updateCheck.checking) {
+ return "正在检测远程版本,请稍候…";
+ }
+ if (updateCheck.upgrading) {
+ return "更新任务已提交,请稍候查看版本变化。";
+ }
+ if (updateCheck.error) {
+ return updateCheck.error;
+ }
+ if (updateCheck.checked && updateCheck.localVersion && updateCheck.remoteVersion) {
+ if (updateCheck.hasUpdate) {
+ return "发现新版本:本地 " + updateCheck.localVersion + ",远程 " + updateCheck.remoteVersion;
+ }
+ return "当前已是最新版:本地 " + updateCheck.localVersion + ",远程 " + updateCheck.remoteVersion;
+ }
+ return "";
+ }
+
function copyIcon(className) {
return '' +
'';
}
+ function communityIcon(className) {
+ return '' +
+ '';
+ }
+
function taskWindowAvailable() {
return !!(window.taskd && window.taskd.show_log);
}
@@ -375,14 +438,17 @@
'';
}).join("");
- var installLabel = status.installing ? "安装中" : "立即安装";
+ var updateCheck = getUpdateCheck();
+ var installLabel = status.installing ? (status.task_op === "upgrade" ? "更新中" : "安装中") : "立即安装";
var installAcceleratedChecked = form.install_accelerated == null ? true : form.install_accelerated === true;
- var showInstallAction = !status.installed || status.installing;
+ var showInstallAction = !status.installed;
+ var showUpdateAction = status.installed && !status.installing;
var showServiceActions = status.installed && !status.installing;
var activeTab = state.activeTab || "basic";
var savingBasic = state.savingSection === "basic";
var savingAi = state.savingSection === "ai";
var savingAccess = state.savingSection === "access";
+ var noteText = statusNoteText(status);
var canStartService = !status.running && !status.reachable;
var canStopService = !!status.running;
@@ -415,9 +481,11 @@
'' +
'' +
'' +
+ '' +
+ '' +
'' +
'' +
- '
安装任务正在后台运行,点击“安装中”可继续查看日志。
' +
+ '' + escapeHtml(noteText) + '
' +
'' +
'' +
@@ -555,19 +623,28 @@
var installInline = byId("oclm-install-inline");
var installBtn = byId("oclm-install-btn");
+ var updateBtn = byId("oclm-update-btn");
var cancelInstallBtn = byId("oclm-cancel-install");
var openConsoleBtn = byId("oclm-open-console");
var noteEl = byId("oclm-status-note");
+ var updateCheck = getUpdateCheck();
- var showInstallAction = !status.installed || status.installing;
+ var showInstallAction = !status.installed;
+ var showUpdateAction = !!(status.installed && !status.installing);
if (installInline) {
if (showInstallAction) installInline.classList.remove("oclm-hidden");
else installInline.classList.add("oclm-hidden");
}
if (installBtn) {
- installBtn.textContent = status.installing ? "安装中" : "立即安装";
+ installBtn.textContent = status.installing ? (status.task_op === "upgrade" ? "更新中" : "安装中") : "立即安装";
installBtn.disabled = !!status.installing;
}
+ if (updateBtn) {
+ updateBtn.textContent = updateActionLabel(status);
+ updateBtn.disabled = !!(updateCheck.checking || updateCheck.upgrading);
+ if (showUpdateAction) updateBtn.classList.remove("oclm-hidden");
+ else updateBtn.classList.add("oclm-hidden");
+ }
if (cancelInstallBtn) {
if (status.installing) cancelInstallBtn.classList.remove("oclm-hidden");
else cancelInstallBtn.classList.add("oclm-hidden");
@@ -579,7 +656,9 @@
openConsoleBtn.innerHTML = openclawIcon("oclm-button-icon") + (state.consoleReady ? "打开控制台" : "控制台准备中…");
}
if (noteEl) {
- if (status.installing) noteEl.classList.remove("oclm-hidden");
+ var noteText = statusNoteText(status);
+ noteEl.textContent = noteText;
+ if (noteText) noteEl.classList.remove("oclm-hidden");
else noteEl.classList.add("oclm-hidden");
}
@@ -796,6 +875,81 @@
};
});
+ Array.prototype.forEach.call(root.querySelectorAll("[data-update-action]"), function(el) {
+ el.onclick = function() {
+ var updateCheck = getUpdateCheck();
+ if (!state.status || !state.status.installed || state.status.installing) {
+ return;
+ }
+
+ if (updateCheck.hasUpdate) {
+ updateCheck.upgrading = true;
+ updateCheck.error = "";
+ state.status.installing = true;
+ state.status.task_running = true;
+ state.status.task_op = "upgrade";
+ render();
+ postForm(config.opUrl, { op: "upgrade" }).then(function(rv) {
+ if (!rv || !rv.ok) {
+ updateCheck.upgrading = false;
+ state.status.installing = false;
+ state.status.task_running = false;
+ state.status.task_op = "";
+ render();
+ if (rv && rv.busy && rv.running_task_id) {
+ showTaskLog(rv.running_task_id);
+ return;
+ }
+ window.alert((rv && rv.error) || "启动更新失败");
+ return;
+ }
+ state.lastTaskRunning = true;
+ showTaskLog((rv && (rv.running_task_id || rv.task_id)) || "openclawmgr");
+ scheduleStatusRefresh(10, 1000);
+ }).catch(function() {
+ updateCheck.upgrading = false;
+ state.status.installing = false;
+ state.status.task_running = false;
+ state.status.task_op = "";
+ render();
+ window.alert("启动更新失败");
+ });
+ return;
+ }
+
+ updateCheck.checking = true;
+ updateCheck.error = "";
+ render();
+ postForm(config.checkUpdateUrl, {}).then(function(rv) {
+ updateCheck.checking = false;
+ if (!rv || !rv.ok) {
+ updateCheck.checked = false;
+ updateCheck.hasUpdate = false;
+ updateCheck.error = (rv && rv.error) || "检测更新失败";
+ updateCheck.localVersion = String((rv && rv.local_version) || (state.status && state.status.openclaw_version) || "");
+ updateCheck.remoteVersion = String((rv && rv.remote_version) || "");
+ render();
+ window.alert(updateCheck.error);
+ return;
+ }
+ updateCheck.checked = true;
+ updateCheck.hasUpdate = !!rv.has_update;
+ updateCheck.upgrading = false;
+ updateCheck.error = "";
+ updateCheck.localVersion = String(rv.local_version || (state.status && state.status.openclaw_version) || "");
+ updateCheck.remoteVersion = String(rv.remote_version || "");
+ render();
+ }).catch(function() {
+ updateCheck.checking = false;
+ updateCheck.checked = false;
+ updateCheck.hasUpdate = false;
+ updateCheck.error = "检测更新失败";
+ render();
+ window.alert("检测更新失败");
+ });
+ };
+ });
+
Array.prototype.forEach.call(root.querySelectorAll("[data-toggle-password]"), function(el) {
el.onclick = function() {
var id = el.getAttribute("data-toggle-password");
@@ -987,6 +1141,24 @@
function refreshStatus(done) {
request(config.statusUrl).then(function(data) {
state.status = data || {};
+ var updateCheck = getUpdateCheck();
+ if (state.status && state.status.openclaw_version) {
+ updateCheck.localVersion = String(state.status.openclaw_version || "");
+ }
+ if (!state.status || !state.status.installed) {
+ updateCheck.upgrading = false;
+ updateCheck.hasUpdate = false;
+ updateCheck.checked = false;
+ } else if (state.status.installing && state.status.task_op === "upgrade") {
+ updateCheck.upgrading = true;
+ } else if (!state.status.installing) {
+ updateCheck.upgrading = false;
+ if (updateCheck.remoteVersion && updateCheck.localVersion && updateCheck.remoteVersion === updateCheck.localVersion) {
+ updateCheck.hasUpdate = false;
+ updateCheck.checked = true;
+ updateCheck.error = "";
+ }
+ }
if (state.status && (state.status.running || state.status.reachable)) {
if (!state.consoleReady) {
pollConsoleReady(20);
diff --git a/luci-app-openclawmgr/luasrc/controller/openclawmgr.lua b/luci-app-openclawmgr/luasrc/controller/openclawmgr.lua
index 64def85c4..1f08e6316 100644
--- a/luci-app-openclawmgr/luasrc/controller/openclawmgr.lua
+++ b/luci-app-openclawmgr/luasrc/controller/openclawmgr.lua
@@ -16,6 +16,7 @@ function index()
entry({"admin", "services", "openclawmgr", "status"}, call("action_status")).leaf = true
entry({"admin", "services", "openclawmgr", "ready"}, call("action_ready")).leaf = true
entry({"admin", "services", "openclawmgr", "op"}, call("action_op")).leaf = true
+ entry({"admin", "services", "openclawmgr", "check_update"}, call("action_check_update")).leaf = true
entry({"admin", "services", "openclawmgr", "config_data"}, call("action_config_data")).leaf = true
entry({"admin", "services", "openclawmgr", "apply_config"}, call("action_apply_config")).leaf = true
@@ -157,6 +158,78 @@ local function safe_int(v, def, minv, maxv)
return n
end
+local function trim(v)
+ return tostring(v or ""):gsub("^%s+", ""):gsub("%s+$", "")
+end
+
+local function split_dots(v)
+ local parts = {}
+ for part in tostring(v or ""):gmatch("[^%.]+") do
+ parts[#parts + 1] = part
+ end
+ return parts
+end
+
+local function semver_compare(a, b)
+ a = trim(a):gsub("^v", "")
+ b = trim(b):gsub("^v", "")
+ if a == "" or b == "" then
+ return nil
+ end
+
+ local a_core, a_pre = a:match("^([^%-]+)%-?(.*)$")
+ local b_core, b_pre = b:match("^([^%-]+)%-?(.*)$")
+ local a_nums = split_dots(a_core)
+ local b_nums = split_dots(b_core)
+ local max_len = math.max(#a_nums, #b_nums)
+
+ for i = 1, max_len do
+ local av = tonumber(a_nums[i] or "0") or 0
+ local bv = tonumber(b_nums[i] or "0") or 0
+ if av ~= bv then
+ return av > bv and 1 or -1
+ end
+ end
+
+ a_pre = trim(a_pre)
+ b_pre = trim(b_pre)
+ if a_pre == "" and b_pre == "" then
+ return 0
+ end
+ if a_pre == "" then
+ return 1
+ end
+ if b_pre == "" then
+ return -1
+ end
+
+ local a_ids = split_dots(a_pre)
+ local b_ids = split_dots(b_pre)
+ max_len = math.max(#a_ids, #b_ids)
+ for i = 1, max_len do
+ local ai = a_ids[i]
+ local bi = b_ids[i]
+ if ai == nil then return -1 end
+ if bi == nil then return 1 end
+
+ local an = tonumber(ai)
+ local bn = tonumber(bi)
+ if an and bn then
+ if an ~= bn then
+ return an > bn and 1 or -1
+ end
+ elseif an and not bn then
+ return -1
+ elseif not an and bn then
+ return 1
+ elseif ai ~= bi then
+ return ai > bi and 1 or -1
+ end
+ end
+
+ return 0
+end
+
local function require_csrf()
local http = require "luci.http"
local disp = require "luci.dispatcher"
@@ -494,6 +567,59 @@ function action_ready()
})
end
+function action_check_update()
+ local sys = require "luci.sys"
+ local uci = require "luci.model.uci".cursor()
+
+ if not require_csrf() then
+ return
+ end
+
+ local base_dir = uci:get("openclawmgr", "main", "base_dir") or ""
+ if trim(base_dir) == "" then
+ write_json({ ok = false, error = "请先配置数据目录" })
+ return
+ end
+
+ local st = trim(sys.exec("/usr/libexec/istorec/openclawmgr.sh status 2>/dev/null"))
+ local installed = (st == "running" or st == "stopped")
+ if not installed then
+ write_json({ ok = false, error = "OpenClaw 尚未安装", installed = false })
+ return
+ end
+
+ local local_ver = trim(sys.exec("/usr/libexec/istorec/openclawmgr.sh local_openclaw_version 2>/dev/null"))
+ if local_ver == "" then
+ local_ver = trim(sys.exec("/usr/libexec/istorec/openclawmgr.sh openclaw_version 2>/dev/null"))
+ end
+ if local_ver == "" then
+ write_json({ ok = false, error = "获取本地版本失败", installed = true })
+ return
+ end
+
+ local remote_ver = trim(sys.exec("/usr/libexec/istorec/openclawmgr.sh latest_openclaw_version 2>/dev/null"))
+ if remote_ver == "" then
+ write_json({ ok = false, error = "获取远程版本失败", installed = true, local_version = local_ver })
+ return
+ end
+
+ local cmp = semver_compare(remote_ver, local_ver)
+ local has_update = false
+ if cmp == nil then
+ has_update = remote_ver ~= local_ver
+ else
+ has_update = cmp > 0
+ end
+
+ write_json({
+ ok = true,
+ installed = true,
+ local_version = local_ver,
+ remote_version = remote_ver,
+ has_update = has_update,
+ })
+end
+
function action_apply_config()
local sys = require "luci.sys"
diff --git a/luci-app-openclawmgr/luasrc/view/openclawmgr/app.htm b/luci-app-openclawmgr/luasrc/view/openclawmgr/app.htm
index 080f5071b..d97b31a57 100644
--- a/luci-app-openclawmgr/luasrc/view/openclawmgr/app.htm
+++ b/luci-app-openclawmgr/luasrc/view/openclawmgr/app.htm
@@ -8,6 +8,7 @@
statusUrl: "<%=url('admin/services/openclawmgr/status')%>",
readyUrl: "<%=url('admin/services/openclawmgr/ready')%>",
opUrl: "<%=url('admin/services/openclawmgr/op')%>",
+ checkUpdateUrl: "<%=url('admin/services/openclawmgr/check_update')%>",
configUrl: "<%=url('admin/services/openclawmgr/config_data')%>",
applyUrl: "<%=url('admin/services/openclawmgr/apply_config')%>",
staticBase: "<%=resource%>/openclawmgr"
diff --git a/luci-app-openclawmgr/root/usr/libexec/istorec/openclawmgr.sh b/luci-app-openclawmgr/root/usr/libexec/istorec/openclawmgr.sh
index 399c462ed..93ff6fcfe 100755
--- a/luci-app-openclawmgr/root/usr/libexec/istorec/openclawmgr.sh
+++ b/luci-app-openclawmgr/root/usr/libexec/istorec/openclawmgr.sh
@@ -381,6 +381,31 @@ openclaw_version() {
sed -n 's/.*"version"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' "$pkg" 2>/dev/null | head -n 1
}
+local_openclaw_version() {
+ [ -x "$NPM_BIN" ] || return 0
+ HOME="$DATA_DIR" npm_config_cache="${BASE_DIR}/npm-cache" \
+ PATH="${NODE_DIR}/bin:/usr/sbin:/usr/bin:/sbin:/bin" \
+ "$NPM_BIN" list -g openclaw --prefix="$GLOBAL_DIR" --depth=0 --json 2>/dev/null \
+ | "$NODE_BIN" -e 'let s="";process.stdin.on("data",d=>s+=d);process.stdin.on("end",()=>{try{let o=JSON.parse(s||"{}");let v=o&&o.dependencies&&o.dependencies.openclaw&&o.dependencies.openclaw.version;if(v)process.stdout.write(String(v));}catch(_){}})'
+}
+
+latest_openclaw_version() {
+ local npm_registry=""
+ [ -x "$NPM_BIN" ] || return 0
+ if [ "${INSTALL_ACCELERATED:-1}" = "1" ]; then
+ npm_registry="https://registry.npmmirror.com"
+ fi
+ if [ -n "$npm_registry" ]; then
+ HOME="$DATA_DIR" npm_config_cache="${BASE_DIR}/npm-cache" npm_config_registry="$npm_registry" \
+ PATH="${NODE_DIR}/bin:/usr/sbin:/usr/bin:/sbin:/bin" \
+ "$NPM_BIN" view openclaw version 2>/dev/null | tr -d '\r' | head -n 1
+ else
+ HOME="$DATA_DIR" npm_config_cache="${BASE_DIR}/npm-cache" \
+ PATH="${NODE_DIR}/bin:/usr/sbin:/usr/bin:/sbin:/bin" \
+ "$NPM_BIN" view openclaw version 2>/dev/null | tr -d '\r' | head -n 1
+ fi
+}
+
have_openclaw_runtime() {
[ -x "$NODE_BIN" ] || return 1
find_entry >/dev/null 2>&1 || return 1
@@ -921,6 +946,47 @@ install_openclaw() {
return 0
}
+upgrade_openclaw() {
+ local was_running=0
+ local st=""
+
+ if ! have_openclaw_runtime; then
+ write_installer_log "OpenClaw is not installed yet; fallback to fresh install."
+ install_openclaw
+ return $?
+ fi
+
+ st="$(do_status 2>/dev/null || true)"
+ if [ "$st" = "running" ]; then
+ was_running=1
+ write_installer_log "Stopping OpenClaw service before update"
+ /etc/init.d/openclawmgr stop >/dev/null 2>&1 || true
+ fi
+
+ write_installer_log "Updating OpenClaw via npm"
+ write_installer_log "Current version: $(openclaw_version || echo unknown)"
+ if ! install_openclaw; then
+ write_installer_log "npm update failed"
+ if [ "$was_running" = "1" ] || [ "${ENABLED:-0}" = "1" ]; then
+ write_installer_log "Trying to restore service after failed update"
+ /etc/init.d/openclawmgr start >/dev/null 2>&1 || true
+ fi
+ return 1
+ fi
+
+ ensure_gateway_config || true
+ fix_data_permissions || true
+
+ if [ "$was_running" = "1" ] || [ "${ENABLED:-0}" = "1" ]; then
+ ensure_safe_port_for_start || return 1
+ write_installer_log "Restarting OpenClaw service after update"
+ /etc/init.d/openclawmgr restart >/dev/null 2>&1 || /etc/init.d/openclawmgr start >/dev/null 2>&1 || true
+ fi
+
+ write_installer_log "OpenClaw updated: $(openclaw_version || echo unknown)"
+ return 0
+}
+
do_install() {
acquire_lock
write_installer_log "== install begin =="
@@ -938,6 +1004,11 @@ install_openclaw() {
ensure_gateway_config || true
if have_openclaw_runtime; then
+ if [ "$ACTION" = "upgrade" ]; then
+ write_installer_log "OpenClaw is already installed: $(openclaw_version || echo unknown)"
+ upgrade_openclaw
+ return $?
+ fi
write_installer_log "OpenClaw is already installed: $(openclaw_version || echo unknown)"
write_installer_log "Skip install. Use restart/apply config if you only need to refresh configuration."
return 0
@@ -1325,6 +1396,12 @@ case "$ACTION" in
openclaw_version)
openclaw_version
;;
+ local_openclaw_version)
+ local_openclaw_version
+ ;;
+ latest_openclaw_version)
+ latest_openclaw_version
+ ;;
diag)
diag_run "${1:-}" "${2:-}"
;;
@@ -1332,7 +1409,7 @@ case "$ACTION" in
diag_poll "${1:-}"
;;
*)
- echo "Usage: $0 {install|upgrade|uninstall|uninstall_openclaw|purge|rm|start|stop|restart|status|port|token|node_version|openclaw_version|diag|diag_poll}" >&2
+ echo "Usage: $0 {install|upgrade|uninstall|uninstall_openclaw|purge|rm|start|stop|restart|status|port|token|node_version|openclaw_version|local_openclaw_version|latest_openclaw_version|diag|diag_poll}" >&2
exit 1
;;
esac
diff --git a/luci-app-passwall/luasrc/controller/passwall.lua b/luci-app-passwall/luasrc/controller/passwall.lua
index 915b25c18..37af41b70 100644
--- a/luci-app-passwall/luasrc/controller/passwall.lua
+++ b/luci-app-passwall/luasrc/controller/passwall.lua
@@ -540,17 +540,11 @@ function copy_node()
local uuid = api.gen_short_uuid()
uci:section(appname, "nodes", uuid)
for k, v in pairs(uci:get_all(appname, section)) do
- local filter = k:find("%.")
- if filter and filter == 1 then
- else
- xpcall(function()
- uci:set(appname, uuid, k, v)
- end,
- function(e)
- end)
+ if not k:match("^%.") and k ~= "group" then
+ if k == "remarks" then v = (v or "") .. "(1)" end
+ uci:set(appname, uuid, k, v)
end
end
- uci:delete(appname, uuid, "group")
uci:set(appname, uuid, "add_mode", 1)
api.uci_save(uci, appname)
http.redirect(api.url("node_config", uuid))
diff --git a/mtproxy/Makefile b/mtproxy/Makefile
index 8c0f8695a..24f210b2f 100644
--- a/mtproxy/Makefile
+++ b/mtproxy/Makefile
@@ -1,8 +1,8 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=mtproxy
-PKG_VERSION:=3.4.0
-PKG_RELEASE:=9
+PKG_VERSION:=3.5.0
+PKG_RELEASE:=10
PKG_MAINTAINER:=Kosntantine Shevlakov
PKG_LICENSE:=GPLv2
@@ -10,7 +10,7 @@ PKG_LICENSE_FILES:=LICENSE
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/GetPageSpeed/MTProxy.git
-PKG_SOURCE_VERSION:=dbd89354dc8ef9f9c624afb9686fd3a0bc93f26b
+PKG_SOURCE_VERSION:=b18e84d21e8385e4df0e486fe45b0904947c5903
PKG_SOURCE_SUBDIR:=$(PKG_NAME)
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
diff --git a/v2ray-plugin/Makefile b/v2ray-plugin/Makefile
index 8abd32042..8fa962ad1 100644
--- a/v2ray-plugin/Makefile
+++ b/v2ray-plugin/Makefile
@@ -6,8 +6,8 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=v2ray-plugin
-PKG_VERSION:=5.46.0
-PKG_RELEASE:=1
+PKG_VERSION:=5.48.0
+PKG_RELEASE:=2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/teddysun/v2ray-plugin/tar.gz/v$(PKG_VERSION)?