get_backgrounds() as $file) self::blacken_image($file); } public static function remove_videos(osu_library $library) { foreach ($library->get_videos() as $file) { if (file_exists($file)) unlink($file); } } public static function remove_storyboards(osu_library $library) : void { // exclude vital files if they are used in the storyboard $storyboards_safe = $library->get_storyboards(); $storyboards_safe = array_diff($storyboards_safe, $library->get_backgrounds()); $storyboards_safe = array_diff($storyboards_safe, $library->get_audiofiles()); foreach ($storyboards_safe as $file) { if (file_exists($file)) unlink($file); } foreach ($library->get_osb_files() as $file) { if (file_exists($file)) unlink($file); } } private static function build_removand_sublist(array &$queue, string $folder, bool $single_level = false) { foreach (glob(utils::globsafe($folder) . "/*") as $file) { if (is_dir($file)) { if (!$single_level) self::build_removand_sublist($queue, $file, false); // recursion } else { $queue[] = $file; } } } public static function build_removand_list(osu_library $library, bool $single_level = false) : array { $queue = array(); foreach ($library->get_folders() as $folder) { self::build_removand_sublist($queue, $folder, $single_level); } return $queue; } public static function build_excluded_list(osu_library $library, array $except = array()) : array { if (in_array("backgrounds", $except)) $background_files = array(); else $background_files = $library->get_backgrounds(); if (in_array("videos", $except)) $video_files = array(); else $video_files = $library->get_videos(); if (in_array("audio", $except)) $audio_files = array(); else $audio_files = $library->get_audiofiles(); $essential_excluded = array_merge($background_files, $video_files, $audio_files); if (in_array("osu", $except) ||in_array("osb", $except)) { if (in_array("osu", $except)) $osu_files = array(); else $osu_files = $library->get_osu_files(); if (in_array("osb", $except)) $osb_files = array(); else $osb_files = $library->get_osb_files(); $physical_excluded = array_merge($osu_files, $osb_files); } else { if (in_array("parsed", $except)) $physical_excluded = array(); else $physical_excluded = $library->get_parsed_files(); } if (in_array("storyboard", $except)) $storyboard_files = array(); else $storyboard_files = $library->get_storyboards(); if (in_array("hitsounds", $except)) $hitsound_files = array(); else $hitsound_files = $library->get_hitsounds(); $other_excluded = array_merge($storyboard_files, $hitsound_files); return array_merge($essential_excluded, $physical_excluded, $other_excluded); } public static function cut_extension(string $path) : string { $directory = pathinfo($path, PATHINFO_DIRNAME) ?? ""; if (!empty($directory)) $directory .= "/"; // append slash if set return $directory . (pathinfo($path, PATHINFO_FILENAME) ?? ""); } // because peppy thinks file extensions are wildcards: // you can have image.mp3 in storyboards in jfif // and you can have ogg vorbis hitsounds in mysound.wav.png.whatever public static function array_diff_ver_peppy(array &$files, array &$exclusions) : array { // osu! is case insensitive $files_lowercase = array(); foreach ($files as $key => $value) { $files_lowercase[$key] = self::cut_extension(mb_strtolower($value)); } $exclusions_lowercase = array(); foreach ($exclusions as $key => $value) { $exclusions_lowercase[$key] = self::cut_extension(mb_strtolower($value)); } // return values from the original, but only the ones that did not get removed return array_intersect_key($files, array_diff($files_lowercase, $exclusions_lowercase)); } public static function remove_skins(osu_library $library) : void { $removand = self::build_removand_list($library, true); $exclusions = self::build_excluded_list($library); $junk_files = self::array_diff_ver_peppy($removand, $exclusions); foreach ($junk_files as $file) { if (self::is_skinnable_image($file) || self::is_skinnable_other($file)) { if (file_exists($file)) unlink($file); } } } public static function remove_hitsounds(osu_library $library) : void { $removand = self::build_removand_list($library, true); $exclusions = self::build_excluded_list($library, [ "hitsounds" ]); $junk_files = self::array_diff_ver_peppy($removand, $exclusions); foreach ($junk_files as $file) { if (self::is_skinnable_sound($file)) { if (file_exists($file)) unlink($file); } } $hitsounds_safe = $library->get_hitsounds(); $hitsounds_safe = array_diff($hitsounds_safe, $library->get_audiofiles()); foreach ($hitsounds_safe as $file) { if (file_exists($file)) unlink($file); } } public static function full_nuke(osu_library $library) : void { self::remove_other($library, true); } public static function remove_other(osu_library $library, bool $nuke = false) : void { if ($nuke) { $excluded_arg = [ "videos", "osb", "storyboard", "hitsounds" ]; } else { $excluded_arg = array(); } $removand = self::build_removand_list($library); $exclusions = self::build_excluded_list($library, $excluded_arg); $junk_files = self::array_diff_ver_peppy($removand, $exclusions); foreach ($junk_files as $file) { if (!$nuke && self::is_skinnable($file)) continue; // ignore default hitsounds if (file_exists($file)) unlink($file); } } public static function repack_all(osu_library $library) : void { foreach ($library->get_library() as $key => $mapset) { self::repack($library, $mapset["key"]); } } public static function repack(osu_library $library, string $key) : string { $path = $library->get_library()[$key]["path"] ?? ""; if (!file_exists($path)) return ""; $name = "session/osz/" . basename($path) . ".osz"; if (file_exists($name)) return $name; $zip = new ZipArchive; try { $zip->open($name, ZipArchive::CREATE); utils::recursive_zip_map($zip, $path, $path); } catch (Exception $e) { return ""; } finally { $zip->close(); } return $name; } public static function cleanup_dir(string $dir, bool $recursion = false) : void { $dir = rtrim(str_replace("\\", "/", $dir), "/"); $glob = glob(utils::globsafe($dir) . "/*"); foreach ($glob as $file) { if (is_dir($file) && $recursion) { self::cleanup_dir($file, true); @rmdir($file); } else { unlink($file); } } } }