V2.0.1: listen override fix, sing-box core fetch, probe settings page + fast report, spx removal, core mem env
CI / go-test (push) Waiting to run
CI / postgres-durable-first (push) Waiting to run
CI / codegen (push) Waiting to run
CI / govulncheck (push) Waiting to run
CI / race (push) Waiting to run
CI / fuzz-smoke (push) Waiting to run
CI / golangci (push) Waiting to run
CI / frontend (push) Waiting to run
Docs CI / build (push) Waiting to run
Docs Deploy (GitHub Pages) / build (push) Waiting to run
Docs Deploy (GitHub Pages) / deploy (push) Blocked by required conditions
Release 3X-UI / build (386) (push) Waiting to run
Release 3X-UI / build (amd64) (push) Waiting to run
Release 3X-UI / build (arm64) (push) Waiting to run
Release 3X-UI / build (armv5) (push) Waiting to run
Release 3X-UI / build (armv6) (push) Waiting to run
Release 3X-UI / build (armv7) (push) Waiting to run
Release 3X-UI / build (s390x) (push) Waiting to run
Release 3X-UI / Build for Windows (amd64) (push) Waiting to run
Release 3X-UI / Publish rolling dev release (push) Blocked by required conditions
CodeQL Advanced / Analyze (go) (push) Waiting to run
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run

- 0: sing-box gen overrides fragment listen/port from the inbound row
  (empty listen -> "::"), Update/Add recompute the stored fragment;
  non-loopback E2E against the real core binary.
- 1: agent fetches the sing-box core from the Gitea release when
  missing, self-checks it, and only then latches the switch.
- 2: node list shows the sing-box core version (heartbeat field,
  persisted on the node row), xray version as fallback.
- 3: public-page fallback returns 404 to anonymous visitors when the
  page is disabled.
- 4: settings restart hint bar removed, dead i18n keys cleaned.
- 5: two PUT calls missing JSON headers fixed (audit: only those two),
  batch probe-task creation endpoint + UI.
- 6: cf-probe retirement card and coverage pipeline removed.
- 7: generated vless links no longer carry spx (panel export + sub);
  parser still accepts spx; golden fixtures updated.
- probe batch: dedicated probe settings tab (public-page settings,
  tasks, per-node meta), retention_days editable, per-node traffic
  calibration + stat-interface pinning, runtime metrics split into a
  lightweight fast report (default 3s, 1-60s adjustable).
- 8: sing-box core processes start with GOMEMLIMIT=32MiB, GOGC=50.
- 9: dead /getTwoFactorEnable docs entries removed (frontend call and
  contract entry already gone at base; verified by grep).
This commit is contained in:
Rogue
2026-10-23 07:53:11 +00:00
parent c2f1840535
commit 29de9761c8
67 changed files with 3081 additions and 832 deletions
+20 -5
View File
@@ -30,6 +30,15 @@ type Meta struct {
CountryPin string
IPv4Pin string
IPv6Pin string
// TrafficCalUpGB / TrafficCalDownGB are the operator's ledger
// corrections in GB (V2.0.1), either sign: added to the counted
// uplink (tx) / downlink (rx) figures wherever the ledger is
// read — panel statistics, the public page and traffic alerts.
TrafficCalUpGB float64
TrafficCalDownGB float64
// StatIface pins the one interface whose counters the agent
// books (V2.0.1); "" keeps the automatic counted-set selection.
StatIface string
}
// DefaultMeta returns the metadata of an agent that has no row yet —
@@ -48,7 +57,8 @@ func DefaultMeta(agentID int64) Meta {
const metaColumns = `agent_id, price, currency, billing_cycle, expires_at,
traffic_limit, traffic_mode, traffic_reset_day, public, sort,
group_name, public_remark, notify, country_pin, ipv4_pin, ipv6_pin`
group_name, public_remark, notify, country_pin, ipv4_pin, ipv6_pin,
traffic_cal_up_gb, traffic_cal_down_gb, stat_iface`
func scanMeta(sc interface{ Scan(...any) error }) (Meta, error) {
var m Meta
@@ -56,7 +66,8 @@ func scanMeta(sc interface{ Scan(...any) error }) (Meta, error) {
var public, notify int64
if err := sc.Scan(&m.AgentID, &m.Price, &m.Currency, &m.BillingCycle, &expires,
&m.TrafficLimit, &m.TrafficMode, &m.TrafficResetDay, &public, &m.Sort,
&m.GroupName, &m.PublicRemark, &notify, &m.CountryPin, &m.IPv4Pin, &m.IPv6Pin); err != nil {
&m.GroupName, &m.PublicRemark, &notify, &m.CountryPin, &m.IPv4Pin, &m.IPv6Pin,
&m.TrafficCalUpGB, &m.TrafficCalDownGB, &m.StatIface); err != nil {
return Meta{}, err
}
if expires.Valid && strings.TrimSpace(expires.String) != "" {
@@ -107,7 +118,7 @@ func (s *Store) UpsertMeta(m Meta) error {
expires = *m.ExpiresAt
}
_, err := s.db.Exec(
`INSERT INTO probe_meta (`+metaColumns+`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
`INSERT INTO probe_meta (`+metaColumns+`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
ON CONFLICT(agent_id) DO UPDATE SET
price=excluded.price, currency=excluded.currency,
billing_cycle=excluded.billing_cycle, expires_at=excluded.expires_at,
@@ -116,10 +127,14 @@ func (s *Store) UpsertMeta(m Meta) error {
sort=excluded.sort, group_name=excluded.group_name,
public_remark=excluded.public_remark, notify=excluded.notify,
country_pin=excluded.country_pin, ipv4_pin=excluded.ipv4_pin,
ipv6_pin=excluded.ipv6_pin`,
ipv6_pin=excluded.ipv6_pin,
traffic_cal_up_gb=excluded.traffic_cal_up_gb,
traffic_cal_down_gb=excluded.traffic_cal_down_gb,
stat_iface=excluded.stat_iface`,
m.AgentID, m.Price, m.Currency, m.BillingCycle, expires,
m.TrafficLimit, m.TrafficMode, m.TrafficResetDay, boolToInt(m.Public), m.Sort,
m.GroupName, m.PublicRemark, boolToInt(m.Notify), m.CountryPin, m.IPv4Pin, m.IPv6Pin)
m.GroupName, m.PublicRemark, boolToInt(m.Notify), m.CountryPin, m.IPv4Pin, m.IPv6Pin,
m.TrafficCalUpGB, m.TrafficCalDownGB, m.StatIface)
return err
}