Skip to content

Commit 0e2ea1e

Browse files
committed
Initial release
0 parents  commit 0e2ea1e

6 files changed

Lines changed: 4707 additions & 0 deletions

File tree

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules
2+
dist

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 xSylla
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# StreamUnity
2+
3+
StreamUnity is an unofficial wrapper of streamingcommunity for the Linux desktop, with an adblock built-in.
4+
5+
## Building from source
6+
7+
```bash
8+
git clone https://github.com/xSylla/StreamingUnity
9+
cd StreamingUnity
10+
npm install
11+
npm run build-linux
12+
```

main.js

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
const { app, BrowserWindow, ipcMain, session } = require('electron');
2+
const path = require('path');
3+
const Store = require('electron-store');
4+
const { ElectronBlocker } = require('@ghostery/adblocker-electron');
5+
const fetch = require('cross-fetch');
6+
7+
const store = new Store();
8+
9+
// Configs
10+
const URL_TO_LOAD = 'https://streamingcommunityz.cc/';
11+
const USER_AGENT = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36";
12+
let mainWindow = null;
13+
let blocker = null;
14+
15+
// Adblock
16+
async function initAdBlocker() {
17+
blocker = await ElectronBlocker.fromPrebuiltAdsAndTracking(fetch);
18+
blocker.enableBlockingInSession(session.defaultSession);
19+
}
20+
21+
// Window
22+
function createWindow() {
23+
const windowBounds = store.get('windowBounds', { width: 1280, height: 720 });
24+
25+
mainWindow = new BrowserWindow({
26+
...windowBounds,
27+
minWidth: 800,
28+
minHeight: 600,
29+
icon: path.join(__dirname, 'assets', 'icon.png'),
30+
titleBarStyle: 'default',
31+
show: false,
32+
webPreferences: {
33+
nodeIntegration: false,
34+
contextIsolation: true,
35+
enableRemoteModule: false,
36+
webSecurity: true,
37+
allowRunningInsecureContent: false,
38+
experimentalFeatures: true,
39+
},
40+
});
41+
42+
// Set UserAgent
43+
mainWindow.webContents.setUserAgent(USER_AGENT);
44+
45+
// Load Site
46+
const loadSite = async (url = URL_TO_LOAD) => {
47+
try {
48+
await mainWindow.loadURL(url);
49+
} catch (error) {
50+
console.error('[Load Error]', error);
51+
}
52+
};
53+
loadSite();
54+
55+
// Show it when ready
56+
mainWindow.once('ready-to-show', () => mainWindow.show());
57+
58+
// Save window
59+
let saveTimeout;
60+
const saveBounds = () => {
61+
clearTimeout(saveTimeout);
62+
saveTimeout = setTimeout(() => {
63+
if (mainWindow) {
64+
store.set('windowBounds', mainWindow.getBounds());
65+
}
66+
}, 300);
67+
};
68+
69+
mainWindow.on('resize', saveBounds);
70+
mainWindow.on('moved', saveBounds);
71+
72+
mainWindow.once('closed', () => {
73+
mainWindow = null;
74+
});
75+
76+
// Block new windows
77+
mainWindow.webContents.setWindowOpenHandler(() => ({ action: 'deny' }));
78+
79+
// Block unauthorized domains
80+
mainWindow.webContents.on('will-navigate', (event, navigationUrl) => {
81+
const allowedDomains = [URL_TO_LOAD];
82+
if (!allowedDomains.some(domain => navigationUrl.startsWith(domain))) {
83+
console.warn('[Blocked Navigation]', navigationUrl);
84+
event.preventDefault();
85+
}
86+
});
87+
}
88+
89+
// Events
90+
app.whenReady().then(async () => {
91+
await initAdBlocker();
92+
createWindow();
93+
94+
app.on('activate', () => {
95+
if (BrowserWindow.getAllWindows().length === 0) createWindow();
96+
});
97+
});
98+
99+
app.on('window-all-closed', () => {
100+
if (process.platform !== 'darwin') app.quit();
101+
});
102+
103+
// IPC
104+
ipcMain.handle('get-store-value', (_, key, def) => store.get(key, def));
105+
ipcMain.handle('set-store-value', (_, key, val) => store.set(key, val));
106+
ipcMain.handle('load-url', (_, url) => mainWindow?.loadURL(url));
107+
ipcMain.handle('go-home', () => mainWindow?.loadURL(URL_TO_LOAD));
108+
ipcMain.handle('reload-page', () => mainWindow?.reload());
109+
110+
// Error handling
111+
process.on('uncaughtException', err => console.error('[Uncaught Exception]', err));
112+
process.on('unhandledRejection', (reason, p) =>
113+
console.error('[Unhandled Rejection]', p, 'Reason:', reason)
114+
);

0 commit comments

Comments
 (0)