diff --git a/src/main/smoke.ts b/src/main/smoke.ts index c874ba1..89554e1 100644 --- a/src/main/smoke.ts +++ b/src/main/smoke.ts @@ -8978,19 +8978,30 @@ export async function runWebSmoke(): Promise { const exact: LivePlayer[] = [ { name: 'Alex', uuid: 'u-1', world: 'world', dim: 'overworld', x: 1234, y: 12, z: -987 } ] - const pub = redactPlayers(exact, { ...PUBLIC_MAP_DEFAULTS, enabled: true, serverId: 's' }) + // Rounding is asked for EXPLICITLY here rather than taken from the + // defaults. It used to come from them, and when the default changed to + // exact this block started asserting that the feature was broken — the + // two questions are "does redaction work when switched on" and "is it on + // by default", and only the first belongs in this block. + const pub = redactPlayers(exact, { ...PUBLIC_MAP_DEFAULTS, enabled: true, serverId: 's', round: 64 }) const one = pub[0] as unknown as Record // The panel payload's fields must not arrive here by being spread // through. Height is the sharp one: y=12 says "in a cave", which is - // when a player cannot defend the base you would then walk to. + // when a player cannot defend the base you would then walk to. This + // holds whatever the rounding is — the fields are the protection that + // does not have a setting. + const bare = redactPlayers(exact, { ...PUBLIC_MAP_DEFAULTS, enabled: true, serverId: 's' })[0] for (const leaked of ['y', 'world', 'uuid']) { if (leaked in one) return fail('the public map payload carries "' + leaked + '"') + if (leaked in (bare as unknown as Record)) { + return fail('with rounding off the public map payload carries "' + leaked + '"') + } } - if (one.x === 1234 || one.z === -987) return fail('the public map published exact coordinates') + if (one.x === 1234 || one.z === -987) return fail('rounding did not move a player at all') if (Math.abs((one.x as number) - 1234) > 32) return fail('rounding moved a player more than half a cell') // Deterministic, not jittered: a watcher who samples a stationary // player repeatedly must not be able to average the noise away. - const again = redactPlayers(exact, { ...PUBLIC_MAP_DEFAULTS, enabled: true, serverId: 's' }) + const again = redactPlayers(exact, { ...PUBLIC_MAP_DEFAULTS, enabled: true, serverId: 's', round: 64 }) if (again[0].x !== pub[0].x || again[0].z !== pub[0].z) return fail('redaction is not deterministic') // Opt-ins. // Heads are drawn from the name since #116, so heads-on must publish @@ -9009,6 +9020,24 @@ export async function runWebSmoke(): Promise { if ('name' in (noNames[0] as unknown as Record)) { return fail('names off still published a name') } + // Exact by default. Rounding is a real protection and stays available, + // but it was ON at 64 blocks for everyone, and on a map that now draws + // terrain that puts a player visibly beside the house they are standing + // in — which reads as a placement bug, and was reported as one. + if (PUBLIC_MAP_DEFAULTS.round !== 0) { + return fail('the public map rounds positions by default: ' + PUBLIC_MAP_DEFAULTS.round) + } + if (MAP_PAGE_DEFAULTS.round !== 0) { + return fail('the map page rounds positions by default: ' + MAP_PAGE_DEFAULTS.round) + } + // Still available, and still exactly as strong when asked for. + { + const exactCfg = { ...PUBLIC_MAP_DEFAULTS, enabled: true, serverId: 's' } + const p = redactPlayers(exact, exactCfg)[0] + if (p.x !== 1234 || p.z !== -987) return fail('the default no longer publishes exact positions') + const rounded = redactPlayers(exact, { ...exactCfg, round: 64 })[0] + if (rounded.x % 64 !== 0 || rounded.z % 64 !== 0) return fail('opting into rounding stopped working') + } if (clampRound(-5) !== 0) return fail('a negative rounding was accepted') if (clampRound(99999) !== 512) return fail('rounding was not capped') if (clampRound('lots') !== PUBLIC_MAP_DEFAULTS.round) return fail('a junk rounding did not fall back') diff --git a/src/renderer/src/locales/en.ts b/src/renderer/src/locales/en.ts index ab46c48..d27ee5a 100644 --- a/src/renderer/src/locales/en.ts +++ b/src/renderer/src/locales/en.ts @@ -764,6 +764,7 @@ export default { mapServer: 'Live map server', showMap: 'Show live map on the site', mapRound: 'Round to (blocks)', + mapRoundHint: '0 publishes exact positions. Any other value hides them: a player is drawn up to half of it away from where they really are, which on a terrain map looks like a mistake rather than like privacy.', mapNames: 'Show names', mapHeads: 'Draw skin heads', mapWorld: 'Show the terrain', @@ -914,6 +915,7 @@ export default { mapStructures: 'Structures', mapHeat: 'Heatmap', mapRound: 'Round positions to', + mapRoundHint: '0 publishes exact positions. Any other value draws a player up to half of it from where they really are.', mapPin: 'Pin one world', mapPinAny: 'Let visitors switch', siteSection: 'Public website', diff --git a/src/renderer/src/locales/tr.ts b/src/renderer/src/locales/tr.ts index 07ec2a0..d837740 100644 --- a/src/renderer/src/locales/tr.ts +++ b/src/renderer/src/locales/tr.ts @@ -768,6 +768,7 @@ const tr: typeof en = { mapServer: 'Canlı harita sunucusu', showMap: 'Sitede canlı haritayı göster', mapRound: 'Yuvarlama (blok)', + mapRoundHint: '0 tam konumu yayımlar. Başka bir değer konumu gizler: oyuncu, gerçekte durduğu yerden bu değerin yarısı kadar uzakta çizilir — arazi haritasında bu, gizlilikten çok yerleştirme hatası gibi görünür.', mapNames: 'İsimleri göster', mapHeads: 'Oyuncu kafalarını çiz', mapWorld: 'Araziyi göster', @@ -918,6 +919,7 @@ const tr: typeof en = { mapStructures: 'Yapılar', mapHeat: 'Isı haritası', mapRound: 'Konumları şuna yuvarla', + mapRoundHint: '0 tam konumu yayımlar. Başka bir değer oyuncuyu gerçek yerinden bu değerin yarısı kadar uzakta çizer.', mapPin: 'Tek dünyaya sabitle', mapPinAny: 'Ziyaretçi değiştirebilsin', siteSection: 'Herkese açık site', diff --git a/src/renderer/src/views/SiteView.tsx b/src/renderer/src/views/SiteView.tsx index 9686eb8..ed03632 100644 --- a/src/renderer/src/views/SiteView.tsx +++ b/src/renderer/src/views/SiteView.tsx @@ -196,6 +196,11 @@ export function SiteView(): JSX.Element { patchMap({ enabled: e.target.checked })} /> {t('site.showMap')} + {/* The number that decides whether the map looks right. Said in + blocks and in consequences, because "Round to 64" reads as a + display nicety and is actually "every player is drawn up to 32 + blocks from where they are" — which on a map that now draws real + terrain is indistinguishable from a bug. */}
patchMap({ round: Number(e.target.value) })} />
+

+ {t('site.mapRoundHint')} +