Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
f1ed1c3
Initial plan
Copilot Oct 1, 2025
445746c
Add Google AdSense to games and apps pages
Copilot Oct 1, 2025
f800bd6
Fix CSS syntax error in v9/main.css
Copilot Oct 1, 2025
82670dd
Fix proxy configuration paths in m/config.js
Copilot Oct 1, 2025
61fa243
Complete production-ready fixes for SlowGuardian
Copilot Oct 1, 2025
591c608
Add Google Analytics, Enzuzo cookie banner, and enhanced AdSense ads
Copilot Oct 1, 2025
a670c30
Revert proxy config to main branch and fix AdSense script placement
Copilot Oct 1, 2025
7eca07d
Fix games/apps grid display to show all rows properly
Copilot Oct 1, 2025
629fc82
Addressing PR comments
Copilot Oct 1, 2025
9a3d5bd
Revert all proxy files (sw.js, bundle.js, handler.js) to main branch
Copilot Oct 1, 2025
26bdd37
Add Enzuzo cookie banner to all HTML pages
Copilot Oct 1, 2025
bd1ba2e
Fix service worker to not intercept external scripts (Enzuzo, AdSense…
Copilot Oct 1, 2025
ea1dba1
Fix service worker to completely skip external requests without inter…
Copilot Oct 1, 2025
3c5ae28
Add Scramjet proxy integration for premium users alongside Ultraviolet
Copilot Oct 2, 2025
538efd0
Add postinstall script and documentation for dual proxy system
Copilot Oct 2, 2025
c5f4625
Fix Scramjet integration: install files, update settings UI, and fix …
Copilot Oct 2, 2025
04384ab
Add Scramjet proxy files to repository
Copilot Oct 2, 2025
fe9a851
Remove Scramjet from service worker due to window compatibility issue
Copilot Oct 2, 2025
58c4633
Fix Scramjet proxy selection - prevent auto-switch to Ultraviolet
Copilot Oct 2, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 129 additions & 0 deletions PROXY_SETUP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
# SlowGuardian Dual Proxy System

SlowGuardian now supports two proxy systems for different user tiers:

## Proxy Systems

### 1. Ultraviolet (All Users)
- **URL Prefix**: `/a/`
- **Access**: Available to all users
- **Repository**: https://github.com/titaniumnetwork-dev/Ultraviolet
- **Status**: ✅ Always enabled

### 2. Scramjet (Premium Users Only)
- **URL Prefix**: `/scram/`
- **Access**: Premium users only (requires `sg_premium=1` cookie)
- **Repository**: https://github.com/MercuryWorkshop/scramjet
- **Status**: ✅ Enabled for premium users

## Setup

### Automatic Setup (Recommended)
When you run `npm install`, the Scramjet files are automatically set up via the `postinstall` script.

### Manual Setup
If you need to manually set up Scramjet:

```bash
npm run setup:scramjet
```

This copies the necessary Scramjet files from `node_modules/@mercuryworkshop/scramjet` to `static/scram/`.

## Premium User Detection

The service worker checks for the `sg_premium` cookie to determine if a user has premium access:

- **Premium users** (`sg_premium=1`): Can access both `/scram/` and `/a/` proxies
- **Non-premium users**: Can only access `/a/` proxy
- If a non-premium user tries to access `/scram/`, they are automatically redirected to `/a/`

## Service Worker Architecture

The service worker (`static/sw.js`) handles routing for all proxy systems:

1. **Dynamic** (`/dy/`) - Base proxy system
2. **Scramjet** (`/scram/`) - Premium only, loaded conditionally
3. **Ultraviolet** (`/a/`) - Available to all users

```javascript
// Premium detection
function isPremiumUser(request) {
const cookies = request.headers.get('cookie') || '';
return cookies.includes('sg_premium=1');
}
```

## File Structure

```
static/
├── scram/ # Scramjet files (gitignored, built on install)
│ ├── config.js
│ ├── scramjet.worker.js
│ ├── scramjet.client.js
│ └── scramjet.codecs.js
├── m/ # Ultraviolet files
│ ├── config.js
│ ├── bundle.js
│ ├── handler.js
│ └── sw.js
└── sw.js # Main service worker with dual proxy support
```

## External Scripts

The service worker is configured to NOT intercept external scripts (AdSense, Analytics, Cookie Consent):

```javascript
// Don't intercept external requests - let browser handle them
if (url.origin !== location.origin) {
return; // Browser handles it naturally
}
```

## Testing

To verify both proxies are working:

1. **Test Ultraviolet** (all users):
- Navigate to: `http://localhost:8080/a/hvtrs8%2F-gmoelg.aoo%2F`

2. **Test Scramjet** (premium only):
- Set cookie: `sg_premium=1`
- Navigate to: `http://localhost:8080/scram/[encoded-url]`

## Troubleshooting

### Scramjet files not found
Run the setup script manually:
```bash
npm run setup:scramjet
```

### Service worker not loading Scramjet
Check browser console for errors. Scramjet will log:
- `✓ Scramjet loaded for premium users` - Success
- `⚠ Scramjet not available` - Failed to load (will fallback to UV only)

### Non-premium user trying to access Scramjet
Users without `sg_premium=1` cookie will be automatically redirected to Ultraviolet.

## Development

When developing, ensure:
1. Run `npm install` to set up all dependencies
2. The `static/scram/` directory is automatically created
3. Check that all proxy files are accessible (should return 200):
- `/sw.js`
- `/m/config.js`
- `/scram/config.js`
- `/scram/scramjet.worker.js`

## Production Deployment

For production:
1. Ensure `npm install` runs during deployment
2. The postinstall script will automatically set up Scramjet
3. Verify both proxies are accessible
4. Configure premium user authentication as needed
3 changes: 3 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
"test-sw-headless": "node scripts/test-sw-puppeteer.js",
"test-sw-simple": "node scripts/test-sw-simple.js",
"build": "npm run build:version && npm run format",
"postinstall": "node scripts/setup-scramjet.cjs",
"setup:scramjet": "node scripts/setup-scramjet.cjs",
"build:production": "NODE_ENV=production npm run build:version && npm run format && npm run audit-fix",
"build:version": "node scripts/build-version.js",
"audit-fix": "npm audit fix",
Expand Down
74 changes: 74 additions & 0 deletions scripts/setup-scramjet.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#!/usr/bin/env node

/**
* Script to set up Scramjet proxy for premium users
* Copies necessary files from node_modules to static directory
*/

const fs = require('fs');
const path = require('path');

const scramjetSrc = path.join(__dirname, '../node_modules/@mercuryworkshop/scramjet');
const scramjetDest = path.join(__dirname, '../static/scram');

console.log('Setting up Scramjet for premium users...');

// Create destination directory
if (!fs.existsSync(scramjetDest)) {
fs.mkdirSync(scramjetDest, { recursive: true });
console.log('✓ Created /static/scram directory');
}

// Check if Scramjet package exists
if (!fs.existsSync(scramjetSrc)) {
console.error('✗ Scramjet package not found in node_modules');
console.log(' Run: npm install @mercuryworkshop/scramjet');
process.exit(1);
}

// List of files to copy (based on Scramjet documentation)
const filesToCopy = [
'scramjet.bundle.js',
'scramjet.worker.js',
'scramjet.client.js',
'scramjet.codecs.js'
];

let copiedCount = 0;

// Try to copy files from various possible locations
const possiblePaths = ['dist', 'lib', '', 'dist/'];

for (const file of filesToCopy) {
let found = false;

for (const subPath of possiblePaths) {
const srcPath = path.join(scramjetSrc, subPath, file);
const destPath = path.join(scramjetDest, file);

if (fs.existsSync(srcPath)) {
try {
fs.copyFileSync(srcPath, destPath);
console.log(`✓ Copied ${file}`);
copiedCount++;
found = true;
break;
} catch (err) {
console.error(`✗ Error copying ${file}:`, err.message);
}
}
}

if (!found) {
console.log(`⚠ ${file} not found (may not be needed)`);
}
}

if (copiedCount > 0) {
console.log(`\n✓ Successfully set up Scramjet with ${copiedCount} files`);
console.log(' Scramjet will be available for premium users at /scram/ prefix');
} else {
console.log('\n⚠ No Scramjet files were copied');
console.log(' Please check the Scramjet package installation');
console.log(' or refer to: https://github.com/MercuryWorkshop/scramjet');
}
3 changes: 3 additions & 0 deletions static/404.html
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,9 @@
}
}
</style>

<!-- Enzuzo Cookie Banner -->
<script src="https://app.enzuzo.com/scripts/cookiebar/f8c4cd70-9ec8-11f0-8a15-efa3a64fef00"></script>
</head>

<body>
Expand Down
54 changes: 54 additions & 0 deletions static/apps.html
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,22 @@
<meta name="theme-color" content="#1a1a2e" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />

<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-00LBBY9N6T"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-00LBBY9N6T');
</script>

<!-- Enzuzo Cookie Banner -->
<script src="https://app.enzuzo.com/scripts/cookiebar/f8c4cd70-9ec8-11f0-8a15-efa3a64fef00"></script>

<!-- Google AdSense -->
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2510115202431848"
crossorigin="anonymous"></script>
</head>
<body>
<!-- Skip to main content for accessibility -->
Expand Down Expand Up @@ -98,10 +114,48 @@ <h2 class="page-title">Applications</h2>
<!-- Pinned Apps -->
<div class="pinned-apps" id="pinned-apps"></div>

<!-- AdSense In-Article Ad -->
<div class="adsense-container" style="margin: 2rem 0; text-align: center;">
<ins class="adsbygoogle"
style="display:block; text-align:center;"
data-ad-layout="in-article"
data-ad-format="fluid"
data-ad-client="ca-pub-2510115202431848"
data-ad-slot="4938663842"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
</div>

<!-- Apps Grid -->
<div class="content-grid" id="apps-grid">
<div class="container-apps"></div>
</div>

<!-- AdSense Multiplex Ad -->
<div class="adsense-container" style="margin: 2rem 0; text-align: center;">
<ins class="adsbygoogle"
style="display:block"
data-ad-format="autorelaxed"
data-ad-client="ca-pub-2510115202431848"
data-ad-slot="1953407856"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
</div>

<!-- AdSense In-Feed Ad -->
<div class="adsense-container" style="margin: 2rem 0; text-align: center;">
<ins class="adsbygoogle"
style="display:block"
data-ad-format="fluid"
data-ad-layout-key="-fb+5w+4e-db+86"
data-ad-client="ca-pub-2510115202431848"
data-ad-slot="7205734533"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
</div>
</section>
</main>

Expand Down
9 changes: 8 additions & 1 deletion static/assets/scripts/frame.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,14 @@ window.addEventListener("load", function () {
}

if (!GoUrl.startsWith("/e/")) {
if (dyValue === "true" || dyValue === "auto") {
// Check proxy service preference
const proxyService = localStorage.getItem("proxy-service") || "ultraviolet";

if (proxyService === "scramjet") {
// Use Scramjet proxy encoding
GoUrl = "/scram/" + GoUrl;
console.log("🔄 Using Scramjet proxy for:", GoUrl);
} else if (dyValue === "true" || dyValue === "auto" || proxyService === "dynamic") {
// Use Dynamic proxy encoding
GoUrl = "/dy/q/" + GoUrl;
console.log("🔄 Using Dynamic proxy for:", GoUrl);
Expand Down
18 changes: 10 additions & 8 deletions static/assets/styles/v9/games.css
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
/* Games page styles for SlowGuardian v9 */

/* Games Grid */
/* Games/Apps Grid - ID selector to override .content-grid */
#games-grid,
#apps-grid,
.games-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
gap: var(--space-3);
padding: var(--space-4) 0;
width: 100%;
max-width: none;
min-height: calc(100vh - 300px);
display: grid !important;
grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)) !important;
gap: var(--space-3) !important;
padding: var(--space-4) 0 !important;
width: 100% !important;
max-width: none !important;
min-height: calc(100vh - 300px) !important;
}

/* Game Item */
Expand Down
4 changes: 0 additions & 4 deletions static/assets/styles/v9/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -387,10 +387,6 @@ body {
#suggestions:empty {
display: none !important;
}
display: none;
max-height: 300px;
overflow-y: auto;
}

.suggestion-item {
display: flex;
Expand Down
3 changes: 3 additions & 0 deletions static/developer.html
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@
color: var(--text-primary) !important;
}
</style>

<!-- Enzuzo Cookie Banner -->
<script src="https://app.enzuzo.com/scripts/cookiebar/f8c4cd70-9ec8-11f0-8a15-efa3a64fef00"></script>
</head>
<body>
<!-- Background -->
Expand Down
Loading