Skip to content

fix: hysteria2 obfs round-trip, subscription identity, log scroll anchoring#25

Merged
PhoenixNil merged 1 commit into
mainfrom
net10
May 21, 2026
Merged

fix: hysteria2 obfs round-trip, subscription identity, log scroll anchoring#25
PhoenixNil merged 1 commit into
mainfrom
net10

Conversation

@PhoenixNil
Copy link
Copy Markdown
Owner

@PhoenixNil PhoenixNil commented May 21, 2026

Summary

A bundle of independent fixes/improvements on net10.

Hysteria2 salamander obfs round-trip (NodeLinkParser, NodeLinkSerializer)

obfs=salamander + obfs-password from share links is now merged into the Finalmask JSON's udp[] array, and re-emitted back out when generating share links. Previously these parameters were dropped on import and never produced on export.

Subscription refresh identity key (ServerListViewModel)

Node Id preservation across subscription refresh now keys on a multi-field tuple — protocol, host, port, network, security, path, credentials, uuid, flow, encryption, public key, short id — instead of just protocol://host:port. Case-insensitive fields are lowercased; credentials/keys are only trimmed. Queue-based matching handles duplicates correctly, and a reusedIds set prevents the same old Id from being assigned to multiple new entries.

Log window scroll anchoring (LogWindow.xaml.cs)

When auto-scroll is OFF and the 500-line ring buffer evicts old lines, the visible region used to drift upward. Now tracks linesReceived vs net buffer growth, computes the evicted count, and shifts the scroll offset down by evicted × lineHeight so visible content stays anchored.

Finalmask textbox truncation (DialogService)

AcceptsReturn = true must be set before Text — the single-line Text setter truncates at the first \r. Object initializers assign in declared order, so the property order in the initializer block matters. Reordered and normalized line endings to \r.

Shadow re-wiring guard (ServerDetailControl.xaml.cs)

Three AI-service Borders share ShadowRect_Loaded. Without a guard, each Loaded firing re-added all three AIShadowCastGrid receivers, ending at 9 entries with duplicates causing wasted compositor work. Added _shadowsWired bool.

x:Bind cleanup (MainWindow.xaml)

Child VM bindings (ServerList, ServerDetail, ControlPanel) and SwitchToSelectedServerCommand are immutable after MainViewModel construction, so they're now OneTime instead of OneWay. Also drops a redundant Mode=OneWay on the MiniStartStopCommand Command binding.

Test plan

  • Hysteria2: import a share link with obfs=salamander&obfs-password=xxx, verify the salamander entry appears under Finalmask.udp[] and the regenerated share link contains both params.
  • Subscription: refresh a subscription where two nodes share host:port but differ by uuid/network — both should keep their Ids.
  • Log window: turn off auto-scroll, scroll up to mid-buffer, generate >500 log lines, confirm the visible region stays anchored.
  • Finalmask dialog: edit a Hysteria2 server's Finalmask containing multi-line JSON, confirm full content shows in the TextBox.
  • ServerDetail: inspect the AI-service cards on first show — no visual artifacts, shadow count stable.

…horing

- hysteria2: parse obfs=salamander + obfs-password from share links into
  Finalmask udp[], and emit them back when generating share links. Previously
  dropped on import and never produced on export.
- subscription refresh: preserve node Ids by a multi-field identity key
  (protocol/host/port/network/security/path/credentials/uuid/flow/...) instead
  of just protocol://host:port. Lowercase case-insensitive fields, queue-match
  to handle duplicates, and dedupe via reusedIds so two new entries can't
  share one old Id.
- log window: when auto-scroll is OFF and the 500-line ring buffer evicts
  old lines, shift the scroll offset down by evicted * lineHeight so visible
  content stays anchored instead of drifting up.
- DialogService: set AcceptsReturn before Text on the Finalmask TextBox —
  single-line Text setter truncates at the first \r. Normalize line endings
  to \r as well.
- ServerDetailControl: guard ShadowRect_Loaded with _shadowsWired so the
  three AI-service Borders don't each re-add receivers (3*3=9 duplicates).
- MainWindow.xaml: child VM bindings and SwitchToSelectedServerCommand are
  immutable after construction, switch to OneTime; drop redundant Mode=OneWay
  on the MiniStartStop Command binding.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@PhoenixNil PhoenixNil merged commit eea5949 into main May 21, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant