mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-07-27 10:31:38 +08:00
🍓 Sync 2026-07-05 20:30:31
This commit is contained in:
parent
5378a4f7c1
commit
a4f37aefb9
@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=daed
|
||||
PKG_VERSION:=2026.06.14
|
||||
PKG_RELEASE:=17
|
||||
PKG_RELEASE:=18
|
||||
|
||||
PKG_SOURCE:=daed-src-2026.06.14-4e215048068a.tar.gz
|
||||
PKG_SOURCE_URL:=https://github.com/kenzok8/openwrt-daede/releases/download/daed-src
|
||||
@ -40,7 +40,7 @@ GO_PKG_LDFLAGS:= \
|
||||
GO_PKG_LDFLAGS_X:= \
|
||||
$(GO_PKG)/db.AppName=$(PKG_NAME) \
|
||||
$(GO_PKG)/db.AppVersion=$(PKG_VERSION)
|
||||
GO_PKG_TAGS:=embedallowed,trace
|
||||
GO_PKG_TAGS:=embedallowed,trace,timetzdata
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
include $(INCLUDE_DIR)/bpf.mk
|
||||
|
||||
@ -24,6 +24,7 @@ start_service() {
|
||||
|
||||
procd_open_instance "$CONF"
|
||||
procd_set_param env DAE_LOCATION_ASSET="/usr/share/v2ray"
|
||||
procd_set_param env TZ="$(uci -q get system.@system[0].zonename)"
|
||||
procd_set_param command "$PROG" run
|
||||
procd_append_param command --config "/etc/daed/"
|
||||
procd_append_param command --listen "$listen_addr"
|
||||
|
||||
@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-daede
|
||||
PKG_VERSION:=1.14.7
|
||||
PKG_RELEASE:=27
|
||||
PKG_RELEASE:=28
|
||||
PKG_MAINTAINER:=kenzok8
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
|
||||
|
||||
|
||||
@ -662,6 +662,7 @@ return view.extend({
|
||||
let before;
|
||||
let newSubId = '';
|
||||
let createdGroupId = '';
|
||||
const createdNodeIds = [];
|
||||
let groupReady = false;
|
||||
const oldSubId = existingAirport ? existingAirport.subscription_id : '';
|
||||
const oldNodeIds = existingAirport ? existingAirport.node_ids : [];
|
||||
@ -671,7 +672,113 @@ return view.extend({
|
||||
return requestDaedToken(endpoint, forceLogin).then(function(auth) {
|
||||
token = auth.token;
|
||||
usedCachedToken = auth.cached;
|
||||
return graphQL(endpoint, 'query State{groups{id name nodes{id}}}', {}, token);
|
||||
return graphQL(endpoint, 'query State{nodes(first:10000){edges{id link tag}} groups{id name nodes{id}}}', {}, token);
|
||||
});
|
||||
};
|
||||
const importDirectNodes = function() {
|
||||
const existing = {};
|
||||
(((before || {}).nodes || {}).edges || []).forEach(function(node) {
|
||||
existing[clashConverter.normalizeLink(node.link)] = node;
|
||||
});
|
||||
const fresh = items.filter(function(item) {
|
||||
const duplicate = existing[clashConverter.normalizeLink(item.link)];
|
||||
if (duplicate)
|
||||
item.duplicate = true;
|
||||
return !duplicate;
|
||||
});
|
||||
const imported = fresh.length
|
||||
? graphQL(endpoint,
|
||||
'mutation ImportNodes($args:[ImportArgument!]!){importNodes(rollbackError:false,args:$args){link error node{id}}}',
|
||||
{ args: fresh.map(function(item, index) { return { link: item.link, tag: airportSync.backendId(airportId) + Date.now().toString(36) + (index + 1) }; }) }, token)
|
||||
: Promise.resolve({ importNodes: [] });
|
||||
|
||||
return imported.then(function(result) {
|
||||
const rows = result.importNodes || [];
|
||||
const nodeIds = [];
|
||||
const ownedIds = [];
|
||||
const rowByLink = {};
|
||||
rows.forEach(function(row) {
|
||||
rowByLink[clashConverter.normalizeLink(row.link)] = row;
|
||||
});
|
||||
let failed = rows.filter(function(row) { return !!row.error && row.error !== 'node already exists'; }).length;
|
||||
items.forEach(function(item) {
|
||||
const key = clashConverter.normalizeLink(item.link);
|
||||
const row = rowByLink[key];
|
||||
const old = existing[key];
|
||||
const id = row && row.node && row.node.id || old && old.id;
|
||||
if (id)
|
||||
nodeIds.push(id);
|
||||
if (row && !row.error && row.node) {
|
||||
ownedIds.push(row.node.id);
|
||||
createdNodeIds.push(row.node.id);
|
||||
}
|
||||
else if (existingAirport && oldNodeIds.indexOf(id) >= 0)
|
||||
ownedIds.push(id);
|
||||
});
|
||||
if (!nodeIds.length) {
|
||||
const details = rows.filter(function(row) { return !!row.error; }).map(function(row) {
|
||||
return row.error;
|
||||
}).filter(function(error, index, errors) {
|
||||
return errors.indexOf(error) === index;
|
||||
}).join('; ');
|
||||
throw new Error(details || _('No usable nodes were imported'));
|
||||
}
|
||||
|
||||
const oldManagedGroup = airportSync.findManagedGroup(before.groups, existingAirport);
|
||||
const ensureGroup = oldManagedGroup
|
||||
? Promise.resolve(oldManagedGroup.id)
|
||||
: graphQL(endpoint,
|
||||
'mutation CreateGroup($name:String!,$policy:Policy!){createGroup(name:$name,policy:$policy){id}}',
|
||||
{ name: groupName, policy: 'min_moving_avg' }, token).then(function(value) {
|
||||
createdGroupId = value.createGroup.id;
|
||||
return createdGroupId;
|
||||
});
|
||||
return ensureGroup.then(function(groupId) {
|
||||
const rename = oldManagedGroup && oldManagedGroup.name !== groupName
|
||||
? graphQL(endpoint, 'mutation RenameGroup($id:ID!,$name:String!){renameGroup(id:$id,name:$name)}', { id: groupId, name: groupName }, token)
|
||||
: Promise.resolve();
|
||||
return rename.then(function() {
|
||||
return graphQL(endpoint, 'mutation SetPolicy($id:ID!,$policy:Policy!){groupSetPolicy(id:$id,policy:$policy)}', { id: groupId, policy: 'min_moving_avg' }, token);
|
||||
}).then(function() {
|
||||
return graphQL(endpoint, 'mutation AddNodes($id:ID!,$nodeIDs:[ID!]!){groupAddNodes(id:$id,nodeIDs:$nodeIDs)}', { id: groupId, nodeIDs: nodeIds }, token);
|
||||
}).then(function() {
|
||||
groupReady = true;
|
||||
const oldMembers = oldManagedGroup ? oldManagedGroup.nodes.map(function(node) { return node.id; }) : [];
|
||||
const removedMembers = oldMembers.filter(function(id) { return nodeIds.indexOf(id) < 0; });
|
||||
return (removedMembers.length
|
||||
? graphQL(endpoint, 'mutation DelNodes($id:ID!,$nodeIDs:[ID!]!){groupDelNodes(id:$id,nodeIDs:$nodeIDs)}', { id: groupId, nodeIDs: removedMembers }, token)
|
||||
: Promise.resolve()).catch(function() {
|
||||
failed++;
|
||||
}).then(function() {
|
||||
const otherAirportNodes = airportRecords().filter(function(record) {
|
||||
return record.backend === 'daed' && (!existingAirport || record.id !== existingAirport.id);
|
||||
}).map(function(record) { return record.node_ids; });
|
||||
const otherGroupNodes = before.groups.filter(function(other) {
|
||||
return other.id !== groupId;
|
||||
}).map(function(other) { return other.nodes.map(function(node) { return node.id; }); });
|
||||
const stale = airportSync.safeOldNodeIds(oldNodeIds, ownedIds, otherAirportNodes, otherGroupNodes);
|
||||
return (stale.length
|
||||
? graphQL(endpoint, 'mutation RemoveNodes($ids:[ID!]!){removeNodes(ids:$ids)}', { ids: stale }, token)
|
||||
: Promise.resolve()).catch(function() {
|
||||
failed++;
|
||||
}).then(function() {
|
||||
writeAirportRecord(existingAirport, {
|
||||
id: airportId,
|
||||
backend: 'daed',
|
||||
name: name,
|
||||
sourceHash: state.sourceHash,
|
||||
groupId: groupId,
|
||||
subscriptionId: '',
|
||||
nodeIds: ownedIds
|
||||
});
|
||||
return applyUciChanges().then(function() {
|
||||
items.forEach(function(item) { item.duplicate = true; item.selected = false; });
|
||||
return { added: ownedIds.length, duplicates: items.length - ownedIds.length, failed: failed };
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
@ -693,14 +800,35 @@ return view.extend({
|
||||
// import the whole converted batch as one subscription
|
||||
return graphQL(endpoint,
|
||||
'mutation Import($a:ImportArgument!){importSubscription(rollbackError:false,arg:$a){sub{id} nodeImportResult{error}}}',
|
||||
{ a: { link: subUrl, tag: groupName } }, token);
|
||||
{ a: { link: subUrl, tag: groupName } }, token).then(function(result) {
|
||||
const sub = result.importSubscription && result.importSubscription.sub;
|
||||
const rows = (result.importSubscription && result.importSubscription.nodeImportResult) || [];
|
||||
const usable = rows.length
|
||||
? rows.some(function(r) { return !r.error || r.error === 'node already exists'; })
|
||||
: !!(sub && sub.id);
|
||||
if (!sub || !sub.id || !usable) {
|
||||
const details = rows.map(function(r) { return r.error; }).filter(Boolean).join('; ');
|
||||
if (sub && sub.id)
|
||||
newSubId = sub.id;
|
||||
throw new Error(details || _('No usable nodes were imported'));
|
||||
}
|
||||
return result;
|
||||
}).catch(function(error) {
|
||||
if (daedSession.isAccessDenied(error))
|
||||
throw error;
|
||||
const cleanupSub = newSubId
|
||||
? graphQL(endpoint, 'mutation Rm($ids:[ID!]!){removeSubscriptions(ids:$ids)}', { ids: [ newSubId ] }, token).catch(function() {})
|
||||
: Promise.resolve();
|
||||
newSubId = '';
|
||||
return cleanupSub.then(importDirectNodes).then(function(result) {
|
||||
return { directResult: result };
|
||||
});
|
||||
});
|
||||
}).then(function(result) {
|
||||
if (result.directResult)
|
||||
return result.directResult;
|
||||
|
||||
const sub = result.importSubscription && result.importSubscription.sub;
|
||||
if (!sub || !sub.id) {
|
||||
const rows = (result.importSubscription && result.importSubscription.nodeImportResult) || [];
|
||||
const details = rows.map(function(r) { return r.error; }).filter(Boolean).join('; ');
|
||||
throw new Error(details || _('No usable nodes were imported'));
|
||||
}
|
||||
newSubId = sub.id;
|
||||
const rows = result.importSubscription.nodeImportResult || [];
|
||||
const failed = rows.filter(function(r) { return !!r.error && r.error !== 'node already exists'; }).length;
|
||||
@ -745,11 +873,13 @@ return view.extend({
|
||||
}).catch(function(error) {
|
||||
if (daedSession.isAccessDenied(error))
|
||||
daedSession.clear(window.localStorage);
|
||||
if (groupReady || !token || (!newSubId && !createdGroupId))
|
||||
if (groupReady || !token || (!newSubId && !createdGroupId && !createdNodeIds.length))
|
||||
throw error;
|
||||
const cleanup = [];
|
||||
if (newSubId)
|
||||
cleanup.push(graphQL(endpoint, 'mutation Rm($ids:[ID!]!){removeSubscriptions(ids:$ids)}', { ids: [ newSubId ] }, token));
|
||||
if (createdNodeIds.length)
|
||||
cleanup.push(graphQL(endpoint, 'mutation Rm($ids:[ID!]!){removeNodes(ids:$ids)}', { ids: createdNodeIds }, token));
|
||||
if (createdGroupId)
|
||||
cleanup.push(graphQL(endpoint, 'mutation RmG($id:ID!){removeGroup(id:$id)}', { id: createdGroupId }, token));
|
||||
return Promise.all(cleanup).catch(function() {}).then(function() { throw error; });
|
||||
|
||||
@ -17,6 +17,7 @@ const DEFAULT_TEMPLATE =
|
||||
'global {\n' +
|
||||
' tproxy_port: 12345\n' +
|
||||
' tproxy_port_protect: true\n' +
|
||||
' so_mark_from_dae: 0\n' +
|
||||
' log_level: info\n' +
|
||||
' lan_interface: br-lan\n' +
|
||||
' wan_interface: auto\n' +
|
||||
|
||||
@ -234,6 +234,7 @@ generate() {
|
||||
echo "global {"
|
||||
echo " tproxy_port: 12345"
|
||||
echo " tproxy_port_protect: true"
|
||||
echo " so_mark_from_dae: 0"
|
||||
echo " log_level: ${log_level}"
|
||||
[ -n "$lan_interface" ] && echo " lan_interface: ${lan_interface}"
|
||||
echo " wan_interface: ${wan_interface}"
|
||||
|
||||
@ -242,7 +242,6 @@ const proxy_group_type = [
|
||||
['fallback', _('Fallback')],
|
||||
['url-test', _('URL test')],
|
||||
['load-balance', _('Load balance')],
|
||||
//['relay', _('Relay')], // Deprecated
|
||||
];
|
||||
|
||||
const routing_port_type = [
|
||||
@ -1763,7 +1762,7 @@ function textvalue2Value(section_id) {
|
||||
let cval = this.cfgvalue(section_id);
|
||||
let i = this.keylist.indexOf(cval);
|
||||
|
||||
return this.vallist[i];
|
||||
return this.vallist[i] ?? cval;
|
||||
}
|
||||
|
||||
function validateAuth(section_id, value) {
|
||||
|
||||
@ -461,9 +461,6 @@ function renderListeners(s, uciconfig, isClient) {
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('field_general', form.ListValue, 'snell_version', _('Version'));
|
||||
o.value('1', _('v1'));
|
||||
o.value('2', _('v2'));
|
||||
o.value('3', _('v3'));
|
||||
o.value('4', _('v4'));
|
||||
o.value('5', _('v5'));
|
||||
o.default = '4';
|
||||
@ -562,21 +559,32 @@ function renderListeners(s, uciconfig, isClient) {
|
||||
o.value('obfs', _('obfs-simple'));
|
||||
o.value('shadow-tls', _('shadow-tls'));
|
||||
//o.value('kcp-tun', _('kcp-tun'));
|
||||
o.depends('type', 'shadowsocks');
|
||||
o.validate = function(section_id, value) {
|
||||
const type = this.section.getOption('type').formvalue(section_id);
|
||||
|
||||
if (value) {
|
||||
if (type === 'snell' && !['obfs', 'shadow-tls'].includes(value)) {
|
||||
return _('Expecting: only support %s.').format(_('obfs-simple') +
|
||||
' / ' + _('shadow-tls'));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
o.depends({type: /^(shadowsocks|snell)$/});
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('field_general', form.ListValue, 'plugin_opts_obfsmode', _('Plugin: ') + _('Obfs Mode'));
|
||||
o.value('http', _('HTTP'));
|
||||
o.value('tls', _('TLS'));
|
||||
o.depends('plugin', 'obfs');
|
||||
o.depends('type', 'snell');
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('field_general', form.Value, 'plugin_opts_host', _('Plugin: ') + _('Host that supports TLS 1.3'));
|
||||
o.datatype = 'hostname';
|
||||
o.placeholder = 'cloud.tencent.com';
|
||||
o.rmempty = false;
|
||||
o.depends('type', 'snell');
|
||||
o.depends({plugin: 'obfs', type: 'snell'});
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('field_general', form.Value, 'plugin_opts_handshake_dest', _('Plugin: ') + _('Handshake target that supports TLS 1.3'));
|
||||
|
||||
@ -13,7 +13,7 @@ const parseProxyGroupYaml = hm.parseYaml.extend({
|
||||
if (!cfg.type)
|
||||
return null;
|
||||
|
||||
// key mapping // 2026/06/10
|
||||
// key mapping // 2026/07/05
|
||||
let config = hm.removeBlankAttrs({
|
||||
id: this.id,
|
||||
label: this.label,
|
||||
@ -23,7 +23,9 @@ const parseProxyGroupYaml = hm.parseYaml.extend({
|
||||
include_all: this.bool2str(cfg["include-all"]), // bool
|
||||
include_all_proxies: this.bool2str(cfg["include-all-proxies"]), // bool
|
||||
include_all_providers: this.bool2str(cfg["include-all-providers"]), // bool
|
||||
empty_fallback: cfg["empty-fallback"] ? hm.preset_outbound.proxy.map(([key, label]) => key).includes(cfg["empty-fallback"]) ? cfg["empty-fallback"] : this.calcID(hm.glossary["proxy_group"].field, cfg["empty-fallback"]) : null, // string
|
||||
empty_fallback: cfg["empty-fallback"], // string
|
||||
// Select fields
|
||||
default_selected: cfg["default-selected"], // string
|
||||
// Url-test fields
|
||||
tolerance: cfg.tolerance,
|
||||
// Load-balance fields
|
||||
@ -683,10 +685,10 @@ function renderPayload(s, total, uciconfig) {
|
||||
initDynamicPayload(o, n, 'factor', uciconfig);
|
||||
o.load = L.bind(function(n, key, uciconfig, section_id) {
|
||||
let fusedval = [
|
||||
['NETWORK', '-- NETWORK --'],
|
||||
['NETWORK', _('-- NETWORK --')],
|
||||
['udp', _('UDP')],
|
||||
['tcp', _('TCP')],
|
||||
['RULESET', '-- RULE-SET --']
|
||||
['RULESET', _('-- RULE-SET --')]
|
||||
];
|
||||
|
||||
hm.loadLabel.call(this, [
|
||||
@ -1011,6 +1013,7 @@ return view.extend({
|
||||
'- name: AllProvider\n' +
|
||||
' type: select\n' +
|
||||
' include-all-providers: true\n' +
|
||||
' default-selected: proxy1\n' +
|
||||
' filter: "(?i)港|hk|hongkong|hong kong"\n' +
|
||||
' exclude-filter: "美|日"\n' +
|
||||
' exclude-type: "Shadowsocks|Http"\n' +
|
||||
@ -1133,6 +1136,7 @@ return view.extend({
|
||||
so.load = function(section_id) {
|
||||
return hm.loadLabel.call(this, [
|
||||
...hm.preset_outbound.proxy,
|
||||
['NODE', _('-- PROXY-NODE --')],
|
||||
...hm.loadLabelValues(this.config, 'node')
|
||||
], section_id);
|
||||
}
|
||||
@ -1189,6 +1193,23 @@ return view.extend({
|
||||
so.depends({type: 'select', '!reverse': true});
|
||||
so.modalonly = true;
|
||||
|
||||
/* Select fields */
|
||||
so = ss.taboption('field_general', form.Value, 'default_selected', _('Default selected'));
|
||||
hm.preset_outbound.proxy.forEach((res) => {
|
||||
so.value.apply(so, res);
|
||||
})
|
||||
so.load = function(section_id) {
|
||||
return hm.loadLabel.call(this, [
|
||||
...hm.preset_outbound.proxy,
|
||||
['GROUP', _('-- PROXY-GROUP --')],
|
||||
...hm.loadLabelValues(this.config, 'proxy_group'),
|
||||
['NODE', _('-- PROXY-NODE --')],
|
||||
...hm.loadLabelValues(this.config, 'node')
|
||||
], section_id);
|
||||
}
|
||||
so.depends('type', 'select');
|
||||
so.textvalue = hm.textvalue2Value;
|
||||
|
||||
/* Url-test fields */
|
||||
so = ss.taboption('field_general', form.Value, 'tolerance', _('Node switch tolerance'),
|
||||
_('In millisecond. <code>%s</code> will be used if empty.').format('150'));
|
||||
@ -1888,6 +1909,23 @@ return view.extend({
|
||||
so = ss.option(form.DynamicList, 'fallback_filter_domain', _('Domain'),
|
||||
_('Match domain. Support wildcards.</br>') +
|
||||
_('The matching <code>%s</code> will be deemed as poisoned.').format(_('Domain')));
|
||||
|
||||
so = ss.option(form.Flag, 'fallback_lazy_query', _('Lazy query'),
|
||||
_('Lazy query.'));
|
||||
so.default = so.disabled;
|
||||
so.validate = function(section_id, value) {
|
||||
let desc = this.getUIElement(section_id).node.nextSibling;
|
||||
value = this.formvalue(section_id);
|
||||
|
||||
if (value == 1)
|
||||
desc.innerHTML = _('Check the response from the <code>%s</code>, only initiate query if the <code>%s</code> is satisfied.')
|
||||
.format(_('Default DNS server'), _('Fallback filter'));
|
||||
else
|
||||
desc.innerHTML = _('Send queries to both the <code>%s</code> and the <code>%s</code>.')
|
||||
.format(_('Default DNS server'), _('Fallback DNS server'));
|
||||
|
||||
return true;
|
||||
}
|
||||
/* Fallback filter END */
|
||||
|
||||
return m.render();
|
||||
|
||||
@ -886,14 +886,25 @@ return view.extend({
|
||||
so.value('shadow-tls', _('shadow-tls'));
|
||||
so.value('restls', _('restls'));
|
||||
//so.value('kcptun', _('kcptun'));
|
||||
so.depends('type', 'ss');
|
||||
so.validate = function(section_id, value) {
|
||||
const type = this.section.getOption('type').formvalue(section_id);
|
||||
|
||||
if (value) {
|
||||
if (type === 'snell' && !['obfs', 'shadow-tls'].includes(value)) {
|
||||
return _('Expecting: only support %s.').format(_('obfs-simple') +
|
||||
' / ' + _('shadow-tls'));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
so.depends({type: /^(ss|snell)$/});
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.ListValue, 'plugin_opts_obfsmode', _('Plugin: ') + _('Obfs Mode'));
|
||||
so.value('http', _('HTTP'));
|
||||
so.value('tls', _('TLS'));
|
||||
so.depends('plugin', 'obfs');
|
||||
so.depends('type', 'snell');
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.Value, 'plugin_opts_host', _('Plugin: ') + _('Host that supports TLS 1.3'));
|
||||
@ -901,7 +912,6 @@ return view.extend({
|
||||
so.placeholder = 'cloud.tencent.com';
|
||||
so.rmempty = false;
|
||||
so.depends({plugin: /^(obfs|v2ray-plugin|shadow-tls|restls)$/});
|
||||
so.depends('type', 'snell');
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.Value, 'plugin_opts_thetlspassword', _('Plugin: ') + _('Password'));
|
||||
@ -949,6 +959,14 @@ return view.extend({
|
||||
so.depends({type: 'hysteria2'});
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.Value, 'handshake_timeout', _('Handshake timeout'),
|
||||
_('In seconds. After configuration, the handshake is not affected by the outer connection timeout.') + '</br>' +
|
||||
_('The default value is <code>%s</code>, indicating that only the outer connection timeout is used.').format('0'));
|
||||
so.datatype = 'uinteger';
|
||||
so.placeholder = '30';
|
||||
so.depends({type: /^(masque|openvpn)$/});
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.Flag, 'udp', _('UDP'));
|
||||
so.default = so.disabled;
|
||||
so.depends({type: /^(rematch|direct|socks5|ss|mieru|vmess|vless|trojan|anytls|trusttunnel|masque|wireguard)$/});
|
||||
@ -1114,6 +1132,7 @@ return view.extend({
|
||||
|
||||
switch (type) {
|
||||
case 'ss':
|
||||
case 'snell':
|
||||
def_alpn = ['h2', 'http/1.1']; // when plugin === 'shadow-tls'
|
||||
break;
|
||||
case 'hysteria':
|
||||
@ -1142,7 +1161,7 @@ return view.extend({
|
||||
return true;
|
||||
}
|
||||
so.depends({tls: '1', type: /^(vmess|vless|trojan|anytls|hysteria|hysteria2|tuic|trusttunnel)$/});
|
||||
so.depends({type: 'ss', plugin: 'shadow-tls'});
|
||||
so.depends({type: /^(ss|snell)$/, plugin: 'shadow-tls'});
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_tls', form.Value, 'tls_fingerprint', _('Cert fingerprint'),
|
||||
@ -1197,7 +1216,7 @@ return view.extend({
|
||||
so = ss.taboption('field_tls', form.Flag, 'tls_ech', _('Enable ECH'));
|
||||
so.default = so.disabled;
|
||||
so.depends({tls: '1', type: /^(vmess|vless|trojan|anytls|hysteria|hysteria2|tuic)$/});
|
||||
so.depends({type: 'ss', plugin: /^(shadow-tls|restls)$/});
|
||||
so.depends({type: 'ss', plugin: /^(v2ray-plugin|gost-plugin)$/});
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_tls', form.Value, 'tls_ech_config', _('ECH config'),
|
||||
@ -1218,7 +1237,7 @@ return view.extend({
|
||||
so.value.apply(so, res);
|
||||
})
|
||||
so.depends({tls: '1', type: /^(vmess|vless|trojan|anytls|trusttunnel)$/});
|
||||
so.depends({type: 'ss', plugin: /^(shadow-tls|restls)$/});
|
||||
so.depends({type: /^(ss|snell)$/, plugin: /^(shadow-tls|restls)$/});
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_tls', form.Flag, 'tls_reality', _('REALITY'));
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -121,7 +121,7 @@ function parse_filter(cfg) {
|
||||
return cfg;
|
||||
}
|
||||
|
||||
function get_proxy(cfg) {
|
||||
function get_proxy(cfg, pass_undefined) {
|
||||
if (isEmpty(cfg))
|
||||
return null;
|
||||
|
||||
@ -129,9 +129,12 @@ function get_proxy(cfg) {
|
||||
return cfg;
|
||||
|
||||
const label = uci.get(uciconf, cfg, 'label');
|
||||
if (isEmpty(label))
|
||||
die(sprintf("%s's label is missing, please check your configuration.", cfg));
|
||||
else
|
||||
if (isEmpty(label)) {
|
||||
if (pass_undefined)
|
||||
return cfg;
|
||||
else
|
||||
die(sprintf("%s's label is missing, please check your configuration.", cfg));
|
||||
} else
|
||||
return label;
|
||||
}
|
||||
|
||||
@ -440,6 +443,7 @@ if (!isEmpty(config.dns.fallback))
|
||||
ipcidr: uci.get(uciconf, ucidns, 'fallback_filter_ipcidr') || [],
|
||||
domain: uci.get(uciconf, ucidns, 'fallback_filter_domain') || [],
|
||||
};
|
||||
config.dns["fallback-lazy-query"] = strToBool(uci.get(uciconf, ucidns, 'fallback_lazy_query'));
|
||||
/* DNS END */
|
||||
|
||||
/* Hosts START */
|
||||
@ -559,10 +563,6 @@ uci.foreach(uciconf, ucinode, (cfg) => {
|
||||
psk: cfg.snell_psk,
|
||||
version: cfg.snell_version,
|
||||
reuse: strToBool(cfg.snell_reuse),
|
||||
"obfs-opts": cfg.type === 'snell' ? {
|
||||
mode: cfg.plugin_opts_obfsmode,
|
||||
host: cfg.plugin_opts_host,
|
||||
} : null,
|
||||
|
||||
/* TUIC */
|
||||
ip: cfg.tuic_ip,
|
||||
@ -610,19 +610,35 @@ uci.foreach(uciconf, ucinode, (cfg) => {
|
||||
"persistent-keepalive": strToInt(cfg.wireguard_persistent_keepalive),
|
||||
|
||||
/* Plugin fields */
|
||||
plugin: cfg.plugin,
|
||||
"plugin-opts": cfg.plugin ? {
|
||||
mode: cfg.plugin_opts_obfsmode,
|
||||
host: cfg.plugin_opts_host,
|
||||
password: cfg.plugin_opts_thetlspassword,
|
||||
version: strToInt(cfg.plugin_opts_shadowtls_version),
|
||||
"version-hint": cfg.plugin_opts_restls_versionhint,
|
||||
"restls-script": cfg.plugin_opts_restls_script
|
||||
} : null,
|
||||
...(cfg.plugin ? (
|
||||
cfg.type === 'snell' ? {
|
||||
// snell
|
||||
"obfs-opts": {
|
||||
mode: cfg.plugin in ['shadow-tls'] ? cfg.plugin : cfg.plugin_opts_obfsmode,
|
||||
host: cfg.plugin_opts_host,
|
||||
password: cfg.plugin_opts_thetlspassword,
|
||||
version: strToInt(cfg.plugin_opts_shadowtls_version),
|
||||
alpn: cfg.tls_alpn // Array
|
||||
}
|
||||
} : {
|
||||
// others
|
||||
plugin: cfg.plugin,
|
||||
"plugin-opts": {
|
||||
mode: cfg.plugin_opts_obfsmode,
|
||||
host: cfg.plugin_opts_host,
|
||||
password: cfg.plugin_opts_thetlspassword,
|
||||
version: strToInt(cfg.plugin_opts_shadowtls_version),
|
||||
alpn: cfg.tls_alpn, // Array
|
||||
"version-hint": cfg.plugin_opts_restls_versionhint,
|
||||
"restls-script": cfg.plugin_opts_restls_script
|
||||
}
|
||||
}
|
||||
) : {}),
|
||||
|
||||
/* Extra fields */
|
||||
"congestion-controller": cfg.congestion_controller,
|
||||
"bbr-profile": cfg.bbr_profile,
|
||||
"handshake-timeout": strToInt(cfg.handshake_timeout),
|
||||
udp: strToBool(cfg.udp),
|
||||
"udp-over-tcp": strToBool(cfg.uot),
|
||||
"udp-over-tcp-version": cfg.uot_version,
|
||||
@ -633,7 +649,7 @@ uci.foreach(uciconf, ucinode, (cfg) => {
|
||||
"disable-sni": strToBool(cfg.tls_disable_sni),
|
||||
...arrToObj([[(cfg.type in ['vmess', 'vless']) ? 'servername' : 'sni', cfg.tls_sni]]),
|
||||
fingerprint: cfg.tls_fingerprint,
|
||||
alpn: cfg.tls_alpn, // Array
|
||||
alpn: cfg.plugin in ['shadow-tls'] ? null : cfg.tls_alpn, // Array
|
||||
"skip-cert-verify": strToBool(cfg.tls_skip_cert_verify),
|
||||
certificate: cfg.tls_cert_path, // mTLS
|
||||
"private-key": cfg.masque_private_key || cfg.wireguard_private_key || cfg.ssh_priv_key || cfg.tls_key_path, // mTLS/SSH/WireGuard/Masque
|
||||
@ -744,7 +760,9 @@ uci.foreach(uciconf, ucipgrp, (cfg) => {
|
||||
"include-all": strToBool(cfg.include_all),
|
||||
"include-all-proxies": strToBool(cfg.include_all_proxies),
|
||||
"include-all-providers": strToBool(cfg.include_all_providers),
|
||||
"empty-fallback": cfg.empty_fallback ? get_proxy(cfg.empty_fallback) : null,
|
||||
"empty-fallback": cfg.empty_fallback ? get_proxy(cfg.empty_fallback, true) : null,
|
||||
// Select fields
|
||||
"default-selected": cfg.default_selected ? get_proxy(cfg.default_selected, true) : null,
|
||||
// Url-test fields
|
||||
tolerance: (cfg.type === 'url-test') ? strToInt(cfg.tolerance) ?? 150 : null,
|
||||
// Load-balance fields
|
||||
|
||||
@ -307,10 +307,6 @@ export function parseListener(cfg, isClient, label) {
|
||||
/* Snell */
|
||||
psk: cfg.snell_psk,
|
||||
version: cfg.snell_version,
|
||||
"obfs-opts": cfg.type === 'snell' ? {
|
||||
mode: cfg.plugin_opts_obfsmode,
|
||||
host: cfg.plugin_opts_host,
|
||||
} : null,
|
||||
|
||||
/* Tuic */
|
||||
"max-idle-time": durationToSecond(cfg.tuic_max_idle_time),
|
||||
@ -334,29 +330,41 @@ export function parseListener(cfg, isClient, label) {
|
||||
target: cfg.tunnel_target,
|
||||
|
||||
/* Plugin fields */
|
||||
...(cfg.plugin ? {
|
||||
...(cfg.plugin ? (
|
||||
cfg.plugin === 'obfs' ? (
|
||||
// obfs-simple
|
||||
"simple-obfs": cfg.plugin === 'obfs' ? {
|
||||
enable: true,
|
||||
mode: cfg.plugin_opts_obfsmode
|
||||
} : null,
|
||||
cfg.type === 'snell' ? {
|
||||
// snell
|
||||
"obfs-opts": {
|
||||
mode: cfg.plugin_opts_obfsmode,
|
||||
host: cfg.plugin_opts_host
|
||||
}
|
||||
} : {
|
||||
// shadowsocks
|
||||
"simple-obfs": {
|
||||
enable: true,
|
||||
mode: cfg.plugin_opts_obfsmode
|
||||
}
|
||||
}
|
||||
) : cfg.plugin === 'shadow-tls' ? {
|
||||
// shadow-tls
|
||||
"shadow-tls": cfg.plugin === 'shadow-tls' ? {
|
||||
enable: true,
|
||||
version: strToInt(cfg.plugin_opts_shadowtls_version),
|
||||
...(strToInt(cfg.plugin_opts_shadowtls_version) >= 3 ? {
|
||||
users: [
|
||||
{
|
||||
name: 1,
|
||||
password: cfg.plugin_opts_thetlspassword
|
||||
}
|
||||
],
|
||||
} : { password: cfg.plugin_opts_thetlspassword }),
|
||||
handshake: {
|
||||
dest: cfg.plugin_opts_handshake_dest
|
||||
},
|
||||
} : null
|
||||
} : {}),
|
||||
"shadow-tls": {
|
||||
enable: true,
|
||||
version: strToInt(cfg.plugin_opts_shadowtls_version),
|
||||
...(strToInt(cfg.plugin_opts_shadowtls_version) >= 3 ? {
|
||||
users: [
|
||||
{
|
||||
name: 1,
|
||||
password: cfg.plugin_opts_thetlspassword
|
||||
}
|
||||
],
|
||||
} : { password: cfg.plugin_opts_thetlspassword }),
|
||||
handshake: {
|
||||
dest: cfg.plugin_opts_handshake_dest
|
||||
}
|
||||
}
|
||||
} : {}
|
||||
) : {}),
|
||||
|
||||
/* Extra fields */
|
||||
"congestion-controller": cfg.congestion_controller,
|
||||
|
||||
@ -12,8 +12,8 @@ PKG_MAINTAINER:=Rafał Wabik <4Rafal@gmail.com>
|
||||
LUCI_DESCRIPTION:=LuCI JS interface for the lite-watchdog scripts.
|
||||
LUCI_DEPENDS:=+sms-tool +kmod-usb-serial +kmod-usb-serial-option +comgt
|
||||
LUCI_PKGARCH:=all
|
||||
PKG_VERSION:=1.0.17
|
||||
PKG_RELEASE:=2
|
||||
PKG_VERSION:=1.0.18
|
||||
PKG_RELEASE:=3
|
||||
|
||||
define Package/luci-app-lite-watchdog/conffiles
|
||||
/etc/modem/log.txt
|
||||
|
||||
@ -241,6 +241,7 @@ return view.extend({
|
||||
o.value('wan', _('Connection restart'));
|
||||
o.value('reboot', _('Reboot'));
|
||||
o.default = action || "wan";
|
||||
o.rmempty = false;
|
||||
}
|
||||
|
||||
return m.render();
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
--bg: oklch(0.967 0.003 264);
|
||||
--surface: oklch(1 0 0);
|
||||
--text: oklch(0.21 0.02 264);
|
||||
--brand: oklch(0.68 0.11 233);
|
||||
--brand: oklch(0.58 0.14 233);
|
||||
--on-brand: oklch(1 0 0);
|
||||
--link: oklch(0.74 0.238 322.16);
|
||||
--info: oklch(0.45 0.12 255);
|
||||
@ -18,16 +18,16 @@
|
||||
--danger: oklch(0.35 0.12 25);
|
||||
--text-muted: oklch(49.77% 0.0135 264);
|
||||
--text-subtle: oklch(60.36% 0.0112 264);
|
||||
--surface-sunken: oklch(95.7% 0.003 264);
|
||||
--surface-sunken: oklch(95.5% 0.003 264);
|
||||
--surface-overlay: oklch(98.3% 0.003 264);
|
||||
--hairline: oklch(21% 0.02 264 / 0.08);
|
||||
--hairline: oklch(21% 0.02 264 / 0.13);
|
||||
--hover-faint: oklch(92.7% 0.003 264);
|
||||
--brand-hover: oklch(62% 0.11 233);
|
||||
--brand-subtle: oklch(93.26% 0.0155 238);
|
||||
--brand-subtle-hover: oklch(89.26% 0.0155 238);
|
||||
--focus-ring: oklch(68% 0.11 233 / 0.6);
|
||||
--progress-start: oklch(77.7% 0.0724 233.4);
|
||||
--progress-end: oklch(0.68 0.11 233);
|
||||
--brand-hover: oklch(52% 0.14 233);
|
||||
--brand-subtle: oklch(92.06% 0.0191 237.1);
|
||||
--brand-subtle-hover: oklch(88.06% 0.0191 237.1);
|
||||
--focus-ring: oklch(58% 0.14 233 / 0.6);
|
||||
--progress-start: oklch(71.13% 0.0919 233.3);
|
||||
--progress-end: oklch(0.58 0.14 233);
|
||||
--info-surface: oklch(94% 0.05 255);
|
||||
--warning-surface: oklch(95% 0.05 60);
|
||||
--success-surface: oklch(94% 0.05 165);
|
||||
|
||||
@ -6,7 +6,7 @@ input[type="text"],
|
||||
input[type="password"],
|
||||
.cbi-input-text,
|
||||
.cbi-input {
|
||||
@apply text-text border-hairline bg-surface-sunken placeholder-text-muted focus:border-brand focus:ring-focus-ring relative rounded-2xl border px-3 py-1.5 text-sm font-normal shadow-sm transition-[border-color,box-shadow] duration-150 focus:ring-2 focus:outline-none;
|
||||
@apply text-text border-hairline bg-surface-overlay dark:bg-surface-sunken placeholder-text-muted focus:border-brand focus:ring-focus-ring relative rounded-2xl border px-3 py-1.5 text-sm font-normal shadow-sm transition-[border-color,box-shadow] duration-150 focus:ring-2 focus:outline-none;
|
||||
|
||||
.table.cbi-section-table & {
|
||||
@apply w-full;
|
||||
@ -23,7 +23,7 @@ input[type="password"],
|
||||
|
||||
input[type="radio"],
|
||||
input[type="checkbox"] {
|
||||
@apply focus:before:border-brand focus:before:ring-focus-ring checked:before:border-brand checked:before:bg-brand before:border-hairline before:bg-surface-sunken after:bg-on-brand hover:before:border-hairline relative mr-3 inline-block h-4 w-4 cursor-pointer appearance-none before:absolute before:top-0 before:left-0 before:h-4 before:w-4 before:border before:transition-[background-color,border-color,box-shadow] before:duration-150 after:absolute after:top-0.5 after:left-0.5 after:h-3 after:w-3 after:opacity-0 after:transition-opacity after:duration-150 checked:after:opacity-100 focus:before:ring-2 focus:before:outline-none disabled:cursor-not-allowed;
|
||||
@apply focus:before:border-brand focus:before:ring-focus-ring checked:before:border-brand checked:before:bg-brand before:border-hairline before:bg-surface-overlay dark:before:bg-surface-sunken after:bg-on-brand hover:before:border-hairline relative mr-3 inline-block h-4 w-4 cursor-pointer appearance-none before:absolute before:top-0 before:left-0 before:h-4 before:w-4 before:border before:transition-[background-color,border-color,box-shadow] before:duration-150 after:absolute after:top-0.5 after:left-0.5 after:h-3 after:w-3 after:opacity-0 after:transition-opacity after:duration-150 checked:after:opacity-100 focus:before:ring-2 focus:before:outline-none disabled:cursor-not-allowed;
|
||||
}
|
||||
|
||||
input[type="radio"] {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
select {
|
||||
@apply text-text border-hairline bg-surface-sunken focus:border-brand focus:ring-focus-ring appearance-none rounded-2xl border px-3 py-1.5 pr-10 text-sm font-normal shadow-sm transition-[border-color,box-shadow] duration-150 focus:ring-2 focus:outline-none;
|
||||
@apply text-text border-hairline bg-surface-overlay dark:bg-surface-sunken focus:border-brand focus:ring-focus-ring appearance-none rounded-2xl border px-3 py-1.5 pr-10 text-sm font-normal shadow-sm transition-[border-color,box-shadow] duration-150 focus:ring-2 focus:outline-none;
|
||||
@apply bg-[url('@assets/icons/arrow-down.svg')] bg-size-[16px] bg-position-[right_0.75rem_center] bg-no-repeat dark:bg-[url('@assets/icons/arrow-down-dark.svg')];
|
||||
&[disabled] {
|
||||
@apply cursor-not-allowed opacity-40 dark:opacity-30;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
textarea {
|
||||
@apply text-text border-hairline bg-surface-sunken placeholder-text-muted focus:border-brand focus:ring-focus-ring min-h-24 w-full resize-y rounded-2xl border px-3 py-2 text-sm font-normal shadow-sm transition-[border-color,box-shadow] duration-150 focus:ring-2 focus:outline-none;
|
||||
@apply text-text border-hairline bg-surface-overlay dark:bg-surface-sunken placeholder-text-muted focus:border-brand focus:ring-focus-ring min-h-24 w-full resize-y rounded-2xl border px-3 py-2 text-sm font-normal shadow-sm transition-[border-color,box-shadow] duration-150 focus:ring-2 focus:outline-none;
|
||||
&[disabled] {
|
||||
@apply cursor-not-allowed opacity-40 dark:opacity-30;
|
||||
}
|
||||
|
||||
@ -92,7 +92,7 @@
|
||||
}
|
||||
|
||||
.input-wrap {
|
||||
@apply border-hairline bg-surface-sunken relative rounded-2xl border [contain:layout_style];
|
||||
@apply border-hairline bg-surface-overlay dark:bg-surface-sunken relative rounded-2xl border [contain:layout_style];
|
||||
}
|
||||
|
||||
/* Focus ring: opacity-only transition runs on compositor thread, not main thread —
|
||||
|
||||
@ -4,7 +4,7 @@ export const DEFAULTS = {
|
||||
bg: "oklch(0.967 0.003 264)",
|
||||
surface: "oklch(1 0 0)",
|
||||
text: "oklch(0.21 0.02 264)",
|
||||
brand: "oklch(0.68 0.11 233)",
|
||||
brand: "oklch(0.58 0.14 233)",
|
||||
on_brand: "oklch(1 0 0)",
|
||||
link: "oklch(0.74 0.238 322.16)",
|
||||
info: "oklch(0.45 0.12 255)",
|
||||
|
||||
@ -4,9 +4,9 @@ export const DERIVATIONS = {
|
||||
light: {
|
||||
text_muted: ["mix", "text", "bg", 0.62],
|
||||
text_subtle: ["mix", "text", "bg", 0.48],
|
||||
surface_sunken: ["shade", "bg", -0.010],
|
||||
surface_sunken: ["shade", "bg", -0.012],
|
||||
surface_overlay: ["shade", "bg", 0.016],
|
||||
hairline: ["alpha", "text", 0.08],
|
||||
hairline: ["alpha", "text", 0.13],
|
||||
hover_faint: ["shade", "bg", -0.04],
|
||||
brand_hover: ["shade", "brand", -0.06],
|
||||
brand_subtle: ["mix", "brand", "bg", 0.12],
|
||||
|
||||
@ -8,8 +8,8 @@ include $(TOPDIR)/rules.mk
|
||||
LUCI_TITLE:=Aurora Theme (A modern browser theme built with Vite and Tailwind CSS)
|
||||
LUCI_DEPENDS:=+luci-base
|
||||
|
||||
PKG_VERSION:=1.0.6
|
||||
PKG_RELEASE:=40
|
||||
PKG_VERSION:=1.0.7
|
||||
PKG_RELEASE:=41
|
||||
PKG_LICENSE:=Apache-2.0
|
||||
|
||||
LUCI_MINIFY_CSS:=
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -10,12 +10,12 @@ include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:=natflow
|
||||
PKG_VERSION:=20260531
|
||||
PKG_RELEASE:=33
|
||||
PKG_RELEASE:=34
|
||||
|
||||
PKG_SOURCE:=$(PKG_VERSION).tar.xz
|
||||
PKG_SOURCE_URL:=https://github.com/ptpt52/natflow.git
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_VERSION:=0a039fc3e686237efa6f89cd593731a039965b14
|
||||
PKG_SOURCE_VERSION:=50b9d608a30193f71f8831ee0d6a1a17a3aac456
|
||||
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
|
||||
PKG_MAINTAINER:=Chen Minqiang <ptpt52@gmail.com>
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=nps
|
||||
PKG_VERSION:=0.26.34
|
||||
PKG_RELEASE:=9
|
||||
PKG_VERSION:=0.26.35
|
||||
PKG_RELEASE:=10
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://codeload.github.com/yisier/nps/tar.gz/v$(PKG_VERSION)?
|
||||
|
||||
2
quectel_MHI/Makefile
Normal file → Executable file
2
quectel_MHI/Makefile
Normal file → Executable file
@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=pcie_mhi
|
||||
PKG_VERSION:=1.3.8
|
||||
PKG_RELEASE:=33
|
||||
PKG_RELEASE:=34
|
||||
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
Loading…
Reference in New Issue
Block a user