Watch Together Plugin + Electron Desktop App mit Ad-Blocker

Neuer Tab: Watch Together - gemeinsam Videos schauen (w2g.tv-Style)
- Raum-System mit optionalem Passwort und Host-Kontrolle
- Video-Queue mit Hinzufuegen/Entfernen/Umordnen
- YouTube (IFrame API) + direkte Video-URLs (.mp4, .webm)
- Synchronisierte Wiedergabe via WebSocket (/ws/watch-together)
- Server-autoritative Playback-State mit Drift-Korrektur (2.5s Sync-Pulse)
- Host-Transfer bei Disconnect, Room-Cleanup nach 30s

Electron Desktop App (electron/):
- Wrapper fuer Gaming Hub mit integriertem Ad-Blocker
- uBlock-Style Request-Filtering via session.webRequest
- 100+ Ad-Domains + YouTube-spezifische Filter
- Download-Button im Web-Header (nur sichtbar wenn nicht in Electron)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Daniel 2026-03-07 02:40:59 +01:00
parent 4943bbf4a1
commit 73f247ada3
16 changed files with 7386 additions and 4833 deletions

87
electron/ad-blocker.js Normal file
View file

@ -0,0 +1,87 @@
const fs = require('fs');
const path = require('path');
function setupAdBlocker(session) {
// Load filter domains
const filtersPath = path.join(__dirname, 'filters.txt');
let rawFilters;
try {
rawFilters = fs.readFileSync(filtersPath, 'utf-8');
} catch (err) {
console.error('[AdBlocker] Could not load filters.txt:', err.message);
return;
}
// Parse: each line is either a domain, a URL path pattern, or a regex
const blockedDomains = new Set();
const blockedPatterns = [];
for (const line of rawFilters.split('\n')) {
const trimmed = line.trim();
if (!trimmed || trimmed.startsWith('#')) continue;
if (trimmed.startsWith('/') && trimmed.endsWith('/')) {
// Regex pattern
try {
blockedPatterns.push(new RegExp(trimmed.slice(1, -1)));
} catch {
// invalid regex, skip
}
} else if (trimmed.includes('/')) {
// URL path pattern (string match)
blockedPatterns.push(trimmed);
} else {
// Domain
blockedDomains.add(trimmed);
}
}
let blockedCount = 0;
session.webRequest.onBeforeRequest((details, callback) => {
try {
const url = new URL(details.url);
const hostname = url.hostname;
// Check domain blocklist (including subdomains)
for (const domain of blockedDomains) {
if (hostname === domain || hostname.endsWith('.' + domain)) {
blockedCount++;
callback({ cancel: true });
return;
}
}
// Check URL patterns
const fullUrl = details.url;
for (const pattern of blockedPatterns) {
if (pattern instanceof RegExp) {
if (pattern.test(fullUrl)) {
blockedCount++;
callback({ cancel: true });
return;
}
} else if (fullUrl.includes(pattern)) {
blockedCount++;
callback({ cancel: true });
return;
}
}
} catch {
// URL parsing error, allow request
}
callback({});
});
// Log stats periodically
setInterval(() => {
if (blockedCount > 0) {
console.log(`[AdBlocker] ${blockedCount} requests blocked`);
}
}, 30000);
console.log(`[AdBlocker] Loaded ${blockedDomains.size} domains + ${blockedPatterns.length} patterns`);
}
module.exports = { setupAdBlocker };

253
electron/filters.txt Normal file
View file

@ -0,0 +1,253 @@
# ============================================================
# Gaming Hub Ad-Blocker Filter List
# Focused on YouTube ads, general ad networks, and trackers
# ============================================================
# ------------------------------------------------------------
# Google Ads & Ad Networks
# ------------------------------------------------------------
doubleclick.net
googlesyndication.com
googleadservices.com
google-analytics.com
googletagmanager.com
googletagservices.com
adservice.google.com
pagead2.googlesyndication.com
ads.google.com
adclick.g.doubleclick.net
googleads.g.doubleclick.net
www.googleadservices.com
partner.googleadservices.com
tpc.googlesyndication.com
# ------------------------------------------------------------
# Major Ad Exchanges & Programmatic
# ------------------------------------------------------------
adnxs.com
adsrvr.org
adform.net
amazon-adsystem.com
adsymptotic.com
adtilt.com
advertising.com
bidswitch.net
casalemedia.com
criteo.com
criteo.net
demdex.net
dotomi.com
exelator.com
eyeblaster.com
flashtalking.com
moat.com
moatads.com
mookie1.com
pubmatic.com
quantserve.com
rubiconproject.com
scorecardresearch.com
serving-sys.com
sharethrough.com
smartadserver.com
tapad.com
turn.com
yieldmo.com
openx.net
indexww.com
lijit.com
mathtag.com
rlcdn.com
bluekai.com
krxd.net
agkn.com
adzerk.net
contextweb.com
3lift.com
triplelift.com
media.net
medianet.com
admixer.net
revenuecat.com
adcolony.com
vungle.com
unity3d.com
unityads.unity3d.com
applovin.com
# ------------------------------------------------------------
# Outbrain / Taboola / Content Recommendations
# ------------------------------------------------------------
outbrain.com
taboola.com
outbrain-com.cdn.ampproject.org
revcontent.com
mgid.com
zergnet.com
content-recommendation.net
nativo.com
adblade.com
content.ad
# ------------------------------------------------------------
# Popup & Overlay Ad Networks
# ------------------------------------------------------------
popads.net
popcash.net
propellerads.com
propellerpops.com
popunder.net
clickadu.com
hilltopads.net
ad-maven.com
admaven.com
juicyads.com
# ------------------------------------------------------------
# YouTube-Specific Ad Patterns (URL path matches)
# ------------------------------------------------------------
/pagead/
/ptracking
/get_midroll_
/api/stats/ads
/api/stats/atr
/log_interaction
/ad_data_204
/generate_204
/s/player/*/player_ias
/youtubei/v1/log_event?alt=
/youtubei/v1/player/ad_break
# ------------------------------------------------------------
# YouTube Ad Regex Patterns
# ------------------------------------------------------------
/googlevideo\.com\/videoplayback\?.*&ctier=L&/
/googlevideo\.com\/videoplayback\?.*&oad=/
/youtube\.com\/api\/stats\/ads/
/youtube\.com\/pagead\//
/youtube\.com\/ptracking/
/youtube\.com\/get_midroll_/
/doubleclick\.net\/pagead\//
/youtube\.com\/sw\.js_data/
/youtube\.com\/api\/stats\/qoe\?.*adformat/
/youtube\.com\/youtubei\/v1\/log_event\?alt=/
# ------------------------------------------------------------
# YouTube Tracking & Telemetry
# ------------------------------------------------------------
s.youtube.com
video-stats.l.google.com
www.youtube.com/api/stats/
yt3.ggpht.com/a/default-user
# ------------------------------------------------------------
# Facebook / Meta Tracking
# ------------------------------------------------------------
facebook.net
connect.facebook.net
pixel.facebook.com
www.facebook.com/tr
an.facebook.com
staticxx.facebook.com
# ------------------------------------------------------------
# Twitter / X Tracking
# ------------------------------------------------------------
analytics.twitter.com
t.co
ads-twitter.com
ads-api.twitter.com
static.ads-twitter.com
# ------------------------------------------------------------
# Microsoft Tracking
# ------------------------------------------------------------
bat.bing.com
clarity.ms
c.bing.com
c.msn.com
# ------------------------------------------------------------
# Analytics & Session Recording
# ------------------------------------------------------------
hotjar.com
mouseflow.com
fullstory.com
heapanalytics.com
mixpanel.com
segment.com
segment.io
amplitude.com
cdn.amplitude.com
api.amplitude.com
inspectlet.com
luckyorange.com
crazyegg.com
optimizely.com
cdn.optimizely.com
newrelic.com
js-agent.newrelic.com
bam.nr-data.net
sentry.io
# ------------------------------------------------------------
# General Tracking & Fingerprinting
# ------------------------------------------------------------
liadm.com
ipredictive.com
bam-cell.nr-data.net
cdn.ravenjs.com
cdn.mxpnl.com
cdn.heapanalytics.com
static.hotjar.com
script.hotjar.com
vars.hotjar.com
identify.hotjar.com
surveys.hotjar.com
in.hotjar.com
sb.scorecardresearch.com
imrworldwide.com
sb.voicefive.com
c.amazon-adsystem.com
s.amazon-adsystem.com
z-na.amazon-adsystem.com
# ------------------------------------------------------------
# Ad-related CDN / Serving Domains
# ------------------------------------------------------------
cdn.doubleverify.com
tps.doubleverify.com
cdn.adsafeprotected.com
fw.adsafeprotected.com
static.adsafeprotected.com
pixel.adsafeprotected.com
dt.adsafeprotected.com
# ------------------------------------------------------------
# Miscellaneous Ad / Tracking Domains
# ------------------------------------------------------------
adroll.com
d.adroll.com
s.adroll.com
ib.adnxs.com
secure.adnxs.com
acdn.adnxs.com
cdn.adnxs.com
m.adnxs.com
nym1-ib.adnxs.com
bttrack.com
clicktale.net
zemanta.com
teads.tv
adskeeper.co.uk
adf.ly
sh.st
linkbucks.com
bc.vc
ouo.io
shorte.st
adfoc.us
coin-hive.com
coinhive.com
authedmine.com
crypto-loot.com

23
electron/forge.config.js Normal file
View file

@ -0,0 +1,23 @@
const path = require('path');
module.exports = {
packagerConfig: {
name: 'Gaming Hub',
executableName: 'gaming-hub',
icon: path.join(__dirname, 'assets', 'icon'),
asar: true,
},
makers: [
{
name: '@electron-forge/maker-squirrel',
config: {
name: 'gaming-hub-desktop',
setupIcon: path.join(__dirname, 'assets', 'icon.ico'),
},
},
{
name: '@electron-forge/maker-zip',
platforms: ['win32', 'linux', 'darwin'],
},
],
};

68
electron/main.js Normal file
View file

@ -0,0 +1,68 @@
const { app, BrowserWindow, session, shell } = require('electron');
const path = require('path');
const { setupAdBlocker } = require('./ad-blocker');
// Handle Squirrel events (Windows installer)
try {
if (require('electron-squirrel-startup')) app.quit();
} catch {
// electron-squirrel-startup not installed, skip
}
const HUB_URL = process.env.GAMING_HUB_URL || 'https://hub.daddelolymp.de';
let mainWindow;
function createWindow() {
mainWindow = new BrowserWindow({
width: 1400,
height: 900,
minWidth: 900,
minHeight: 600,
title: 'Gaming Hub',
icon: path.join(__dirname, 'assets', 'icon.png'),
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
contextIsolation: true,
nodeIntegration: false,
},
backgroundColor: '#1a1b1e',
autoHideMenuBar: true,
});
// Setup ad blocker BEFORE loading URL
setupAdBlocker(session.defaultSession);
// Custom User-Agent to identify Electron app
const currentUA = mainWindow.webContents.getUserAgent();
mainWindow.webContents.setUserAgent(currentUA + ' GamingHubDesktop/1.0.0');
mainWindow.loadURL(HUB_URL);
// Open external links in default browser
mainWindow.webContents.setWindowOpenHandler(({ url }) => {
if (!url.startsWith(HUB_URL)) {
shell.openExternal(url);
return { action: 'deny' };
}
return { action: 'allow' };
});
// Handle navigation to external URLs
mainWindow.webContents.on('will-navigate', (event, url) => {
if (!url.startsWith(HUB_URL)) {
event.preventDefault();
shell.openExternal(url);
}
});
}
app.whenReady().then(createWindow);
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit();
});
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) createWindow();
});

21
electron/package.json Normal file
View file

@ -0,0 +1,21 @@
{
"name": "gaming-hub-desktop",
"productName": "Gaming Hub",
"version": "1.0.0",
"description": "Gaming Hub Desktop App mit Ad-Blocker",
"main": "main.js",
"scripts": {
"start": "electron .",
"package": "electron-forge package",
"make": "electron-forge make"
},
"dependencies": {
"electron-squirrel-startup": "^1.0.1"
},
"devDependencies": {
"electron": "^33.0.0",
"@electron-forge/cli": "^7.6.0",
"@electron-forge/maker-squirrel": "^7.6.0",
"@electron-forge/maker-zip": "^7.6.0"
}
}

6
electron/preload.js Normal file
View file

@ -0,0 +1,6 @@
const { contextBridge } = require('electron');
contextBridge.exposeInMainWorld('electronAPI', {
isElectron: true,
version: '1.0.0',
});