fourmovie commited on
Commit
3c5e6bf
·
1 Parent(s): 820a968
Dockerfile ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM node:20-bullseye
2
+
3
+ # Install ALL dependencies untuk OpenCV + Chrome
4
+ RUN apt update && apt install -y \
5
+ wget gnupg ca-certificates xvfb \
6
+ fonts-liberation libappindicator3-1 libasound2 libatk-bridge2.0-0 \
7
+ libatk1.0-0 libxss1 libnss3 libxcomposite1 libxdamage1 libxrandr2 libgbm1 \
8
+ python3 make g++ pkg-config cmake \
9
+ libcairo2-dev libjpeg-dev libpng-dev libgif-dev librsvg2-dev \
10
+ libopencv-dev \
11
+ && wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb \
12
+ && apt install -y ./google-chrome-stable_current_amd64.deb \
13
+ && rm google-chrome-stable_current_amd64.deb \
14
+ && apt clean
15
+
16
+ WORKDIR /app
17
+
18
+ RUN mkdir -p /app/endpoints && \
19
+ mkdir -p /app/cache
20
+
21
+ COPY package*.json ./
22
+
23
+ # Install OpenCV dengan build from source
24
+ RUN npm install
25
+
26
+ COPY . .
27
+
28
+ EXPOSE 7860
29
+
30
+ CMD rm -f /tmp/.X99-lock && \
31
+ Xvfb :99 -screen 0 1024x768x24 & \
32
+ export DISPLAY=:99 && \
33
+ npm start
README.md CHANGED
@@ -3,10 +3,8 @@ title: Antibot3
3
  emoji: 👁
4
  colorFrom: blue
5
  colorTo: yellow
6
- sdk: gradio
7
  sdk_version: 6.0.0
8
- app_file: app.py
9
- pinned: false
10
  license: apache-2.0
11
  short_description: antibot ai
12
  ---
 
3
  emoji: 👁
4
  colorFrom: blue
5
  colorTo: yellow
6
+ sdk: docker
7
  sdk_version: 6.0.0
 
 
8
  license: apache-2.0
9
  short_description: antibot ai
10
  ---
api_test.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import asyncio
2
+ import httpx
3
+
4
+ async def main():
5
+ async with httpx.AsyncClient(timeout=30.0) as client:
6
+ resp1 = await client.post(
7
+ "http://localhost:8080/cloudflare",
8
+ json={
9
+ "domain": "https://olamovies.watch/generate",
10
+ "mode": "iuam",
11
+ },
12
+ )
13
+ print(resp1.json())
14
+
15
+ resp2 = await client.post(
16
+ "http://localhost:8080/cloudflare",
17
+ json={
18
+ "domain": "https://lksfy.com/",
19
+ "siteKey": "0x4AAAAAAA49NnPZwQijgRoi",
20
+ "mode": "turnstile",
21
+ },
22
+ )
23
+ print(resp2.json())
24
+
25
+ if __name__ == "__main__":
26
+ asyncio.run(main())
cache/cache.json ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "{\"domain\":\"https://v2links.org\",\"mode\":\"iuam\"}": {
3
+ "timestamp": 1758616160392,
4
+ "value": {
5
+ "cf_clearance": "qqs5f4MpFMgA0v78Qmh_HYDWoKhbwqlQ57bTW5KeIr8-1758616161-1.2.1.1-D5PdpmheHl.26ssIRKQBsXzPtPPkSXntEZ_H9FUJVt7MMTS_BEE8iH.E48MDzKtFBLwZqRYxE_1GLo1gj3ChXrwatOGEJcmGRUwavy2qvGgUPizn7qufd.sW0ULfhaRO7Gz_H_eO1TU3iEqCzltEUDNk0SviKRFkF8ozbvJ91MW_qmO.qrjQorbu_jxcgJv5BHs6rTNOitWtVDAmYMDukASq0viHXIUAIvTM.LIfQ88",
6
+ "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36",
7
+ "elapsed_time": 5.028
8
+ }
9
+ }
10
+ }
endpoints/antibot.js ADDED
@@ -0,0 +1,277 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const { extractTextFromImage } = require('./imageProcessor');
4
+
5
+ function mapAnswer(soalArray, jawaban, botIndex) {
6
+ return jawaban;
7
+ }
8
+
9
+ function normalizeText(text) {
10
+ return text.toLowerCase().replace(/[^\w\s]/g, '').trim();
11
+ }
12
+
13
+ function isValueMatch(value, targetSoal) {
14
+ const numberMap = {
15
+ '0': 'zero', '1': 'one', '2': 'two', '3': 'three', '4': 'four',
16
+ '5': 'five', '6': 'six', '7': 'seven', '8': 'eight', '9': 'nine', '10': 'ten',
17
+ 'zero': '0', 'one': '1', 'two': '2', 'three': '3', 'four': '4',
18
+ 'five': '5', 'six': '6', 'seven': '7', 'eight': '8', 'nine': '9', 'ten': '10',
19
+ 'I': '1', 'II': '2', 'III': '3', 'IV': '4', 'V': '5',
20
+ 'VI': '6', 'VII': '7', 'VIII': '8', 'IX': '9', 'X': '10',
21
+ 'slx': '6', 's1x': '6', 'six': '6',
22
+ 'f0ur': '4', 'f0r': '4', 'fuor': '4',
23
+ 'f1ve': '5', 'fiv': '5', 'f1v': '5',
24
+ 'e1ght': '8', 'elght': '8', 'eight': '8',
25
+ 'n1ne': '9', 'n1n': '9', 'nne': '9',
26
+ 'se7en': '7', 'sven': '7', 'seven': '7',
27
+ 'thre': '3', 'tree': '3', 'thr33': '3',
28
+ 'tw0': '2', 'to': '2', 'tw': '2',
29
+ '0ne': '1', 'on': '1', 'oen': '1'
30
+ };
31
+
32
+ const leetMap = {
33
+ 'O': '0', 'o': '0',
34
+ 'I': '1', 'i': '1', 'l': '1',
35
+ 'Z': '2', 'z': '2',
36
+ 'E': '3', 'e': '3',
37
+ 'A': '4', 'a': '4',
38
+ 'S': '5', 's': '5',
39
+ 'G': '6', 'g': '6',
40
+ 'T': '7', 't': '7',
41
+ 'B': '8', 'b': '8',
42
+ 'Q': '9', 'q': '9',
43
+ 'U': '4', 'u': '4',
44
+ 'R': '2', 'r': '2',
45
+ 'N': '9', 'n': '9',
46
+ 'V': '7', 'v': '7'
47
+ };
48
+
49
+ const normalizedValue = normalizeText(value);
50
+ const normalizedSoal = normalizeText(targetSoal);
51
+
52
+ if (normalizedValue === normalizedSoal) {
53
+ return true;
54
+ }
55
+
56
+ const convertLeet = (text) => {
57
+ return text.split('').map(char => leetMap[char] || char).join('');
58
+ };
59
+
60
+ const leetValue = convertLeet(value);
61
+ const leetSoal = convertLeet(targetSoal);
62
+
63
+ if (leetValue === normalizedSoal) return true;
64
+ if (normalizedValue === leetSoal) return true;
65
+ if (leetValue === leetSoal) return true;
66
+
67
+ const mappedValue = numberMap[normalizedValue] || numberMap[value] || normalizedValue;
68
+ const mappedSoal = numberMap[normalizedSoal] || numberMap[targetSoal] || normalizedSoal;
69
+
70
+ if (mappedValue === normalizedSoal) return true;
71
+ if (normalizedValue === mappedSoal) return true;
72
+ if (mappedValue === mappedSoal) return true;
73
+
74
+ const similarity = calculateSimilarity(normalizedValue, normalizedSoal);
75
+ if (similarity >= 0.8) {
76
+ return true;
77
+ }
78
+
79
+ try {
80
+ const valueResult = evaluateSimpleMath(value);
81
+ const soalResult = evaluateSimpleMath(targetSoal);
82
+ if (valueResult !== null && soalResult !== null && valueResult === soalResult) {
83
+ return true;
84
+ }
85
+ } catch (e) {}
86
+
87
+ return false;
88
+ }
89
+
90
+ function calculateSimilarity(str1, str2) {
91
+ if (str1 === str2) return 1;
92
+ if (str1.length === 0 || str2.length === 0) return 0;
93
+
94
+ const longer = str1.length > str2.length ? str1 : str2;
95
+ const shorter = str1.length > str2.length ? str2 : str1;
96
+
97
+ if (longer.includes(shorter)) return shorter.length / longer.length;
98
+
99
+ let matches = 0;
100
+ for (let i = 0; i < shorter.length; i++) {
101
+ if (shorter[i] === longer[i]) matches++;
102
+ }
103
+
104
+ return matches / longer.length;
105
+ }
106
+
107
+ function evaluateSimpleMath(expression) {
108
+ if (!expression) return null;
109
+ const cleanExpr = expression.toString().replace(/[^\d+\-*/.()]/g, '');
110
+ if (!cleanExpr) return null;
111
+ try {
112
+ if (cleanExpr.length > 10) return null;
113
+ const result = Function(`"use strict"; return (${cleanExpr})`)();
114
+ return typeof result === 'number' ? result : null;
115
+ } catch (e) {
116
+ return null;
117
+ }
118
+ }
119
+
120
+ function parseSoalText(text) {
121
+ const delimiters = /[.,:;\\/\s]+/;
122
+ let parts = text.split(delimiters).filter(part => part.trim() !== '');
123
+ if (parts.length === 1) {
124
+ parts = text.split(/\s+/).filter(part => part.trim() !== '');
125
+ }
126
+ return parts;
127
+ }
128
+
129
+ async function antibot(data) {
130
+ try {
131
+ const { main, bots } = data;
132
+
133
+ const mainBuffer = Buffer.from(main, 'base64');
134
+ const mainText = await extractTextFromImage(mainBuffer);
135
+
136
+ const soalArray = parseSoalText(mainText.response);
137
+
138
+ if (soalArray.length === 0) {
139
+ throw new Error('Tidak ada soal yang terdeteksi');
140
+ }
141
+
142
+ const botResults = [];
143
+
144
+ for (let i = 0; i < bots.length; i++) {
145
+ const bot = bots[i];
146
+ try {
147
+ const botBuffer = Buffer.from(bot.img, 'base64');
148
+ const botText = await extractTextFromImage(botBuffer);
149
+ const mappedValue = mapAnswer(soalArray, botText.response, i);
150
+
151
+ botResults.push({
152
+ id: bot.id,
153
+ text: botText.response,
154
+ value: mappedValue,
155
+ normalized: normalizeText(botText.response)
156
+ });
157
+
158
+ } catch (error) {
159
+ botResults.push({
160
+ id: bot.id,
161
+ text: '',
162
+ value: '',
163
+ normalized: '',
164
+ error: error.message
165
+ });
166
+ }
167
+ }
168
+
169
+ const result = [];
170
+ const usedIds = new Set();
171
+ let matchedCount = 0;
172
+
173
+ for (let i = 0; i < soalArray.length; i++) {
174
+ const targetSoal = soalArray[i];
175
+ let foundId = null;
176
+
177
+ for (const bot of botResults) {
178
+ if (!usedIds.has(bot.id) && bot.value && bot.value.trim() !== '' &&
179
+ isValueMatch(bot.value, targetSoal)) {
180
+ foundId = bot.id;
181
+ usedIds.add(bot.id);
182
+ matchedCount++;
183
+ break;
184
+ }
185
+ }
186
+
187
+ result.push({
188
+ id: foundId,
189
+ soal: targetSoal,
190
+ matchType: foundId ? 'exact' : 'none'
191
+ });
192
+ }
193
+
194
+ if (matchedCount < soalArray.length) {
195
+ for (let i = 0; i < result.length; i++) {
196
+ if (!result[i].id) {
197
+ const targetSoal = soalArray[i];
198
+ const normalizedSoal = normalizeText(targetSoal);
199
+
200
+ for (const bot of botResults) {
201
+ if (!usedIds.has(bot.id) && bot.normalized && bot.normalized.trim() !== '') {
202
+ if (bot.normalized === normalizedSoal) {
203
+ result[i].id = bot.id;
204
+ result[i].matchType = 'normalized';
205
+ usedIds.add(bot.id);
206
+ matchedCount++;
207
+ break;
208
+ }
209
+ }
210
+ }
211
+ }
212
+ }
213
+ }
214
+
215
+ if (matchedCount >= 2) {
216
+ for (let i = 0; i < result.length; i++) {
217
+ if (!result[i].id) {
218
+ for (const bot of botResults) {
219
+ if (!usedIds.has(bot.id) && bot.value && bot.value.trim() !== '') {
220
+ result[i].id = bot.id;
221
+ result[i].matchType = 'fallback';
222
+ usedIds.add(bot.id);
223
+ break;
224
+ }
225
+ }
226
+ }
227
+ }
228
+ } else if (matchedCount === 1) {
229
+ for (let i = 0; i < result.length; i++) {
230
+ if (!result[i].id) {
231
+ result[i].id = 'invalid';
232
+ result[i].matchType = 'invalid';
233
+ }
234
+ }
235
+ } else {
236
+ for (let i = 0; i < result.length; i++) {
237
+ result[i].id = 'invalid';
238
+ result[i].matchType = 'invalid';
239
+ }
240
+ }
241
+
242
+ for (let i = 0; i < result.length; i++) {
243
+ if (!result[i].id) {
244
+ result[i].id = 'invalid';
245
+ result[i].matchType = 'invalid';
246
+ }
247
+ }
248
+
249
+ return {
250
+ success: true,
251
+ data: {
252
+ soal: soalArray,
253
+ soalLeet: soalArray,
254
+ botResults: botResults,
255
+ result: result.map(r => ({ id: r.id })),
256
+ debug: {
257
+ parsedSoal: soalArray,
258
+ matches: result.map(r => ({ id: r.id, matchType: r.matchType, soal: r.soal })),
259
+ totalMatches: matchedCount
260
+ }
261
+ }
262
+ };
263
+
264
+ } catch (error) {
265
+ return {
266
+ success: false,
267
+ error: error.message,
268
+ data: {
269
+ soal: [],
270
+ botResults: [],
271
+ result: []
272
+ }
273
+ };
274
+ }
275
+ }
276
+
277
+ module.exports = antibot;
endpoints/cloudflare.js ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ async function cloudflare(data, page) {
2
+ return new Promise(async (resolve, reject) => {
3
+ if (!data.domain) return reject(new Error("Missing domain parameter"))
4
+
5
+ const startTime = Date.now()
6
+ let isResolved = false
7
+ let userAgent = null
8
+
9
+ const cl = setTimeout(() => {
10
+ if (!isResolved) {
11
+ isResolved = true
12
+ const elapsedTime = (Date.now() - startTime) / 1000
13
+ resolve({
14
+ cf_clearance: null,
15
+ user_agent: userAgent,
16
+ elapsed_time: elapsedTime,
17
+ })
18
+ }
19
+ }, 20000)
20
+
21
+ try {
22
+ if (data.proxy?.username && data.proxy?.password) {
23
+ await page.authenticate({
24
+ username: data.proxy.username,
25
+ password: data.proxy.password,
26
+ })
27
+ }
28
+
29
+ page.removeAllListeners("request")
30
+ page.removeAllListeners("response")
31
+ await page.setRequestInterception(true)
32
+
33
+ page.on("request", async (req) => {
34
+ try {
35
+ await req.continue()
36
+ } catch (_) {}
37
+ })
38
+
39
+ page.on("response", async (res) => {
40
+ try {
41
+ const url = res.url()
42
+ if (url.includes("/cdn-cgi/challenge-platform/")) {
43
+ const headers = res.headers()
44
+ if (headers["set-cookie"]) {
45
+ const match = headers["set-cookie"].match(/cf_clearance=([^;]+)/)
46
+ if (match) {
47
+ const cf_clearance = match[1]
48
+ const userAgent = (await res.request().headers())["user-agent"]
49
+ const elapsedTime = (Date.now() - startTime) / 1000
50
+
51
+ if (!isResolved) {
52
+ isResolved = true
53
+ clearTimeout(cl)
54
+
55
+ resolve({
56
+ cf_clearance,
57
+ user_agent: userAgent,
58
+ elapsed_time: elapsedTime,
59
+ })
60
+ }
61
+ }
62
+ }
63
+ }
64
+ } catch (_) {}
65
+ })
66
+
67
+ await page.goto(data.domain, { waitUntil: "domcontentloaded" })
68
+ userAgent = await page.evaluate(() => navigator.userAgent)
69
+ } catch (err) {
70
+ if (!isResolved) {
71
+ isResolved = true
72
+ clearTimeout(cl)
73
+ reject(err)
74
+ }
75
+ }
76
+ })
77
+ }
78
+
79
+ module.exports = cloudflare
endpoints/imageProcessor ADDED
@@ -0,0 +1,181 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const fs = require('fs');
2
+ const https = require('https');
3
+
4
+ // API Keys configuration
5
+ const API_KEYS = [
6
+ "fw_3ZNhzPGSUhHBxTL5PuB5Cpkv",
7
+ "fw_3ZchAJSfZBupby3hnESzSkbk"
8
+ ];
9
+
10
+ function getRandomApiKey() {
11
+ return API_KEYS[Math.floor(Math.random() * API_KEYS.length)];
12
+ }
13
+
14
+ async function extractTextFromImage(imagePath) {
15
+ return new Promise(async (resolve, reject) => {
16
+ try {
17
+ // Baca file gambar dan encode ke base64
18
+ const imageBuffer = fs.readFileSync(imagePath);
19
+ const base64Image = imageBuffer.toString('base64');
20
+
21
+ // Dapatkan API key secara random
22
+ const apiKey = getRandomApiKey();
23
+
24
+ // Request payload untuk Fireworks.ai
25
+ const requestData = JSON.stringify({
26
+ model: "accounts/fireworks/models/llama4-maverick-instruct-basic",
27
+ max_tokens: 1024,
28
+ temperature: 0.1, // Temperature rendah untuk hasil yang lebih konsisten
29
+ messages: [
30
+ {
31
+ role: "user",
32
+ content: [
33
+ {
34
+ type: "text",
35
+ text: "Berikan text yang ada di gambar ini saja, tidak ada informasi lain cukup yang ada di gambar saja, jangan ada text lain kalo bukan dari gambar nya. dan ini adalah pembatas iya _ , : ; dan tolong tiap text berbeda beda kalo ada pembatas itu kirim satu kalimat saja"
36
+ },
37
+ {
38
+ type: "image_url",
39
+ image_url: {
40
+ url: `data:image/png;base64,${base64Image}`
41
+ }
42
+ }
43
+ ]
44
+ }
45
+ ]
46
+ });
47
+
48
+ const options = {
49
+ hostname: 'api.fireworks.ai',
50
+ path: '/inference/v1/chat/completions',
51
+ method: 'POST',
52
+ headers: {
53
+ 'Accept': 'application/json',
54
+ 'Content-Type': 'application/json',
55
+ 'Authorization': `Bearer ${apiKey}`,
56
+ 'Content-Length': Buffer.byteLength(requestData)
57
+ }
58
+ };
59
+
60
+ const req = https.request(options, (res) => {
61
+ let data = '';
62
+
63
+ res.on('data', (chunk) => {
64
+ data += chunk;
65
+ });
66
+
67
+ res.on('end', () => {
68
+ try {
69
+ const response = JSON.parse(data);
70
+
71
+ if (response.choices && response.choices[0] && response.choices[0].message) {
72
+ const text = response.choices[0].message.content;
73
+ resolve({ status: true, response: text });
74
+ } else {
75
+ console.error('API Response structure unexpected:', response);
76
+ resolve({ status: false, response: 'Struktur respons tidak sesuai' });
77
+ }
78
+ } catch (error) {
79
+ console.error('Error parsing response:', error);
80
+ reject(error);
81
+ }
82
+ });
83
+ });
84
+
85
+ req.on('error', (error) => {
86
+ console.error('Request error:', error);
87
+ reject(error);
88
+ });
89
+
90
+ req.write(requestData);
91
+ req.end();
92
+
93
+ } catch (error) {
94
+ reject(error);
95
+ }
96
+ });
97
+ }
98
+
99
+ // Fungsi untuk upload gambar ke hosting (opsional)
100
+ async function uploadImageToHosting(buffer) {
101
+ try {
102
+ // Karena kita menggunakan base64 langsung, fungsi ini mungkin tidak diperlukan
103
+ // Tapi tetap disediakan untuk kompatibilitas
104
+ return null;
105
+ } catch (error) {
106
+ console.error("Gagal mengunggah gambar:", error);
107
+ return null;
108
+ }
109
+ }
110
+
111
+ // Fungsi untuk analisis gambar yang lebih detail
112
+ async function analyzeImage(imagePath) {
113
+ try {
114
+ const imageBuffer = fs.readFileSync(imagePath);
115
+ const base64Image = imageBuffer.toString('base64');
116
+ const apiKey = getRandomApiKey();
117
+
118
+ const payload = {
119
+ model: "accounts/fireworks/models/llama4-maverick-instruct-basic",
120
+ max_tokens: 1024,
121
+ temperature: 0.6,
122
+ messages: [
123
+ {
124
+ role: "user",
125
+ content: [
126
+ { type: "text", text: "Berikan text yang ada di gambar ini saja, tidak ada informasi lain cukup yang ada di gambar saja, jangan ada text lain kalo bukan dari gambar nya. dan ini adalah pembatas iya _ , : ; dan tolong tiap text berbeda beda kalo ada pembatas itu kirim satu kalimat saja" },
127
+ { type: "image_url", image_url: { url: `data:image/jpeg;base64,${base64Image}` } }
128
+ ]
129
+ }
130
+ ]
131
+ };
132
+
133
+ const response = await fetch("https://api.fireworks.ai/inference/v1/chat/completions", {
134
+ method: "POST",
135
+ headers: {
136
+ "Accept": "application/json",
137
+ "Content-Type": "application/json",
138
+ "Authorization": `Bearer ${apiKey}`
139
+ },
140
+ body: JSON.stringify(payload)
141
+ });
142
+
143
+ if (!response.ok) {
144
+ const errorText = await response.text();
145
+ console.error("API Error response:", errorText);
146
+ throw new Error(`HTTP error! status: ${response.status}`);
147
+ }
148
+
149
+ const data = await response.json();
150
+ return data.choices?.[0]?.message?.content || "Tidak bisa menganalisis gambar ini";
151
+ } catch (error) {
152
+ console.error("Error analyzing image:", error);
153
+ return "Error saat menganalisis gambar";
154
+ }
155
+ }
156
+
157
+ // Contoh penggunaan
158
+ async function main() {
159
+ try {
160
+ const result = await extractTextFromImage('main_instruction.png');
161
+ if (result.status) {
162
+ console.log('Teks yang diekstrak:', result.response);
163
+ } else {
164
+ console.log('Gagal:', result.response);
165
+ }
166
+ } catch (error) {
167
+ console.error('Error:', error);
168
+ }
169
+ }
170
+
171
+ // Jalankan jika file dijalankan langsung
172
+ if (require.main === module) {
173
+ main();
174
+ }
175
+
176
+ module.exports = {
177
+ extractTextFromImage,
178
+ uploadImageToHosting,
179
+ analyzeImage,
180
+ getRandomApiKey
181
+ };
endpoints/turnstile.js ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ async function turnstile({ domain, proxy, siteKey }, page) {
2
+ if (!domain) throw new Error("Missing domain parameter");
3
+ if (!siteKey) throw new Error("Missing siteKey parameter");
4
+
5
+ const timeout = global.timeOut || 60000;
6
+ let isResolved = false;
7
+
8
+ const cl = setTimeout(async () => {
9
+ if (!isResolved) {
10
+ throw new Error("Timeout Error");
11
+ }
12
+ }, timeout);
13
+
14
+ try {
15
+ if (proxy?.username && proxy?.password) {
16
+ await page.authenticate({
17
+ username: proxy.username,
18
+ password: proxy.password,
19
+ });
20
+ }
21
+
22
+ const htmlContent = `
23
+ <!DOCTYPE html>
24
+ <html lang="en">
25
+ <body>
26
+ <div class="turnstile"></div>
27
+ <script src="https://challenges.cloudflare.com/turnstile/v0/api.js?onload=onloadTurnstileCallback" defer></script>
28
+ <script>
29
+ window.onloadTurnstileCallback = function () {
30
+ turnstile.render('.turnstile', {
31
+ sitekey: '${siteKey}',
32
+ callback: function (token) {
33
+ var c = document.createElement('input');
34
+ c.type = 'hidden';
35
+ c.name = 'cf-response';
36
+ c.value = token;
37
+ document.body.appendChild(c);
38
+ },
39
+ });
40
+ };
41
+ </script>
42
+ </body>
43
+ </html>
44
+ `;
45
+
46
+ await page.setRequestInterception(true);
47
+ page.removeAllListeners("request");
48
+ page.on("request", async (request) => {
49
+ if ([domain, domain + "/"].includes(request.url()) && request.resourceType() === "document") {
50
+ await request.respond({
51
+ status: 200,
52
+ contentType: "text/html",
53
+ body: htmlContent,
54
+ });
55
+ } else {
56
+ await request.continue();
57
+ }
58
+ });
59
+
60
+ await page.goto(domain, { waitUntil: "domcontentloaded" });
61
+
62
+ await page.waitForSelector('[name="cf-response"]', { timeout });
63
+
64
+ const token = await page.evaluate(() => {
65
+ try {
66
+ return document.querySelector('[name="cf-response"]').value;
67
+ } catch {
68
+ return null;
69
+ }
70
+ });
71
+
72
+ isResolved = true;
73
+ clearTimeout(cl);
74
+
75
+ if (!token || token.length < 10) throw new Error("Failed to get token");
76
+ return token;
77
+
78
+ } catch (e) {
79
+ clearTimeout(cl);
80
+ throw e;
81
+ }
82
+ }
83
+
84
+ module.exports = turnstile;
index.js ADDED
@@ -0,0 +1,179 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const express = require('express');
2
+ const { connect } = require("puppeteer-real-browser");
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+
6
+ const app = express();
7
+ const port = process.env.PORT || 7860;
8
+ const authToken = process.env.authToken || null;
9
+ const domain = process.env.DOMAIN || `https://fourstore-antibot3.hf.space`;
10
+
11
+ global.browserLimit = Number(process.env.browserLimit) || 20;
12
+ global.timeOut = Number(process.env.timeOut) || 60000;
13
+
14
+ const CACHE_DIR = path.join(__dirname, "cache");
15
+ const CACHE_FILE = path.join(CACHE_DIR, "cache.json");
16
+ const CACHE_TTL = 5 * 60 * 1000;
17
+
18
+ function loadCache() {
19
+ if (!fs.existsSync(CACHE_FILE)) return {};
20
+ try {
21
+ return JSON.parse(fs.readFileSync(CACHE_FILE, 'utf-8'));
22
+ } catch {
23
+ return {};
24
+ }
25
+ }
26
+
27
+ function saveCache(cache) {
28
+ if (!fs.existsSync(CACHE_DIR)) {
29
+ fs.mkdirSync(CACHE_DIR, { recursive: true });
30
+ }
31
+ fs.writeFileSync(CACHE_FILE, JSON.stringify(cache, null, 2), 'utf-8');
32
+ }
33
+
34
+ function readCache(key) {
35
+ const cache = loadCache();
36
+ const entry = cache[key];
37
+ if (entry && Date.now() - entry.timestamp < CACHE_TTL) {
38
+ return entry.value;
39
+ }
40
+ return null;
41
+ }
42
+
43
+ function writeCache(key, value) {
44
+ const cache = loadCache();
45
+ cache[key] = { timestamp: Date.now(), value };
46
+ saveCache(cache);
47
+ }
48
+
49
+ app.use(express.json({ limit: "50mb" }));
50
+ app.use(express.urlencoded({ extended: true, limit: "50mb" }));
51
+
52
+ app.get("/", (req, res) => {
53
+ res.json({
54
+ message: "Server is running!",
55
+ domain: domain,
56
+ endpoints: {
57
+ cloudflare: `${domain}/cloudflare`,
58
+ antibot: `${domain}/antibot`
59
+ },
60
+ status: {
61
+ browserLimit: global.browserLimit,
62
+ timeOut: global.timeOut,
63
+ authRequired: authToken !== null
64
+ }
65
+ });
66
+ });
67
+
68
+ if (process.env.NODE_ENV !== 'development') {
69
+ let server = app.listen(port, () => {
70
+ console.log(`Server running on port ${port}`);
71
+ console.log(`Domain: ${domain}`);
72
+ console.log(`Auth required: ${authToken !== null}`);
73
+ });
74
+ try {
75
+ server.timeout = global.timeOut;
76
+ } catch {}
77
+ }
78
+
79
+ async function createBrowser(proxyServer = null) {
80
+ const connectOptions = {
81
+ headless: false,
82
+ turnstile: true,
83
+ connectOption: { defaultViewport: null },
84
+ disableXvfb: false,
85
+ };
86
+ if (proxyServer) connectOptions.args = [`--proxy-server=${proxyServer}`];
87
+
88
+ const { browser } = await connect(connectOptions);
89
+ const [page] = await browser.pages();
90
+
91
+ await page.goto('about:blank');
92
+ await page.setRequestInterception(true);
93
+ page.on('request', (req) => {
94
+ const type = req.resourceType();
95
+ if (["image", "stylesheet", "font", "media"].includes(type)) req.abort();
96
+ else req.continue();
97
+ });
98
+
99
+ return { browser, page };
100
+ }
101
+
102
+ const turnstile = require('./endpoints/turnstile');
103
+ const cloudflare = require('./endpoints/cloudflare');
104
+ const antibot = require('./endpoints/antibot');
105
+
106
+ app.post('/cloudflare', async (req, res) => {
107
+ const data = req.body;
108
+ if (!data || typeof data.mode !== 'string')
109
+ return res.status(400).json({ message: 'Bad Request: missing or invalid mode' });
110
+
111
+ if (global.browserLimit <= 0)
112
+ return res.status(429).json({ message: 'Too Many Requests' });
113
+
114
+ let cacheKey, cached;
115
+ if (data.mode === "iuam") {
116
+ cacheKey = JSON.stringify(data);
117
+ cached = readCache(cacheKey);
118
+ if (cached) return res.status(200).json({ ...cached, cached: true });
119
+ }
120
+
121
+ global.browserLimit--;
122
+ let result, browser;
123
+
124
+ try {
125
+ const proxyServer = data.proxy ? `${data.proxy.hostname}:${data.proxy.port}` : null;
126
+ const ctx = await createBrowser(proxyServer);
127
+ browser = ctx.browser;
128
+ const page = ctx.page;
129
+
130
+ await page.goto('about:blank');
131
+
132
+ switch (data.mode) {
133
+ case "turnstile":
134
+ result = await turnstile(data, page).then(t => ({ token: t }));
135
+ break;
136
+
137
+ case "iuam":
138
+ result = await cloudflare(data, page).then(r => ({ ...r }));
139
+ writeCache(cacheKey, result);
140
+ break;
141
+
142
+ case "antibot":
143
+ result = await antibot(data);
144
+ break;
145
+
146
+ default:
147
+ result = { code: 400, message: 'Invalid mode' };
148
+ }
149
+ } catch (err) {
150
+ result = { code: 500, message: err.message };
151
+ } finally {
152
+ if (browser) try { await browser.close(); } catch {}
153
+ global.browserLimit++;
154
+ }
155
+
156
+ res.status(result.code ?? 200).json(result);
157
+ });
158
+
159
+ app.post("/antibot", async (req, res) => {
160
+ const data = req.body;
161
+
162
+ if (!data || !data.main || !Array.isArray(data.bots))
163
+ return res.status(400).json({ message: "Invalid body" });
164
+
165
+ try {
166
+ const result = await antibot(data);
167
+ res.json(result);
168
+ } catch (err) {
169
+ res.status(500).json({ message: err.message });
170
+ }
171
+ });
172
+
173
+ app.use((req, res) => {
174
+ res.status(404).json({ message: 'Not Found' });
175
+ });
176
+
177
+ if (process.env.NODE_ENV === 'development') {
178
+ module.exports = app;
179
+ }
package.json ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "cf-bypass",
3
+ "version": "1.0",
4
+ "description": "get the cf_clearance cookie from any website",
5
+ "scripts": {
6
+ "start": "node index.js",
7
+ "dev": "nodemon index.js"
8
+ },
9
+ "dependencies": {
10
+ "express": "^5.1.0",
11
+ "canvas": "^2.11.2",
12
+ "sharp": "^0.32.0",
13
+ "puppeteer-real-browser": "^1.4.0",
14
+ "axios": "^1.9.0",
15
+ "child_process": "*",
16
+ "tesseract.js": "^5.0.3",
17
+ "jimp": "^0.22.10"
18
+ },
19
+ "devDependencies": {
20
+ "nodemon": "^3.1.10"
21
+ }
22
+ }