1use std::path::PathBuf;
2use std::sync::atomic::{AtomicU64, Ordering};
3
4const CHROME_MAJOR: &str = "134";
5const CHROME_FULL: &str = "134.0.6998.0";
6const GREASE_BRAND: &str = "Not:A-Brand";
7
8const NV: &str = "Google Inc. (NVIDIA)";
9const AMD: &str = "Google Inc. (AMD)";
10const INTEL: &str = "Google Inc. (Intel)";
11
12macro_rules! nv { ($n:expr) => { concat!("ANGLE (NVIDIA, NVIDIA GeForce ", $n, " Direct3D11 vs_5_0 ps_5_0, D3D11)") } }
13macro_rules! amd { ($n:expr) => { concat!("ANGLE (AMD, AMD Radeon ", $n, " Direct3D11 vs_5_0 ps_5_0, D3D11)") } }
14macro_rules! amd_i { ($n:expr) => { concat!("ANGLE (AMD, AMD Radeon(TM) ", $n, " Direct3D11 vs_5_0 ps_5_0, D3D11)") } }
15macro_rules! intel { ($n:expr) => { concat!("ANGLE (Intel, Intel(R) ", $n, " Direct3D11 vs_5_0 ps_5_0, D3D11)") } }
16
17#[derive(Debug, Clone, Copy)]
18pub struct HwProfile {
19 pub gpu_vendor: &'static str,
20 pub gpu_renderer: &'static str,
21 pub width: u32,
22 pub height: u32,
23 pub cores: u32,
24 pub memory: u32,
25 pub dpr: f64,
26 pub max_texture_size: u32,
27}
28
29#[rustfmt::skip]
31pub static PROFILES: [HwProfile; 100] = [
32 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("RTX 5090"), width: 3840, height: 2160, cores: 32, memory: 64, dpr: 2.0, max_texture_size: 32768 },
34 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("RTX 5090"), width: 2560, height: 1440, cores: 24, memory: 32, dpr: 1.0, max_texture_size: 32768 },
35 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("RTX 5080"), width: 2560, height: 1440, cores: 16, memory: 32, dpr: 1.0, max_texture_size: 32768 },
36 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("RTX 5080"), width: 3840, height: 2160, cores: 24, memory: 64, dpr: 1.5, max_texture_size: 32768 },
37 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("RTX 5070 Ti"), width: 2560, height: 1440, cores: 16, memory: 32, dpr: 1.0, max_texture_size: 16384 },
38 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("RTX 5070"), width: 1920, height: 1080, cores: 12, memory: 16, dpr: 1.0, max_texture_size: 16384 },
39 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("RTX 4090"), width: 3840, height: 2160, cores: 24, memory: 64, dpr: 1.5, max_texture_size: 32768 },
40 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("RTX 4090"), width: 2560, height: 1440, cores: 32, memory: 32, dpr: 1.0, max_texture_size: 32768 },
41 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("RTX 4080 SUPER"), width: 2560, height: 1440, cores: 16, memory: 32, dpr: 1.0, max_texture_size: 16384 },
42 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("RTX 4080"), width: 2560, height: 1440, cores: 24, memory: 32, dpr: 1.0, max_texture_size: 16384 },
43 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("RTX 4070 Ti SUPER"), width: 2560, height: 1440, cores: 16, memory: 32, dpr: 1.0, max_texture_size: 16384 },
44 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("RTX 4070 Ti"), width: 1920, height: 1080, cores: 12, memory: 32, dpr: 1.0, max_texture_size: 16384 },
45 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("RTX 4070 SUPER"), width: 1920, height: 1080, cores: 12, memory: 16, dpr: 1.0, max_texture_size: 16384 },
46 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("RTX 4070"), width: 1920, height: 1080, cores: 12, memory: 16, dpr: 1.0, max_texture_size: 16384 },
47 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("RTX 4060 Ti"), width: 1920, height: 1080, cores: 12, memory: 16, dpr: 1.0, max_texture_size: 16384 },
48 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("RTX 4060"), width: 1920, height: 1080, cores: 8, memory: 16, dpr: 1.0, max_texture_size: 16384 },
49 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("RTX 3090 Ti"), width: 3840, height: 2160, cores: 24, memory: 64, dpr: 1.5, max_texture_size: 16384 },
50 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("RTX 3090"), width: 2560, height: 1440, cores: 16, memory: 32, dpr: 1.0, max_texture_size: 16384 },
51 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("RTX 3080 Ti"), width: 2560, height: 1440, cores: 16, memory: 32, dpr: 1.0, max_texture_size: 16384 },
52 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("RTX 3080"), width: 2560, height: 1440, cores: 12, memory: 32, dpr: 1.0, max_texture_size: 16384 },
53 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("RTX 3070 Ti"), width: 1920, height: 1080, cores: 12, memory: 16, dpr: 1.0, max_texture_size: 16384 },
54 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("RTX 3070"), width: 1920, height: 1080, cores: 12, memory: 16, dpr: 1.0, max_texture_size: 16384 },
55 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("RTX 3060 Ti"), width: 1920, height: 1080, cores: 8, memory: 16, dpr: 1.0, max_texture_size: 16384 },
56 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("RTX 3060"), width: 1920, height: 1080, cores: 8, memory: 16, dpr: 1.0, max_texture_size: 16384 },
57 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("RTX 3050"), width: 1920, height: 1080, cores: 6, memory: 16, dpr: 1.0, max_texture_size: 16384 },
58 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("GTX 1660 SUPER"), width: 1920, height: 1080, cores: 6, memory: 16, dpr: 1.0, max_texture_size: 16384 },
60 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("GTX 1660"), width: 1920, height: 1080, cores: 6, memory: 16, dpr: 1.0, max_texture_size: 16384 },
61 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("GTX 1650 SUPER"), width: 1920, height: 1080, cores: 6, memory: 8, dpr: 1.0, max_texture_size: 16384 },
62 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("GTX 1650"), width: 1920, height: 1080, cores: 4, memory: 8, dpr: 1.0, max_texture_size: 16384 },
63 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("GTX 1050 Ti"), width: 1920, height: 1080, cores: 4, memory: 8, dpr: 1.0, max_texture_size: 16384 },
64 HwProfile { gpu_vendor: AMD, gpu_renderer: amd!("RX 9070 XT"), width: 2560, height: 1440, cores: 16, memory: 32, dpr: 1.0, max_texture_size: 16384 },
66 HwProfile { gpu_vendor: AMD, gpu_renderer: amd!("RX 9070"), width: 1920, height: 1080, cores: 12, memory: 16, dpr: 1.0, max_texture_size: 16384 },
67 HwProfile { gpu_vendor: AMD, gpu_renderer: amd!("RX 7900 XTX"), width: 3840, height: 2160, cores: 24, memory: 64, dpr: 1.5, max_texture_size: 16384 },
68 HwProfile { gpu_vendor: AMD, gpu_renderer: amd!("RX 7900 XT"), width: 2560, height: 1440, cores: 16, memory: 32, dpr: 1.0, max_texture_size: 16384 },
69 HwProfile { gpu_vendor: AMD, gpu_renderer: amd!("RX 7900 GRE"), width: 2560, height: 1440, cores: 16, memory: 32, dpr: 1.0, max_texture_size: 16384 },
70 HwProfile { gpu_vendor: AMD, gpu_renderer: amd!("RX 7800 XT"), width: 1920, height: 1080, cores: 12, memory: 16, dpr: 1.0, max_texture_size: 16384 },
71 HwProfile { gpu_vendor: AMD, gpu_renderer: amd!("RX 7700 XT"), width: 1920, height: 1080, cores: 12, memory: 16, dpr: 1.0, max_texture_size: 16384 },
72 HwProfile { gpu_vendor: AMD, gpu_renderer: amd!("RX 7600 XT"), width: 1920, height: 1080, cores: 8, memory: 16, dpr: 1.0, max_texture_size: 16384 },
73 HwProfile { gpu_vendor: AMD, gpu_renderer: amd!("RX 7600"), width: 1920, height: 1080, cores: 8, memory: 16, dpr: 1.0, max_texture_size: 16384 },
74 HwProfile { gpu_vendor: AMD, gpu_renderer: amd!("RX 6950 XT"), width: 2560, height: 1440, cores: 16, memory: 32, dpr: 1.0, max_texture_size: 16384 },
75 HwProfile { gpu_vendor: AMD, gpu_renderer: amd!("RX 6900 XT"), width: 2560, height: 1440, cores: 16, memory: 32, dpr: 1.0, max_texture_size: 16384 },
76 HwProfile { gpu_vendor: AMD, gpu_renderer: amd!("RX 6800 XT"), width: 2560, height: 1440, cores: 12, memory: 32, dpr: 1.0, max_texture_size: 16384 },
77 HwProfile { gpu_vendor: AMD, gpu_renderer: amd!("RX 6800"), width: 1920, height: 1080, cores: 12, memory: 16, dpr: 1.0, max_texture_size: 16384 },
78 HwProfile { gpu_vendor: AMD, gpu_renderer: amd!("RX 6700 XT"), width: 1920, height: 1080, cores: 8, memory: 16, dpr: 1.0, max_texture_size: 16384 },
79 HwProfile { gpu_vendor: AMD, gpu_renderer: amd!("RX 6700"), width: 1920, height: 1080, cores: 8, memory: 16, dpr: 1.0, max_texture_size: 16384 },
80 HwProfile { gpu_vendor: AMD, gpu_renderer: amd!("RX 6650 XT"), width: 1920, height: 1080, cores: 8, memory: 16, dpr: 1.0, max_texture_size: 16384 },
81 HwProfile { gpu_vendor: AMD, gpu_renderer: amd!("RX 6600 XT"), width: 1920, height: 1080, cores: 6, memory: 16, dpr: 1.0, max_texture_size: 16384 },
82 HwProfile { gpu_vendor: AMD, gpu_renderer: amd!("RX 6600"), width: 1920, height: 1080, cores: 6, memory: 16, dpr: 1.0, max_texture_size: 16384 },
83 HwProfile { gpu_vendor: AMD, gpu_renderer: amd!("RX 6500 XT"), width: 1920, height: 1080, cores: 6, memory: 8, dpr: 1.0, max_texture_size: 16384 },
84 HwProfile { gpu_vendor: AMD, gpu_renderer: amd!("RX 5700 XT"), width: 1920, height: 1080, cores: 8, memory: 16, dpr: 1.0, max_texture_size: 16384 },
85 HwProfile { gpu_vendor: INTEL, gpu_renderer: intel!("Arc(TM) A770 Graphics"), width: 2560, height: 1440, cores: 16, memory: 32, dpr: 1.0, max_texture_size: 16384 },
87 HwProfile { gpu_vendor: INTEL, gpu_renderer: intel!("Arc(TM) A750 Graphics"), width: 1920, height: 1080, cores: 12, memory: 16, dpr: 1.0, max_texture_size: 16384 },
88 HwProfile { gpu_vendor: INTEL, gpu_renderer: intel!("Arc(TM) A580 Graphics"), width: 1920, height: 1080, cores: 12, memory: 16, dpr: 1.0, max_texture_size: 16384 },
89 HwProfile { gpu_vendor: INTEL, gpu_renderer: intel!("UHD Graphics 770"), width: 1920, height: 1080, cores: 24, memory: 32, dpr: 1.0, max_texture_size: 16384 },
90 HwProfile { gpu_vendor: INTEL, gpu_renderer: intel!("UHD Graphics 770"), width: 1920, height: 1080, cores: 16, memory: 16, dpr: 1.0, max_texture_size: 16384 },
91 HwProfile { gpu_vendor: INTEL, gpu_renderer: intel!("UHD Graphics 730"), width: 1920, height: 1080, cores: 8, memory: 16, dpr: 1.0, max_texture_size: 16384 },
92 HwProfile { gpu_vendor: INTEL, gpu_renderer: intel!("UHD Graphics 630"), width: 1920, height: 1080, cores: 8, memory: 16, dpr: 1.0, max_texture_size: 16384 },
93 HwProfile { gpu_vendor: INTEL, gpu_renderer: intel!("UHD Graphics 630"), width: 1920, height: 1080, cores: 6, memory: 16, dpr: 1.0, max_texture_size: 16384 },
94 HwProfile { gpu_vendor: INTEL, gpu_renderer: intel!("UHD Graphics 610"), width: 1920, height: 1080, cores: 4, memory: 8, dpr: 1.0, max_texture_size: 16384 },
95 HwProfile { gpu_vendor: INTEL, gpu_renderer: intel!("HD Graphics 530"), width: 1920, height: 1080, cores: 4, memory: 8, dpr: 1.0, max_texture_size: 16384 },
96 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("RTX 4090 Laptop GPU"), width: 2560, height: 1600, cores: 16, memory: 32, dpr: 1.25, max_texture_size: 16384 },
98 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("RTX 4080 Laptop GPU"), width: 2560, height: 1440, cores: 16, memory: 32, dpr: 1.0, max_texture_size: 16384 },
99 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("RTX 4070 Laptop GPU"), width: 1920, height: 1200, cores: 12, memory: 16, dpr: 1.25, max_texture_size: 16384 },
100 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("RTX 4060 Laptop GPU"), width: 1920, height: 1080, cores: 12, memory: 16, dpr: 1.0, max_texture_size: 16384 },
101 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("RTX 4050 Laptop GPU"), width: 1920, height: 1080, cores: 8, memory: 16, dpr: 1.25, max_texture_size: 16384 },
102 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("RTX 3080 Laptop GPU"), width: 2560, height: 1440, cores: 12, memory: 32, dpr: 1.0, max_texture_size: 16384 },
103 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("RTX 3070 Laptop GPU"), width: 1920, height: 1080, cores: 8, memory: 16, dpr: 1.0, max_texture_size: 16384 },
104 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("RTX 3060 Laptop GPU"), width: 1920, height: 1080, cores: 8, memory: 16, dpr: 1.25, max_texture_size: 16384 },
105 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("RTX 3050 Laptop GPU"), width: 1920, height: 1080, cores: 8, memory: 16, dpr: 1.0, max_texture_size: 16384 },
106 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("RTX 2060"), width: 1920, height: 1080, cores: 8, memory: 16, dpr: 1.0, max_texture_size: 16384 },
107 HwProfile { gpu_vendor: INTEL, gpu_renderer: intel!("Iris(R) Xe Graphics"), width: 1920, height: 1200, cores: 12, memory: 16, dpr: 1.25, max_texture_size: 16384 },
109 HwProfile { gpu_vendor: INTEL, gpu_renderer: intel!("Iris(R) Xe Graphics"), width: 1920, height: 1080, cores: 8, memory: 16, dpr: 1.0, max_texture_size: 16384 },
110 HwProfile { gpu_vendor: INTEL, gpu_renderer: intel!("Iris(R) Xe Graphics"), width: 2560, height: 1600, cores: 12, memory: 16, dpr: 1.5, max_texture_size: 16384 },
111 HwProfile { gpu_vendor: INTEL, gpu_renderer: intel!("UHD Graphics"), width: 1920, height: 1080, cores: 12, memory: 16, dpr: 1.25, max_texture_size: 16384 },
112 HwProfile { gpu_vendor: INTEL, gpu_renderer: intel!("UHD Graphics"), width: 1920, height: 1080, cores: 12, memory: 16, dpr: 1.0, max_texture_size: 16384 },
113 HwProfile { gpu_vendor: INTEL, gpu_renderer: intel!("Iris(R) Plus Graphics"), width: 1920, height: 1080, cores: 8, memory: 16, dpr: 1.0, max_texture_size: 16384 },
114 HwProfile { gpu_vendor: INTEL, gpu_renderer: intel!("UHD Graphics"), width: 1920, height: 1080, cores: 16, memory: 32, dpr: 1.25, max_texture_size: 16384 },
115 HwProfile { gpu_vendor: AMD, gpu_renderer: amd_i!("780M"), width: 1920, height: 1200, cores: 8, memory: 16, dpr: 1.25, max_texture_size: 16384 },
117 HwProfile { gpu_vendor: AMD, gpu_renderer: amd_i!("780M"), width: 2560, height: 1600, cores: 8, memory: 16, dpr: 1.5, max_texture_size: 16384 },
118 HwProfile { gpu_vendor: AMD, gpu_renderer: amd_i!("680M"), width: 1920, height: 1080, cores: 8, memory: 16, dpr: 1.0, max_texture_size: 16384 },
119 HwProfile { gpu_vendor: AMD, gpu_renderer: amd!("RX 7600M XT"), width: 1920, height: 1080, cores: 8, memory: 16, dpr: 1.0, max_texture_size: 16384 },
120 HwProfile { gpu_vendor: AMD, gpu_renderer: amd!("RX 6700M"), width: 1920, height: 1080, cores: 8, memory: 16, dpr: 1.0, max_texture_size: 16384 },
121 HwProfile { gpu_vendor: AMD, gpu_renderer: amd!("RX 6600M"), width: 1920, height: 1080, cores: 8, memory: 16, dpr: 1.25, max_texture_size: 16384 },
122 HwProfile { gpu_vendor: AMD, gpu_renderer: amd_i!("Vega 8 Graphics"), width: 1920, height: 1080, cores: 8, memory: 16, dpr: 1.0, max_texture_size: 16384 },
123 HwProfile { gpu_vendor: AMD, gpu_renderer: amd_i!("Vega 10 Graphics"), width: 1920, height: 1080, cores: 4, memory: 8, dpr: 1.0, max_texture_size: 16384 },
124 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("RTX 4070 Ti"), width: 3440, height: 1440, cores: 16, memory: 32, dpr: 1.0, max_texture_size: 16384 },
126 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("RTX 3080"), width: 3440, height: 1440, cores: 12, memory: 32, dpr: 1.0, max_texture_size: 16384 },
127 HwProfile { gpu_vendor: AMD, gpu_renderer: amd!("RX 7900 XTX"), width: 3440, height: 1440, cores: 24, memory: 64, dpr: 1.0, max_texture_size: 16384 },
128 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("RTX 4090"), width: 2560, height: 1440, cores: 24, memory: 128, dpr: 1.0, max_texture_size: 32768 },
129 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("RTX 3060"), width: 1366, height: 768, cores: 6, memory: 8, dpr: 1.0, max_texture_size: 16384 },
130 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("RTX 4060 Ti"), width: 2560, height: 1440, cores: 12, memory: 16, dpr: 1.0, max_texture_size: 16384 },
131 HwProfile { gpu_vendor: AMD, gpu_renderer: amd!("RX 7800 XT"), width: 2560, height: 1440, cores: 12, memory: 32, dpr: 1.0, max_texture_size: 16384 },
132 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("RTX 3070 Ti"), width: 2560, height: 1440, cores: 12, memory: 16, dpr: 1.0, max_texture_size: 16384 },
133 HwProfile { gpu_vendor: AMD, gpu_renderer: amd!("RX 7600"), width: 1920, height: 1080, cores: 6, memory: 16, dpr: 1.25, max_texture_size: 16384 },
134 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("RTX 4070 SUPER"), width: 2560, height: 1440, cores: 16, memory: 32, dpr: 1.0, max_texture_size: 16384 },
135 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("RTX 5070 Ti"), width: 3840, height: 2160, cores: 16, memory: 32, dpr: 1.5, max_texture_size: 16384 },
136 HwProfile { gpu_vendor: INTEL, gpu_renderer: intel!("Arc(TM) A770 Graphics"), width: 1920, height: 1080, cores: 16, memory: 32, dpr: 1.0, max_texture_size: 16384 },
137 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("RTX 3060"), width: 2560, height: 1080, cores: 8, memory: 16, dpr: 1.0, max_texture_size: 16384 },
138 HwProfile { gpu_vendor: AMD, gpu_renderer: amd!("RX 6700 XT"), width: 2560, height: 1440, cores: 8, memory: 16, dpr: 1.0, max_texture_size: 16384 },
139 HwProfile { gpu_vendor: NV, gpu_renderer: nv!("GTX 1660 Ti"), width: 1920, height: 1080, cores: 6, memory: 16, dpr: 1.0, max_texture_size: 16384 },
140];
141
142static TIMEZONES: &[(&str, &str)] = &[
143 ("America/New_York", "en-US"),
144 ("America/Chicago", "en-US"),
145 ("America/Denver", "en-US"),
146 ("America/Los_Angeles", "en-US"),
147 ("America/Phoenix", "en-US"),
148 ("Europe/London", "en-GB"),
149 ("Europe/Paris", "fr-FR"),
150 ("Europe/Berlin", "de-DE"),
151 ("Europe/Madrid", "es-ES"),
152 ("Europe/Rome", "it-IT"),
153 ("Europe/Amsterdam", "nl-NL"),
154 ("Europe/Warsaw", "pl-PL"),
155 ("Europe/Bucharest", "ro-RO"),
156 ("Europe/Istanbul", "tr-TR"),
157 ("Europe/Moscow", "ru-RU"),
158 ("Asia/Tokyo", "ja-JP"),
159 ("Asia/Seoul", "ko-KR"),
160 ("Asia/Shanghai", "zh-CN"),
161 ("Asia/Hong_Kong", "zh-HK"),
162 ("Asia/Taipei", "zh-TW"),
163 ("Asia/Singapore", "en-SG"),
164 ("Asia/Bangkok", "th-TH"),
165 ("Australia/Sydney", "en-AU"),
166 ("America/Toronto", "en-CA"),
167 ("America/Sao_Paulo", "pt-BR"),
168 ("Asia/Kolkata", "hi-IN"),
169];
170
171static FONTS: &[&str] = &[
172 "Arial", "Arial Black", "Calibri", "Cambria", "Candara",
173 "Comic Sans MS", "Consolas", "Constantia", "Corbel",
174 "Courier New", "Georgia", "Impact", "Lucida Console",
175 "Lucida Sans Unicode", "Microsoft Sans Serif", "Palatino Linotype",
176 "Segoe Print", "Segoe Script", "Segoe UI", "Segoe UI Symbol",
177 "Tahoma", "Times New Roman", "Trebuchet MS", "Verdana",
178 "Webdings", "Wingdings",
179];
180
181struct Rng(u64);
184
185impl Rng {
186 fn new(seed: u64) -> Self {
187 Self(if seed == 0 { 1 } else { seed })
188 }
189
190 fn next(&mut self) -> u64 {
191 let mut x = self.0;
192 x ^= x << 13;
193 x ^= x >> 7;
194 x ^= x << 17;
195 self.0 = x;
196 x
197 }
198
199 fn range(&mut self, max: usize) -> usize {
200 (self.next() % max as u64) as usize
201 }
202}
203
204static COUNTER: AtomicU64 = AtomicU64::new(0);
207
208pub fn random_profile() -> (usize, u64) {
210 let nanos = std::time::SystemTime::now()
211 .duration_since(std::time::UNIX_EPOCH)
212 .unwrap()
213 .as_nanos() as u64;
214 let count = COUNTER.fetch_add(1, Ordering::Relaxed);
215 let seed = nanos ^ count.wrapping_mul(6364136223846793005);
216 let idx = (seed as usize) % PROFILES.len();
217 (idx, seed)
218}
219
220pub fn generate_config_json(profile_index: usize, seed: u64) -> String {
222 let idx = profile_index % PROFILES.len();
223 let p = &PROFILES[idx];
224 let mut rng = Rng::new(seed);
225
226 let langs: Vec<String> = vec!["en-US".to_string(), "en".to_string()];
229
230 let config = serde_json::json!({
231 "profile_id": format!("clawser_{}_{}", idx, seed),
232 "navigator": {
233 "user_agent": format!(
234 "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/{}.0.0.0 Safari/537.36",
235 CHROME_MAJOR
236 ),
237 "app_version": format!(
238 "5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/{}.0.0.0 Safari/537.36",
239 CHROME_MAJOR
240 ),
241 "platform": "Win32",
242 "vendor": "Google Inc.",
243 "languages": langs,
244 "hardware_concurrency": p.cores,
245 "device_memory": p.memory,
246 "max_touch_points": 0,
247 "user_agent_data": {
248 "brands": [
249 { "brand": "Chromium", "version": CHROME_MAJOR },
250 { "brand": "Google Chrome", "version": CHROME_MAJOR },
251 { "brand": GREASE_BRAND, "version": "24" }
252 ],
253 "mobile": false,
254 "platform": "Windows",
255 "platform_version": "15.0.0",
256 "architecture": "x86",
257 "bitness": "64",
258 "model": "",
259 "full_version_list": [
260 { "brand": "Chromium", "version": CHROME_FULL },
261 { "brand": "Google Chrome", "version": CHROME_FULL },
262 { "brand": GREASE_BRAND, "version": "24.0.0.0" }
263 ]
264 }
265 },
266 "screen": {
267 "width": p.width,
268 "height": p.height,
269 "avail_width": p.width,
270 "avail_height": p.height.saturating_sub(40),
271 "color_depth": 24,
272 "pixel_depth": 24,
273 "device_pixel_ratio": p.dpr
274 },
275 "gpu": {
276 "vendor": p.gpu_vendor,
277 "renderer": p.gpu_renderer
278 },
279 "noise_seeds": {
280 "canvas": rng.next(),
281 "webgl": rng.next(),
282 "audio": rng.next(),
283 "client_rects": rng.next()
284 },
285 "locale": "en-US",
286 "fonts": FONTS,
287 "media_devices": {
288 "audio_inputs": 1 + rng.range(2),
289 "audio_outputs": 1 + rng.range(3),
290 "video_inputs": rng.range(2)
291 },
292 "webrtc": { "policy": "disabled" },
293 "battery": false,
294 "bluetooth": false,
295 "usb": false
296 });
297
298 serde_json::to_string_pretty(&config).unwrap()
299}
300
301pub fn write_config_file(profile_index: usize, seed: u64) -> std::io::Result<PathBuf> {
303 let json = generate_config_json(profile_index, seed);
304 let dir = std::env::temp_dir().join("clawser_configs");
305 std::fs::create_dir_all(&dir)?;
306 let file = dir.join(format!("profile_{}_{}.json", profile_index % PROFILES.len(), seed));
307 std::fs::write(&file, &json)?;
308 let canonical = file.canonicalize()?;
309 let s = canonical.to_string_lossy();
311 if let Some(stripped) = s.strip_prefix("\\\\?\\") {
312 Ok(PathBuf::from(stripped))
313 } else {
314 Ok(canonical)
315 }
316}