feat(ci): switch Cloudflare bypass from FlareSolverr to Byparr
This commit is contained in:
1 parent
fabd160250
commit
25f4d74209
10 files changed
+138
-131
No files matched your search
@@ -5,9 +5,9 @@ import { autoDetectInteraction } from "@/lib/furni/auto-interaction";
|
||||
import { normalizeClassname } from "@/lib/furni/classname";
|
||||
import { HABBO_GAMEDATA_HOTEL_SETTING_KEY } from "@/lib/habbo-gamedata-hotel";
|
||||
import { logger } from "@/lib/logger";
|
||||
import { fetchWithByparr } from "@/lib/services/byparr";
|
||||
import { extractFurniIconPng } from "@/lib/services/clone-icon";
|
||||
import type { CloneSource } from "@/lib/services/clone-sources";
|
||||
import { fetchWithFlareSolver } from "@/lib/services/flare-solver";
|
||||
import { getFurniAssetDirs } from "@/lib/services/furni-asset-dirs";
|
||||
import { appendFurniEntry } from "@/lib/services/furni-data";
|
||||
import {
|
||||
@@ -101,7 +101,7 @@ const TTL = 5 * 60 * 1000;
|
||||
/**
|
||||
* Some sources serve their furnidata wrapped in an HTML document (e.g. Leet's
|
||||
* JSON is embedded in a `<pre>` block inside the page, often surfaced by the
|
||||
* FlareSolverr fallback). Extract the JSON payload before giving up.
|
||||
* Byparr fallback). Extract the JSON payload before giving up.
|
||||
*/
|
||||
function extractJsonFromHtml(body: string): string | null {
|
||||
const pre = body.match(/<pre[^>]*>([\s\S]*?)<\/pre>/);
|
||||
@@ -117,20 +117,20 @@ function extractJsonFromHtml(body: string): string | null {
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a source's furnidata via FlareSolverr, falling back to a curl
|
||||
* Fetch a source's furnidata via Byparr, falling back to a curl
|
||||
* subprocess. Some CDNs (e.g. Leet.city) block Node's TLS fingerprint while
|
||||
* the same request succeeds from curl — so curl is a useful second fallback
|
||||
* when FlareSolverr is unavailable.
|
||||
* when Byparr is unavailable.
|
||||
*/
|
||||
async function fetchWithFallback(url: string): Promise<string> {
|
||||
try {
|
||||
return await fetchWithFlareSolver(url);
|
||||
return await fetchWithByparr(url);
|
||||
} catch {
|
||||
try {
|
||||
return await curlFetchText(url);
|
||||
} catch (err) {
|
||||
throw new Error(
|
||||
`FlareSolverr + curl fallback failed for ${url}: ${(err as Error).message}`,
|
||||
`Byparr + curl fallback failed for ${url}: ${(err as Error).message}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -150,8 +150,8 @@ export async function fetchSourceFurnidata(
|
||||
});
|
||||
if (res.ok) {
|
||||
// Some sources (e.g. GitHub raw) serve JSON with a text/plain
|
||||
// content-type — only route to FlareSolverr when the body is
|
||||
// actually HTML, otherwise parse the JSON directly.
|
||||
// content-type — only route to Byparr when the body is actually
|
||||
// HTML, otherwise parse the JSON directly.
|
||||
const text = await res.text();
|
||||
if (
|
||||
text.trimStart().startsWith("{") ||
|
||||
@@ -171,7 +171,7 @@ export async function fetchSourceFurnidata(
|
||||
const extracted = extractJsonFromHtml(body);
|
||||
if (!extracted) {
|
||||
throw new Error(
|
||||
`Source ${url} is behind a Cloudflare challenge that could not be bypassed. Start FlareSolverr and check its logs.`,
|
||||
`Source ${url} is behind a Cloudflare challenge that could not be bypassed. Start Byparr and check its logs.`,
|
||||
);
|
||||
}
|
||||
body = extracted;
|
||||
|
||||
Reference in new issue
Block a user