cfWorker.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  1. function looksLikeAsset(pathname) {
  2. // 末段包含 .xxx 扩展名就当资源(.js/.css/.png/.map 等)
  3. return /\.[a-zA-Z0-9]{1,8}$/.test(pathname);
  4. }
  5. function isHtmlNavigation(request) {
  6. const method = request.method.toUpperCase();
  7. if (method !== "GET" && method !== "HEAD") return false;
  8. const accept = request.headers.get("accept") || "";
  9. // 浏览器访问页面通常会带 text/html
  10. if (!accept.includes("text/html")) return false;
  11. return true;
  12. }
  13. /**
  14. * 混淆 HTML,给标签增加随机冗余属性
  15. * @param {string} html 原始 HTML
  16. * @param {string} seed 用于随机的种子(如域名)
  17. * @returns {string} 混淆后的 HTML
  18. */
  19. function obfuscateHtml(html, seed) {
  20. // 简单的伪随机函数
  21. let hash = 0;
  22. for (let i = 0; i < seed.length; i++) {
  23. hash = (hash << 5) - hash + seed.charCodeAt(i);
  24. hash |= 0;
  25. }
  26. const pseudoRandom = () => {
  27. hash = (hash * 16807) % 2147483647;
  28. return (hash - 1) / 2147483646;
  29. };
  30. const randomStr = (len) => {
  31. const chars = "abcdefghijklmnopqrstuvwxyz";
  32. let str = "";
  33. for (let i = 0; i < len; i++) {
  34. str += chars[Math.floor(pseudoRandom() * chars.length)];
  35. }
  36. return str;
  37. };
  38. // 1) 注入混淆属性到现有标签
  39. // 匹配常见的开始标签,如 <title, <script, <div, <span, <link, <meta, <p, <body
  40. // 排除已经闭合的标签和带 / 的结束标签
  41. const targetTags = ["title", "script", "div", "span", "link", "meta", "p", "body", "h1", "h2", "button", "img"];
  42. targetTags.forEach(tag => {
  43. const regex = new RegExp(`<${tag}(\\s|>)`, "gi");
  44. html = html.replace(regex, (match, p1) => {
  45. // 随机生成 1-2 个混淆属性
  46. const attrCount = 1 + Math.floor(pseudoRandom() * 2);
  47. let attrs = "";
  48. for (let i = 0; i < attrCount; i++) {
  49. attrs += ` ${randomStr(5 + Math.floor(pseudoRandom() * 5))}`;
  50. }
  51. return `<${tag}${attrs}${p1}`;
  52. });
  53. });
  54. // 2) 之前保留的冗余标签逻辑(可选,用户重点是属性,但也保留一些结构冗余)
  55. const tags = ["div", "span", "p", "i", "b"];
  56. const classes = ["hidden-content", "meta-info", "v-data", "loading-state", "wrapper-inner"];
  57. const generateJunk = (count) => {
  58. let junk = "\n<!-- obfuscation start -->\n";
  59. for (let i = 0; i < count; i++) {
  60. const tag = tags[Math.floor(pseudoRandom() * tags.length)];
  61. const cls = classes[Math.floor(pseudoRandom() * classes.length)];
  62. const id = "ui-" + Math.floor(pseudoRandom() * 10000);
  63. const extra = randomStr(6);
  64. junk += `<${tag} ${extra} id="${id}" class="${cls}" style="display:none; visibility:hidden; position:absolute; z-index:-1;"></${tag}>\n`;
  65. }
  66. junk += "<!-- obfuscation end -->\n";
  67. return junk;
  68. };
  69. if (html.includes("</body>")) {
  70. return html.replace("</body>", `${generateJunk(3 + Math.floor(pseudoRandom() * 5))}</body>`);
  71. }
  72. return html + generateJunk(3);
  73. }
  74. export default {
  75. async fetch(request, env, ctx) {
  76. const url = new URL(request.url);
  77. // 1) 国家/地区访问控制
  78. // 如果当前国家不是来自 AU, GB, UM, US, SG 这些的时候,显示为 /403.html
  79. const allowedCountries = ["AU", "GB", "UM", "US", "SG"];
  80. const country = request.cf ? request.cf.country : null;
  81. if (country && !allowedCountries.includes(country)) {
  82. // 构造 403.html 的请求路径
  83. const forbiddenUrl = new URL("/403.html", url.origin);
  84. const forbiddenResp = await fetch(forbiddenUrl.toString());
  85. const forbiddenHtml = await forbiddenResp.text();
  86. return new Response(forbiddenHtml, {
  87. status: 403,
  88. headers: { "Content-Type": "text/html;charset=UTF-8" }
  89. });
  90. }
  91. // 不是页面导航 or 看起来是静态资源:直接回源,不替换
  92. if (!isHtmlNavigation(request) || looksLikeAsset(url.pathname)) {
  93. return fetch(request);
  94. }
  95. const host = url.hostname; // e.g. bigwin7.vip
  96. const sub = host.split(".")[0] || "default";
  97. // 1) 子品牌配置表:根据 load.m.js 的 sites_config 配置
  98. const BRAND_MAP = {
  99. // 默认配置
  100. default: {
  101. BRAND_NAME: "UsSlot777",
  102. BRAND_TITLE: "UsSlot777 | Online Slots & Real Money Games",
  103. BRAND_DESCRIPTION:
  104. "High-quality games, instant access, daily rewards, and a smooth experience built for serious slot fans.",
  105. BRAND_OG_TITLE: "UsSlot777 | Online Slots & Real Money Games",
  106. BRAND_OG_DESCRIPTION:
  107. "High-quality games, instant access, daily rewards, and a smooth experience built for serious slot fans.",
  108. BRAND_HERO_TITLE: "Play America's Best Slots",
  109. BRAND_HERO_SUBTITLE:
  110. "High-quality games, instant access, daily rewards, and a smooth experience built for serious slot fans.",
  111. BRAND_PRIMARY_CTA_TEXT: "Start Playing Now",
  112. BRAND_PRIMARY_CTA_LINK: "/start",
  113. SUPPORT_EMAIL: "support@usslot777.com",
  114. THEME_COLOR: "#0f172a",
  115. FAV_ICO: "./resources/favicons/favicon.ico",
  116. BRAND_LOGO: url.origin + "/resources/logos/logo.png",
  117. BRAND_OG_IMAGE: url.origin + "/resources/product/thumbn.webp",
  118. },
  119. // bigwin7.vip - 红色文字 + 金色7
  120. bigwin7: {
  121. BRAND_NAME: "BigWin7",
  122. BRAND_TITLE: "BigWin7 | Online Slots & Real Money Games",
  123. BRAND_DESCRIPTION:
  124. "Experience the thrill of big wins with premium slot games.",
  125. BRAND_OG_TITLE: "BigWin7 | Online Slots & Real Money Games",
  126. BRAND_OG_DESCRIPTION:
  127. "Experience the thrill of big wins with premium slot games.",
  128. BRAND_HERO_TITLE: "Experience Big Wins",
  129. BRAND_HERO_SUBTITLE:
  130. "Experience the thrill of big wins with premium slot games.",
  131. BRAND_PRIMARY_CTA_TEXT: "Start Winning",
  132. BRAND_PRIMARY_CTA_LINK: "/start",
  133. SUPPORT_EMAIL: "support@bigwin7.vip",
  134. THEME_COLOR: "#B91C1C",
  135. FAV_ICO: "./resources/favicons/bigwin7.ico",
  136. BRAND_LOGO: url.origin + "/resources/logos/bigwin7.webp",
  137. BRAND_OG_IMAGE: url.origin + "/resources/product/thumbn.webp",
  138. },
  139. // bigwinrush.vip - 紫色/粉色文字 + 绿色$
  140. bigwinrush: {
  141. BRAND_NAME: "BigWinRush",
  142. BRAND_TITLE: "BigWinRush | Online Slots & Real Money Games",
  143. BRAND_DESCRIPTION:
  144. "Rush to your biggest wins ever with exciting slot games.",
  145. BRAND_OG_TITLE: "BigWinRush | Online Slots & Real Money Games",
  146. BRAND_OG_DESCRIPTION:
  147. "Rush to your biggest wins ever with exciting slot games.",
  148. BRAND_HERO_TITLE: "Rush to Big Wins",
  149. BRAND_HERO_SUBTITLE:
  150. "Rush to your biggest wins ever with exciting slot games.",
  151. BRAND_PRIMARY_CTA_TEXT: "Join the Rush",
  152. BRAND_PRIMARY_CTA_LINK: "/start",
  153. SUPPORT_EMAIL: "support@bigwinrush.vip",
  154. THEME_COLOR: "#5B21B6",
  155. FAV_ICO: "./resources/favicons/bigwinrush.ico",
  156. BRAND_LOGO: url.origin + "/resources/logos/bigwinrush.webp",
  157. BRAND_OG_IMAGE: url.origin + "/resources/product/thumbn.webp",
  158. },
  159. // cashstorm.net - 青色/蓝绿龙卷风
  160. cashstorm: {
  161. BRAND_NAME: "CashStorm",
  162. BRAND_TITLE: "CashStorm | Online Slots & Real Money Games",
  163. BRAND_DESCRIPTION:
  164. "Ride the storm and collect massive cash rewards.",
  165. BRAND_OG_TITLE: "CashStorm | Online Slots & Real Money Games",
  166. BRAND_OG_DESCRIPTION:
  167. "Ride the storm and collect massive cash rewards.",
  168. BRAND_HERO_TITLE: "Ride the Cash Storm",
  169. BRAND_HERO_SUBTITLE:
  170. "Ride the storm and collect massive cash rewards.",
  171. BRAND_PRIMARY_CTA_TEXT: "Enter the Storm",
  172. BRAND_PRIMARY_CTA_LINK: "/start",
  173. SUPPORT_EMAIL: "support@cashstorm.net",
  174. THEME_COLOR: "#0E7490",
  175. FAV_ICO: "./resources/favicons/cashstorm.ico",
  176. BRAND_LOGO: url.origin + "/resources/logos/cashstorm.webp",
  177. BRAND_OG_IMAGE: url.origin + "/resources/product/thumbn.webp",
  178. },
  179. // hotwinzone.net - 红色/橙色火焰
  180. hotwinzone: {
  181. BRAND_NAME: "HotWinZone",
  182. BRAND_TITLE: "HotWinZone | Online Slots & Real Money Games",
  183. BRAND_DESCRIPTION:
  184. "Enter the hot zone where every spin is a winner.",
  185. BRAND_OG_TITLE: "HotWinZone | Online Slots & Real Money Games",
  186. BRAND_OG_DESCRIPTION:
  187. "Enter the hot zone where every spin is a winner.",
  188. BRAND_HERO_TITLE: "Enter the Hot Zone",
  189. BRAND_HERO_SUBTITLE:
  190. "Enter the hot zone where every spin is a winner.",
  191. BRAND_PRIMARY_CTA_TEXT: "Get Hot Wins",
  192. BRAND_PRIMARY_CTA_LINK: "/start",
  193. SUPPORT_EMAIL: "support@hotwinzone.net",
  194. THEME_COLOR: "#C2410C",
  195. FAV_ICO: "./resources/favicons/hotwinzone.ico",
  196. BRAND_LOGO: url.origin + "/resources/logos/hotwinzone.webp",
  197. BRAND_OG_IMAGE: url.origin + "/resources/product/thumbn.webp",
  198. },
  199. // jackpotfury.net - 红色/橙色火焰文字
  200. jackpotfury: {
  201. BRAND_NAME: "JackpotFury",
  202. BRAND_TITLE: "JackpotFury | Online Slots & Real Money Games",
  203. BRAND_DESCRIPTION:
  204. "Unleash the fury and hit massive jackpots.",
  205. BRAND_OG_TITLE: "JackpotFury | Online Slots & Real Money Games",
  206. BRAND_OG_DESCRIPTION:
  207. "Unleash the fury and hit massive jackpots.",
  208. BRAND_HERO_TITLE: "Unleash Jackpot Fury",
  209. BRAND_HERO_SUBTITLE:
  210. "Unleash the fury and hit massive jackpots.",
  211. BRAND_PRIMARY_CTA_TEXT: "Hit Jackpots",
  212. BRAND_PRIMARY_CTA_LINK: "/start",
  213. SUPPORT_EMAIL: "support@jackpotfury.net",
  214. THEME_COLOR: "#B91C1C",
  215. FAV_ICO: "./resources/favicons/jackpotfury.ico",
  216. BRAND_LOGO: url.origin + "/resources/logos/jackpotfury.webp",
  217. BRAND_OG_IMAGE: url.origin + "/resources/product/thumbn.webp",
  218. },
  219. // luckyhitnow.vip - 绿色四叶草
  220. luckyhitnow: {
  221. BRAND_NAME: "LuckyHitNow",
  222. BRAND_TITLE: "LuckyHitNow | Online Slots & Real Money Games",
  223. BRAND_DESCRIPTION:
  224. "Get lucky and hit big wins right now.",
  225. BRAND_OG_TITLE: "LuckyHitNow | Online Slots & Real Money Games",
  226. BRAND_OG_DESCRIPTION:
  227. "Get lucky and hit big wins right now.",
  228. BRAND_HERO_TITLE: "Get Lucky Now",
  229. BRAND_HERO_SUBTITLE:
  230. "Get lucky and hit big wins right now.",
  231. BRAND_PRIMARY_CTA_TEXT: "Try Your Luck",
  232. BRAND_PRIMARY_CTA_LINK: "/start",
  233. SUPPORT_EMAIL: "support@luckyhitnow.vip",
  234. THEME_COLOR: "#046E55",
  235. FAV_ICO: "./resources/favicons/luckyhitnow.ico",
  236. BRAND_LOGO: url.origin + "/resources/logos/luckyhitnow.webp",
  237. BRAND_OG_IMAGE: url.origin + "/resources/product/thumbn.webp",
  238. },
  239. // megacashgo.vip - 绿色/金色文字
  240. megacashgo: {
  241. BRAND_NAME: "MegaCashGo",
  242. BRAND_TITLE: "MegaCashGo | Online Slots & Real Money Games",
  243. BRAND_DESCRIPTION:
  244. "Go big or go home with mega cash prizes.",
  245. BRAND_OG_TITLE: "MegaCashGo | Online Slots & Real Money Games",
  246. BRAND_OG_DESCRIPTION:
  247. "Go big or go home with mega cash prizes.",
  248. BRAND_HERO_TITLE: "Go for Mega Cash",
  249. BRAND_HERO_SUBTITLE:
  250. "Go big or go home with mega cash prizes.",
  251. BRAND_PRIMARY_CTA_TEXT: "Go Mega",
  252. BRAND_PRIMARY_CTA_LINK: "/start",
  253. SUPPORT_EMAIL: "support@megacashgo.vip",
  254. THEME_COLOR: "#046E55",
  255. FAV_ICO: "./resources/favicons/megacashgo.ico",
  256. BRAND_LOGO: url.origin + "/resources/logos/megacashgo.webp",
  257. BRAND_OG_IMAGE: url.origin + "/resources/product/thumbn.webp",
  258. },
  259. // rapidjackpot.vip - 橙色火箭
  260. rapidjackpot: {
  261. BRAND_NAME: "RapidJackpot",
  262. BRAND_TITLE: "RapidJackpot | Online Slots & Real Money Games",
  263. BRAND_DESCRIPTION:
  264. "Fast spins, rapid jackpots, instant wins.",
  265. BRAND_OG_TITLE: "RapidJackpot | Online Slots & Real Money Games",
  266. BRAND_OG_DESCRIPTION:
  267. "Fast spins, rapid jackpots, instant wins.",
  268. BRAND_HERO_TITLE: "Rapid Jackpots Await",
  269. BRAND_HERO_SUBTITLE:
  270. "Fast spins, rapid jackpots, instant wins.",
  271. BRAND_PRIMARY_CTA_TEXT: "Win Fast",
  272. BRAND_PRIMARY_CTA_LINK: "/start",
  273. SUPPORT_EMAIL: "support@rapidjackpot.vip",
  274. THEME_COLOR: "#C2410C",
  275. FAV_ICO: "./resources/favicons/rapidjackpot.ico",
  276. BRAND_LOGO: url.origin + "/resources/logos/rapidjackpot.webp",
  277. BRAND_OG_IMAGE: url.origin + "/resources/product/thumbn.webp",
  278. },
  279. // slotfrenzy.vip - 红色/黄色小丑
  280. slotfrenzy: {
  281. BRAND_NAME: "SlotFrenzy",
  282. BRAND_TITLE: "SlotFrenzy | Online Slots & Real Money Games",
  283. BRAND_DESCRIPTION:
  284. "Join the frenzy with non-stop slot action.",
  285. BRAND_OG_TITLE: "SlotFrenzy | Online Slots & Real Money Games",
  286. BRAND_OG_DESCRIPTION:
  287. "Join the frenzy with non-stop slot action.",
  288. BRAND_HERO_TITLE: "Join the Slot Frenzy",
  289. BRAND_HERO_SUBTITLE:
  290. "Join the frenzy with non-stop slot action.",
  291. BRAND_PRIMARY_CTA_TEXT: "Go Frenzy",
  292. BRAND_PRIMARY_CTA_LINK: "/start",
  293. SUPPORT_EMAIL: "support@slotfrenzy.vip",
  294. THEME_COLOR: "#B91C1C",
  295. FAV_ICO: "./resources/favicons/slotfrenzy.ico",
  296. BRAND_LOGO: url.origin + "/resources/logos/slotfrenzy.webp",
  297. BRAND_OG_IMAGE: url.origin + "/resources/product/thumbn.webp",
  298. },
  299. // spinblitz.vip - 蓝色文字 + 黄色闪电
  300. spinblitz: {
  301. BRAND_NAME: "SpinBlitz",
  302. BRAND_TITLE: "SpinBlitz | Online Slots & Real Money Games",
  303. BRAND_DESCRIPTION:
  304. "Blitz through wins with lightning-fast spins.",
  305. BRAND_OG_TITLE: "SpinBlitz | Online Slots & Real Money Games",
  306. BRAND_OG_DESCRIPTION:
  307. "Blitz through wins with lightning-fast spins.",
  308. BRAND_HERO_TITLE: "Blitz to Victory",
  309. BRAND_HERO_SUBTITLE:
  310. "Blitz through wins with lightning-fast spins.",
  311. BRAND_PRIMARY_CTA_TEXT: "Start Blitz",
  312. BRAND_PRIMARY_CTA_LINK: "/start",
  313. SUPPORT_EMAIL: "support@spinblitz.vip",
  314. THEME_COLOR: "#1E40AF",
  315. FAV_ICO: "./resources/favicons/spinblitz.ico",
  316. BRAND_LOGO: url.origin + "/resources/logos/spinblitz.webp",
  317. BRAND_OG_IMAGE: url.origin + "/resources/product/thumbn.webp",
  318. },
  319. // ultrawinner.net - 蓝色/紫色钻石
  320. ultrawinner: {
  321. BRAND_NAME: "UltraWinner",
  322. BRAND_TITLE: "UltraWinner | Online Slots & Real Money Games",
  323. BRAND_DESCRIPTION:
  324. "Become the ultimate winner with ultra rewards.",
  325. BRAND_OG_TITLE: "UltraWinner | Online Slots & Real Money Games",
  326. BRAND_OG_DESCRIPTION:
  327. "Become the ultimate winner with ultra rewards.",
  328. BRAND_HERO_TITLE: "Be the Ultra Winner",
  329. BRAND_HERO_SUBTITLE:
  330. "Become the ultimate winner with ultra rewards.",
  331. BRAND_PRIMARY_CTA_TEXT: "Win Ultra",
  332. BRAND_PRIMARY_CTA_LINK: "/start",
  333. SUPPORT_EMAIL: "support@ultrawinner.net",
  334. THEME_COLOR: "#5B21B6",
  335. FAV_ICO: "./resources/favicons/ultrawinner.ico",
  336. BRAND_LOGO: url.origin + "/resources/logos/ultrawinner.webp",
  337. BRAND_OG_IMAGE: url.origin + "/resources/product/thumbn.webp",
  338. },
  339. // winexplosion.vip - 红色/黄色/绿色混合
  340. winexplosion: {
  341. BRAND_NAME: "WinExplosion",
  342. BRAND_TITLE: "WinExplosion | Online Slots & Real Money Games",
  343. BRAND_DESCRIPTION:
  344. "Explosive wins await in every spin.",
  345. BRAND_OG_TITLE: "WinExplosion | Online Slots & Real Money Games",
  346. BRAND_OG_DESCRIPTION:
  347. "Explosive wins await in every spin.",
  348. BRAND_HERO_TITLE: "Explosive Wins Await",
  349. BRAND_HERO_SUBTITLE:
  350. "Explosive wins await in every spin.",
  351. BRAND_PRIMARY_CTA_TEXT: "Explode to Win",
  352. BRAND_PRIMARY_CTA_LINK: "/start",
  353. SUPPORT_EMAIL: "support@winexplosion.vip",
  354. THEME_COLOR: "#B91C1C",
  355. FAV_ICO: "./resources/favicons/winexplosion.ico",
  356. BRAND_LOGO: url.origin + "/resources/logos/winexplosion.webp",
  357. BRAND_OG_IMAGE: url.origin + "/resources/product/thumbn.webp",
  358. },
  359. };
  360. const brand = BRAND_MAP[sub] || BRAND_MAP.default;
  361. // 2) 计算 BRAND_URL(保持当前 host,不要写死)
  362. brand.BRAND_URL = `${url.protocol}//${host}${url.pathname === "/" ? "/" : url.pathname}`;
  363. // 3) 拉取源站 HTML(如果你是 Pages,可直接 return new Response(...) 处理)
  364. // 这里用"回源"方式示例:把请求转发到真正的源站(例如你的 Pages/服务器)
  365. const originResp = await fetch(request);
  366. // 非 HTML 资源直接透传(css/js/png 等)
  367. const contentType = originResp.headers.get("content-type") || "";
  368. if (!contentType.includes("text/html")) return originResp;
  369. // 4) 用 HTMLRewriter + 文本替换
  370. // HTMLRewriter 更适合替换 title/meta;占位符替换更适合批量文本替换
  371. // 这里两种一起用:先把响应体转文本做占位符替换,再返回
  372. let html = await originResp.text();
  373. // 4.1 占位符替换(%%KEY%%)
  374. for (const [k, v] of Object.entries(brand)) {
  375. const safeV = String(v).replaceAll("$", "&#36;"); // 防止某些模板字符串/特殊符号干扰
  376. html = html.replaceAll(`%%${k}%%`, safeV);
  377. }
  378. // 4.2 如果路径包含 landingpage 或 startup,则进行混淆
  379. if (url.pathname.includes("landingpage") || url.pathname.includes("startup")) {
  380. html = obfuscateHtml(html, host);
  381. }
  382. // 4.3 安全兜底:如果页面里存在未替换占位符,可选择清空或保留
  383. // html = html.replace(/%%[A-Z0-9_]+%%/g, "");
  384. // 5) 返回响应(保留原响应的大部分 header,但要修正 content-length)
  385. const newHeaders = new Headers(originResp.headers);
  386. newHeaders.delete("content-length");
  387. return new Response(html, {
  388. status: originResp.status,
  389. statusText: originResp.statusText,
  390. headers: newHeaders,
  391. });
  392. },
  393. };