function unc_serial_curl_test($files, $target_directory) { // these are Certificates for testing. Get your own, updated ones here: // http://curl.haxx.se/docs/caextract.html $ssl_cert = __DIR__ . "/ca-bundle_2015_07_18.crt"; $result_arr = unc_serial_curl($files, 0, 50, $ssl_cert); foreach ($result_arr as $file_id => $R) { $url = $R['response']['url']; $filename = basename($url); // let's make a rename in case 2 files have the same name $safe_filename = $file_id . "_" . $filename; // target directory writable check if (!is_writable($target_directory)) { die("directory {$target_directory} is not writable!"); } // write file content to current directory $write_check = file_put_contents($target_directory . "/" . $safe_filename, $R['content']); if (!$write_check) { die("Failed to write {$safe_filename} to {$target_directory}"); } } }
function umc_usericon_get($users = false, $update = true) { XMPP_ERROR_trace(__FUNCTION__, func_get_args()); global $UMC_PATH_MC; $steve_head = '/home/minecraft/server/bin/data/steve.png'; if (!$users) { $users = umc_get_active_members(); } else { if (is_array($users) && count($users) == 0) { XMPP_ERROR_send_msg("umc_update_usericons got zero users!"); } else { if (!is_array($users)) { $U = umc_uuid_getboth($users); $users = array($U['uuid'] => $U['username']); } } } $users_raw = array(); foreach ($users as $uuid => $username) { $uuid_raw = str_replace("-", "", $uuid); $users_raw[$uuid] = $url = "https://sessionserver.mojang.com/session/minecraft/profile/{$uuid_raw}"; } $no_skin = array(); $failed_users = array(); $skin_urls = array(); $D = unc_serial_curl($users_raw, 0, 50, '/home/includes/unc_serial_curl/google.crt'); foreach ($D as $uuid => $d) { // we only update the skin if it does not exist if (!$update && file_exists("{$UMC_PATH_MC}/server/bin/data/full_skins/{$uuid}.png")) { continue; } if ($uuid == 'abandone-0000-0000-0000-000000000000') { continue; } if ($d['response']['http_code'] !== 200) { $failed_users[] = array('uuid' => $uuid, 'url' => $d['response']['url'], 'reason' => 'Could not download user data'); } $base64_texture = ''; $d_arr = json_decode($d['content']); if (!$d_arr) { XMPP_ERROR_trigger("Failed to retrieve session profile for {$uuid}"); } //object(stdClass)#2 (3) { // ["id"]=> // string(32) "ab3bc877443445a993bdbab6df41eabf" // ["name"]=> // string(8) "uncovery" // ["properties"]=> // array(1) { // [0]=> // object(stdClass)#3 (2) { // ["name"]=> // string(8) "textures" // ["value"]=> // string(308) "eyJ0aW1lc3RhbXAiOjE0NDA0NzUyOTQ2NDksInByb2ZpbGVJZCI6ImFiM2JjODc3NDQzNDQ1YTk5M2JkYmFiNmRmNDFlYWJmIiwicHJvZmlsZU5hbWUiOiJ1bmNvdmVyeSIsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS9jYWVhMjljODY2ZDkyMTVhYWJjMTk5MDQyMTE1ZWMwNTUzMzJkNjZlMGI4ZWY2ZjkyNjNmZTRiMWZlNzZlIn19fQ==" // } // } //} if (!isset($d_arr->properties)) { XMPP_ERROR_trace("json", $d_arr); XMPP_ERROR_trigger("Failed to retrieve properties for {$uuid}"); } $prop_count = count($d_arr->properties); for ($i = 0; $i < $prop_count; $i++) { if ($d_arr->properties[$i]->name == 'textures') { $base64_texture = $d_arr->properties[$i]->value; } else { echo "Wrong property: " . $d_arr->properties[$i]->name; } } $raw_texture = base64_decode($base64_texture); // {"timestamp":1440475294649,"profileId":"ab3bc877443445a993bdbab6df41eabf","profileName":"uncovery","textures":{"SKIN":{"url":"http://textures.minecraft.net/texture/caea29c866d9215aabc199042115ec055332d66e0b8ef6f9263fe4b1fe76e"}}} $texture_arr = json_decode($raw_texture); if (!$texture_arr) { XMPP_ERROR_trigger("Failed to decode texture: {$raw_texture}"); } $time_stamp = $texture_arr->timestamp; // check if the file on the drive is newer $current_file = "{$UMC_PATH_MC}/server/bin/data/full_skins/{$uuid}.png"; if (!file_exists($current_file) || filemtime($current_file) > $time_stamp) { if (isset($texture_arr->textures->SKIN)) { // user did not set skin $skin_urls[$uuid] = $texture_arr->textures->SKIN->url; // echo $texture_arr->textures->SKIN->url . "<br>\n"; } else { XMPP_ERROR_trace("{$uuid} does not have a skin: {$raw_texture}"); $no_skin[] = $uuid; } } } $S = unc_serial_curl($skin_urls); foreach ($S as $uuid => $s) { $skin_file = "{$UMC_PATH_MC}/server/bin/data/full_skins/{$uuid}.png"; $head_file = "{$UMC_PATH_MC}/server/bin/data/user_icons/{$uuid}.png"; if ($s['response']['content_type'] !== 'image/png' && $s['response']['http_code'] !== 200) { $failed_users[] = array('uuid' => $uuid, 'url' => $s['response']['url'], 'reason' => 'Could not download image'); continue; } $written = file_put_contents($skin_file, $s['content']); if (!$written) { $failed_users[] = array('uuid' => $uuid, 'url' => $s['response']['url'], 'reason' => "Could not save file to {$skin_file}"); continue; } // convert to head icon, resize to 20x20 $command = "convert -crop '8x8+8+8' -scale 20 \"{$skin_file}\" \"{$head_file}\""; exec($command); } // process users w/o skin foreach ($no_skin as $uuid) { $head_file = "{$UMC_PATH_MC}/server/bin/data/user_icons/{$uuid}.png"; if (!file_exists($steve_head)) { XMPP_ERROR_trigger("Steve head icon not available"); } else { $check = copy($steve_head, $head_file); if (!$check || !file_exists($head_file)) { XMPP_ERROR_trigger("Could not create steve head for file {$head_file}"); } else { XMPP_ERROR_trace("used steve head for {$head_file}"); } } } if (count($failed_users) > 0) { XMPP_ERROR_trace("failed users:", $failed_users); XMPP_ERROR_trigger("Users failed to get icon, see error report for details"); } }
/** * This downloads all icons from Minecraft Wiki and stores it on the website * * @global array $UMC_DATA_ID2NAME */ function umc_get_icons() { global $UMC_DATA, $UMC_PATH_MC; $base_url = 'http://hydra-media.cursecdn.com/minecraft.gamepedia.com'; $base_path = "{$UMC_PATH_MC}/server/bin/data/icons/"; $img_arr = array(); foreach ($UMC_DATA as $item => $D) { if (isset($D['subtypes'])) { foreach ($D['subtypes'] as $id => $S) { if ($S['icon_url'] != '?') { $img_arr[$S['name']] = $base_url . $S['icon_url']; } } } if ($D['icon_url'] === '?') { continue; } else { $img_arr[$item] = $base_url . $D['icon_url']; } } // pass all arrays to mass-downloader $complete_count = count($img_arr); $D = unc_serial_curl($img_arr); $failed_icons = array(); foreach ($D as $img => $R) { if ($R['response']['http_code'] !== 200) { $failed_icons[] = array('img' => $img, 'url' => $R['response']['url'], 'reason' => "failed to get file from source"); } else { // assemble target path $full_url = $R['response']['url']; $path_info = pathinfo($full_url); if (!isset($path_info['extension'])) { XMPP_ERROR_trace("Extension missning for {$img}", $full_url); } $ext = $path_info['extension']; $target_path = $base_path . "{$img}.{$ext}"; // write target file $written = file_put_contents($target_path, $R['content']); if (!$written) { $failed_icons[] = array('img' => $img, 'url' => $R['response']['url'], 'reason' => 'failed to write file to $target_path'); } } } $count = count($failed_icons); if ($count > 0) { XMPP_ERROR_trace("failed users:", $failed_icons); XMPP_ERROR_trigger("Failed to get {$count} of {$complete_count} Block icons, see error report for details"); } }
/** * Extension function of unc_serial_curl to parse output and re-run the function * if necessary * * @param type $channel * @param type $user_agent * @param type $javascript_loop * @return type */ function unc_serial_curl_response_process($channel, $user_agent, $javascript_loop) { $content = curl_multi_getcontent($channel); $response = curl_getinfo($channel); if ($response['http_code'] == 301 || $response['http_code'] == 302) { ini_set("user_agent", $user_agent); $headers = get_headers($response['url']); if ($headers) { foreach ($headers as $value) { if (substr(strtolower($value), 0, 9) == "location:") { return unc_serial_curl(trim(substr($value, 9, strlen($value)))); } } } } $pattern_1 = "/>[[:space:]]+window\\.location\\.replace\\('(.*)'\\)/i"; $pattern_2 = "/>[[:space:]]+window\\.location\\=\"(.*)\"/i"; if ((preg_match($pattern_1, $content, $value) || preg_match($pattern_2, $content, $value)) && $javascript_loop < 5) { return unc_serial_curl($value[1], $javascript_loop + 1); } else { return array('content' => $content, 'response' => $response); } }