mirror of
https://github.com/Shik3i/KoalaSync.git
synced 2026-08-28 03:27:10 +00:00
fix: sync FORCE_SYNC_TIMEOUT constant with actual usage, tokenize showError cleanup, fix EVENT_ACK indent
- FORCE_SYNC_TIMEOUT in shared/constants.js was 5000 but all code uses 8500ms. Update constant to 8500 and reference it in background.js instead of hardcoded values (4 occurrences) - Add errorToken counter in popup showError() so stale 5s timeout doesn't clear styling of a newer error that arrived in between - Fix EVENT_ACK handler indentation in server/index.js to match surrounding socket.on handlers
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { EVENTS, PROTOCOL_VERSION, OFFICIAL_SERVER_URL, OFFICIAL_SERVER_TOKEN, APP_VERSION, EPISODE_LOBBY_TIMEOUT } from './shared/constants.js';
|
import { EVENTS, PROTOCOL_VERSION, OFFICIAL_SERVER_URL, OFFICIAL_SERVER_TOKEN, APP_VERSION, EPISODE_LOBBY_TIMEOUT, FORCE_SYNC_TIMEOUT } from './shared/constants.js';
|
||||||
|
|
||||||
// --- State Management ---
|
// --- State Management ---
|
||||||
let socket = null;
|
let socket = null;
|
||||||
@@ -849,7 +849,7 @@ function executeEpisodeLobby() {
|
|||||||
|
|
||||||
isForceSyncInitiator = true;
|
isForceSyncInitiator = true;
|
||||||
forceSyncAcks.clear();
|
forceSyncAcks.clear();
|
||||||
const deadline = Date.now() + 8500;
|
const deadline = Date.now() + FORCE_SYNC_TIMEOUT;
|
||||||
const timestamp = Date.now();
|
const timestamp = Date.now();
|
||||||
updateLastAction(EVENTS.FORCE_SYNC_PREPARE, 'You', timestamp);
|
updateLastAction(EVENTS.FORCE_SYNC_PREPARE, 'You', timestamp);
|
||||||
lastActionState.targetTime = 0.0;
|
lastActionState.targetTime = 0.0;
|
||||||
@@ -869,7 +869,7 @@ function executeEpisodeLobby() {
|
|||||||
addLog('Force Sync (Episode): Timeout waiting for ACKs, executing anyway...', 'warn');
|
addLog('Force Sync (Episode): Timeout waiting for ACKs, executing anyway...', 'warn');
|
||||||
executeForceSync();
|
executeForceSync();
|
||||||
}
|
}
|
||||||
}, 8500);
|
}, FORCE_SYNC_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkEpisodeLobbyCompletion() {
|
function checkEpisodeLobbyCompletion() {
|
||||||
@@ -1149,7 +1149,7 @@ async function handleAsyncMessage(message, sender, sendResponse) {
|
|||||||
if (message.action === EVENTS.FORCE_SYNC_PREPARE) {
|
if (message.action === EVENTS.FORCE_SYNC_PREPARE) {
|
||||||
isForceSyncInitiator = true;
|
isForceSyncInitiator = true;
|
||||||
forceSyncAcks.clear();
|
forceSyncAcks.clear();
|
||||||
const deadline = Date.now() + 8500;
|
const deadline = Date.now() + FORCE_SYNC_TIMEOUT;
|
||||||
chrome.storage.session.set({
|
chrome.storage.session.set({
|
||||||
isForceSyncInitiator: true,
|
isForceSyncInitiator: true,
|
||||||
forceSyncAcks: [],
|
forceSyncAcks: [],
|
||||||
@@ -1164,7 +1164,7 @@ async function handleAsyncMessage(message, sender, sendResponse) {
|
|||||||
addLog('Force Sync: Timeout waiting for ACKs, executing anyway...', 'warn');
|
addLog('Force Sync: Timeout waiting for ACKs, executing anyway...', 'warn');
|
||||||
executeForceSync();
|
executeForceSync();
|
||||||
}
|
}
|
||||||
}, 8500);
|
}, FORCE_SYNC_TIMEOUT);
|
||||||
}
|
}
|
||||||
addToHistory(message.action, 'You');
|
addToHistory(message.action, 'You');
|
||||||
emit(message.action, { ...message.payload, peerId });
|
emit(message.action, { ...message.payload, peerId });
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ let joinBtnTimeout = null;
|
|||||||
let forceSyncResetTimer = null;
|
let forceSyncResetTimer = null;
|
||||||
let popupIntervals = [];
|
let popupIntervals = [];
|
||||||
let populateTabsToken = null;
|
let populateTabsToken = null;
|
||||||
|
let errorToken = 0;
|
||||||
let forceSyncDone = false;
|
let forceSyncDone = false;
|
||||||
|
|
||||||
// --- Initialization ---
|
// --- Initialization ---
|
||||||
@@ -838,6 +839,7 @@ function showToast(message, type = 'info', duration = 3000) {
|
|||||||
|
|
||||||
function showError(msg) {
|
function showError(msg) {
|
||||||
if (!elements.roomError) return;
|
if (!elements.roomError) return;
|
||||||
|
const currentToken = ++errorToken;
|
||||||
elements.roomError.textContent = msg;
|
elements.roomError.textContent = msg;
|
||||||
elements.roomError.style.display = 'block';
|
elements.roomError.style.display = 'block';
|
||||||
elements.roomId.style.borderColor = 'var(--error)';
|
elements.roomId.style.borderColor = 'var(--error)';
|
||||||
@@ -846,6 +848,7 @@ function showError(msg) {
|
|||||||
showToast(msg, 'error', 5000);
|
showToast(msg, 'error', 5000);
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
if (currentToken !== errorToken) return;
|
||||||
if (elements.roomError) elements.roomError.style.display = 'none';
|
if (elements.roomError) elements.roomError.style.display = 'none';
|
||||||
elements.roomId.style.borderColor = '';
|
elements.roomId.style.borderColor = '';
|
||||||
elements.password.style.borderColor = '';
|
elements.password.style.borderColor = '';
|
||||||
|
|||||||
+23
-23
@@ -480,30 +480,30 @@ io.on('connection', (socket) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on(EVENTS.EVENT_ACK, (data) => {
|
socket.on(EVENTS.EVENT_ACK, (data) => {
|
||||||
if (!checkEventRate(socket.id)) {
|
if (!checkEventRate(socket.id)) {
|
||||||
log('SECURITY', `Event rate limit exceeded for socket (ACK): ${socket.id}`);
|
log('SECURITY', `Event rate limit exceeded for socket (ACK): ${socket.id}`);
|
||||||
socket.disconnect(true);
|
socket.disconnect(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!data || typeof data !== 'object') return;
|
if (!data || typeof data !== 'object') return;
|
||||||
if (typeof data.targetId !== 'string') return;
|
if (typeof data.targetId !== 'string') return;
|
||||||
if (data.actionTimestamp !== undefined && (typeof data.actionTimestamp !== 'number' || !Number.isFinite(data.actionTimestamp))) return;
|
if (data.actionTimestamp !== undefined && (typeof data.actionTimestamp !== 'number' || !Number.isFinite(data.actionTimestamp))) return;
|
||||||
|
|
||||||
const senderMapping = socketToRoom.get(socket.id);
|
const senderMapping = socketToRoom.get(socket.id);
|
||||||
const targetSocketId = peerToSocket.get(data.targetId);
|
const targetSocketId = peerToSocket.get(data.targetId);
|
||||||
const targetMapping = targetSocketId ? socketToRoom.get(targetSocketId) : null;
|
const targetMapping = targetSocketId ? socketToRoom.get(targetSocketId) : null;
|
||||||
|
|
||||||
// Security: Only relay ACK if both peers are in the same room
|
// Security: Only relay ACK if both peers are in the same room
|
||||||
if (senderMapping && targetMapping && senderMapping.roomId === targetMapping.roomId) {
|
if (senderMapping && targetMapping && senderMapping.roomId === targetMapping.roomId) {
|
||||||
io.to(targetSocketId).emit(EVENTS.EVENT_ACK, {
|
io.to(targetSocketId).emit(EVENTS.EVENT_ACK, {
|
||||||
senderId: senderMapping.peerId,
|
senderId: senderMapping.peerId,
|
||||||
actionTimestamp: data.actionTimestamp
|
actionTimestamp: data.actionTimestamp
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
log('SECURITY', `Blocked cross-room ACK attempt from ${socket.id} to ${data.targetId}`);
|
log('SECURITY', `Blocked cross-room ACK attempt from ${socket.id} to ${data.targetId}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('disconnect', () => {
|
socket.on('disconnect', () => {
|
||||||
eventCounts.delete(socket.id);
|
eventCounts.delete(socket.id);
|
||||||
|
|||||||
+1
-1
@@ -40,5 +40,5 @@ export const EVENTS = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const HEARTBEAT_INTERVAL = 15000; // 15s
|
export const HEARTBEAT_INTERVAL = 15000; // 15s
|
||||||
export const FORCE_SYNC_TIMEOUT = 5000; // 5s timeout for ACKs
|
export const FORCE_SYNC_TIMEOUT = 8500; // 8.5s timeout for force sync ACKs (must be > content.js poll timeout of 8s)
|
||||||
export const EPISODE_LOBBY_TIMEOUT = 60000; // 60s timeout for episode lobby
|
export const EPISODE_LOBBY_TIMEOUT = 60000; // 60s timeout for episode lobby
|
||||||
|
|||||||
Reference in New Issue
Block a user