function stream_notification_callback($notification_code, $severity, $message, $message_code, $bytes_transferred, $bytes_max) { static $filesize = null; switch ($notification_code) { case STREAM_NOTIFY_RESOLVE: case STREAM_NOTIFY_COMPLETED: case STREAM_NOTIFY_AUTH_REQUIRED: case STREAM_NOTIFY_FAILURE: case STREAM_NOTIFY_AUTH_RESULT: break; case STREAM_NOTIFY_REDIRECTED: consoleLog("Being redirected to: " . $message); break; case STREAM_NOTIFY_CONNECT: consoleLog("Connected..."); break; case STREAM_NOTIFY_FILE_SIZE_IS: $filesize = $bytes_max; consoleLog("Filesize: " . $filesize); break; case STREAM_NOTIFY_MIME_TYPE_IS: consoleLog("Mime-type: " . $message); break; case STREAM_NOTIFY_PROGRESS: if ($bytes_transferred > 0) { if ($filesize == 0) { $str = sprintf("\rUnknown filesize.. %2d kb done..", $bytes_transferred / 1024); consoleLog($str, true); } else { consoleLogProgressBar($bytes_transferred, $filesize); } } break; } }
function ExtractSWF($filename) { $swfID = basename($filename, ".swf"); consoleLog("<b>Extract SWF: " . $swfID . ".swf</b>"); consoleLogBlank(); checkDIR(OUTPUT_DIRECTORY . $swfID); $raw = file_get_contents_with_console($filename); if ($raw === false) { return false; } if (substr($raw, 0, 3) == 'CWS') { $raw = 'F' . substr($raw, 1, 7) . gzuncompress(substr($raw, 8)); } list(, $file_length) = unpack('V', substr($raw, 4, 4)); $header_length = 8 + 1 + ceil(((ord($raw[8]) >> 3) * 4 - 3) / 8) + 4; $symbols = []; $pngs = []; $xmls = []; consoleLog("Analyzing SWF..."); for ($cursor = $header_length; $cursor < $file_length;) { consoleLogProgressBar($cursor, $file_length); list(, $tag_header) = unpack('v', substr($raw, $cursor, 2)); $cursor += 2; list($tag_code, $tag_length) = [$tag_header >> 6, $tag_header & 0x3f]; if ($tag_length == 0x3f) { list(, $tag_length) = unpack('V', substr($raw, $cursor, 4)); $cursor += 4; } switch ($tag_code) { case 36: if ($swfID != "Habbo") { $tag = SWFREAD_PNG(substr($raw, $cursor, $tag_length)); $pngs[$tag['symbol_id']] = $tag['im']; } break; case 76: $symbols = SWFREAD_SYM(substr($raw, $cursor, $tag_length)); break; case 87: $tag = SWFREAD_BIN(substr($raw, $cursor, $tag_length)); $xmls[$tag['symbol_id']] = $tag['data']; break; } $cursor += $tag_length; } consoleLogProgressBar($file_length, $file_length); consoleLogBlank(); consoleLogBlank(); consoleLog("Analyzing XML..."); $cnt = 0; $xmls_length = count($xmls); foreach ($xmls as $symbol_id => $xml) { $cnt++; consoleLogProgressBar($cnt, $xmls_length, "items"); $name = isset($symbols[$symbol_id]) ? $symbols[$symbol_id] : 'symbol_' . $symbol_id; $_xml = @simplexml_load_string($xml); if ($_xml !== false) { $_name = $_xml->getName(); if (($_name == "animationSet" || $_name == "geometry" || $_name == "partSets" || $_name == "actions") && $swfID == "Habbo") { switch ($_name) { case "animationSet": $name = "HabboAvatarAnimation"; ExtractAvatarAnimation($_xml); break; case "geometry": $name = "HabboAvatarGeometry"; ExtractAvatarGeometry($_xml); break; case "partSets": $name = "HabboAvatarPartSets"; ExtractAvatarPartSets($_xml); break; case "actions": $name = "HabboAvatarActions"; ExtractAvatarActions($_xml); break; case "figuredata": $name = "HabboAvatarFigure_" . $symbol_id; ExtractFigureData($_xml, $name . ".json"); } } elseif ($_name == "manifest" && $swfID != "Habbo") { ExtractCastOffset($_xml); } //file_put_contents(OUTPUT_DIRECTORY.$swfID.'/'.$name.'.xml', $xml); } else { //file_put_contents(OUTPUT_DIRECTORY.$swfID.'/'.$name.'.dat', $xml); } } consoleLogBlank(); consoleLogBlank(); consoleLog("Extracting image cast files..."); $cnt = 0; $pngs_length = count($pngs); foreach ($pngs as $symbol_id => $png) { $cnt++; consoleLogProgressBar($cnt, $pngs_length, "images"); $name = isset($symbols[$symbol_id]) ? $symbols[$symbol_id] : 'symbol_' . $symbol_id; ob_start(); imagepng($png); $image_data = ob_get_contents(); ob_end_clean(); file_put_contents(OUTPUT_DIRECTORY . $swfID . '/' . $name . '.png', $image_data); if (strpos($name, 'hh_human_item_h_') === 0) { pushItemSet($name); } //consoleLog('<img src="data:image/png;base64,'.base64_encode($image_data).'"> '); } consoleLogBlank(); consoleLogBlank(); }