├── LICENSE ├── README.md ├── accounts.json ├── main.php └── proxy.txt /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Furqonflynn 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🌀 openloop-bot-php 2 | OpenLoop Node Point Mining Automation: Automate OpenLoop point mining with this robust PHP script. 3 | 4 | > [!TIP] 5 | > If you find this script helpful and beneficial, please star ⭐ this repository. Your support motivates me to create more useful tools in the future. 6 | 7 | > [!WARNING] 8 | > ## The use of this bot is entirely at your own risk. I assume no liability for any losses, damages, or consequences arising from its use. 9 | 10 | ## 🦾 Bot Script Features 11 | 12 | - Login 13 | - Multiple Accounts Connection through Proxy 14 | - Complete All Task 15 | - Bandwidth Share 16 | 17 | ## 🔓 Register 18 | 19 | - If you don't have a OpenLoop.SO account yet 20 | - Signup Here [https://openloop.so/](https://openloop.so/auth/register?ref=ol3844356f) 21 | - Register and input Referral code 22 | ```bash 23 | ol3844356f 24 | ``` 25 | ## 🤔 How To Do 26 | 27 | - Clone This Repo 28 | - ```bash 29 | git clone https://github.com/cmalf/openloop-bot-php.git 30 | ``` 31 | - Go To Folder 32 | - ```bash 33 | cd openloop-bot-php 34 | ``` 35 | - Configuration 36 | - Run the script 37 | 38 | ```bash 39 | php main.php 40 | ``` 41 | 42 | ## ⚙️ Configuration 43 | 44 | - Add your Account information to the accounts.json file. 45 | - Add proxy to proxy.txt file. 46 | 47 | ## [◉°] ScreenShoot 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /accounts.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "email": "xxxx", 4 | "password": "xxxx" 5 | }, 6 | { 7 | "email": "xxxx", 8 | "password": "xxxx" 9 | } // Just Copy paste the form to Add more Accounts 10 | 11 | ] -------------------------------------------------------------------------------- /main.php: -------------------------------------------------------------------------------- 1 | "\x1b[38;5;27m", 36 | 'gl' => "\x1b[38;5;46m", 37 | 'gr' => "\x1b[32m", 38 | 'gb' => "\x1b[4m", 39 | 'br' => "\x1b[34m", 40 | 'st' => "\x1b[9m", 41 | 'yl' => "\x1b[33m", 42 | 'am' => "\x1b[38;5;198m", 43 | 'rd' => "\x1b[31m", 44 | 'ug' => "\x1b[38;5;165m", 45 | 'rt' => "\x1b[0m", 46 | 'Green' => "\x1b[32m", 47 | 'Red' => "\x1b[31m", 48 | 'Yellow'=> "\x1b[93m", 49 | 'Teal' => "\x1b[38;5;51m", 50 | 'Neon' => "\x1b[38;5;198m", 51 | 'Gold' => "\x1b[38;5;220m", 52 | 'Dim' => "\x1b[2m", 53 | 'RESET' => "\x1b[0m" 54 | ]; 55 | 56 | // Check if cURL extension is installed 57 | if (!extension_loaded('curl')) { 58 | $installInstructions = "Error: PHP cURL extension is not installed.\n\n"; 59 | $installInstructions .= "Installation instructions:\n\n"; 60 | $installInstructions .= "For Windows:\n"; 61 | $installInstructions .= "1. Open php.ini file\n"; 62 | $installInstructions .= "2. Uncomment extension=curl\n"; 63 | $installInstructions .= "3. Restart your web server\n\n"; 64 | $installInstructions .= "For Linux (Ubuntu/Debian):\n"; 65 | $installInstructions .= "sudo apt-get install php-curl\n"; 66 | $installInstructions .= "sudo service apache2 restart\n\n"; 67 | $installInstructions .= "For macOS:\n"; 68 | $installInstructions .= "1. Using Homebrew: brew install php@8.x\n"; 69 | $installInstructions .= "2. Or modify php.ini to enable curl extension\n"; 70 | die($Colors['Red'] . $installInstructions . $Colors['rt']); 71 | } 72 | 73 | $CoderMarkPrinted = false; 74 | 75 | // File paths 76 | $ACCOUNTS_FILE = __DIR__ . '/accounts.json'; 77 | $PROXY_FILE = __DIR__ . '/proxy.txt'; 78 | $TOKEN_FILE = __DIR__ . '/data_token.json'; 79 | 80 | // API Endpoints 81 | $LOGIN_URL = 'https://api.openloop.so/users/login'; 82 | $BANDWIDTH_SHARE_URL = 'https://api.openloop.so/bandwidth/share'; 83 | function TASK_URL($missionId) { 84 | return "https://api.openloop.so/missions/{$missionId}/complete"; 85 | } 86 | 87 | // User Agents Array 88 | $userAgents = [ 89 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Edge/537.36", 90 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Edge/537.36", 91 | "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36", 92 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Edge/120.0.0.0", 93 | "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36", 94 | "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.2.1 Safari/605.1.15", 95 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:133.0) Gecko/20100101 Firefox/133.", 96 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.3", 97 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 OPR/114.0.0.", 98 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.3", 99 | "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.3", 100 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 AtContent/95.5.5462.5", 101 | ]; 102 | 103 | // Create common headers 104 | $COMMON_HEADERS = [ 105 | 'User-Agent' => $userAgents[array_rand($userAgents)], 106 | 'Accept-Language' => 'id-ID,id;q=0.9,en-US;q=0.8,en;q=0.7,zh-TW;q=0.6,zh;q=0.5' 107 | ]; 108 | 109 | /** 110 | * Utility function to format date as "yyyy-MM-dd HH:mm:ss" 111 | */ 112 | function formatDate($date) { 113 | return $date->format('Y-m-d H:i:s'); 114 | } 115 | 116 | /** 117 | * Log message with color and timestamp. 118 | * messageType can be: success, error, warning, process, info. 119 | */ 120 | function logMessage($message = "", $messageType = "info", $currentAccount = 0, $totalAccounts = 0) { 121 | global $Colors; 122 | $timestamp = formatDate(new DateTime()); 123 | 124 | $colors = [ 125 | 'success' => $Colors['Green'], 126 | 'error' => $Colors['Red'], 127 | 'warning' => $Colors['Yellow'], 128 | 'process' => $Colors['Neon'], 129 | 'info' => $Colors['Teal'] 130 | ]; 131 | 132 | $logColor = isset($colors[$messageType]) ? $colors[$messageType] : $colors['info']; 133 | $line = str_repeat('―', 70); 134 | echo $line . PHP_EOL; 135 | echo "{$Colors['Dim']}[{$timestamp}] {$Colors['RESET']}{$Colors['Gold']}> {$logColor}{$message}{$Colors['RESET']}" . PHP_EOL; 136 | echo $line . PHP_EOL; 137 | } 138 | 139 | /** 140 | * Display CoderMark (banner) 141 | */ 142 | function CoderMark() { 143 | global $CoderMarkPrinted, $Colors; 144 | if (!$CoderMarkPrinted) { 145 | echo " 146 | ╭━━━╮╱╱╱╱╱╱╱╱╱╱╱╱╱╭━━━┳╮ 147 | ┃╭━━╯╱╱╱╱╱╱╱╱╱╱╱╱╱┃╭━━┫┃{$Colors['gr']} 148 | ┃╰━━┳╮╭┳━┳━━┳━━┳━╮┃╰━━┫┃╭╮╱╭┳━╮╭━╮ 149 | ┃╭━━┫┃┃┃╭┫╭╮┃╭╮┃╭╮┫╭━━┫┃┃┃╱┃┃╭╮┫╭╮╮{$Colors['br']} 150 | ┃┃╱╱┃╰╯┃┃┃╰╯┃╰╯┃┃┃┃┃╱╱┃╰┫╰━╯┃┃┃┃┃┃┃ 151 | ╰╯╱╱╰━━┻╯╰━╮┣━━┻╯╰┻╯╱╱╰━┻━╮╭┻╯╰┻╯╰╯{$Colors['rt']} 152 | ╱╱╱╱╱╱╱╱╱╱╱┃┃╱╱╱╱╱╱╱╱╱╱╱╭━╯┃{$Colors['am']}{{$Colors['rt']}cmalf{$Colors['am']}}{$Colors['rt']} 153 | ╱╱╱╱╱╱╱╱╱╱╱╰╯╱╱╱╱╱╱╱╱╱╱╱╰━━╯ 154 | \n{$Colors['rt']}{$Colors['gb']} OpenLoop Bot {$Colors['gl']}PHP {$Colors['bl']}v1.0 {$Colors['rt']} 155 | \n{$Colors['gr']}―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― 156 | \n{$Colors['yl']}[+]{$Colors['rt']} DM : {$Colors['bl']}https://t.me/furqonflynn 157 | \n{$Colors['yl']}[+]{$Colors['rt']} GH : {$Colors['bl']}https://github.com/cmalf/ 158 | \n{$Colors['gr']}―――――――――――――――――――――――――――――――――――――――――――――――――― 159 | \n{$Colors['yl']}]-> {$Colors['am']}{ {$Colors['rt']}OpenLoop Extension{$Colors['bl']} v0.1.2{$Colors['am']} } {$Colors['rt']} 160 | \n{$Colors['gr']}――――――――――――――――――――――――――――――――――――――――――――――――――{$Colors['rt']} 161 | " . PHP_EOL; 162 | $CoderMarkPrinted = true; 163 | } 164 | } 165 | 166 | /** 167 | * Hide parts of the email for privacy. 168 | */ 169 | function hideEmail($email) { 170 | if (empty($email) || strpos($email, '@') === false) { 171 | return $email; 172 | } 173 | list($local, $domain) = explode('@', $email, 2); 174 | $domainParts = explode('.', $domain); 175 | $tld = array_pop($domainParts); 176 | $hideDomain = str_repeat('*', strlen($domain) - strlen($tld) - 1) . '.' . $tld; 177 | $hideLocal = substr($local, 0, 3) . str_repeat('*', max(strlen($local) - 6, 3)) . substr($local, -3); 178 | return "{$hideLocal}@{$hideDomain}"; 179 | } 180 | 181 | /** 182 | * Utility function to read proxies from file 183 | */ 184 | function loadProxies() { 185 | global $PROXY_FILE; 186 | if (!file_exists($PROXY_FILE)) { 187 | logMessage("Proxy file not found: {$PROXY_FILE}", "error"); 188 | return []; 189 | } 190 | $content = file_get_contents($PROXY_FILE); 191 | $lines = explode("\n", $content); 192 | $proxies = []; 193 | foreach ($lines as $line) { 194 | $trim = trim($line); 195 | if (!empty($trim)) { 196 | $proxies[] = $trim; 197 | } 198 | } 199 | return $proxies; 200 | } 201 | 202 | /** 203 | * Utility function to get a random proxy from list 204 | */ 205 | function getRandomProxy($proxies) { 206 | if (empty($proxies)) { 207 | return null; 208 | } 209 | return $proxies[array_rand($proxies)]; 210 | } 211 | 212 | /** 213 | * Utility function to get a random quality for bandwidth share 214 | */ 215 | function getRandomQuality() { 216 | $qualities = [68, 76, 88, 99]; 217 | return $qualities[array_rand($qualities)]; 218 | } 219 | 220 | /** 221 | * Read accounts.json file. Expecting an array of account objects. 222 | */ 223 | function loadAccounts() { 224 | global $ACCOUNTS_FILE; 225 | if (!file_exists($ACCOUNTS_FILE)) { 226 | logMessage("Accounts file not found: {$ACCOUNTS_FILE}", "error"); 227 | return []; 228 | } 229 | $content = file_get_contents($ACCOUNTS_FILE); 230 | $accounts = json_decode($content, true); 231 | if ($accounts === null) { 232 | logMessage("Error decoding accounts file.", "error"); 233 | return []; 234 | } 235 | return $accounts; 236 | } 237 | 238 | /** 239 | * Save token data to data_token.json file 240 | */ 241 | function saveTokenData($tokenData) { 242 | global $TOKEN_FILE; 243 | $jsonData = json_encode($tokenData, JSON_PRETTY_PRINT); 244 | if (file_put_contents($TOKEN_FILE, $jsonData) !== false) { 245 | logMessage("Token data saved to {$TOKEN_FILE}", "success"); 246 | } else { 247 | logMessage("Error saving token data to {$TOKEN_FILE}", "error"); 248 | } 249 | } 250 | 251 | /** 252 | * Load token data from data_token.json file 253 | */ 254 | function loadTokenData() { 255 | global $TOKEN_FILE; 256 | if (!file_exists($TOKEN_FILE)) { 257 | logMessage("Token file not found: {$TOKEN_FILE}", "error"); 258 | return []; 259 | } 260 | $content = file_get_contents($TOKEN_FILE); 261 | $tokenData = json_decode($content, true); 262 | if ($tokenData === null) { 263 | logMessage("Error decoding token data.", "error"); 264 | return []; 265 | } 266 | return $tokenData; 267 | } 268 | 269 | /** 270 | * Function for making HTTP requests with proxy support using cURL. 271 | */ 272 | function makeRequest($params) { 273 | $url = isset($params['url']) ? $params['url'] : ''; 274 | $method = isset($params['method']) ? strtoupper($params['method']) : 'GET'; 275 | $headersArray = []; 276 | $headers = isset($params['headers']) ? $params['headers'] : []; 277 | foreach ($headers as $key => $value) { 278 | $headersArray[] = "{$key}: {$value}"; 279 | } 280 | $data = isset($params['data']) ? $params['data'] : null; 281 | $proxy = isset($params['proxy']) ? $params['proxy'] : null; 282 | $timeout = 30; 283 | 284 | $ch = curl_init(); 285 | 286 | curl_setopt($ch, CURLOPT_URL, $url); 287 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 288 | curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); 289 | curl_setopt($ch, CURLOPT_HTTPHEADER, $headersArray); 290 | /** 291 | * Enable this code if you have problems with SSL certificate issues. 292 | */ 293 | // Disable SSL peer verification to solve certificate issues. 294 | // curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); 295 | // curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); 296 | 297 | // Set method and data for POST 298 | if ($method === 'POST') { 299 | curl_setopt($ch, CURLOPT_POST, true); 300 | if ($data !== null) { 301 | $jsonData = json_encode($data); 302 | curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData); 303 | } 304 | } else { 305 | curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); 306 | } 307 | 308 | // Set proxy if provided 309 | if ($proxy !== null) { 310 | curl_setopt($ch, CURLOPT_PROXY, $proxy); 311 | } 312 | 313 | $response = curl_exec($ch); 314 | if (curl_errno($ch)) { 315 | logMessage("Request error ({$url}): " . curl_error($ch), "error"); 316 | curl_close($ch); 317 | return null; 318 | } 319 | curl_close($ch); 320 | 321 | // Attempt to decode JSON. If not JSON, return raw response. 322 | $decoded = json_decode($response, true); 323 | return $decoded !== null ? $decoded : $response; 324 | } 325 | 326 | /** 327 | * Option 1: Login All Accounts 328 | */ 329 | function loginAllAccounts() { 330 | global $COMMON_HEADERS, $LOGIN_URL; 331 | logMessage('Logging in all accounts...', "info"); 332 | $accounts = loadAccounts(); 333 | $proxies = loadProxies(); 334 | $tokenData = []; 335 | 336 | foreach ($accounts as $account) { 337 | $proxy = getRandomProxy($proxies); 338 | $agentInfo = $proxy ? "(Using proxy: {$proxy})" : "(No proxy)"; 339 | logMessage("Logging in: {$account['email']} {$agentInfo}", "process"); 340 | 341 | // Merge common headers with additional headers 342 | $headers = array_merge($COMMON_HEADERS, [ 343 | 'accept' => 'application/json', 344 | 'content-type' => 'application/json' 345 | ]); 346 | 347 | $payload = [ 348 | 'username' => $account['email'], 349 | 'password' => $account['password'] 350 | ]; 351 | 352 | $response = makeRequest([ 353 | 'url' => $LOGIN_URL, 354 | 'method' => 'POST', 355 | 'headers'=> $headers, 356 | 'data' => $payload, 357 | 'proxy' => $proxy 358 | ]); 359 | 360 | if ($response && isset($response['code']) && $response['code'] === 2000 && isset($response['data']['accessToken'])) { 361 | logMessage("Login success: {$account['email']}", "success"); 362 | $tokenData[] = [ 363 | 'email' => $account['email'], 364 | 'accessToken' => $response['data']['accessToken'] 365 | ]; 366 | } else { 367 | $errMsg = isset($response['message']) ? $response['message'] : 'No response'; 368 | logMessage("Login failed for {$account['email']}: {$errMsg}", "error"); 369 | } 370 | } 371 | 372 | saveTokenData($tokenData); 373 | } 374 | 375 | /** 376 | * Complete Task All Accounts 377 | * 378 | * For each account, retrieve the missions list using GET request. 379 | * For every mission with status "available", perform: 380 | * - A GET request to the mission's social link. 381 | * - Then, complete the mission in two steps: 382 | * 1. First, send an OPTIONS request to the mission complete endpoint without the Authorization header. 383 | * This request includes headers to simulate a CORS preflight and waits for 10 seconds. 384 | * 2. Second, send a GET request to the mission complete endpoint with the Authorization header. 385 | * This finalizes the mission completion. 386 | * 387 | * Additionally, after processing all missions for an account: 388 | * - If no mission is available from the start, log that all tasks are already complete. 389 | * - If available missions were processed and all completed successfully, log that all tasks have been completed. 390 | * - Otherwise, log the number of tasks that could not be completed. 391 | */ 392 | function completeTaskAllAccounts() { 393 | global $COMMON_HEADERS; 394 | logMessage('Completing tasks for all accounts...', "info"); 395 | $tokenData = loadTokenData(); 396 | $proxies = loadProxies(); 397 | 398 | foreach ($tokenData as $tokenEntry) { 399 | $hiddenEmail = hideEmail($tokenEntry['email']); 400 | logMessage("Processing tasks for {$hiddenEmail}", "process"); 401 | 402 | $proxy = getRandomProxy($proxies); 403 | 404 | // Prepare headers for missions list request with authorization 405 | $authHeaders = array_merge($COMMON_HEADERS, [ 406 | 'Accept' => '*/*', 407 | 'Origin' => 'chrome-extension://effapmdildnpkiaeghlkicpfflpiambm', 408 | 'Authorization' => "Bearer " . $tokenEntry['accessToken'] 409 | ]); 410 | 411 | // Retrieve missions list 412 | $missionListResponse = makeRequest([ 413 | 'url' => 'https://api.openloop.so/missions', 414 | 'method' => 'GET', 415 | 'headers' => $authHeaders, 416 | 'proxy' => $proxy 417 | ]); 418 | 419 | if (!$missionListResponse || !isset($missionListResponse['code']) || $missionListResponse['code'] !== 2000) { 420 | logMessage("Failed to retrieve missions for {$hiddenEmail}.", "error"); 421 | continue; 422 | } 423 | 424 | if (!isset($missionListResponse['data']['missions']) || !is_array($missionListResponse['data']['missions'])) { 425 | logMessage("No missions found for {$hiddenEmail}.", "warning"); 426 | continue; 427 | } 428 | 429 | // Counters for tracking mission statuses 430 | $totalAvailable = 0; 431 | $completedCount = 0; 432 | 433 | // Process each available mission 434 | foreach ($missionListResponse['data']['missions'] as $mission) { 435 | if (isset($mission['status']) && $mission['status'] === "available") { 436 | $totalAvailable++; 437 | $missionId = $mission['missionId']; 438 | $missionName = $mission['name']; 439 | $socialLink = isset($mission['social']['link']) ? $mission['social']['link'] : ''; 440 | 441 | logMessage("Account {$hiddenEmail}: Processing Mission {$missionId} - {$missionName}", "process"); 442 | 443 | // Step 1: Access the social link if provided 444 | if (!empty($socialLink)) { 445 | logMessage("Accessing social link: {$socialLink}", "info"); 446 | // Execute GET request to the social link; response is not used 447 | makeRequest([ 448 | 'url' => $socialLink, 449 | 'method' => 'GET', 450 | 'headers' => $COMMON_HEADERS, 451 | 'proxy' => $proxy 452 | ]); 453 | } else { 454 | logMessage("Social link not provided for Mission {$missionId}", "warning"); 455 | } 456 | 457 | // Step 2: First, send an OPTIONS request without the Authorization header. 458 | $optionsHeaders = array_merge($COMMON_HEADERS, [ 459 | 'Accept' => '*/*', 460 | 'Origin' => 'chrome-extension://effapmdildnpkiaeghlkicpfflpiambm', 461 | 'Access-Control-Request-Method' => 'GET', 462 | 'Access-Control-Request-Headers' => 'authorization' 463 | // Authorization header is intentionally omitted. 464 | ]); 465 | 466 | $completeUrl = TASK_URL($missionId); 467 | logMessage("Sending preflight OPTIONS request for Mission {$missionId}", "info"); 468 | $optionsResponse = makeRequest([ 469 | 'url' => $completeUrl, 470 | 'method' => 'OPTIONS', 471 | 'headers' => $optionsHeaders, 472 | 'proxy' => $proxy 473 | ]); 474 | 475 | // Wait for 10 seconds as per instructions to simulate delay after preflight. 476 | logMessage("Waiting for 10 seconds after OPTIONS request for Mission {$missionId}", "info"); 477 | sleep(10); 478 | 479 | // Step 3: Send the actual GET request with Authorization header to complete the mission. 480 | logMessage("Sending final GET request (with Authorization) for Mission {$missionId}", "info"); 481 | $completeResponse = makeRequest([ 482 | 'url' => $completeUrl, 483 | 'method' => 'GET', 484 | 'headers' => $authHeaders, 485 | 'proxy' => $proxy 486 | ]); 487 | 488 | if ($completeResponse && isset($completeResponse['code']) && $completeResponse['code'] === 2000) { 489 | logMessage("{$hiddenEmail} Mission {$missionId} completed: " . $completeResponse['message'], "success"); 490 | $completedCount++; 491 | } else { 492 | $errMsg = isset($completeResponse['message']) ? $completeResponse['message'] : 'No response'; 493 | logMessage("{$hiddenEmail} Mission {$missionId} failed: {$errMsg}", "error"); 494 | } 495 | } 496 | } 497 | 498 | // Log mission completion summary for the account. 499 | if ($totalAvailable === 0) { 500 | logMessage("{$hiddenEmail}: All tasks have already been completed.", "success"); 501 | } elseif ($completedCount === $totalAvailable) { 502 | logMessage("{$hiddenEmail}: All {$completedCount} available tasks have now been completed.", "success"); 503 | } else { 504 | $remaining = $totalAvailable - $completedCount; 505 | logMessage("{$hiddenEmail}: {$completedCount} tasks completed, but {$remaining} task(s) still remain available.", "warning"); 506 | } 507 | } 508 | } 509 | 510 | /** 511 | * Option 3: Run Bandwidth Share (runs every few minutes) 512 | */ 513 | function runBandwidthShare() { 514 | global $COMMON_HEADERS; 515 | logMessage('Starting Bandwidth Share process...', "info"); 516 | $tokenData = loadTokenData(); 517 | $proxies = loadProxies(); 518 | 519 | foreach ($tokenData as $tokenEntry) { 520 | $proxy = getRandomProxy($proxies); 521 | $quality = getRandomQuality(); 522 | $headers = array_merge($COMMON_HEADERS, [ 523 | 'Content-Type' => 'application/json', 524 | 'Accept' => '*/*', 525 | 'Origin' => 'chrome-extension://effapmdildnpkiaeghlkicpfflpiambm', 526 | 'Authorization' => "Bearer " . $tokenEntry['accessToken'] 527 | ]); 528 | 529 | $payload = [ 530 | 'quality' => $quality 531 | ]; 532 | 533 | $response = makeRequest([ 534 | 'url' => $GLOBALS['BANDWIDTH_SHARE_URL'], 535 | 'method' => 'POST', 536 | 'headers'=> $headers, 537 | 'data' => $payload, 538 | 'proxy' => $proxy 539 | ]); 540 | 541 | if ($response && isset($response['code']) && $response['code'] === 2000) { 542 | $point = isset($response['data']['balances']['POINT']) ? $response['data']['balances']['POINT'] : 'N/A'; 543 | // Using reset color for POINT output 544 | logMessage(hideEmail($tokenEntry['email']) . " " . $GLOBALS['Colors']['Neon'] . "POINT: {$point}", "success"); 545 | } else { 546 | $errMsg = isset($response['message']) ? $response['message'] : 'No response'; 547 | logMessage(hideEmail($tokenEntry['email']) . " Bandwidth Share failed: {$errMsg}", "error"); 548 | } 549 | } 550 | } 551 | 552 | /** 553 | * Function to repeatedly run bandwidth share every few minutes. 554 | * This function will run indefinitely until interrupted. 555 | */ 556 | function startBandwidthShareInterval() { 557 | // Run initially 558 | runBandwidthShare(); 559 | while (true) { 560 | // Sleep for 3 minutes (180 seconds) 561 | sleep(180); 562 | runBandwidthShare(); 563 | } 564 | } 565 | 566 | /** 567 | * Display menu and process user input. 568 | */ 569 | function showMenu() { 570 | global $Colors; 571 | echo "{$Colors['Teal']}Menu Options:" . PHP_EOL . PHP_EOL; 572 | echo "{$Colors['RESET']}1. Login All Accounts" . PHP_EOL; 573 | echo "{$Colors['RESET']}2. Complete Task All Accounts" . PHP_EOL; 574 | echo "{$Colors['RESET']}3. Run Bandwidth Share" . PHP_EOL; 575 | echo "{$Colors['RESET']}4. {$Colors['Red']}Exit{$Colors['RESET']}" . PHP_EOL . PHP_EOL; 576 | echo "Choose an option: "; 577 | } 578 | 579 | /** 580 | * Main function to run the CLI interactive menu. 581 | */ 582 | function main() { 583 | // Clear console 584 | if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { 585 | system('cls'); 586 | } else { 587 | system('clear'); 588 | } 589 | CoderMark(); 590 | 591 | while (true) { 592 | showMenu(); 593 | $input = trim(fgets(STDIN)); 594 | switch ($input) { 595 | case '1': 596 | loginAllAccounts(); 597 | break; 598 | case '2': 599 | completeTaskAllAccounts(); 600 | break; 601 | case '3': 602 | // Option 3 will run indefinitely. 603 | logMessage($GLOBALS['Colors']['Neon'] . "Bandwidth share process. " . $GLOBALS['Colors']['RESET'] . "(Press Ctrl+C to exit)", "info"); 604 | startBandwidthShareInterval(); 605 | // This point will not be reached unless an interrupt occurs. 606 | break; 607 | case '4': 608 | logMessage("Exiting...", "info"); 609 | exit(0); 610 | break; 611 | default: 612 | logMessage("Invalid option. Please select 1, 2, 3, or 4.", "warning"); 613 | break; 614 | } 615 | } 616 | } 617 | 618 | main(); 619 | ?> 620 | -------------------------------------------------------------------------------- /proxy.txt: -------------------------------------------------------------------------------- 1 | //Supported Format Protocol://username:password@ip:port --------------------------------------------------------------------------------