removed fingerprint again and added salt for the name creator

This commit is contained in:
jenz 2026-06-06 22:10:59 +01:00
parent 4e4bd6a145
commit d02a51f0ca
3 changed files with 67 additions and 79 deletions

View File

@ -151,67 +151,37 @@
</div> </div>
<script type="module"> <script type="module">
const fpPromise = import('https://openfpcdn.io/fingerprintjs/v5') // ── Name generation from IP ───────────────────────────────────────────
.then(FingerprintJS => FingerprintJS.load());
function hashString(str) { function hashString(str) {
let hash = 5381; let hash = 5381;
for (let i = 0; i < str.length; i++) { for (let i = 0; i < str.length; i++) {
hash = ((hash << 5) + hash) + str.charCodeAt(i); hash = ((hash << 5) + hash) + str.charCodeAt(i);
hash = hash & 0x7fffffff; // keep positive 31-bit hash = hash & 0x7fffffff;
} }
return hash; return hash;
} }
function visitorIdToName(input) {
const adjectives = [
'Fast', 'Slow', 'Red', 'Blue', 'Green', 'Dark', 'Bright', 'Wild',
'Cool', 'Hot', 'Big', 'Small', 'Sharp', 'Brave', 'Swift', 'Bold'
];
const nouns = [
'Wolf', 'Eagle', 'Tiger', 'Bear', 'Fox', 'Lion', 'Hawk', 'Shark',
'Snake', 'Raven', 'Storm', 'Rock', 'Fire', 'Ice', 'Wind', 'Steel'
];
const h1 = hashString(input);
const h2 = hashString(input + '1');
const h3 = hashString(input + '2');
const adjIndex = h1 % adjectives.length;
const nounIndex = h2 % nouns.length;
const number = h3 % 9999;
return `${adjectives[adjIndex]} ${nouns[nounIndex]} ${number}`;
}
let visitorName = null; let visitorName = null;
async function initVisitorName() { async function initVisitorName() {
try { await new Promise(resolve => {
const fp = await fpPromise;
const result = await fp.get();
if (result.visitorId) {
visitorName = visitorIdToName(result.visitorId);
return;
}
} catch (e) {
}
// Fallback: request IP from server
// Wait until WebSocket is open
const waitForIp = new Promise(resolve => {
const handler = e => { const handler = e => {
if (e.data instanceof Blob) return; if (e.data instanceof Blob) return;
const msg = JSON.parse(e.data); try {
if (msg.type === 'your_ip') { const msg = JSON.parse(e.data);
visitorName = visitorIdToName(msg.ip); if (msg.type === 'your_ip') {
sigWs.removeEventListener('message', handler); visitorName = msg.ip; // server already sent the name
resolve(); sigWs.removeEventListener('message', handler);
} resolve();
}
} catch {}
}; };
sigWs.addEventListener('message', handler); sigWs.addEventListener('message', handler);
sigWs.send(JSON.stringify({ type: 'get_ip' })); sigWs.send(JSON.stringify({ type: 'get_ip' }));
}); });
await waitForIp;
} }
// ── State ─────────────────────────────────────────────────────────────
const SIG_URL = `${location.protocol === 'https:' ? 'wss' : 'ws'}://${location.host}`; const SIG_URL = `${location.protocol === 'https:' ? 'wss' : 'ws'}://${location.host}`;
const statusEl = document.getElementById('status'); const statusEl = document.getElementById('status');
@ -220,17 +190,15 @@
const queueList = document.getElementById('queue-list'); const queueList = document.getElementById('queue-list');
const loadingEl = document.getElementById('loading-overlay'); const loadingEl = document.getElementById('loading-overlay');
let sigWs = null; let sigWs = null;
let pc = null; let pc = null;
let sessionId = null; let sessionId = null;
let pointerLocked = false; let pointerLocked = false;
let isControlling = false; let isControlling = false;
let isInQueue = false; let isInQueue = false;
let isWaitingForRestart = false; let isWaitingForRestart = false;
function setStatus(msg) { function setStatus(msg) { statusEl.textContent = msg; }
statusEl.textContent = msg;
}
function setLoading(visible) { function setLoading(visible) {
loadingEl.classList.toggle('visible', visible); loadingEl.classList.toggle('visible', visible);
@ -270,9 +238,7 @@
video: false, video: false,
}); });
return true; return true;
} catch (e) { } catch (e) { return false; }
return false;
}
} }
async function startMic() { async function startMic() {
@ -292,7 +258,9 @@
if (sigWs && sigWs.readyState === WebSocket.OPEN) sigWs.send(int16.buffer); if (sigWs && sigWs.readyState === WebSocket.OPEN) sigWs.send(int16.buffer);
}; };
source.connect(micProcessor); source.connect(micProcessor);
micProcessor.connect(audioContext.destination); // Connect to a dummy destination to keep onaudioprocess firing
// without routing audio to speakers
micProcessor.connect(audioContext.createMediaStreamDestination());
micActive = true; micActive = true;
} }
@ -316,9 +284,9 @@
} }
function enterControl() { function enterControl() {
isControlling = true; isControlling = true;
isInQueue = false; isInQueue = false;
isWaitingForRestart = false; isWaitingForRestart = false;
canvas.classList.replace('watching', 'controlling'); canvas.classList.replace('watching', 'controlling');
canvas.muted = false; canvas.muted = false;
canvas.requestPointerLock(); canvas.requestPointerLock();
@ -326,15 +294,13 @@
} }
function exitControl() { function exitControl() {
isControlling = false; isControlling = false;
isInQueue = false; isInQueue = false;
isWaitingForRestart = false; isWaitingForRestart = false;
canvas.classList.replace('controlling', 'watching'); canvas.classList.replace('controlling', 'watching');
hintEl.textContent = 'Click to take control'; hintEl.textContent = 'Click to take control';
stopMic(); stopMic();
if (document.pointerLockElement === canvas) { if (document.pointerLockElement === canvas) document.exitPointerLock();
document.exitPointerLock();
}
} }
// ── WebRTC ──────────────────────────────────────────────────────────── // ── WebRTC ────────────────────────────────────────────────────────────
@ -366,12 +332,11 @@
setStatus('Connecting...'); setStatus('Connecting...');
sigWs = new WebSocket(SIG_URL); sigWs = new WebSocket(SIG_URL);
sigWs.onopen = () => { sigWs.onopen = () => {
setStatus('Connected — setting up stream...'); setStatus('Connected — setting up stream...');
initVisitorName().then(() => { initVisitorName();
}); setupPeerConnection();
setupPeerConnection(); };
};
sigWs.onmessage = async e => { sigWs.onmessage = async e => {
if (e.data instanceof Blob) return; if (e.data instanceof Blob) return;
@ -443,13 +408,12 @@
} }
canvas.addEventListener('click', () => { canvas.addEventListener('click', () => {
if (isControlling) { if (isControlling) {
// Already controller, just recapture pointer lock canvas.muted = false;
canvas.muted = false; canvas.requestPointerLock();
canvas.requestPointerLock(); } else {
} else { requestControl();
requestControl(); }
}
}); });
document.addEventListener('pointerlockchange', () => { document.addEventListener('pointerlockchange', () => {

View File

@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
cd ~/webclient_css_ze/streaming-agent cd ~/webclient_css_ze/streaming-agent
CF_APP_ID= CF_APP_TOKEN= node signaling-server.js &> ../signaling.log & CF_APP_ID= CF_APP_TOKEN= NAME_SALT= node signaling-server.js &> ../signaling.log &
echo "Signaling server started (PID $!), logs at webclient_css_ze/signaling.log" echo "Signaling server started (PID $!), logs at webclient_css_ze/signaling.log"
#pkill -f signaling-server.js #pkill -f signaling-server.js

View File

@ -204,6 +204,29 @@ function stopPacat(browserSessId) {
if (pacat) { pacat.kill(); pacatProcesses.delete(browserSessId); } if (pacat) { pacat.kill(); pacatProcesses.delete(browserSessId); }
} }
const NAME_SALT = process.env.NAME_SALT || 'change-this-secret';
function hashString(str) {
let hash = 5381;
for (let i = 0; i < str.length; i++) {
hash = ((hash << 5) + hash) + str.charCodeAt(i);
hash = hash & 0x7fffffff;
}
return hash;
}
function ipToName(ip) {
const adjectives = ['Fast','Slow','Red','Blue','Green','Dark','Bright','Wild',
'Cool','Hot','Big','Small','Sharp','Brave','Swift','Bold'];
const nouns = ['Wolf','Eagle','Tiger','Bear','Fox','Lion','Hawk','Shark',
'Snake','Raven','Storm','Rock','Fire','Ice','Wind','Steel'];
const salted = ip + NAME_SALT;
const h1 = hashString(salted);
const h2 = hashString(salted + '1');
const h3 = hashString(salted + '2');
return `${adjectives[h1 % adjectives.length]} ${nouns[h2 % nouns.length]} ${h3 % 9999}`;
}
// ── WebSocket handler ───────────────────────────────────────────────────────── // ── WebSocket handler ─────────────────────────────────────────────────────────
wss.on('connection', ws => { wss.on('connection', ws => {
let role = null; let role = null;
@ -337,7 +360,8 @@ wss.on('connection', ws => {
} }
else if (msg.type === 'get_ip') { else if (msg.type === 'get_ip') {
const ip = ws._socket.remoteAddress.replace('::ffff:', ''); const ip = ws._socket.remoteAddress.replace('::ffff:', '');
ws.send(JSON.stringify({ type: 'your_ip', ip })); const name = ipToName(ip);
ws.send(JSON.stringify({ type: 'your_ip', ip: name }));
} }
}); });