Skip to content

Commit 0c1b958

Browse files
Matrixbirdsclaude
andcommitted
fix: remove conflicting COI service worker and add SW update detection
- Remove coi-serviceworker.js script tag from both games (Godot's own SW already handles COOP/COEP headers, the duplicate caused conflicts) - Add auto-deregistration of stale COI service workers on page load - Add update banner that detects new SW versions and prompts user to reload for fresh assets - controllerchange listener auto-reloads when new SW activates Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent be32b8e commit 0c1b958

2 files changed

Lines changed: 245 additions & 2 deletions

File tree

infinite-loop-hex/index.html

Lines changed: 119 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,12 +108,62 @@
108108
padding: 4px 6px;
109109
visibility: visible;
110110
}
111+
112+
#update-banner {
113+
display: none;
114+
position: fixed;
115+
top: 0;
116+
left: 0;
117+
right: 0;
118+
background: linear-gradient(135deg, #2d6a4f, #40916c);
119+
color: #fff;
120+
font-family: 'Noto Sans', 'Droid Sans', Arial, sans-serif;
121+
font-size: 14px;
122+
padding: 10px 16px;
123+
z-index: 9999;
124+
text-align: center;
125+
box-shadow: 0 2px 8px rgba(0,0,0,0.3);
126+
}
127+
128+
#update-banner button {
129+
background: #fff;
130+
color: #2d6a4f;
131+
border: none;
132+
border-radius: 4px;
133+
padding: 4px 14px;
134+
margin-left: 12px;
135+
font-weight: bold;
136+
cursor: pointer;
137+
font-size: 13px;
138+
}
139+
140+
#update-banner button:hover {
141+
background: #d8f3dc;
142+
}
143+
144+
#update-banner .dismiss {
145+
background: transparent;
146+
color: rgba(255,255,255,0.8);
147+
margin-left: 8px;
148+
padding: 4px 8px;
149+
font-size: 16px;
150+
}
151+
152+
#update-banner .dismiss:hover {
153+
color: #fff;
154+
}
111155
</style>
112156
<link id='-gd-engine-icon' rel='icon' type='image/png' href='index.icon.png' />
113157
<link rel='apple-touch-icon' href='index.apple-touch-icon.png'/>
114158

115159
</head>
116160
<body>
161+
<div id="update-banner">
162+
A new version is available!
163+
<button onclick="updateAndReload()">Update Now</button>
164+
<button class="dismiss" onclick="this.parentElement.style.display='none'">&times;</button>
165+
</div>
166+
117167
<canvas id="canvas">
118168
HTML5 canvas appears to be unsupported in the current browser.<br >
119169
Please try updating or use a different browser.
@@ -135,9 +185,77 @@
135185
<div id="status-notice" class="godot" style="display: none;"></div>
136186
</div>
137187

138-
<script src="coi-serviceworker.js"></script>
139188
<script src="index.js"></script>
140189
<script>
190+
/**
191+
* Service Worker Update Manager
192+
* - Deregisters stale COI service workers that conflict with game loading
193+
* - Detects new SW versions and shows an update banner
194+
*/
195+
let _pendingWorker = null;
196+
197+
function updateAndReload() {
198+
if (_pendingWorker) {
199+
_pendingWorker.postMessage('update');
200+
} else {
201+
// Clear all caches and hard reload
202+
if ('serviceWorker' in navigator) {
203+
navigator.serviceWorker.getRegistrations().then(function (registrations) {
204+
registrations.forEach(function (reg) { reg.unregister(); });
205+
});
206+
caches.keys().then(function (names) {
207+
names.forEach(function (name) { caches.delete(name); });
208+
});
209+
}
210+
setTimeout(function () { window.location.reload(); }, 300);
211+
}
212+
}
213+
214+
(function () {
215+
if (!('serviceWorker' in navigator)) return;
216+
217+
// Deregister stale COI service workers
218+
navigator.serviceWorker.getRegistrations().then(function (registrations) {
219+
registrations.forEach(function (reg) {
220+
if (reg.active && reg.active.scriptURL.indexOf('coi-serviceworker') !== -1) {
221+
console.log('[SW] Deregistering stale COI service worker:', reg.active.scriptURL);
222+
reg.unregister().then(function () {
223+
console.log('[SW] COI service worker removed — reloading');
224+
window.location.reload();
225+
});
226+
}
227+
});
228+
});
229+
230+
// Monitor for SW updates (if any SW is registered)
231+
navigator.serviceWorker.getRegistration().then(function (reg) {
232+
if (!reg) return;
233+
234+
if (reg.waiting) {
235+
_pendingWorker = reg.waiting;
236+
document.getElementById('update-banner').style.display = 'block';
237+
}
238+
239+
reg.addEventListener('updatefound', function () {
240+
var newWorker = reg.installing;
241+
if (!newWorker) return;
242+
243+
newWorker.addEventListener('statechange', function () {
244+
if (newWorker.state === 'installed' && navigator.serviceWorker.controller) {
245+
_pendingWorker = newWorker;
246+
document.getElementById('update-banner').style.display = 'block';
247+
console.log('[SW] New version available — update banner shown');
248+
}
249+
});
250+
});
251+
});
252+
253+
navigator.serviceWorker.addEventListener('controllerchange', function () {
254+
console.log('[SW] New service worker activated — reloading');
255+
window.location.reload();
256+
});
257+
}());
258+
141259
const GODOT_CONFIG = {"args":[],"canvasResizePolicy":2,"executable":"index","experimentalVK":false,"fileSizes":{"index.pck":56544,"index.wasm":28001575},"focusCanvas":true,"gdextensionLibs":[]};
142260
const engine = new Engine(GODOT_CONFIG);
143261

vibe-money/index.html

Lines changed: 126 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<!DOCTYPE html>
22
<html lang="en">
3-
<head><script src="coi-serviceworker.js"></script>
3+
<head>
44
<meta charset="utf-8">
55
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0">
66
<title>Vibe Money</title>
@@ -89,13 +89,63 @@
8989
text-align: center;
9090
z-index: 1;
9191
}
92+
93+
#update-banner {
94+
display: none;
95+
position: fixed;
96+
top: 0;
97+
left: 0;
98+
right: 0;
99+
background: linear-gradient(135deg, #2d6a4f, #40916c);
100+
color: #fff;
101+
font-family: 'Noto Sans', 'Droid Sans', Arial, sans-serif;
102+
font-size: 14px;
103+
padding: 10px 16px;
104+
z-index: 9999;
105+
text-align: center;
106+
box-shadow: 0 2px 8px rgba(0,0,0,0.3);
107+
}
108+
109+
#update-banner button {
110+
background: #fff;
111+
color: #2d6a4f;
112+
border: none;
113+
border-radius: 4px;
114+
padding: 4px 14px;
115+
margin-left: 12px;
116+
font-weight: bold;
117+
cursor: pointer;
118+
font-size: 13px;
119+
}
120+
121+
#update-banner button:hover {
122+
background: #d8f3dc;
123+
}
124+
125+
#update-banner .dismiss {
126+
background: transparent;
127+
color: rgba(255,255,255,0.8);
128+
margin-left: 8px;
129+
padding: 4px 8px;
130+
font-size: 16px;
131+
}
132+
133+
#update-banner .dismiss:hover {
134+
color: #fff;
135+
}
92136
</style>
93137
<link id="-gd-engine-icon" rel="icon" type="image/png" href="index.icon.png" />
94138
<link rel="apple-touch-icon" href="index.apple-touch-icon.png"/>
95139
<link rel="manifest" href="index.manifest.json">
96140

97141
</head>
98142
<body>
143+
<div id="update-banner">
144+
A new version is available!
145+
<button onclick="updateAndReload()">Update Now</button>
146+
<button class="dismiss" onclick="this.parentElement.style.display='none'">&times;</button>
147+
</div>
148+
99149
<canvas id="canvas">
100150
Your browser does not support the canvas tag.
101151
</canvas>
@@ -112,6 +162,81 @@
112162

113163
<script src="index.js"></script>
114164
<script>
165+
/**
166+
* Service Worker Update Manager
167+
* - Deregisters stale COI service workers that conflict with Godot's SW
168+
* - Detects new Godot SW versions and shows an update banner
169+
*/
170+
let _pendingWorker = null;
171+
172+
function updateAndReload() {
173+
if (_pendingWorker) {
174+
// Tell Godot SW to activate immediately and reload all clients
175+
_pendingWorker.postMessage('update');
176+
} else {
177+
// Fallback: clear cache and hard reload
178+
if ('serviceWorker' in navigator) {
179+
navigator.serviceWorker.getRegistration().then(function (reg) {
180+
if (reg && reg.active) {
181+
reg.active.postMessage('clear');
182+
}
183+
});
184+
}
185+
setTimeout(function () { window.location.reload(); }, 300);
186+
}
187+
}
188+
189+
// Deregister any rogue COI service worker, then set up update monitoring
190+
(function () {
191+
if (!('serviceWorker' in navigator)) return;
192+
193+
// Phase 1: Find and deregister stale COI service workers
194+
navigator.serviceWorker.getRegistrations().then(function (registrations) {
195+
registrations.forEach(function (reg) {
196+
// COI SW script URL contains "coi-serviceworker"
197+
if (reg.active && reg.active.scriptURL.indexOf('coi-serviceworker') !== -1) {
198+
console.log('[SW] Deregistering stale COI service worker:', reg.active.scriptURL);
199+
reg.unregister().then(function () {
200+
console.log('[SW] COI service worker removed — reloading');
201+
window.location.reload();
202+
});
203+
}
204+
});
205+
});
206+
207+
// Phase 2: Monitor Godot's service worker for updates
208+
navigator.serviceWorker.getRegistration().then(function (reg) {
209+
if (!reg) return;
210+
211+
// A new worker is already waiting (installed before page load)
212+
if (reg.waiting) {
213+
_pendingWorker = reg.waiting;
214+
document.getElementById('update-banner').style.display = 'block';
215+
}
216+
217+
// Listen for future updates
218+
reg.addEventListener('updatefound', function () {
219+
var newWorker = reg.installing;
220+
if (!newWorker) return;
221+
222+
newWorker.addEventListener('statechange', function () {
223+
// New version installed and ready to activate
224+
if (newWorker.state === 'installed' && navigator.serviceWorker.controller) {
225+
_pendingWorker = newWorker;
226+
document.getElementById('update-banner').style.display = 'block';
227+
console.log('[SW] New version available — update banner shown');
228+
}
229+
});
230+
});
231+
});
232+
233+
// If the new SW took control (e.g. via skipWaiting), reload to get fresh assets
234+
navigator.serviceWorker.addEventListener('controllerchange', function () {
235+
console.log('[SW] New service worker activated — reloading');
236+
window.location.reload();
237+
});
238+
}());
239+
115240
const GODOT_CONFIG = {"args":[],"canvasResizePolicy":2,"emscriptenPoolSize":8,"ensureCrossOriginIsolationHeaders":true,"executable":"index","experimentalVK":false,"fileSizes":{"index.pck":302796,"index.wasm":37685705},"focusCanvas":true,"gdextensionLibs":[],"godotPoolSize":4,"serviceWorker":"index.service.worker.js"};
116241
const GODOT_THREADS_ENABLED = false;
117242
const engine = new Engine(GODOT_CONFIG);

0 commit comments

Comments
 (0)