private function Fetch($URLs, $Tries) { $this->Requests = array(); $Master = cURL_Multi_Init(); $WindowSize = 10; if ($WindowSize > Count($URLs)) { $WindowSize = Count($URLs); } for ($i = 0; $i < $WindowSize; $i++) { $URL = Array_Shift($URLs); $this->CreateHandle($Master, $URL); } unset($URL, $WindowSize, $i); do { while (($Exec = cURL_Multi_Exec($Master, $Running)) === CURLM_CALL_MULTI_PERFORM) { } if ($Exec !== CURLM_OK) { break; } while ($Done = cURL_Multi_Info_Read($Master)) { $Slave = $Done['handle']; $URL = cURL_GetInfo($Slave, CURLINFO_EFFECTIVE_URL); $Code = cURL_GetInfo($Slave, CURLINFO_HTTP_CODE); $Data = cURL_Multi_GetContent($Slave); $Request = $this->Requests[(int) $Slave]; $HeaderSize = cURL_GetInfo($Slave, CURLINFO_HEADER_SIZE); $Header = SubStr($Data, 0, $HeaderSize); $Data = SubStr($Data, $HeaderSize); if (isset($Done['error'])) { $this->Log('{yellow}cURL Error: {yellow}' . $Done['error'] . '{normal} - ' . $URL); $this->URLsToFetch[] = array('URL' => $URL, 'File' => $Request); } else { if ($Code === 304) { $this->Log('{yellow}Not Modified{normal} - ' . $URL); } else { if ($Code !== 200) { $this->Log('{yellow}HTTP Error ' . $Code . '{normal} - ' . $URL); if ($Code !== 404) { $this->URLsToFetch[] = array('URL' => $URL, 'File' => $Request); } } else { $LengthExpected = cURL_GetInfo($Slave, CURLINFO_CONTENT_LENGTH_DOWNLOAD); $LengthDownload = cURL_GetInfo($Slave, CURLINFO_SIZE_DOWNLOAD); if ($LengthExpected !== $LengthDownload) { $this->Log('{lightred}Wrong Length {normal}(' . $LengthDownload . ' != ' . $LengthExpected . '){normal} - ' . $URL); $this->URLsToFetch[] = array('URL' => $URL, 'File' => $Request); } else { if (Preg_Match('/^ETag: (.+)$/m', $Header, $Test) === 1) { $this->ETags[$Request] = Trim($Test[1]); } if ($this->HandleResponse($Request, $Data) === true) { $this->Log('{green}Fetched{normal} - ' . $URL); } else { $this->Log('{green}Not Modified{normal} - ' . $URL); } } } } } if (Count($URLs)) { $URL = Array_Shift($URLs); $this->CreateHandle($Master, $URL); } cURL_Multi_Remove_Handle($Master, $Slave); cURL_Close($Slave); unset($Request, $Slave); } if ($Running) { cURL_Multi_Select($Master, 5); } } while ($Running); cURL_Multi_Close($Master); }
public function __construct($MakeMojangNewsRequest = false) { $Checks = array(array('Name' => 'session', 'Callback' => 'CheckSession', 'Timeout' => 6, 'URL' => 'https://sessionserver.mojang.com/'), array('Name' => 'website', 'Callback' => 'CheckWebsite', 'Timeout' => 7, 'URL' => 'https://minecraft.net/'), array('Name' => 'skins', 'Callback' => 'CheckSkins', 'Timeout' => 5, 'URL' => 'http://textures.minecraft.net/texture/a116e69a845e227f7ca1fdde8c357c8c821ebd4ba619382ea4a1f87d4ae94')); if ($MakeMojangNewsRequest) { $Checks[] = array('Name' => 'news', 'Callback' => '', 'Timeout' => 4, 'URL' => 'http://status.mojang.com/news'); } $Requests = array(); $Master = cURL_Multi_Init(); foreach ($Checks as $Check) { $Slave = $this->CreateSlave($Check['URL'], $Check['Timeout']); if ($Check['Name'] === 'login') { cURL_SetOpt_Array($Slave, array(CURLOPT_POST => true, CURLOPT_POSTFIELDS => '{"agent":"Minecraft","clientToken":"","username":"******","password":"******"}', CURLOPT_HTTPHEADER => array('Content-Type: application/json'))); } cURL_Multi_Add_Handle($Master, $Slave); $Requests[(int) $Slave] = array('Name' => $Check['Name'], 'Callback' => $Check['Callback']); } unset($Checks); echo 'Doing a thing' . PHP_EOL; do { while (($Exec = cURL_Multi_Exec($Master, $Running)) === CURLM_CALL_MULTI_PERFORM) { } if ($Exec !== CURLM_OK) { break; } while ($Done = cURL_Multi_Info_Read($Master)) { $Slave = $Done['handle']; $Request = $Requests[(int) $Slave]; $Name = $Request['Name']; $Code = cURL_GetInfo($Slave, CURLINFO_HTTP_CODE); $Data = cURL_Multi_GetContent($Slave); echo $Name . ' - HTTP ' . $Code . PHP_EOL; //cURL_Multi_Remove_Handle( $Master, $Slave ); if ($Name === 'news') { HandleNews($Data, isset($Done['error']) ? 0 : $Code); } else { if (isset($Done['error'])) { $this->Report[$Name] = array('status' => self::STATUS_OFFLINE, 'title' => 'cURL Error'); } else { if ($Code === 0) { $this->Report[$Name] = array('status' => self::STATUS_OFFLINE, 'title' => 'Timed Out'); } else { if ($Code !== ($Name === 'realms' ? 401 : 200)) { $Set = false; if ($Name === 'login' && !empty($Data)) { $a = $Data; $Data = JSON_Decode($Data, true); if (JSON_Last_Error() === JSON_ERROR_NONE && Array_Key_Exists('error', $Data)) { if ($Data['error'] === 'Internal Server Error') { $Set = 'Server Error'; } else { $Set = Array_Key_Exists('errorMessage', $Data) ? $Data['errorMessage'] : $Data['error']; if (StrLen($Set) > 23) { $Set = SubStr($Set, 0, 23) . '...'; } } $this->Report[$Name] = array('status' => self::STATUS_OFFLINE, 'title' => $Set); } } if ($Set === false) { $this->Report[$Name] = array('status' => self::STATUS_OFFLINE, 'title' => 'HTTP Error ' . $Code); } unset($Set); } else { if ($this->{$Request['Callback']}($Data) !== true) { $this->Report[$Name] = array('status' => self::STATUS_OFFLINE, 'title' => 'Unexpected Response'); } else { if (cURL_GetInfo($Slave, CURLINFO_TOTAL_TIME) > 1.5) { $this->Report[$Name] = array('status' => self::STATUS_PERF_DEGRADATION, 'title' => 'Quite Slow'); } else { $this->Report[$Name] = array('status' => self::STATUS_ONLINE, 'title' => 'Online'); } } } } } } /*if( $this->SessionID !== false ) { echo 'Got it ' . $Name . PHP_EOL; $SlaveNew = $this->CreateSlave( 'https://sessionserver.mojang.com/session/minecraft/join', 3 ); cURL_SetOpt_Array( $SlaveNew, Array( CURLOPT_POST => true, CURLOPT_POSTFIELDS => '{"accessToken":"' . $this->SessionID . '"}', CURLOPT_HTTPHEADER => Array( 'Content-Type: application/json' ) ) ); $this->SessionID = false; $Requests[ (int)$SlaveNew ] = Array( 'Name' => 'session_auth', 'Callback' => 'CheckSessionReal' ); cURL_Multi_Add_Handle( $Master, $SlaveNew ); unset( $SlaveNew ); }*/ cURL_Multi_Remove_Handle($Master, $Slave); cURL_Close($Slave); unset($Request, $Slave, $Data, $Code); } if ($Running) { cURL_Multi_Select($Master, 3.0); } } while ($Running); cURL_Multi_Close($Master); if (Array_Key_Exists('legacy_session', $this->Report)) { if ($this->Report['legacy_session']['status'] !== self::STATUS_ONLINE && $this->Report['session']['status'] === self::STATUS_ONLINE) { $this->Report['session']['status'] = $this->Report['legacy_session']['status']; $this->Report['session']['title'] = 'Legacy ' . $this->Report['legacy_session']['title']; } unset($this->Report['legacy_session']); } if ($this->AccessToken !== false) { $Slave = $this->CreateSlave('https://sessionserver.mojang.com/session/minecraft/join', 3); cURL_SetOpt_Array($Slave, array(CURLOPT_POST => true, CURLOPT_POSTFIELDS => '{"accessToken":"' . $this->AccessToken . '","selectedProfile":"' . $this->SelectedProfile . '","serverId":0}', CURLOPT_HTTPHEADER => array('Content-Type: application/json'))); $Data = cURL_Exec($Slave); $Code = cURL_GetInfo($Slave, CURLINFO_HTTP_CODE); cURL_Close($Slave); if ($Code !== 0 && $Code !== 200) { $Data = JSON_Decode($Data, true); if (JSON_Last_Error() === JSON_ERROR_NONE && Is_Array($Data) && Array_Key_Exists('error', $Data)) { $Set = $Data['error']; if (StrLen($Set) > 23) { $Set = SubStr($Set, 0, 23) . '...'; } $this->Report['session'] = array('status' => self::STATUS_OFFLINE, 'title' => $Set); } } } }