ignitetnt
Version:
IGNITE OS — Advanced proxy-enabled gaming platform with comprehensive filter bypass system
300 lines (251 loc) • 9.62 kB
JavaScript
import "./custom.js";
const sitename = "Ignite OS";
const subtext = "FIND YOUR NEXT OBSESSION.";
const gameServerUrl = "https://gms.parcoil.com";
const gamesContainer = document.getElementById("gamesContainer");
const searchInput = document.getElementById("searchInput");
const titleElement = document.getElementById("title");
const subtitleElement = document.getElementById("subtitle");
// Proxy configuration
const PROXY_ENDPOINTS = [
'https://proxy1.ignite-os.workers.dev',
'https://proxy2.ignite-os.vercel.app/api/proxy',
'https://proxy3.ignite-os.netlify.app/.netlify/functions/proxy',
'https://cors-anywhere.herokuapp.com',
'https://api.allorigins.win/raw?url=',
'https://thingproxy.freeboard.io/fetch/'
];
// Backup game servers
const BACKUP_SERVERS = [
'https://gms.parcoil.com',
'https://games.cdn.parcoil.com',
'https://content.gameserver.net',
'https://assets.playzone.io'
];
let currentProxyIndex = 0;
let currentServerIndex = 0;
let proxyEncoder = new SimpleEncoder(); // Initialize with fallback immediately
// Simple fallback encoder if ProxyEncoder is not available
class SimpleEncoder {
xorEncode(text) {
return btoa(text).replace(/[+/=]/g, c => ({ '+': '-', '/': '_', '=': '' }[c]));
}
xorDecode(encoded) {
try {
let b64 = encoded.replace(/-/g, '+').replace(/_/g, '/');
while (b64.length % 4) b64 += '=';
return atob(b64);
} catch (e) {
return null;
}
}
}
// Load proxy utilities asynchronously (don't block page load)
async function loadProxyUtils() {
try {
await import('./proxy-utils.js');
if (typeof ProxyEncoder !== 'undefined') {
proxyEncoder = new ProxyEncoder();
console.log('Advanced proxy encoder loaded');
} else {
proxyEncoder = new SimpleEncoder();
console.log('Using simple encoder');
}
} catch (error) {
console.warn('Could not load proxy utilities:', error);
proxyEncoder = new SimpleEncoder();
}
}
document.title = titleElement ? `${sitename} | Arcade` : `${sitename} | Now Playing`;
if (titleElement) titleElement.textContent = sitename;
if (subtitleElement) subtitleElement.textContent = subtext;
let gamesData = [];
// Initialize proxy system
async function initializeProxy() {
try {
// Load proxy utilities first
await loadProxyUtils();
// Register service worker (async, don't block)
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('./sw.js').then(registration => {
console.log('Service Worker registered:', registration);
}).catch(error => {
console.warn('Service Worker registration failed:', error);
});
}
// Test proxy endpoints (async, don't block)
setTimeout(() => testProxyEndpoints(), 2000);
} catch (error) {
console.warn('Proxy initialization failed:', error);
// Ensure we have at least a basic encoder
if (!proxyEncoder) {
proxyEncoder = new SimpleEncoder();
}
}
}
// Test proxy endpoints and find working ones
async function testProxyEndpoints() {
const testUrl = 'https://httpbin.org/status/200';
for (let i = 0; i < PROXY_ENDPOINTS.length; i++) {
try {
const proxyUrl = createProxyUrl(PROXY_ENDPOINTS[i], testUrl);
const response = await fetch(proxyUrl, {
method: 'HEAD',
signal: AbortSignal.timeout(3000)
});
if (response.ok) {
console.log(`Proxy ${i} is working:`, PROXY_ENDPOINTS[i]);
currentProxyIndex = i;
return;
}
} catch (error) {
console.warn(`Proxy ${i} failed:`, error);
}
}
}
// Create proxy URL with obfuscation
function createProxyUrl(proxyEndpoint, targetUrl) {
if (!proxyEncoder) {
proxyEncoder = new ProxyEncoder();
}
const encoded = proxyEncoder.xorEncode(targetUrl);
if (proxyEndpoint.includes('?url=')) {
return `${proxyEndpoint}${encodeURIComponent(targetUrl)}`;
} else if (proxyEndpoint.includes('allorigins.win')) {
return `${proxyEndpoint}${encodeURIComponent(targetUrl)}`;
} else if (proxyEndpoint.includes('thingproxy.freeboard.io')) {
return `${proxyEndpoint}${encodeURIComponent(targetUrl)}`;
} else {
return `${proxyEndpoint}?target=${encoded}&origin=${encodeURIComponent(location.origin)}&t=${Date.now()}`;
}
}
// Get working game server
function getWorkingServer() {
return BACKUP_SERVERS[currentServerIndex] || gameServerUrl;
}
// Rotate to next proxy endpoint
function rotateProxy() {
currentProxyIndex = (currentProxyIndex + 1) % PROXY_ENDPOINTS.length;
}
// Rotate to next server
function rotateServer() {
currentServerIndex = (currentServerIndex + 1) % BACKUP_SERVERS.length;
}
function displayFilteredGames(filteredGames) {
if (!gamesContainer) return;
gamesContainer.replaceChildren();
if (filteredGames.length === 0) {
const emptyState = document.createElement("div");
emptyState.className = "empty-state";
emptyState.innerHTML = "<strong>NO GAMES FOUND</strong><span>Try another search and keep the spark alive.</span>";
gamesContainer.appendChild(emptyState);
return;
}
filteredGames.forEach((game, index) => {
const gameLink = document.createElement("a");
gameLink.className = "game";
// Create obfuscated game URL
const gameUrl = `${getWorkingServer()}/${game.url}/`;
const encodedGameUrl = proxyEncoder ?
proxyEncoder.xorEncode(gameUrl) :
btoa(gameUrl).replace(/[+/=]/g, c => ({ '+': '-', '/': '_', '=': '' }[c]));
gameLink.href = `play.html?g=${encodedGameUrl}&r=${Math.random().toString(36).substring(2)}`;
gameLink.setAttribute("aria-label", `Play ${game.name}`);
gameLink.style.setProperty("--card-delay", `${Math.min(index, 18) * 35}ms`);
const gameImage = document.createElement("img");
// Use proxy for game images only if needed
const imageUrl = `${getWorkingServer()}/${game.url}/${game.image}`;
gameImage.src = imageUrl; // Start with direct URL
gameImage.alt = "";
gameImage.loading = "lazy";
gameImage.decoding = "async";
// Add error handling for images - try proxy on failure
gameImage.onerror = function() {
if (this.dataset.proxyTried !== 'true' && PROXY_ENDPOINTS[currentProxyIndex]) {
this.dataset.proxyTried = 'true';
this.src = createProxyUrl(PROXY_ENDPOINTS[currentProxyIndex], imageUrl);
} else {
// Try next server
rotateServer();
const fallbackImageUrl = `${getWorkingServer()}/${game.url}/${game.image}`;
this.src = fallbackImageUrl;
}
};
const gameName = document.createElement("span");
gameName.className = "game-name";
gameName.textContent = game.name;
const playLabel = document.createElement("span");
playLabel.className = "game-play";
playLabel.textContent = "PLAY";
gameLink.append(gameImage, gameName, playLabel);
gamesContainer.appendChild(gameLink);
});
}
function updateSearchResults() {
if (!searchInput) return;
const query = searchInput.value.trim().toLowerCase();
const filteredGames = gamesData.filter((game) =>
game.name.toLowerCase().includes(query)
);
displayFilteredGames(filteredGames);
const resultsLabel = document.getElementById("resultsLabel");
if (resultsLabel) {
resultsLabel.textContent = query
? `${filteredGames.length} OF ${gamesData.length} GAMES`
: "PICK YOUR NEXT GAME";
}
}
if (gamesContainer) {
if (searchInput) searchInput.addEventListener("input", updateSearchResults);
// Load games.json first (priority)
fetch("./config/games.json")
.then((response) => {
if (!response.ok) throw new Error(`Game list request failed (${response.status})`);
return response.json();
})
.then((data) => {
gamesData = data;
const gameCount = document.getElementById("gameCount");
if (gameCount) gameCount.textContent = String(data.length);
displayFilteredGames(data);
console.log(`Loaded ${data.length} games successfully`);
// Initialize proxy system after games are loaded
setTimeout(() => initializeProxy(), 500);
})
.catch((error) => {
console.error("Error fetching games:", error);
// Try alternative fetch methods
if (!window.gamesFallbackTried) {
window.gamesFallbackTried = true;
console.log("Trying fallback fetch method...");
// Try with XMLHttpRequest
const xhr = new XMLHttpRequest();
xhr.open('GET', './config/games.json');
xhr.onload = function() {
if (xhr.status === 200) {
try {
const data = JSON.parse(xhr.responseText);
gamesData = data;
const gameCount = document.getElementById("gameCount");
if (gameCount) gameCount.textContent = String(data.length);
displayFilteredGames(data);
console.log(`Loaded ${data.length} games via fallback`);
// Initialize proxy system after games are loaded
setTimeout(() => initializeProxy(), 500);
} catch (e) {
showErrorState();
}
} else {
showErrorState();
}
};
xhr.onerror = showErrorState;
xhr.send();
} else {
showErrorState();
}
});
function showErrorState() {
gamesContainer.innerHTML = '<div class="empty-state" role="alert"><strong>THE ARCADE IS TAKING A BREATHER</strong><span>We could not load the game list. Refresh the page to try again.</span></div>';
}
}