Skip to content

Commit f1883e1

Browse files
committed
ocr base64 from canvas
1 parent 28af43f commit f1883e1

8 files changed

Lines changed: 112 additions & 38 deletions

File tree

funcaptcha.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99

1010
function is_image_frame() {
11-
return get_task() !== null && get_image() !== null;
11+
return get_task() !== null && get_image_data() !== null;
1212
}
1313

1414

@@ -46,7 +46,7 @@
4646
}
4747

4848

49-
function get_image() {
49+
function get_image_data() {
5050
const $image = document.querySelector('img#game_challengeItem_image');
5151
// return $image?.src?.replace('data:image/jpeg;base64,', '');
5252
return $image?.src?.split(';base64,')[1];
@@ -83,7 +83,7 @@
8383
return;
8484
}
8585

86-
const image_data = get_image();
86+
const image_data = get_image_data();
8787
if (!image_data) {
8888
// console.log('no image data');
8989
checking = false;
@@ -132,8 +132,7 @@
132132

133133
// Detect images
134134
const {job_id, data} = await NopeCHA.post({
135-
captcha_type: 'funcaptcha',
136-
// captcha_type: 'test',
135+
captcha_type: IS_DEVELOPMENT ? 'funcaptcha_dev' : 'funcaptcha',
137136
task: task,
138137
image_data: [image_data],
139138
key: settings.key,

funcaptcha_demo.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
'outlook': 'https://iframe.arkoselabs.com/B7D8911C-5CC8-A9A3-35B0-554ACEE604DA/index.html?mkt=en', // Pick the penguin
2121
'outlook auth': 'https://iframe-auth.arkoselabs.com/B7D8911C-5CC8-A9A3-35B0-554ACEE604DA/index.html?mkt=en', // Pick one square that shows two identical objects.
2222
}
23-
let nframes = 14;
23+
let nframes = 21;
2424

2525
reset();
2626
open_frame_token('ea signup', 0, nframes);

funcaptcha_scrape.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
(async () => {
2-
const RELOAD_ON_SOLVED = false; // If true, restart captcha to scrape more data
2+
const RELOAD_ON_SOLVED = IS_DEVELOPMENT; // If true, restart captcha to scrape more data
33
const SUBMISSION_STRATEGY = 'lazy'; // One of: eager, lazy, or none
44
window.nopecha = []; // Lazy cache
55
const listeners = {}; // Click listeners
@@ -39,7 +39,8 @@
3939
// return await reload_if_roblox();
4040
// }
4141

42-
const data = {task, image, index};
42+
const url = (await BG.exec('info_tab'))?.url;
43+
const data = {task, image, index, url};
4344

4445
if (SUBMISSION_STRATEGY === 'lazy') {
4546
// Lazy submission
@@ -65,7 +66,7 @@
6566
if (data && data.nopecha === true) {
6667
// console.log('message', key, data);
6768
if (data.action === 'append') {
68-
// console.log('append', data, window.location.href);
69+
// console.log('append', data);
6970
window.nopecha.push(data.data);
7071
}
7172
else if (data.action === 'clear') {

hcaptcha.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@
193193

194194
// Detect images
195195
const {job_id, data} = await NopeCHA.post({
196-
captcha_type: 'hcaptcha',
196+
captcha_type: IS_DEVELOPMENT ? 'hcaptcha_dev' : 'hcaptcha',
197197
task: task,
198198
image_urls: urls,
199199
key: settings.key,

manifest.base.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"default_icon": "icon/16.png",
1111
"default_popup": "popup.html"
1212
},
13-
"version": "0.2.3",
13+
"version": "0.2.4",
1414
"description": "Automatically solve reCAPTCHA, hCaptcha, FunCAPTCHA, and text-based CAPTCHA using AI.",
1515
"permissions": [
1616
"storage",
@@ -21,7 +21,8 @@
2121
"matches": ["<all_urls>"],
2222
"js": ["utils.js", "content.js"],
2323
"all_frames": true,
24-
"run_at": "document_start"
24+
"run_at": "document_start",
25+
"match_about_blank": true
2526
},
2627

2728
{

ocr.js

Lines changed: 90 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,27 +7,78 @@
77
}
88

99

10-
function get_image_url($e) {
11-
// Div with css background (e.g. hcaptcha)
12-
const matches = $e?.style['background']?.trim()?.match(/(?!^)".*?"/g);
13-
if (matches?.length > 0) {
14-
return matches[0].replaceAll('"', '');
10+
// function get_image_url($e) {
11+
// // Div with css background (e.g. hcaptcha)
12+
// const matches = $e?.style['background']?.trim()?.match(/(?!^)".*?"/g);
13+
// if (matches?.length > 0) {
14+
// return matches[0].replaceAll('"', '');
15+
// }
16+
17+
// // Img with src or data-src
18+
// let url = $e.src || $e.dataset.src;
19+
// if (url) {
20+
// if (url.startsWith('/')) {
21+
// url = `${window.location.origin}${url}`;
22+
// }
23+
// return url;
24+
// }
25+
26+
// return null;
27+
// }
28+
29+
30+
async function get_image_data(selector) {
31+
function get_image_from_style($e) {
32+
return new Promise(resolve => {
33+
let bg = $e.style.backgroundImage;
34+
if (bg) {
35+
const matches = bg.trim().match(/(?!^)".*?"/g);
36+
if (!matches || matches.length === 0) {
37+
bg = null;
38+
}
39+
bg = matches[0].replaceAll('"', '');
40+
}
41+
const $img = new Image();
42+
$img.onload = () => resolve($img);
43+
$img.src = bg;
44+
});
1545
}
1646

17-
// Img with src or data-src
18-
let url = $e.src || $e.dataset.src;
19-
if (url) {
20-
if (url.startsWith('/')) {
21-
url = `${window.location.origin}${url}`;
47+
async function get_canvas(selector) {
48+
const $e = document.querySelector(selector);
49+
50+
// Canvas
51+
if ($e instanceof HTMLCanvasElement) {
52+
return $e;
53+
}
54+
55+
let $img;
56+
if ($e instanceof HTMLImageElement) {
57+
$img = $e;
58+
}
59+
else {
60+
$img = await get_image_from_style($e);
2261
}
23-
return url;
62+
63+
if (!$img) {
64+
throw Error(`failed to get image element for ${selector}`);
65+
}
66+
67+
const $canvas = document.createElement('canvas');
68+
$canvas.width = $img.width;
69+
$canvas.height = $img.height;
70+
const ctx = $canvas.getContext('2d');
71+
ctx.drawImage($img, 0, 0);
72+
73+
return $canvas;
2474
}
2575

26-
return null;
76+
const $canvas = await get_canvas(selector);
77+
return $canvas.toDataURL('image/jpeg').split(';base64,')[1];
2778
}
2879

2980

30-
let last_url_hash = null;
81+
let last_image_data = null;
3182
function on_task_ready(settings, i=100) {
3283
return new Promise(resolve => {
3384
let checking = false;
@@ -37,37 +88,51 @@
3788
}
3889
checking = true;
3990

40-
const $image = document.querySelector(settings.ocr_image_selector);
41-
const image_url = get_image_url($image);
42-
if (!image_url || image_url === '') {
43-
console.log('no image url', $image);
91+
// const $image = document.querySelector(settings.ocr_image_selector);
92+
// const image_url = get_image_url($image);
93+
// if (!image_url || image_url === '') {
94+
// console.log('no image url', $image);
95+
// checking = false;
96+
// return;
97+
// }
98+
99+
// const url_hash = JSON.stringify(image_url);
100+
// if (last_image_data === url_hash) {
101+
// console.log('task unchanged');
102+
// checking = false;
103+
// return;
104+
// }
105+
// last_image_data = url_hash;
106+
107+
const image_data = await get_image_data(settings.ocr_image_selector);
108+
if (!image_data) {
109+
// console.log('no image data');
44110
checking = false;
45111
return;
46112
}
47113

48-
const url_hash = JSON.stringify(image_url);
49-
if (last_url_hash === url_hash) {
50-
console.log('task unchanged');
114+
if (last_image_data === image_data) {
115+
// console.log('image_data unchanged');
51116
checking = false;
52117
return;
53118
}
54-
last_url_hash = url_hash;
119+
last_image_data = image_data;
55120

56121
clearInterval(check_interval);
57122
checking = false;
58-
return resolve({image_url});
123+
return resolve({image_data});
59124
}, i);
60125
});
61126
}
62127

63128

64129
async function on_present(settings) {
65-
const {image_url} = await on_task_ready(settings);
130+
const {image_data} = await on_task_ready(settings);
66131

67132
// Detect images
68133
const {job_id, data} = await NopeCHA.post({
69-
captcha_type: 'ocr',
70-
image_urls: [image_url],
134+
captcha_type: IS_DEVELOPMENT ? 'ocr_dev' : 'ocr',
135+
image_data: [image_data],
71136
key: settings.key,
72137
});
73138
if (!data) {

recaptcha.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@
275275

276276
// Solve task
277277
const {job_id, data} = await NopeCHA.post({
278-
captcha_type: 'recaptcha',
278+
captcha_type: IS_DEVELOPMENT ? 'recaptcha_dev' : 'recaptcha',
279279
task: task,
280280
image_urls: image_urls,
281281
grid: grid,

utils.mjs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
'use strict';
22

33

4+
/**
5+
* Set to true for the following behavior:
6+
* - Request server to recognize using bleeding-edge models
7+
* - Reload FunCAPTCHA on verification
8+
*/
9+
export const IS_DEVELOPMENT = false;
10+
11+
412
/**
513
* Trying to be an Enum but javascript doesn't have enums
614
*/

0 commit comments

Comments
 (0)