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.
- package/CHANGELOG.md +359 -1
- package/README.md +48 -27
- package/SECURITY.md +2 -2
- package/bin/blockyard.js +2 -1
- package/docs/API.md +17 -15
- package/docs/ARCHITECTURE.md +128 -10
- package/docs/CONFIGURATION.md +39 -30
- package/docs/DEFECTS.md +4 -1
- package/docs/GETTING-STARTED.md +18 -8
- package/docs/INSTALL.md +97 -37
- package/docs/MEASUREMENTS.md +147 -0
- package/docs/PLAN-SCORCHED-YARD.md +456 -0
- package/docs/PLAN-SKIES.md +142 -0
- package/docs/SECURITY-AUDIT-2026-09-16.md +647 -0
- package/docs/SECURITY.md +58 -22
- package/docs/TROUBLESHOOTING.md +44 -5
- package/docs/USER-GUIDE.md +505 -35
- package/package.json +4 -2
- package/public/404.html +1 -1
- package/public/css/app.css +393 -82
- package/public/donate-qr.png +0 -0
- package/public/index.html +353 -109
- package/public/js/agents.js +228 -51
- package/public/js/app.js +131 -16
- package/public/js/blockanoid.js +15 -7
- package/public/js/blockout.js +15 -7
- package/public/js/blockscene3d.js +230 -38
- package/public/js/charts.js +21 -21
- package/public/js/depthchart.js +31 -27
- package/public/js/details3d.js +1481 -73
- package/public/js/doom.js +31 -0
- package/public/js/dosaudio.js +48 -0
- package/public/js/dosgame.js +389 -0
- package/public/js/dosio.js +186 -0
- package/public/js/dospc.js +1353 -0
- package/public/js/dosworker.js +196 -0
- package/public/js/explorer.js +7 -1
- package/public/js/livingsky.js +494 -0
- package/public/js/login.js +8 -2
- package/public/js/markets.js +46 -8
- package/public/js/mining.js +314 -36
- package/public/js/panels.js +41 -28
- package/public/js/pricechart.js +14 -13
- package/public/js/quake.js +20 -0
- package/public/js/safenext.js +14 -0
- package/public/js/scorched.js +1051 -0
- package/public/js/scorchedai.js +227 -0
- package/public/js/scorchedair.js +286 -0
- package/public/js/scorchedfx.js +376 -0
- package/public/js/scorchedshop.js +105 -0
- package/public/js/scorchedwind.js +69 -0
- package/public/js/scorchedyard.js +1338 -0
- package/public/js/settings.js +368 -100
- package/public/js/soundcard.js +459 -0
- package/public/js/tetrust.js +15 -6
- package/public/js/tetsound.js +35 -5
- package/public/js/theme.js +235 -0
- package/public/js/wolf3d.js +22 -0
- package/public/js/x86.js +1978 -0
- package/scripts/check.js +46 -0
- package/scripts/donate-qr.py +12 -9
- package/scripts/dos-bench.js +56 -0
- package/scripts/index-build.js +9 -2
- package/scripts/pool-map.js +152 -36
- package/scripts/setup.js +142 -22
- package/scripts/shots.mjs +27 -0
- package/scripts/smoke.sh +7 -6
- package/scripts/tls.js +31 -0
- package/scripts/ui.js +4 -2
- package/server/auth/sessions.js +33 -13
- package/server/chain/blockfile.js +64 -5
- package/server/chain/index/build.js +451 -58
- package/server/chain/index/heights.js +29 -3
- package/server/chain/index/live.js +13 -7
- package/server/chain/index/rows.js +6 -1
- package/server/chain/index/store.js +28 -5
- package/server/chain/index/worker.js +23 -11
- package/server/collect/logparse.js +65 -18
- package/server/collect/markets.js +76 -7
- package/server/collect/mining.js +32 -0
- package/server/collect/monitor.js +54 -12
- package/server/collect/network.js +305 -0
- package/server/config.js +53 -22
- package/server/http/api.js +119 -18
- package/server/http/games.js +77 -0
- package/server/http/server.js +30 -5
- package/server/http/sse.js +53 -7
- package/server/main.js +66 -11
- package/server/rpc/allowlist.js +26 -0
- package/server/rpc/client.js +30 -2
- package/server/store/audit.js +6 -1
- package/server/store/history.js +19 -3
- package/server/store/ledger.js +15 -4
- package/server/tls/selfsigned.js +160 -0
- package/systemd/blockyard.service +41 -8
- package/docs/PRIVATE-LEADERBOARD.md +0 -230
- package/docs/STATE-2026-09-09.md +0 -200
package/public/js/pricechart.js
CHANGED
|
@@ -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 =
|
|
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 =
|
|
96
|
+
ctx.strokeStyle = INK.grid;
|
|
96
97
|
ctx.beginPath(); ctx.moveTo(PAD.left, y); ctx.lineTo(right, y); ctx.stroke();
|
|
97
|
-
ctx.fillStyle =
|
|
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(' ') ?
|
|
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(' ') ?
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
171
|
-
ctx.fillStyle =
|
|
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 =
|
|
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 =
|
|
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
|
+
}
|