Skip to content

Commit 4a5c929

Browse files
committed
Beta Chrome Forwarding WS Data correctly, OBS receiving and responding correctly
1 parent 7ab4e26 commit 4a5c929

13 files changed

Lines changed: 180 additions & 38 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.gitignore

background.js

Lines changed: 145 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ let latestStatus = {
2525
obsStats: obsStats
2626
};
2727

28+
let debuggeeId = null;
29+
2830
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
2931
switch(request.action) {
3032
case "getStatus":
@@ -42,26 +44,87 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
4244
disconnectFromObs();
4345
sendResponse({success: true});
4446
break;
47+
case "toggleChromeWs":
48+
if (debuggeeId) {
49+
chrome.debugger.detach(debuggeeId);
50+
debuggeeId = null;
51+
updateStatus('chromeWebSocket', 'disconnected');
52+
} else {
53+
attachDebugger(request.tabId);
54+
}
55+
sendResponse({success: true});
56+
break;
4557
}
4658
return true; // Indicates that the response is sent asynchronously
4759
});
4860

4961
chrome.action.onClicked.addListener((tab) => {
50-
connectToChromeWebSocket(tab.id);
51-
connectToObs(); // You might want to make this optional or triggered separately
62+
if (debuggeeId) {
63+
chrome.debugger.detach(debuggeeId);
64+
debuggeeId = null;
65+
updateStatus('chromeWebSocket', 'disconnected');
66+
} else {
67+
attachDebugger(tab.id);
68+
}
5269
});
5370

71+
function attachDebugger(tabId) {
72+
chrome.debugger.attach({tabId: tabId}, "1.3", () => {
73+
if (chrome.runtime.lastError) {
74+
console.error(chrome.runtime.lastError.message);
75+
return;
76+
}
77+
debuggeeId = {tabId: tabId};
78+
chrome.debugger.sendCommand(debuggeeId, "Network.enable");
79+
chrome.debugger.onEvent.addListener(onEvent);
80+
updateStatus('chromeWebSocket', 'connected');
81+
});
82+
}
83+
84+
function onEvent(debuggeeId, message, params) {
85+
if (message === "Network.webSocketFrameReceived") {
86+
const payload = params.response?.payloadData || params.request?.payloadData;
87+
if (payload) {
88+
console.log("WebSocket Frame Received:", payload);
89+
messageStats.received++;
90+
try {
91+
// Attempt to parse the message to ensure it's valid JSON
92+
JSON.parse(payload);
93+
forwardToObs(payload);
94+
} catch (error) {
95+
console.error("Error parsing WebSocket frame:", error);
96+
messageStats.lost++;
97+
}
98+
} else {
99+
console.warn("Received WebSocket frame without payload data");
100+
}
101+
} else if (message === "Network.webSocketFrameSent") {
102+
const payload = params.request?.payloadData;
103+
if (payload) {
104+
console.log("WebSocket Frame Sent:", payload);
105+
messageStats.sent++;
106+
} else {
107+
console.warn("Sent WebSocket frame without payload data");
108+
}
109+
}
110+
updateStatus('chromeWebSocket', 'connected');
111+
}
112+
54113
function onWebSocketEvent(debuggeeId, message, params) {
55114
if (message === "Network.webSocketFrameReceived") {
56115
console.log("WebSocket Frame Received:", params.response.payloadData);
57116
messageStats.received++;
58117
// Here you would process and potentially forward the message to OBS
59118
} else if (message === "Network.webSocketFrameSent") {
60-
console.log("WebSocket Frame Sent:", params.request.payloadData);
61-
messageStats.sent++;
119+
const payload = params.response?.payloadData || params.request?.payloadData;
120+
if (payload) {
121+
console.log("WebSocket Frame Sent:", payload);
122+
messageStats.sent++;
123+
} else {
124+
console.warn("Sent WebSocket frame without payload data. Full params:", JSON.stringify(params));
125+
}
62126
}
63-
64-
updateStatus('chromeWebSocket', 'connected'); // Ensure status stays updated
127+
updateStatus('chromeWebSocket', 'connected');
65128
}
66129

67130
function connectToObs() {
@@ -181,6 +244,9 @@ function handleOBSResponse(message) {
181244
console.log('Updated recording status:', obsStats.recording);
182245
}
183246
break;
247+
case 'BroadcastCustomMessage':
248+
console.log('Custom message broadcasted successfully');
249+
break;
184250
default:
185251
console.log('Unhandled response type:', message.d.requestType);
186252
}
@@ -216,35 +282,87 @@ function handleAuthChallenge(message, password) {
216282
}
217283

218284
function updateStatus(type, status) {
219-
connectionStatus[type] = status;
220-
console.log(`Updating status: ${type} = ${status}`);
221-
222-
latestStatus = {
223-
connectionStatus: connectionStatus,
224-
messageStats: messageStats,
225-
obsStats: obsStats
226-
};
285+
// Only update if the status has changed
286+
if (connectionStatus[type] !== status) {
287+
connectionStatus[type] = status;
288+
console.log(`Updating status: ${type} = ${status}`);
289+
290+
latestStatus = {
291+
connectionStatus: connectionStatus,
292+
messageStats: messageStats,
293+
obsStats: obsStats
294+
};
227295

228-
// Attempt to send update to popup (if open)
229-
chrome.runtime.sendMessage({
230-
action: 'statusUpdate',
231-
...latestStatus
232-
}, () => {
233-
if (chrome.runtime.lastError) {
234-
console.log('Error sending status update (this is normal if popup is closed):', chrome.runtime.lastError.message);
235-
} else {
236-
console.log('Status update sent successfully');
237-
}
238-
});
296+
// Use chrome.runtime.sendMessage instead of chrome.tabs.sendMessage
297+
chrome.runtime.sendMessage({
298+
action: 'statusUpdate',
299+
...latestStatus
300+
}).catch(error => {
301+
console.log('Error sending status update:', error.message);
302+
});
303+
304+
// Update extension icon
305+
const iconPath = status === 'connected' ? {
306+
16: 'images/icon_active_16.png',
307+
32: 'images/icon_active_32.png',
308+
48: 'images/icon_active_48.png',
309+
128: 'images/icon_active_128.png'
310+
} : {
311+
16: 'images/icon_inactive_16.png',
312+
32: 'images/icon_inactive_32.png',
313+
48: 'images/icon_inactive_48.png',
314+
128: 'images/icon_inactive_128.png'
315+
};
316+
chrome.action.setIcon({path: iconPath});
317+
}
239318
}
240319

241320
function forwardToObs(message) {
242321
if (obsSocket && obsSocket.readyState === WebSocket.OPEN) {
243-
obsSocket.send(message);
244-
messageStats.forwarded++;
322+
try {
323+
// Parse the Phoenix framework message
324+
const parsedMessage = JSON.parse(message);
325+
if (!Array.isArray(parsedMessage)) {
326+
throw new Error("Unexpected message format");
327+
}
328+
329+
// Transform the message into OBS WebSocket format
330+
const obsMessage = {
331+
op: 6,
332+
d: {
333+
requestType: "BroadcastCustomMessage",
334+
requestId: generateUniqueId(),
335+
requestData: {
336+
realm: "obs-websocket",
337+
data: {
338+
eventType: "ChromeWebSocketMessage",
339+
eventData: {
340+
channel: parsedMessage[2],
341+
event: parsedMessage[3],
342+
payload: parsedMessage[4]
343+
}
344+
}
345+
}
346+
}
347+
};
348+
349+
// Send the transformed message to OBS
350+
obsSocket.send(JSON.stringify(obsMessage));
351+
messageStats.forwarded++;
352+
console.log("Forwarded to OBS:", obsMessage);
353+
} catch (error) {
354+
console.error("Error forwarding message to OBS:", error);
355+
messageStats.lost++;
356+
}
245357
} else {
246358
console.warn('OBS WebSocket not connected. Message not forwarded.');
359+
messageStats.lost++;
247360
}
361+
updateStatus('obsWebSocket', obsSocket && obsSocket.readyState === WebSocket.OPEN ? 'connected' : 'disconnected');
362+
}
363+
364+
function generateUniqueId() {
365+
return Date.now().toString(36) + Math.random().toString(36).substr(2);
248366
}
249367

250368
function getOBSStats() {

images/icon_active_128.png

10 KB
Loading

images/icon_active_16.png

862 Bytes
Loading

images/icon_active_32.png

2.36 KB
Loading

images/icon_active_48.png

3.61 KB
Loading

images/icon_inactive_32.png

2.72 KB
Loading

0 commit comments

Comments
 (0)