Prepare game updates and single-process PM2 deployment

This commit is contained in:
2026-10-14 19:13:36 +09:00
parent 4f24129e29
commit 22792bc2b4
50 changed files with 1546 additions and 197 deletions
+14 -1
View File
@@ -1,12 +1,20 @@
// Diagnostic harness for real-browser testing; excluded from production bundles.
(() => {
const NativePeer = window.RTCPeerConnection, NativeSocket = window.WebSocket;
const trace = []; let sockets = 0, nextPeer = 0;
const trace = [], channels = new Set(); let sockets = 0, nextPeer = 0, dropPackets = false;
document.addEventListener('DOMContentLoaded', () => {
const controls = document.createElement('aside');
controls.style.cssText = 'position:fixed;right:0;top:0;z-index:100;background:white;color:black;padding:4px';
controls.innerHTML = '<label>검증 입력 <select id="test-input"><option value="none">수동</option><option value="charge">충전 반복</option><option value="blast">충전 후 파</option><option value="guard">막기 반복</option></select></label>';
document.body.append(controls);
for (const [label, action] of [
['채널 종료', () => { for (const channel of channels) if (channel.readyState === 'open') channel.close(); }],
['패킷 차단', () => { dropPackets = true; report('packets-blocked'); }],
['패킷 복구', () => { dropPackets = false; report('packets-restored'); }],
]) {
const button = document.createElement('button'); button.textContent = label;
button.onclick = action; controls.append(button);
}
setInterval(() => {
const mode = controls.querySelector('select').value;
if (mode === 'none') return;
@@ -36,6 +44,11 @@
setConfiguration(value) { try { super.setConfiguration(value); report('configuration-updated', { id: this.testId }); } catch (error) { report('configuration-error', { message: error.message, state: this.connectionState, before: this.getConfiguration().bundlePolicy, after: value.bundlePolicy }); throw error; } }
restartIce() { try { super.restartIce(); report('ice-restart', { id: this.testId }); } catch (error) { report('restart-error', { message: error.message, state: this.connectionState }); throw error; } }
monitor(channel) {
channels.add(channel);
channel.addEventListener('close', () => channels.delete(channel));
const send = channel.send.bind(channel);
channel.send = data => { if (!dropPackets) send(data); };
channel.addEventListener('message', event => { if (dropPackets) event.stopImmediatePropagation(); }, { capture: true });
for (const event of ['open', 'close', 'error']) channel.addEventListener(event, () => report('channel-' + event, { id: this.testId }));
channel.addEventListener('message', event => { try { const m = JSON.parse(event.data); report('message', { id: this.testId, type: m.type, epoch: m.connectionEpoch ?? m.epoch, turn: m.turnId }); } catch {} });
channel.addEventListener('open', () => { void this.getStats().then(stats => {