Loading snippets...
/**
* game3rb
* base: https://game3rb.com
* Creator: ShanMolvyr
* reupload cantumkan sumber ini ygy
*
* Note: cek https://snippet.vyr.my.id/shanmolvyr/game3rb/README.md
* Sumber: https://whatsapp.com/channel/0029VbB4Kw8EFeXfeExaXc3Q
*/
const axios = require('axios');
const cheerio = require('cheerio');
const BASE = 'https://game3rb.com';
const http = axios.create({
baseURL: BASE,
timeout: 15000,
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
'Accept-Language': 'en-US,en;q=0.9',
'Accept-Encoding': 'gzip, deflate, br',
'Connection': 'keep-alive',
'Upgrade-Insecure-Requests': '1',
'Sec-Fetch-Dest': 'document',
'Sec-Fetch-Mode': 'navigate',
'Sec-Fetch-Site': 'none',
},
maxRedirects: 5,
});
const ICON_PATHS = ['file-edit', 'database', 'user-1', 'Clock', 'tag', '/T.', '/R.', 'spinner', 'placeholder', 'discord', 'join-us'];
function parseCards($) {
return $('article.post-hentry').map((_, el) => {
const $el = $(el);
const titleEl = $el.find('h3.entry-title a, h2.entry-title a').first();
const title = titleEl.text().trim();
const url = titleEl.attr('href') || '';
if (!title || !url) return null;
return {
postId: ($el.attr('id') || '').replace('post-', '') || null,
title,
slug: url.replace(BASE, '').replace(/^\/|\/$/g, ''),
url,
thumbnail: $el.find('img.entry-image').attr('src') || null,
date: $el.find('time.entry-date').attr('datetime') || null,
categories: $el.find('span.entry-categories-inner a.entry-category').map((_, a) => $(a).text().trim()).get(),
badges: $el.find('#carts #cart').map((_, b) => $(b).text().trim()).get().filter(t => t && t !== 'Request'),
excerpt: $el.find('.summaryy').text().replace(/\s+/g, ' ').trim() || null,
};
}).get().filter(Boolean);
}
function parsePagination($) {
const nums = $('a.page-numbers').map((_, el) => parseInt($(el).text().trim())).get().filter(n => !isNaN(n));
return nums.length ? Math.max(...nums) : 1;
}
function parseInfo($) {
const info = {};
$('.entry-content span.uk-text-meta, .post-content span.uk-text-meta').each((_, el) => {
const m = $(el).text().trim().match(/^([^:]+):\s*(.+)$/);
if (m) info[m[1].trim().toLowerCase().replace(/\s+/g, '_')] = m[2].trim();
});
return info;
}
function parseCategories($) {
const cats = [];
const seen = new Set();
$('select.selectnav option[value*="/category/"], select#selectnav1 option[value*="/category/"]').each((_, el) => {
const name = $(el).text().replace(/^-\s*/, '').trim();
const url = $(el).attr('value');
if (name && url && !seen.has(url)) { seen.add(url); cats.push({ name, url }); }
});
if (!cats.length) {
$('ul.sub-menu a[href*="/category/"], nav a[href*="/category/"]').each((_, el) => {
const name = $(el).text().trim();
const url = $(el).attr('href');
if (name && url && !seen.has(url)) { seen.add(url); cats.push({ name, url }); }
});
}
return cats;
}
async function getHome() {
const { data } = await http.get('/');
const $ = cheerio.load(data);
return { latest: parseCards($), categories: parseCategories($) };
}
async function search(query) {
const { data } = await http.get('/', { params: { s: query } });
return { query, results: parseCards(cheerio.load(data)) };
}
async function getCategory(categorySlug, page = 1) {
const path = page > 1 ? `/category/${categorySlug}/page/${page}/` : `/category/${categorySlug}/`;
const { data } = await http.get(path);
const $ = cheerio.load(data);
return { category: categorySlug, page, totalPages: parsePagination($), results: parseCards($) };
}
async function getGame(slugOrUrl) {
const path = slugOrUrl.startsWith('http') ? slugOrUrl.replace(BASE, '') : `/${slugOrUrl}/`;
const { data } = await http.get(path);
const $ = cheerio.load(data);
const seen = new Set();
const categories = $('article[id^="post-"] span.entry-categories-inner a.entry-category, .entry-header span.entry-categories-inner a')
.map((_, a) => ({ name: $(a).text().trim(), url: $(a).attr('href') || '' }))
.get()
.filter(c => c.name && c.url && !seen.has(c.url) && seen.add(c.url));
const screenshots = [...new Set(
$('.entry-content img, .post-content img')
.map((_, el) => $(el).attr('src') || $(el).attr('data-lazy-src') || '')
.get()
.filter(src => src && !ICON_PATHS.some(p => src.includes(p)) && !($(`.entry-content img[src="${src}"]`).attr('width') && parseInt($(`.entry-content img[src="${src}"]`).attr('width')) < 50))
)];
const downloadLinks = $('a#download-link')
.map((_, el) => {
const url = $(el).attr('href');
if (!url || url === '#' || url.startsWith('javascript')) return null;
const label = $(el).closest('div').prev().find('strong, h3, h4').last().text().trim() || $(el).text().trim() || 'Download';
return { label, url };
})
.get()
.filter(Boolean);
return {
title: $('h1.post-title, h1.entry-title').first().text().trim(),
postId: $('article[id^="post-"]').first().attr('id')?.replace('post-', '') || null,
slug: slugOrUrl.startsWith('http') ? slugOrUrl.replace(BASE + '/', '').replace(/\/$/, '') : slugOrUrl,
url: `${BASE}${path}`,
date: $('time.entry-date, time.updated').first().attr('datetime') || null,
thumbnail: $('h4.separator img, .entry-content img').first().attr('src') || $('h4.separator img, .entry-content img').first().attr('data-lazy-src') || null,
categories,
info: parseInfo($),
downloadLinks,
screenshots,
};
}
async function getPopular() {
const { data } = await http.get('/');
const $ = cheerio.load(data);
return $('.wpp-list li a, [id*="wordpress-popular-posts"] a')
.map((_, el) => {
const title = $(el).text().trim();
const url = $(el).attr('href') || '';
if (!title || !url.startsWith(BASE)) return null;
return { title, url, slug: url.replace(BASE + '/', '').replace(/\/$/, '') };
})
.get()
.filter(Boolean);
}
async function getUpdates(page = 1) { return getCategory('game-updates', page); }
async function getOnlineGames(page = 1) { return getCategory('games-online', page); }
async function getPCGames(page = 1) { return getCategory('pc-games', page); }
const CATEGORIES = {
action: 'pc-games/action',
adventure: 'pc-games/adventure',
rpg: 'pc-games/rpg',
simulation: 'pc-games/simulation',
strategy: 'pc-games/strategy',
horror: 'pc-games/horror',
racing: 'pc-games/racing',
sports: 'pc-games/sports',
indie: 'pc-games/indie',
casual: 'pc-games/casual',
vr: 'pc-games/vr',
gore: 'pc-games/gore',
early_access: 'pc-games/early-access',
violent: 'pc-games/violent',
nostalgia: 'pc-games/nostalgia-games',
online: 'games-online',
repack: 'pc-repack',
updates: 'game-updates',
};
module.exports = { getHome, search, getGame, getCategory, getPopular, getUpdates, getOnlineGames, getPCGames, CATEGORIES };
if (require.main === module) {
const [,, cmd, ...args] = process.argv;
const run = async () => {
if (!cmd) {
process.stderr.write('Usage: node index.js <command> [args]\nCommands: home | search <query> | game <slug|url> | category <slug> [page] | popular | updates [page] | online [page] | pcgames [page]\n');
return;
}
const map = {
home: () => getHome(),
search: () => search(args.join(' ')),
game: () => getGame(args[0]),
category: () => getCategory(args[0], parseInt(args[1]) || 1),
popular: () => getPopular(),
updates: () => getUpdates(parseInt(args[0]) || 1),
online: () => getOnlineGames(parseInt(args[0]) || 1),
pcgames: () => getPCGames(parseInt(args[0]) || 1),
};
if (!map[cmd]) { process.stderr.write(`Unknown command: ${cmd}\n`); return; }
process.stdout.write(JSON.stringify(await map[cmd](), null, 2) + '\n');
};
run().catch(e => { process.stderr.write(e.message + '\n'); process.exit(1); });
}
bashnpm install axios cheerio
bashnode game3rb.js home node game3rb.js search "beamng drive" node game3rb.js game beamng-drive-online node game3rb.js game https://game3rb.com/beamng-drive-online/ node game3rb.js category pc-games/action 1 node game3rb.js popular node game3rb.js updates node game3rb.js online 2 node game3rb.js pcgames
bashby ShanMolvyr