blockyard 0.0.9 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/CHANGELOG.md +359 -1
  2. package/README.md +48 -27
  3. package/SECURITY.md +2 -2
  4. package/bin/blockyard.js +2 -1
  5. package/docs/API.md +17 -15
  6. package/docs/ARCHITECTURE.md +128 -10
  7. package/docs/CONFIGURATION.md +39 -30
  8. package/docs/DEFECTS.md +4 -1
  9. package/docs/GETTING-STARTED.md +18 -8
  10. package/docs/INSTALL.md +97 -37
  11. package/docs/MEASUREMENTS.md +147 -0
  12. package/docs/PLAN-SCORCHED-YARD.md +456 -0
  13. package/docs/PLAN-SKIES.md +142 -0
  14. package/docs/SECURITY-AUDIT-2026-09-16.md +647 -0
  15. package/docs/SECURITY.md +58 -22
  16. package/docs/TROUBLESHOOTING.md +44 -5
  17. package/docs/USER-GUIDE.md +505 -35
  18. package/package.json +4 -2
  19. package/public/404.html +1 -1
  20. package/public/css/app.css +393 -82
  21. package/public/donate-qr.png +0 -0
  22. package/public/index.html +353 -109
  23. package/public/js/agents.js +228 -51
  24. package/public/js/app.js +131 -16
  25. package/public/js/blockanoid.js +15 -7
  26. package/public/js/blockout.js +15 -7
  27. package/public/js/blockscene3d.js +230 -38
  28. package/public/js/charts.js +21 -21
  29. package/public/js/depthchart.js +31 -27
  30. package/public/js/details3d.js +1481 -73
  31. package/public/js/doom.js +31 -0
  32. package/public/js/dosaudio.js +48 -0
  33. package/public/js/dosgame.js +389 -0
  34. package/public/js/dosio.js +186 -0
  35. package/public/js/dospc.js +1353 -0
  36. package/public/js/dosworker.js +196 -0
  37. package/public/js/explorer.js +7 -1
  38. package/public/js/livingsky.js +494 -0
  39. package/public/js/login.js +8 -2
  40. package/public/js/markets.js +46 -8
  41. package/public/js/mining.js +314 -36
  42. package/public/js/panels.js +41 -28
  43. package/public/js/pricechart.js +14 -13
  44. package/public/js/quake.js +20 -0
  45. package/public/js/safenext.js +14 -0
  46. package/public/js/scorched.js +1051 -0
  47. package/public/js/scorchedai.js +227 -0
  48. package/public/js/scorchedair.js +286 -0
  49. package/public/js/scorchedfx.js +376 -0
  50. package/public/js/scorchedshop.js +105 -0
  51. package/public/js/scorchedwind.js +69 -0
  52. package/public/js/scorchedyard.js +1338 -0
  53. package/public/js/settings.js +368 -100
  54. package/public/js/soundcard.js +459 -0
  55. package/public/js/tetrust.js +15 -6
  56. package/public/js/tetsound.js +35 -5
  57. package/public/js/theme.js +235 -0
  58. package/public/js/wolf3d.js +22 -0
  59. package/public/js/x86.js +1978 -0
  60. package/scripts/check.js +46 -0
  61. package/scripts/donate-qr.py +12 -9
  62. package/scripts/dos-bench.js +56 -0
  63. package/scripts/index-build.js +9 -2
  64. package/scripts/pool-map.js +152 -36
  65. package/scripts/setup.js +142 -22
  66. package/scripts/shots.mjs +27 -0
  67. package/scripts/smoke.sh +7 -6
  68. package/scripts/tls.js +31 -0
  69. package/scripts/ui.js +4 -2
  70. package/server/auth/sessions.js +33 -13
  71. package/server/chain/blockfile.js +64 -5
  72. package/server/chain/index/build.js +451 -58
  73. package/server/chain/index/heights.js +29 -3
  74. package/server/chain/index/live.js +13 -7
  75. package/server/chain/index/rows.js +6 -1
  76. package/server/chain/index/store.js +28 -5
  77. package/server/chain/index/worker.js +23 -11
  78. package/server/collect/logparse.js +65 -18
  79. package/server/collect/markets.js +76 -7
  80. package/server/collect/mining.js +32 -0
  81. package/server/collect/monitor.js +54 -12
  82. package/server/collect/network.js +305 -0
  83. package/server/config.js +53 -22
  84. package/server/http/api.js +119 -18
  85. package/server/http/games.js +77 -0
  86. package/server/http/server.js +30 -5
  87. package/server/http/sse.js +53 -7
  88. package/server/main.js +66 -11
  89. package/server/rpc/allowlist.js +26 -0
  90. package/server/rpc/client.js +30 -2
  91. package/server/store/audit.js +6 -1
  92. package/server/store/history.js +19 -3
  93. package/server/store/ledger.js +15 -4
  94. package/server/tls/selfsigned.js +160 -0
  95. package/systemd/blockyard.service +41 -8
  96. package/docs/PRIVATE-LEADERBOARD.md +0 -230
  97. package/docs/STATE-2026-09-09.md +0 -200
@@ -4,6 +4,7 @@
4
4
  // crosshair that says exactly what an hour did. This is that chart. The 3D board under it is a
5
5
  // view of the same hours, not a substitute for it.
6
6
  import { niceTicks } from './charts.js';
7
+ import { INK } from './theme.js'; // the axis, grid and tooltip colours of the chosen theme
7
8
 
8
9
  export const EX_COLORS = { coinbase: '#4c8dff', kraken: '#a78bfa', bitstamp: '#2ecc8f', bitfinex: '#4dd0e1', okx: '#f0b429' };
9
10
  const UP = '#26c281', DOWN = '#ef5350';
@@ -79,7 +80,7 @@ export function drawPriceChart(canvas, { candles = [], overlays = [], name = '',
79
80
  if (!canvas?.getContext) return null;
80
81
  const { ctx, w, h } = prep(canvas);
81
82
  if (!candles.length) {
82
- ctx.fillStyle = '#6a7484'; ctx.textAlign = 'center';
83
+ ctx.fillStyle = INK.text; ctx.textAlign = 'center';
83
84
  ctx.fillText('no candles yet', w / 2, h / 2);
84
85
  return null;
85
86
  }
@@ -92,22 +93,22 @@ export function drawPriceChart(canvas, { candles = [], overlays = [], name = '',
92
93
  for (const v of niceTicks(L.lo, L.hi, Math.max(3, Math.floor(L.priceH / 46)))) {
93
94
  const y = Math.round(L.Y(v)) + 0.5;
94
95
  if (y < PAD.top || y > PAD.top + L.priceH) continue;
95
- ctx.strokeStyle = '#1a2029';
96
+ ctx.strokeStyle = INK.grid;
96
97
  ctx.beginPath(); ctx.moveTo(PAD.left, y); ctx.lineTo(right, y); ctx.stroke();
97
- ctx.fillStyle = '#7d8898';
98
+ ctx.fillStyle = INK.axisText;
98
99
  ctx.fillText(money(v, 0), right + 7, y);
99
100
  }
100
101
  // time grid and axis
101
102
  ctx.textAlign = 'center';
102
103
  for (const tk of timeTicks(L.t0, L.t1, L.plotW)) {
103
104
  const x = Math.round(L.XT(tk.t)) + 0.5;
104
- ctx.strokeStyle = tk.label.includes(' ') ? '#27303b' : '#161b22';
105
+ ctx.strokeStyle = tk.label.includes(' ') ? INK.axis : INK.grid;
105
106
  ctx.beginPath(); ctx.moveTo(x, PAD.top); ctx.lineTo(x, L.VY0); ctx.stroke();
106
- ctx.fillStyle = tk.label.includes(' ') ? '#b5c0cc' : '#7d8898';
107
+ ctx.fillStyle = tk.label.includes(' ') ? INK.label : INK.axisText;
107
108
  ctx.fillText(tk.label, x, h - PAD.bottom / 2);
108
109
  }
109
110
  // the pane edges
110
- ctx.strokeStyle = '#2a323d';
111
+ ctx.strokeStyle = INK.axis;
111
112
  ctx.beginPath(); ctx.moveTo(right + 0.5, PAD.top); ctx.lineTo(right + 0.5, L.VY0); ctx.stroke();
112
113
  ctx.beginPath(); ctx.moveTo(PAD.left, L.VY0 + 0.5); ctx.lineTo(right, L.VY0 + 0.5); ctx.stroke();
113
114
 
@@ -119,7 +120,7 @@ export function drawPriceChart(canvas, { candles = [], overlays = [], name = '',
119
120
  ctx.fillStyle = k.c >= k.o ? UP_V : DOWN_V;
120
121
  ctx.fillRect(L.X(i) - bodyW / 2, L.VY0 - vh, bodyW, vh);
121
122
  });
122
- ctx.fillStyle = '#56606e'; ctx.textAlign = 'left';
123
+ ctx.fillStyle = INK.textDim; ctx.textAlign = 'left';
123
124
  ctx.fillText('volume', PAD.left + 4, L.VY0 - L.volH + 6);
124
125
 
125
126
  // the other exchanges, as thin close lines
@@ -152,7 +153,7 @@ export function drawPriceChart(canvas, { candles = [], overlays = [], name = '',
152
153
  ctx.beginPath(); ctx.moveTo(PAD.left, ly); ctx.lineTo(right, ly); ctx.stroke();
153
154
  ctx.setLineDash([]);
154
155
  ctx.fillStyle = lcol; ctx.fillRect(right + 1, ly - 9, PAD.right - 2, 18);
155
- ctx.fillStyle = '#ffffff'; ctx.textAlign = 'left';
156
+ ctx.fillStyle = INK.bright; ctx.textAlign = 'left';
156
157
  ctx.fillText(money(lastK.c), right + 6, ly);
157
158
 
158
159
  // the crosshair
@@ -161,26 +162,26 @@ export function drawPriceChart(canvas, { candles = [], overlays = [], name = '',
161
162
  const i = L.index(hover.x);
162
163
  shown = candles[i];
163
164
  const x = Math.round(L.X(i)) + 0.5;
164
- ctx.strokeStyle = 'rgba(200,215,230,0.45)'; ctx.setLineDash([3, 3]);
165
+ ctx.strokeStyle = INK.dash; ctx.setLineDash([3, 3]);
165
166
  ctx.beginPath(); ctx.moveTo(x, PAD.top); ctx.lineTo(x, L.VY0); ctx.stroke();
166
167
  if (hover.y >= PAD.top && hover.y <= PAD.top + L.priceH) {
167
168
  const y = Math.round(hover.y) + 0.5;
168
169
  ctx.beginPath(); ctx.moveTo(PAD.left, y); ctx.lineTo(right, y); ctx.stroke();
169
170
  ctx.setLineDash([]);
170
- ctx.fillStyle = '#3a4452'; ctx.fillRect(right + 1, y - 9, PAD.right - 2, 18);
171
- ctx.fillStyle = '#ffffff'; ctx.fillText(money(L.V(hover.y)), right + 6, y);
171
+ ctx.fillStyle = INK.cursorFill; ctx.fillRect(right + 1, y - 9, PAD.right - 2, 18);
172
+ ctx.fillStyle = INK.cursorText; ctx.fillText(money(L.V(hover.y)), right + 6, y);
172
173
  }
173
174
  ctx.setLineDash([]);
174
175
  }
175
176
  // readout (top-left) and overlay legend (top-right)
176
177
  ctx.textAlign = 'left';
177
- ctx.fillStyle = '#dfe6ee';
178
+ ctx.fillStyle = INK.bright;
178
179
  ctx.fillText(readout(shown, name), PAD.left + 2, 12);
179
180
  ctx.textAlign = 'right';
180
181
  let lx = right;
181
182
  for (const o of [...overlays].reverse()) {
182
183
  const wT = ctx.measureText(o.name).width;
183
- ctx.fillStyle = '#9aa5b3'; ctx.fillText(o.name, lx, 12);
184
+ ctx.fillStyle = INK.label; ctx.fillText(o.name, lx, 12);
184
185
  ctx.fillStyle = o.color; ctx.fillRect(lx - wT - 16, 11, 11, 2);
185
186
  lx -= wT + 26;
186
187
  }
@@ -0,0 +1,20 @@
1
+ // QUAKE, the tab (operator, 2026-09-15: "yes, get Quake working as a diversion").
2
+ //
3
+ // The shareware QUAKE.EXE v1.06 and its PAK0.PAK from games/quake_dos/, unmodified, on the emulated
4
+ // PC (dosgame.js has the tab, dosworker.js the machine). Quake is a DJGPP program where DOOM was a
5
+ // DOS/4GW one, so the same machine plays the go32 stub and CWSDPMI for it (dospc.js bootCoff), and it
6
+ // asks far more of the FPU. Its keys are its own: W A S D and mouse look on the first run
7
+ // (dosio.js quakeAutoexec), and after that whatever the player binds in Quake's own menu.
8
+ import { createDosGame } from './dosgame.js';
9
+
10
+ export const renderQuake = createDosGame({
11
+ game: 'quake',
12
+ page: 'quake',
13
+ prefix: 'quake',
14
+ title: 'Quake',
15
+ idleText: 'The shareware episode, Dimension of the Doomed: the real QUAKE.EXE v1.06 running on a PC this monitor emulates. Click the screen to use the mouse.',
16
+ loadingText: 'loading the shareware episode (18 MB)…',
17
+ saveName: /\.SAV$/i,
18
+ keysText: () => 'W S walk · A D strafe · mouse to look · left click fire · Space or right click jump · Shift run · 1–8 weapons · − = smaller or bigger view (smaller runs faster) · Esc menu · ~ console · F6 quicksave · F9 quickload',
19
+ switches: [],
20
+ });
@@ -0,0 +1,14 @@
1
+ // The sign-in page's redirect target, checked. Its own module so the tests can hold it without a DOM.
2
+ /**
3
+ * Where to go after signing in: a path on THIS site, or the dashboard (audit 2026-09-16, L1).
4
+ * `startsWith('/')` let `//evil.example/` and `/\\evil.example/` through, and browsers treat both as
5
+ * another host -- a genuine sign-in page that hands you to a lookalike. Resolve it against our own
6
+ * origin and keep it only if the origin did not change.
7
+ */
8
+ export function safeNext(next, origin) {
9
+ if (typeof next !== 'string' || !next.startsWith('/')) return '/';
10
+ try {
11
+ const u = new URL(next, origin);
12
+ return u.origin === new URL(origin).origin ? `${u.pathname}${u.search}${u.hash}` : '/';
13
+ } catch { return '/'; }
14
+ }