diff --git a/MANUAL.md b/MANUAL.md index 76a8a64..5af25a4 100644 --- a/MANUAL.md +++ b/MANUAL.md @@ -295,6 +295,7 @@ Control| Shortcut| What it does **Discovered peers**| Alt+D| People RemSound has heard from in the last few seconds. Tick someone to connect to them. **Remembered peers**| Alt+R| People you've connected to before, or added by address. This list is kept between sessions. Tick someone to reconnect. **Add peer by IP**| Alt+A| Opens a small box where you type an address or computer name. It adds that peer to the remembered list and connects. +**Lock to these exact peer addresses**| Alt+L| When ticked, this profile uses only the exact addresses you set and never follows the other computer by name or switches to a different address — even if the address stops working. Off by default, saved with the profile. See Locking a profile to one exact address. **Connection status**| Alt+S| A read-only box of text that sums up everything happening right now — how long you've been connected, how many peers you have, how much sound is flowing each way, and the connection health of each peer. Open it to read the current connection status. ## 7. Audio inputs and outputs tab @@ -463,18 +464,28 @@ List| Contents| What ticking does There's also the **Add peer by IP (Alt+A)** button, which opens a small box for a computer name or address. It's useful for a first connection over a VPN, where discovery hasn't reached the other computer yet. -### Connecting to one specific IP address (and only that one) +### Locking a profile to one exact address (and only that one) -RemSound can reach another computer two ways, and the difference matters if a computer has more than one IP address: +There are two ways to reach another computer, and the difference matters if that computer has more than one address: - * **By name** — ticking someone in **Discovered peers**. RemSound found them from their announcement and the entry shows their computer name. This is the easy, automatic way on an ordinary network. - * **By a fixed IP** — **Add peer by IP (Alt+A)** , then type the exact address, for example `10.8.0.1`. RemSound talks to _that address and nothing else_ : it doesn't look up a name, so it can never drift to a different IP, and if that address isn't reachable, no connection is made at all. + * **By name** — ticking someone in **Discovered peers**. RemSound found them from their announcement, and the entry shows their computer name. This is the easy, automatic way on an ordinary network. + * **By a fixed address** — **Add peer by IP (Alt+A)** , then type the exact address, for example `10.8.0.1`. -So to force a connection to one specific IP — say a machine that appears under two addresses and you only want one of them — add it by that IP and tick only that entry. If the same machine also turns up in Discovered peers under its _other_ address, it shows as a separate entry that you simply leave unticked; RemSound keeps the two apart by their actual address, so they never merge. +Normally RemSound is helpful about addresses, even one you typed: it can recognise that the address belongs to a computer it also hears announcing itself on the network, and if that computer turns up at a _different_ address — a new IP after a reboot, or a second address over a VPN — RemSound follows it there automatically so your sound keeps flowing. Most of the time that is exactly what you want. -Either way, **the profile remembers exactly what you ticked.** Tick a discovered name and the profile reconnects by that name next time; add and tick an IP and the profile reconnects to that exact IP. So the way to make a profile always use one specific IP is simply to add and tick it by that IP, then save the profile. +Sometimes you want the opposite: connect to one specific address and nothing else, _ever_. For that, tick **Lock to these exact peer addresses, no matter what (Alt+L)** on the Connectivity tab. It is off by default and is saved with the profile, so you can lock one profile down while another keeps the automatic behaviour. When it is ticked, for that profile: + + * RemSound uses **only the exact address you set** for each peer. + * It will **not** look the other computer up by the name it advertises on the network, and it will **not** switch to any other address it discovers — even if that same computer is reachable at a second address at the same moment. + * If the address you set stops working — the computer is off, the network is down, or it has moved to a new address — the connection simply **waits, or drops, until that exact address is reachable again**. RemSound will not go looking for another way through. + + + +**When you use this, set your peers by their IP address** (Add peer by IP, then type the address). That is the setting for a machine that appears under two addresses when you only ever want one of them: add that one IP, tick the box, and save the profile — the connection will use that address and never wander. + +With the box left unticked, RemSound behaves as it always has: the profile remembers exactly what you ticked, reconnects by that name or address next time, and quietly follows a peer that genuinely moves to a new address. ### You only hear peers you've ticked diff --git a/readme.html b/readme.html index b9d523c..606c01d 100644 --- a/readme.html +++ b/readme.html @@ -333,6 +333,7 @@ ul, ol { padding-left: 1.4em; }
There's also the Add peer by IP (Alt+A) button, which opens a small box for a computer name or address. It's useful for a first connection over a VPN, where discovery hasn't reached the other computer yet.
-RemSound can reach another computer two ways, and the difference matters if a computer has more than one IP address:
+There are two ways to reach another computer, and the difference matters if that computer has more than one address:
10.8.0.1. RemSound talks to that address and nothing else: it doesn't look up a name, so it can never drift to a different IP, and if that address isn't reachable, no connection is made at all.10.8.0.1.So to force a connection to one specific IP — say a machine that appears under two addresses and you only want one of them — add it by that IP and tick only that entry. If the same machine also turns up in Discovered peers under its other address, it shows as a separate entry that you simply leave unticked; RemSound keeps the two apart by their actual address, so they never merge.
-Either way, the profile remembers exactly what you ticked. Tick a discovered name and the profile reconnects by that name next time; add and tick an IP and the profile reconnects to that exact IP. So the way to make a profile always use one specific IP is simply to add and tick it by that IP, then save the profile.
+Normally RemSound is helpful about addresses, even one you typed: it can recognise that the address belongs to a computer it also hears announcing itself on the network, and if that computer turns up at a different address — a new IP after a reboot, or a second address over a VPN — RemSound follows it there automatically so your sound keeps flowing. Most of the time that is exactly what you want.
+Sometimes you want the opposite: connect to one specific address and nothing else, ever. For that, tick Lock to these exact peer addresses, no matter what (Alt+L) on the Connectivity tab. It is off by default and is saved with the profile, so you can lock one profile down while another keeps the automatic behaviour. When it is ticked, for that profile:
+When you use this, set your peers by their IP address (Add peer by IP, then type the address). That is the setting for a machine that appears under two addresses when you only ever want one of them: add that one IP, tick the box, and save the profile — the connection will use that address and never wander.
+With the box left unticked, RemSound behaves as it always has: the profile remembers exactly what you ticked, reconnects by that name or address next time, and quietly follows a peer that genuinely moves to a new address.
Even if a peer is sending sound your way, you won't hear it until you've ticked their checkbox. This is deliberate — connecting is a step where you give your consent. A peer's name appears in Discovered the moment they come online, but they can't make any sound on your speakers until you say yes.
diff --git a/src/RemSound.App/MainForm.cs b/src/RemSound.App/MainForm.cs index 25aa598..91a709c 100644 --- a/src/RemSound.App/MainForm.cs +++ b/src/RemSound.App/MainForm.cs @@ -238,6 +238,14 @@ public sealed class MainForm : Form private readonly CheckedListBox rememberedPeersList = new() { CheckOnClick = true, Width = 430, Height = 90, AccessibleName = "Remembered peers (Alt+R)" }; private readonly Label rememberedPeersStatus = new() { AutoSize = true, Text = "No remembered peer selected." }; private readonly Button manualAddButton = new() { Text = "Add peer by IP (Alt+&A)", AutoSize = true, AccessibleName = "Add peer by IP" }; + // Per-profile "pin to exact addresses" toggle (#17). When ticked, RefreshKnownPeers skips the + // discovered-peer merge and the address-follow, so the profile's peers stay exactly as the user set. + private readonly AccessibleCheckBox lockPeerAddressesBox = new() + { + Text = "Lock to these exact peer addresses, no matter what — never follow names or switch (Alt+&L)", + AccessibleName = "Lock to these exact peer addresses, no matter what; never follow names or switch address", + AutoSize = true, + }; // loggingBox + writeLogsNowButton field instances retired 2026-05-08 — both controls // now live inside PreferencesDialog. The form-level logFile.Enabled gate is set // directly from the settings store at startup (see ApplyLoggingEnabled). @@ -2797,7 +2805,7 @@ public sealed class MainForm : Form Dock = DockStyle.Fill, Padding = new Padding(12), ColumnCount = 2, - RowCount = 5, + RowCount = 6, AutoScroll = true, }; panel.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize)); @@ -2921,19 +2929,29 @@ public sealed class MainForm : Form // Preferences dialog (File → Preferences, Ctrl+P) as the last two items. // === Layout === - // 5 rows: 0–2 the three peer lists, 3 manual-add, 4 connection-status readout. - panel.RowCount = 5; + // 6 rows: 0–2 the three peer lists, 3 manual-add, 4 the lock-to-fixed-addresses toggle, 5 status. + panel.RowCount = 6; FormLayoutRows.AddCheckedListRow(panel, 0, "Connected peers (Alt+&C)", connectedPeersList, connectedPeersStatus, FocusListControl); FormLayoutRows.AddCheckedListRow(panel, 1, "Discovered peers (Alt+&D)", discoveredPeersList, discoveredPeersStatus, FocusListControl); FormLayoutRows.AddCheckedListRow(panel, 2, "Remembered peers (Alt+&R)", rememberedPeersList, rememberedPeersStatus, FocusListControl); panel.Controls.Add(new Label { Text = "Manual peer", AutoSize = true, Anchor = AnchorStyles.Left }, 0, 3); panel.Controls.Add(manualAddButton, 1, 3); + lockPeerAddressesBox.Checked = settings.LoadLockPeerAddresses(); + lockPeerAddressesBox.CheckedChanged += (_, _) => + { + settings.SaveLockPeerAddresses(lockPeerAddressesBox.Checked); + MarkProfileDirty(); + logFile.Event($"lock peer addresses: {(lockPeerAddressesBox.Checked ? "on" : "off")}"); + }; + panel.Controls.Add(lockPeerAddressesBox, 0, 4); + panel.SetColumnSpan(lockPeerAddressesBox, 2); + // Connection status readout — last row, tab-into-able. var statusLabel = new MnemonicLabel { Text = "Connection status (Alt+&S)", AutoSize = true, Anchor = AnchorStyles.Left, MnemonicTarget = statusReadout }; statusLabel.Click += (_, _) => statusReadout.Focus(); - panel.Controls.Add(statusLabel, 0, 4); - panel.Controls.Add(statusReadout, 1, 4); + panel.Controls.Add(statusLabel, 0, 5); + panel.Controls.Add(statusReadout, 1, 5); // Initial render so the box has content the moment the user tabs into it. RefreshStatusReadout(); @@ -5226,6 +5244,16 @@ public sealed class MainForm : Form foreach (var peer in discovery.Peers) knownPeers[peer.InstanceId] = peer; foreach (var peer in manualPeers.Values) knownPeers[peer.InstanceId] = peer; + // Locked-to-fixed-addresses profiles (#17): the user wants RemSound to use exactly the peer + // addresses they set and never substitute one found on the network. Skip the discovered-peer + // merge (which would attach a computer name to their selection) and the address-follow below; + // the selection's allow-list is still pushed so audio flows to those exact addresses, unchanged. + if (settings.LoadLockPeerAddresses()) + { + PushAllowedReceiveSenders(); + return; + } + // Dedupe by endpoint (address:port). When a manual peer (typed by IP) and a discovered // peer (broadcasting hostname) point to the same machine, drop the manual entry and // forward any active selection to the discovered peer so the user doesn't lose it. diff --git a/src/RemSound.Core/Profile.cs b/src/RemSound.Core/Profile.cs index 942b19b..550b8c3 100644 --- a/src/RemSound.Core/Profile.cs +++ b/src/RemSound.Core/Profile.cs @@ -177,6 +177,12 @@ public sealed class Profile /// list at save time. On load, RemSound auto-connects to any of these that resolve. public List