playwright-stealth-ultimate 5.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- playwright_stealth/__init__.py +46 -0
- playwright_stealth/config/capabilities/chromium/136.json +19 -0
- playwright_stealth/config/capabilities/chromium/137.json +20 -0
- playwright_stealth/config/capabilities/chromium/138.json +21 -0
- playwright_stealth/config/capabilities/chromium/139.json +22 -0
- playwright_stealth/config/policies/balanced.yaml +19 -0
- playwright_stealth/config/policies/performance.yaml +22 -0
- playwright_stealth/config/policies/strict.yaml +19 -0
- playwright_stealth/config/profiles/macos_ventura_chrome_139.yaml +38 -0
- playwright_stealth/config/profiles/windows_10_chrome_138.yaml +38 -0
- playwright_stealth/config/profiles/windows_11_chrome_139.yaml +38 -0
- playwright_stealth/js/audio.js +348 -0
- playwright_stealth/js/canvas.js +333 -0
- playwright_stealth/js/chrome.app.js +226 -0
- playwright_stealth/js/chrome.csi.js +194 -0
- playwright_stealth/js/chrome.hairline.js +138 -0
- playwright_stealth/js/chrome.load.times.js +330 -0
- playwright_stealth/js/chrome.runtime.js +698 -0
- playwright_stealth/js/concurrency.js +272 -0
- playwright_stealth/js/errors.js +321 -0
- playwright_stealth/js/evasions.proxies.js +278 -0
- playwright_stealth/js/fonts.js +497 -0
- playwright_stealth/js/generate.magic.arrays.js +317 -0
- playwright_stealth/js/iframe.contentWindow.js +318 -0
- playwright_stealth/js/intl.js +455 -0
- playwright_stealth/js/media.codecs.js +283 -0
- playwright_stealth/js/navigator.deviceMemory.js +290 -0
- playwright_stealth/js/navigator.hardware.js +362 -0
- playwright_stealth/js/navigator.hardwareConcurrency.js +133 -0
- playwright_stealth/js/navigator.languages.js +174 -0
- playwright_stealth/js/navigator.maxTouchPoints.js +387 -0
- playwright_stealth/js/navigator.permissions.js +240 -0
- playwright_stealth/js/navigator.platform.js +179 -0
- playwright_stealth/js/navigator.plugins.js +245 -0
- playwright_stealth/js/navigator.userAgent.js +218 -0
- playwright_stealth/js/navigator.vendor.js +158 -0
- playwright_stealth/js/navigator.webdriver.js +332 -0
- playwright_stealth/js/screen.js +386 -0
- playwright_stealth/js/utils.js +567 -0
- playwright_stealth/js/webgl.anisotropy.js +230 -0
- playwright_stealth/js/webgl.js +549 -0
- playwright_stealth/js/webgl.vendor.js +243 -0
- playwright_stealth/js/webrtc.js +514 -0
- playwright_stealth/js/window.outerdimensions.js +173 -0
- playwright_stealth/js/window.properties.js +242 -0
- playwright_stealth/version.py +16 -0
- playwright_stealth_ultimate-5.0.0.dist-info/METADATA +425 -0
- playwright_stealth_ultimate-5.0.0.dist-info/RECORD +52 -0
- playwright_stealth_ultimate-5.0.0.dist-info/WHEEL +5 -0
- playwright_stealth_ultimate-5.0.0.dist-info/entry_points.txt +2 -0
- playwright_stealth_ultimate-5.0.0.dist-info/licenses/LICENSE +21 -0
- playwright_stealth_ultimate-5.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# playwright_stealth/__init__.py
|
|
2
|
+
"""Playwright Stealth — Advanced Anti-Bot Evasion Suite."""
|
|
3
|
+
|
|
4
|
+
from .version import __version__, __version_info__, get_version, get_version_info
|
|
5
|
+
|
|
6
|
+
from .core import (
|
|
7
|
+
HardwareTier,
|
|
8
|
+
OSType,
|
|
9
|
+
BrowserVendor,
|
|
10
|
+
HardwareProfile,
|
|
11
|
+
BrowserProfile,
|
|
12
|
+
FingerprintProfile,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
from .models import (
|
|
16
|
+
InjectionPlan,
|
|
17
|
+
SnapshotNode,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
from .js import ScriptLoader, get_loader
|
|
21
|
+
|
|
22
|
+
from .adapters.playwright import (
|
|
23
|
+
stealth_sync,
|
|
24
|
+
stealth_async,
|
|
25
|
+
dump_configuration,
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
__all__ = [
|
|
29
|
+
"__version__",
|
|
30
|
+
"__version_info__",
|
|
31
|
+
"get_version",
|
|
32
|
+
"get_version_info",
|
|
33
|
+
"HardwareTier",
|
|
34
|
+
"OSType",
|
|
35
|
+
"BrowserVendor",
|
|
36
|
+
"HardwareProfile",
|
|
37
|
+
"BrowserProfile",
|
|
38
|
+
"FingerprintProfile",
|
|
39
|
+
"InjectionPlan",
|
|
40
|
+
"SnapshotNode",
|
|
41
|
+
"ScriptLoader",
|
|
42
|
+
"get_loader",
|
|
43
|
+
"stealth_sync",
|
|
44
|
+
"stealth_async",
|
|
45
|
+
"dump_configuration",
|
|
46
|
+
]
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "136.0.0.0",
|
|
3
|
+
"features": {
|
|
4
|
+
"webgpu": {"supported": false},
|
|
5
|
+
"fedcm": {"supported": false},
|
|
6
|
+
"storage_buckets": {"supported": false},
|
|
7
|
+
"private_network_access": {"supported": true},
|
|
8
|
+
"navigator_uadata": {"supported": true},
|
|
9
|
+
"pdf_viewer": {"supported": true},
|
|
10
|
+
"webgl2": {"supported": true},
|
|
11
|
+
"webgl_extensions": {"supported": true}
|
|
12
|
+
},
|
|
13
|
+
"apis": {
|
|
14
|
+
"storage": {"status": "stable"},
|
|
15
|
+
"permissions": {"status": "stable"}
|
|
16
|
+
},
|
|
17
|
+
"deprecations": [],
|
|
18
|
+
"experimental": []
|
|
19
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "137.0.0.0",
|
|
3
|
+
"features": {
|
|
4
|
+
"webgpu": false,
|
|
5
|
+
"fedcm": false,
|
|
6
|
+
"storage_buckets": true,
|
|
7
|
+
"private_network_access": true,
|
|
8
|
+
"navigator_uadata": true,
|
|
9
|
+
"pdf_viewer": true,
|
|
10
|
+
"webgl2": true,
|
|
11
|
+
"webgl_extensions": true
|
|
12
|
+
},
|
|
13
|
+
"apis": {
|
|
14
|
+
"storage": "stable",
|
|
15
|
+
"permissions": "stable",
|
|
16
|
+
"storage_buckets": "experimental"
|
|
17
|
+
},
|
|
18
|
+
"deprecations": [],
|
|
19
|
+
"experimental": ["storage_buckets"]
|
|
20
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "138.0.0.0",
|
|
3
|
+
"features": {
|
|
4
|
+
"webgpu": false,
|
|
5
|
+
"fedcm": true,
|
|
6
|
+
"storage_buckets": true,
|
|
7
|
+
"private_network_access": true,
|
|
8
|
+
"navigator_uadata": true,
|
|
9
|
+
"pdf_viewer": true,
|
|
10
|
+
"webgl2": true,
|
|
11
|
+
"webgl_extensions": true
|
|
12
|
+
},
|
|
13
|
+
"apis": {
|
|
14
|
+
"storage": "stable",
|
|
15
|
+
"permissions": "stable",
|
|
16
|
+
"fedcm": "experimental",
|
|
17
|
+
"storage_buckets": "experimental"
|
|
18
|
+
},
|
|
19
|
+
"deprecations": [],
|
|
20
|
+
"experimental": ["fedcm", "storage_buckets"]
|
|
21
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "139.0.0.0",
|
|
3
|
+
"features": {
|
|
4
|
+
"webgpu": {"supported": true, "experimental": true},
|
|
5
|
+
"fedcm": {"supported": true, "experimental": true},
|
|
6
|
+
"storage_buckets": {"supported": true, "experimental": true},
|
|
7
|
+
"private_network_access": {"supported": true},
|
|
8
|
+
"navigator_uadata": {"supported": true},
|
|
9
|
+
"pdf_viewer": {"supported": true},
|
|
10
|
+
"webgl2": {"supported": true},
|
|
11
|
+
"webgl_extensions": {"supported": true}
|
|
12
|
+
},
|
|
13
|
+
"apis": {
|
|
14
|
+
"storage": {"status": "stable"},
|
|
15
|
+
"permissions": {"status": "stable"},
|
|
16
|
+
"webgpu": {"status": "experimental"},
|
|
17
|
+
"fedcm": {"status": "experimental"},
|
|
18
|
+
"storage_buckets": {"status": "experimental"}
|
|
19
|
+
},
|
|
20
|
+
"deprecations": [],
|
|
21
|
+
"experimental": ["webgpu", "fedcm", "storage_buckets"]
|
|
22
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# config/policies/balanced.yaml
|
|
2
|
+
consistency: balanced
|
|
3
|
+
performance: balanced
|
|
4
|
+
fallback: auto
|
|
5
|
+
retry:
|
|
6
|
+
max: 3
|
|
7
|
+
delay: 1.0
|
|
8
|
+
validation:
|
|
9
|
+
hardware: true
|
|
10
|
+
browser: true
|
|
11
|
+
locale: true
|
|
12
|
+
network: false
|
|
13
|
+
display: false
|
|
14
|
+
modules:
|
|
15
|
+
require_all: false
|
|
16
|
+
allow_fallback: true
|
|
17
|
+
injection:
|
|
18
|
+
verify_checksum: true
|
|
19
|
+
optimize: true
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# config/policies/performance.yaml
|
|
2
|
+
consistency: relaxed
|
|
3
|
+
performance: high
|
|
4
|
+
fallback: auto
|
|
5
|
+
retry:
|
|
6
|
+
max: 2
|
|
7
|
+
delay: 0.5
|
|
8
|
+
validation:
|
|
9
|
+
hardware: false
|
|
10
|
+
browser: false
|
|
11
|
+
locale: false
|
|
12
|
+
network: false
|
|
13
|
+
display: false
|
|
14
|
+
modules:
|
|
15
|
+
require_all: false
|
|
16
|
+
allow_fallback: true
|
|
17
|
+
injection:
|
|
18
|
+
verify_checksum: false
|
|
19
|
+
optimize: true
|
|
20
|
+
cache:
|
|
21
|
+
enabled: true
|
|
22
|
+
ttl: 3600
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# config/policies/strict.yaml
|
|
2
|
+
consistency: strict
|
|
3
|
+
performance: balanced
|
|
4
|
+
fallback: none
|
|
5
|
+
retry:
|
|
6
|
+
max: 1
|
|
7
|
+
delay: 0.5
|
|
8
|
+
validation:
|
|
9
|
+
hardware: true
|
|
10
|
+
browser: true
|
|
11
|
+
locale: true
|
|
12
|
+
network: true
|
|
13
|
+
display: true
|
|
14
|
+
modules:
|
|
15
|
+
require_all: true
|
|
16
|
+
allow_fallback: false
|
|
17
|
+
injection:
|
|
18
|
+
verify_checksum: true
|
|
19
|
+
optimize: true
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# config/profiles/macos_ventura_chrome_139.yaml
|
|
2
|
+
id: macos_ventura_chrome_139
|
|
3
|
+
hardware:
|
|
4
|
+
tier: high
|
|
5
|
+
cpu: Apple M2
|
|
6
|
+
cpu_cores: 8
|
|
7
|
+
ram: 16
|
|
8
|
+
gpu: Apple M2 GPU
|
|
9
|
+
gpu_vendor: Apple Inc.
|
|
10
|
+
gpu_renderer: ANGLE (Apple, Apple M2 GPU OpenGL)
|
|
11
|
+
screen: [2560, 1600]
|
|
12
|
+
dpi: 2.0
|
|
13
|
+
browser:
|
|
14
|
+
os: macos
|
|
15
|
+
version: 139.0.0.0
|
|
16
|
+
chrome_version: 139.0.0.0
|
|
17
|
+
platform: MacIntel
|
|
18
|
+
platform_version: 10.15.7
|
|
19
|
+
locale: en-US
|
|
20
|
+
languages: [en-US, en, fr-FR, fr]
|
|
21
|
+
timezone: America/Los_Angeles
|
|
22
|
+
user_agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36
|
|
23
|
+
accept_language: en-US,en;q=0.9,fr-FR;q=0.8,fr;q=0.7
|
|
24
|
+
fonts: [Helvetica, Arial, Times New Roman, Courier New, Verdana, Georgia]
|
|
25
|
+
modules:
|
|
26
|
+
enabled:
|
|
27
|
+
- webdriver
|
|
28
|
+
- chrome_runtime
|
|
29
|
+
- canvas
|
|
30
|
+
- audio
|
|
31
|
+
- intl
|
|
32
|
+
- webgl
|
|
33
|
+
- permissions
|
|
34
|
+
- user_agent_data
|
|
35
|
+
- pdf_viewer
|
|
36
|
+
policies:
|
|
37
|
+
consistency: strict
|
|
38
|
+
performance: balanced
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# config/profiles/windows_10_chrome_138.yaml
|
|
2
|
+
id: windows_10_chrome_138
|
|
3
|
+
hardware:
|
|
4
|
+
tier: medium
|
|
5
|
+
cpu: Intel Core i5-1135G7
|
|
6
|
+
cpu_cores: 4
|
|
7
|
+
ram: 8
|
|
8
|
+
gpu: Intel Iris Xe Graphics
|
|
9
|
+
gpu_vendor: Intel Inc.
|
|
10
|
+
gpu_renderer: ANGLE (Intel, Intel Iris Xe Graphics Direct3D11)
|
|
11
|
+
screen: [1920, 1080]
|
|
12
|
+
dpi: 1.0
|
|
13
|
+
browser:
|
|
14
|
+
os: windows
|
|
15
|
+
version: 138.0.0.0
|
|
16
|
+
chrome_version: 138.0.0.0
|
|
17
|
+
platform: Win32
|
|
18
|
+
platform_version: 10.0.0
|
|
19
|
+
locale: en-US
|
|
20
|
+
languages: [en-US, en, fr-FR, fr]
|
|
21
|
+
timezone: America/New_York
|
|
22
|
+
user_agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36
|
|
23
|
+
accept_language: en-US,en;q=0.9,fr-FR;q=0.8,fr;q=0.7
|
|
24
|
+
fonts: [Arial, Helvetica, Times New Roman, Courier New, Verdana, Georgia]
|
|
25
|
+
modules:
|
|
26
|
+
enabled:
|
|
27
|
+
- webdriver
|
|
28
|
+
- chrome_runtime
|
|
29
|
+
- canvas
|
|
30
|
+
- audio
|
|
31
|
+
- intl
|
|
32
|
+
- webgl
|
|
33
|
+
- permissions
|
|
34
|
+
- user_agent_data
|
|
35
|
+
- pdf_viewer
|
|
36
|
+
policies:
|
|
37
|
+
consistency: strict
|
|
38
|
+
performance: balanced
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# config/profiles/windows_11_chrome_139.yaml
|
|
2
|
+
id: windows_11_chrome_139
|
|
3
|
+
hardware:
|
|
4
|
+
tier: high
|
|
5
|
+
cpu: Intel Core i7-12700H
|
|
6
|
+
cpu_cores: 8
|
|
7
|
+
ram: 16
|
|
8
|
+
gpu: NVIDIA GeForce RTX 3060
|
|
9
|
+
gpu_vendor: NVIDIA Corporation
|
|
10
|
+
gpu_renderer: ANGLE (NVIDIA, NVIDIA GeForce RTX 3060 Direct3D11)
|
|
11
|
+
screen: [2560, 1440]
|
|
12
|
+
dpi: 1.25
|
|
13
|
+
browser:
|
|
14
|
+
os: windows
|
|
15
|
+
version: 139.0.0.0
|
|
16
|
+
chrome_version: 139.0.0.0
|
|
17
|
+
platform: Win32
|
|
18
|
+
platform_version: 10.0.0
|
|
19
|
+
locale: fr-FR
|
|
20
|
+
languages: [fr-FR, fr, en-US, en]
|
|
21
|
+
timezone: Europe/Paris
|
|
22
|
+
user_agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36
|
|
23
|
+
accept_language: fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7
|
|
24
|
+
fonts: [Arial, Helvetica, Times New Roman, Courier New, Verdana, Georgia, Tahoma]
|
|
25
|
+
modules:
|
|
26
|
+
enabled:
|
|
27
|
+
- webdriver
|
|
28
|
+
- chrome_runtime
|
|
29
|
+
- canvas
|
|
30
|
+
- audio
|
|
31
|
+
- intl
|
|
32
|
+
- webgl
|
|
33
|
+
- permissions
|
|
34
|
+
- user_agent_data
|
|
35
|
+
- pdf_viewer
|
|
36
|
+
policies:
|
|
37
|
+
consistency: strict
|
|
38
|
+
performance: balanced
|
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* audio.js
|
|
3
|
+
* Évasion pour l'API AudioContext / fingerprinting audio
|
|
4
|
+
*
|
|
5
|
+
* Ajoute un bruit déterministe aux signaux audio pour masquer
|
|
6
|
+
* les caractéristiques du système et éviter le fingerprinting.
|
|
7
|
+
*
|
|
8
|
+
* Problème ciblé: Les scripts de détection utilisent l'API AudioContext
|
|
9
|
+
* pour générer une empreinte unique du système audio.
|
|
10
|
+
*
|
|
11
|
+
* Compatibilité: Chrome 80+
|
|
12
|
+
*
|
|
13
|
+
* Référence: https://developer.mozilla.org/en-US/docs/Web/API/AudioContext
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
(function() {
|
|
17
|
+
'use strict';
|
|
18
|
+
|
|
19
|
+
// =========================================================================
|
|
20
|
+
// 1. VÉRIFICATION DES DÉPENDANCES
|
|
21
|
+
// =========================================================================
|
|
22
|
+
|
|
23
|
+
// Vérifier que opts existe
|
|
24
|
+
var opts = window.__STEALTH_OPTS__ || {};
|
|
25
|
+
|
|
26
|
+
// Vérifier que AudioContext existe
|
|
27
|
+
if (typeof AudioContext === 'undefined' && typeof OfflineAudioContext === 'undefined') {
|
|
28
|
+
if (typeof window.__STEALTH_DEBUG__ !== 'undefined' && window.__STEALTH_DEBUG__) {
|
|
29
|
+
console.warn('[stealth] AudioContext not available, skipping audio.js');
|
|
30
|
+
}
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// =========================================================================
|
|
35
|
+
// 2. FONCTION DE BRUIT DÉTERMINISTE
|
|
36
|
+
// =========================================================================
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Génère une valeur de bruit déterministe basée sur une graine
|
|
40
|
+
* @param {number} seed - Graine pour le générateur
|
|
41
|
+
* @param {number} index - Index pour variation
|
|
42
|
+
* @returns {number} Valeur de bruit entre -1 et 1
|
|
43
|
+
*/
|
|
44
|
+
function deterministicNoise(seed, index) {
|
|
45
|
+
// Combiner la graine et l'index
|
|
46
|
+
var value = seed + index * 0.01;
|
|
47
|
+
// Utiliser une fonction sinusoïdale pour générer un bruit pseudo-aléatoire
|
|
48
|
+
var noise = Math.sin(value * 10000) * Math.cos(value * 7777);
|
|
49
|
+
// Normaliser entre -1 et 1
|
|
50
|
+
return Math.max(-1, Math.min(1, noise));
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Obtient la graine pour le bruit audio
|
|
55
|
+
* @returns {number} Graine de bruit
|
|
56
|
+
*/
|
|
57
|
+
function getAudioSeed() {
|
|
58
|
+
// Utiliser la seed du profil si disponible
|
|
59
|
+
if (typeof opts.seed !== 'undefined') {
|
|
60
|
+
return opts.seed;
|
|
61
|
+
}
|
|
62
|
+
// Utiliser une valeur basée sur le profil matériel
|
|
63
|
+
if (opts.hardware_profile) {
|
|
64
|
+
var profileHash = 0;
|
|
65
|
+
for (var i = 0; i < opts.hardware_profile.length; i++) {
|
|
66
|
+
profileHash = ((profileHash << 5) - profileHash) + opts.hardware_profile.charCodeAt(i);
|
|
67
|
+
profileHash = profileHash & profileHash;
|
|
68
|
+
}
|
|
69
|
+
return Math.abs(profileHash);
|
|
70
|
+
}
|
|
71
|
+
// Valeur par défaut
|
|
72
|
+
return 42;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// =========================================================================
|
|
76
|
+
// 3. PATCH DE AudioBuffer.prototype.getChannelData
|
|
77
|
+
// =========================================================================
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Patch getChannelData pour ajouter du bruit déterministe
|
|
81
|
+
*/
|
|
82
|
+
function patchGetChannelData() {
|
|
83
|
+
try {
|
|
84
|
+
if (typeof AudioBuffer === 'undefined' || !AudioBuffer.prototype) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
var seed = getAudioSeed();
|
|
89
|
+
var originalGetChannelData = AudioBuffer.prototype.getChannelData;
|
|
90
|
+
|
|
91
|
+
AudioBuffer.prototype.getChannelData = function(channel) {
|
|
92
|
+
// Appeler la méthode originale
|
|
93
|
+
var result = originalGetChannelData.call(this, channel);
|
|
94
|
+
|
|
95
|
+
// Ajouter du bruit déterministe
|
|
96
|
+
var noiseAmount = 0.0001 + (seed % 100) / 1000000;
|
|
97
|
+
var step = Math.max(1, Math.floor(result.length / 100));
|
|
98
|
+
|
|
99
|
+
for (var i = 0; i < result.length; i += step) {
|
|
100
|
+
var noise = deterministicNoise(seed, i) * noiseAmount;
|
|
101
|
+
result[i] = Math.max(-1, Math.min(1, result[i] + noise));
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return result;
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
if (typeof window.__STEALTH_DEBUG__ !== 'undefined' && window.__STEALTH_DEBUG__) {
|
|
108
|
+
console.log('[stealth] AudioBuffer.prototype.getChannelData patched');
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
} catch (e) {
|
|
112
|
+
console.warn('[stealth] patchGetChannelData error:', e);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// =========================================================================
|
|
117
|
+
// 4. PATCH DE AnalyserNode
|
|
118
|
+
// =========================================================================
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Patch AnalyserNode pour masquer les caractéristiques audio
|
|
122
|
+
*/
|
|
123
|
+
function patchAnalyserNode() {
|
|
124
|
+
try {
|
|
125
|
+
if (typeof AnalyserNode === 'undefined' || !AnalyserNode.prototype) {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
var seed = getAudioSeed();
|
|
130
|
+
|
|
131
|
+
// Patch getByteFrequencyData
|
|
132
|
+
var originalGetByteFrequencyData = AnalyserNode.prototype.getByteFrequencyData;
|
|
133
|
+
AnalyserNode.prototype.getByteFrequencyData = function(array) {
|
|
134
|
+
originalGetByteFrequencyData.call(this, array);
|
|
135
|
+
// Ajouter du bruit déterministe
|
|
136
|
+
var noiseAmount = 0.5 + (seed % 50) / 100;
|
|
137
|
+
for (var i = 0; i < array.length; i++) {
|
|
138
|
+
var noise = deterministicNoise(seed + i, i) * noiseAmount;
|
|
139
|
+
array[i] = Math.max(0, Math.min(255, array[i] + noise));
|
|
140
|
+
}
|
|
141
|
+
return array;
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
// Patch getByteTimeDomainData
|
|
145
|
+
var originalGetByteTimeDomainData = AnalyserNode.prototype.getByteTimeDomainData;
|
|
146
|
+
AnalyserNode.prototype.getByteTimeDomainData = function(array) {
|
|
147
|
+
originalGetByteTimeDomainData.call(this, array);
|
|
148
|
+
var noiseAmount = 0.5 + (seed % 50) / 100;
|
|
149
|
+
for (var i = 0; i < array.length; i++) {
|
|
150
|
+
var noise = deterministicNoise(seed + i * 2, i) * noiseAmount;
|
|
151
|
+
array[i] = Math.max(0, Math.min(255, array[i] + noise));
|
|
152
|
+
}
|
|
153
|
+
return array;
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
// Patch getFloatFrequencyData
|
|
157
|
+
if (typeof AnalyserNode.prototype.getFloatFrequencyData === 'function') {
|
|
158
|
+
var originalGetFloatFrequencyData = AnalyserNode.prototype.getFloatFrequencyData;
|
|
159
|
+
AnalyserNode.prototype.getFloatFrequencyData = function(array) {
|
|
160
|
+
originalGetFloatFrequencyData.call(this, array);
|
|
161
|
+
var noiseAmount = 0.5 + (seed % 50) / 100;
|
|
162
|
+
for (var i = 0; i < array.length; i++) {
|
|
163
|
+
var noise = deterministicNoise(seed + i * 3, i) * noiseAmount;
|
|
164
|
+
array[i] = Math.max(-200, Math.min(200, array[i] + noise));
|
|
165
|
+
}
|
|
166
|
+
return array;
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (typeof window.__STEALTH_DEBUG__ !== 'undefined' && window.__STEALTH_DEBUG__) {
|
|
171
|
+
console.log('[stealth] AnalyserNode patched');
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
} catch (e) {
|
|
175
|
+
console.warn('[stealth] patchAnalyserNode error:', e);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// =========================================================================
|
|
180
|
+
// 5. PATCH DE OscillatorNode
|
|
181
|
+
// =========================================================================
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Patch OscillatorNode pour masquer les caractéristiques audio
|
|
185
|
+
*/
|
|
186
|
+
function patchOscillatorNode() {
|
|
187
|
+
try {
|
|
188
|
+
if (typeof OscillatorNode === 'undefined' || !OscillatorNode.prototype) {
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
var seed = getAudioSeed();
|
|
193
|
+
|
|
194
|
+
// Patch start pour ajouter un décalage temporel
|
|
195
|
+
var originalStart = OscillatorNode.prototype.start;
|
|
196
|
+
OscillatorNode.prototype.start = function(when) {
|
|
197
|
+
// Ajouter un micro-décalage déterministe
|
|
198
|
+
var offset = (seed % 100) / 1000000;
|
|
199
|
+
var newWhen = (when || 0) + offset;
|
|
200
|
+
return originalStart.call(this, newWhen);
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
// Patch stop pour ajouter un décalage temporel
|
|
204
|
+
var originalStop = OscillatorNode.prototype.stop;
|
|
205
|
+
OscillatorNode.prototype.stop = function(when) {
|
|
206
|
+
var offset = (seed % 100) / 1000000;
|
|
207
|
+
var newWhen = (when || 0) + offset;
|
|
208
|
+
return originalStop.call(this, newWhen);
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
if (typeof window.__STEALTH_DEBUG__ !== 'undefined' && window.__STEALTH_DEBUG__) {
|
|
212
|
+
console.log('[stealth] OscillatorNode patched');
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
} catch (e) {
|
|
216
|
+
console.warn('[stealth] patchOscillatorNode error:', e);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// =========================================================================
|
|
221
|
+
// 6. PATCH DE AudioContext
|
|
222
|
+
// =========================================================================
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Patch AudioContext pour masquer les caractéristiques audio
|
|
226
|
+
*/
|
|
227
|
+
function patchAudioContext() {
|
|
228
|
+
try {
|
|
229
|
+
if (typeof AudioContext === 'undefined') {
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
var seed = getAudioSeed();
|
|
234
|
+
|
|
235
|
+
// Patch createAnalyser pour ajouter du bruit
|
|
236
|
+
var originalCreateAnalyser = AudioContext.prototype.createAnalyser;
|
|
237
|
+
AudioContext.prototype.createAnalyser = function() {
|
|
238
|
+
var analyser = originalCreateAnalyser.call(this);
|
|
239
|
+
// Ajouter une propriété cachée pour identifier le patch
|
|
240
|
+
analyser.__stealth_patched = true;
|
|
241
|
+
return analyser;
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
// Patch createOscillator pour ajouter du bruit
|
|
245
|
+
var originalCreateOscillator = AudioContext.prototype.createOscillator;
|
|
246
|
+
AudioContext.prototype.createOscillator = function() {
|
|
247
|
+
var oscillator = originalCreateOscillator.call(this);
|
|
248
|
+
oscillator.__stealth_patched = true;
|
|
249
|
+
return oscillator;
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
// Patch createBuffer pour ajouter du bruit
|
|
253
|
+
var originalCreateBuffer = AudioContext.prototype.createBuffer;
|
|
254
|
+
AudioContext.prototype.createBuffer = function(numChannels, length, sampleRate) {
|
|
255
|
+
var buffer = originalCreateBuffer.call(this, numChannels, length, sampleRate);
|
|
256
|
+
// Ajouter du bruit déterministe au buffer
|
|
257
|
+
for (var channel = 0; channel < numChannels; channel++) {
|
|
258
|
+
var data = buffer.getChannelData(channel);
|
|
259
|
+
var noiseAmount = 0.0001 + (seed % 100) / 1000000;
|
|
260
|
+
for (var i = 0; i < data.length; i += 10) {
|
|
261
|
+
var noise = deterministicNoise(seed + channel * 1000 + i, i) * noiseAmount;
|
|
262
|
+
data[i] = Math.max(-1, Math.min(1, data[i] + noise));
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
return buffer;
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
if (typeof window.__STEALTH_DEBUG__ !== 'undefined' && window.__STEALTH_DEBUG__) {
|
|
269
|
+
console.log('[stealth] AudioContext patched');
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
} catch (e) {
|
|
273
|
+
console.warn('[stealth] patchAudioContext error:', e);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// =========================================================================
|
|
278
|
+
// 7. PATCH DE OfflineAudioContext
|
|
279
|
+
// =========================================================================
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Patch OfflineAudioContext pour masquer les caractéristiques audio
|
|
283
|
+
*/
|
|
284
|
+
function patchOfflineAudioContext() {
|
|
285
|
+
try {
|
|
286
|
+
if (typeof OfflineAudioContext === 'undefined') {
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
var seed = getAudioSeed();
|
|
291
|
+
|
|
292
|
+
// Patch startRendering pour ajouter du bruit
|
|
293
|
+
var originalStartRendering = OfflineAudioContext.prototype.startRendering;
|
|
294
|
+
OfflineAudioContext.prototype.startRendering = function() {
|
|
295
|
+
var result = originalStartRendering.call(this);
|
|
296
|
+
// Ajouter du bruit déterministe au résultat
|
|
297
|
+
if (result && typeof result.then === 'function') {
|
|
298
|
+
return result.then(function(audioBuffer) {
|
|
299
|
+
if (audioBuffer && audioBuffer.getChannelData) {
|
|
300
|
+
var noiseAmount = 0.0001 + (seed % 100) / 1000000;
|
|
301
|
+
for (var channel = 0; channel < audioBuffer.numberOfChannels; channel++) {
|
|
302
|
+
var data = audioBuffer.getChannelData(channel);
|
|
303
|
+
for (var i = 0; i < data.length; i += 10) {
|
|
304
|
+
var noise = deterministicNoise(seed + channel * 1000 + i, i) * noiseAmount;
|
|
305
|
+
data[i] = Math.max(-1, Math.min(1, data[i] + noise));
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
return audioBuffer;
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
return result;
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
if (typeof window.__STEALTH_DEBUG__ !== 'undefined' && window.__STEALTH_DEBUG__) {
|
|
316
|
+
console.log('[stealth] OfflineAudioContext patched');
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
} catch (e) {
|
|
320
|
+
console.warn('[stealth] patchOfflineAudioContext error:', e);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// =========================================================================
|
|
325
|
+
// 8. APPLICATION DES PATCHS
|
|
326
|
+
// =========================================================================
|
|
327
|
+
|
|
328
|
+
// Appliquer tous les patches
|
|
329
|
+
patchGetChannelData();
|
|
330
|
+
patchAnalyserNode();
|
|
331
|
+
patchOscillatorNode();
|
|
332
|
+
patchAudioContext();
|
|
333
|
+
patchOfflineAudioContext();
|
|
334
|
+
|
|
335
|
+
// =========================================================================
|
|
336
|
+
// 9. LOG DE DÉBOGAGE
|
|
337
|
+
// =========================================================================
|
|
338
|
+
|
|
339
|
+
if (typeof window.__STEALTH_DEBUG__ !== 'undefined' && window.__STEALTH_DEBUG__) {
|
|
340
|
+
console.log('[stealth] audio.js loaded successfully');
|
|
341
|
+
console.log('[stealth] AudioContext patched:',
|
|
342
|
+
typeof AudioContext !== 'undefined');
|
|
343
|
+
console.log('[stealth] OfflineAudioContext patched:',
|
|
344
|
+
typeof OfflineAudioContext !== 'undefined');
|
|
345
|
+
console.log('[stealth] Audio seed:', getAudioSeed());
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
})();
|