diff --git a/libraries/osu_cacher.php b/libraries/osu_cacher.php index eca44a2..16d1236 100644 --- a/libraries/osu_cacher.php +++ b/libraries/osu_cacher.php @@ -8,6 +8,7 @@ class osu_cacher { $this->root = $root; $this->cache_root = $cache_root; + if (!file_exists($cache_root)) mkdir($cache_root, 0777, true); } public function get_root() : string @@ -30,21 +31,29 @@ class osu_cacher return file_exists($this->get_cached_path($path)); } - public function get_cached(string $path, $hash=false)// : array|bool // see you again in php8 + public function get_cache(string $path, $hash=false)// : array|bool // see you again in php8 { - if (!is_cached($path)) return false; + if (!$this->is_cached($path)) return false; $raw = file_get_contents($this->get_cached_path($path)); $json = json_decode($raw, true); - if ($hash !== false && $hash != $json["hash"]) return false; // hash check failed + if (empty($json)) return false; // cache had empty save + + if ($hash !== false && $hash != ($json["hash"] ?? false)) return false; // hash check failed return $json; } public function set_cache(string $path, array $content) : void { + $cache_path = $this->get_cached_path($path); + $cache_dir = dirname($cache_path); + if (!file_exists($cache_dir)) mkdir($cache_dir, 0777, true); + + if (!isset($content["hash"])) $content["hash"] = hash_file("md5", $path); + $encoded = json_encode($content); - file_put_contents($this->get_cached_path($path), $encoded); + file_put_contents($cache_path, $encoded); } } \ No newline at end of file diff --git a/libraries/osu_library.php b/libraries/osu_library.php index b77a894..e610ae1 100644 --- a/libraries/osu_library.php +++ b/libraries/osu_library.php @@ -6,6 +6,7 @@ class osu_library { private static $song_library_folder = "Songs"; private static $db_file_location = "session/optimizer_data.json"; + private static $cache_root = "session/cache"; private $db; @@ -22,7 +23,11 @@ class osu_library $this->set_root($root); // update db entry - foreach(glob($this->get_library_folder() . "/*", GLOB_ONLYDIR) as $folder) + $this->clear_library(); + $glob = glob($this->get_library_folder() . "/*", GLOB_ONLYDIR); + + natsort($glob); // i like wasting your processing power + foreach($glob as $folder) { $this->scan_add_folder($folder); } @@ -30,11 +35,11 @@ class osu_library public function rescan_library(string $root) : void { - $this->clear_library_cache(); + $this->clear_library(); $this->scan_library($root); } - private function clear_library_cache() : void + private function clear_library() : void { unset($this->db["library"]); } @@ -50,9 +55,12 @@ class osu_library $osb_glob = glob(utils::globsafe($folder) . "/*.osb"); $glob = array_merge($osu_glob, $osb_glob); + $cacher = new osu_cacher($this->get_library_folder(), self::$cache_root); + $parser = new osu_parser($cacher); + foreach ($glob as $file) { - $difficulty = osu_parser::parse_osu_file_format($file); + $difficulty = $parser->parse_osu_file_format($file); $difficulty["key"] = basename($file); $difficulty["path"] = $file; @@ -71,7 +79,9 @@ class osu_library // if (!isset($this->db["library"])) $this->db["library"] = array(); - $this->db["library"] = array(); // init or reset + // init empty + if (!isset($this->db["library"])) $this->db["library"] = array(); + $this->db["library"][$key] = $entry; } diff --git a/libraries/osu_old_parser.php b/libraries/osu_old_parser.php index b2d157b..c30834f 100644 --- a/libraries/osu_old_parser.php +++ b/libraries/osu_old_parser.php @@ -20,7 +20,7 @@ class osu_old_parser foreach ($file as $key => $line) { - if (strpos($line, "[") === 0 && strpos($line, "]") === (strlen($line)-1)) + if (mb_strpos($line, "[") === 0 && mb_strpos($line, "]") === (strlen($line)-1)) { $current_section = str_replace([ "[", "]" ], "", $line); if (!isset($osu[$current_section])) @@ -73,15 +73,15 @@ class osu_old_parser if ($skip) continue; - if (strpos($line, "//") === 0) // there were commented files that broke my script + if (mb_strpos($line, "//") === 0) // there were commented files that broke my script { } else if ($section_type == "key-value pairs") { - $delimiter_position = strpos($line, $delimiter); + $delimiter_position = mb_strpos($line, $delimiter); - $value = substr($line, $delimiter_position + strlen($delimiter_position)); - $osu[$current_section][substr($line, 0, $delimiter_position)] = $value; + $value = mb_substr($line, $delimiter_position + strlen($delimiter_position)); + $osu[$current_section][mb_substr($line, 0, $delimiter_position)] = $value; } else if ($section_type == "lists") { @@ -90,7 +90,7 @@ class osu_old_parser // group events by type and start time if ($current_section == "Events") { - if (strpos($line, " ") === 0) continue; // skip storyboard details lines + if (mb_strpos($line, " ") === 0) continue; // skip storyboard details lines // event types: https://github.com/ppy/osu/blob/master/osu.Game/Beatmaps/Legacy/LegacyEventType.cs $list[0] = str_replace( @@ -199,7 +199,7 @@ class osu_old_parser $current_section = "UnofficialComments"; foreach ($file as $key => $line) { - if (strpos($line, "[") === 0 && strpos($line, "]") === (strlen($line)-1)) + if (mb_strpos($line, "[") === 0 && mb_strpos($line, "]") === (strlen($line)-1)) { $current_section = str_replace([ "[", "]" ], "", $line); continue; diff --git a/libraries/osu_parser.php b/libraries/osu_parser.php index 2213f6a..184f004 100644 --- a/libraries/osu_parser.php +++ b/libraries/osu_parser.php @@ -48,7 +48,7 @@ class osu_parser $parsed = array(); // file format declaration - if (stripos($file[0], "osu file format ") === false) + if (stripos($file[0], "osu file format ") !== false) { // the ranker script had a bug where random "ZERO WIDTH NO-BREAK SPACE" // characters were at beginning of the .osu files @@ -61,17 +61,19 @@ class osu_parser } $current_section = false; + $section_type = false; + $delimiter = false; $needed_sections = [ "General", "Metadata", "Difficulty", "Events" ]; foreach ($file as $key => $line) { - if (strpos($line, "[") === 0 && strpos($line, "]") === (strlen($line)-1)) + if (mb_strpos($line, "[") === 0 && mb_strpos($line, "]") === (strlen($line)-1)) { list($current_section, $section_type, $delimiter) = self::parse_osu_file_section_header($line, $needed_sections); continue; // this line has been analyzed } - if (strpos($line, "//") === 0 || // the editor puts hella lot of comments in the files + if (mb_strpos($line, "//") === 0 || // the editor puts hella lot of comments in the files $section_type === false) { } @@ -80,20 +82,24 @@ class osu_parser // init empty array if (!isset($parsed[$current_section])) $parsed[$current_section] = array(); - $delimiter_position = strpos($line, $delimiter); + $delimiter_position = mb_strpos($line, $delimiter); - $kv_key = substr($line, 0, $delimiter_position); - $kv_value = substr($line, $delimiter_position + strlen($delimiter_position)); - - // after some thinking, keeping the original names was a good idea - $parsed[$current_section][$kv_key] = $kv_value; + // old maps had random lines and lines with different delimiters (why?) + if ($delimiter_position !== false) + { + $kv_key = mb_substr($line, 0, $delimiter_position); + $kv_value = mb_substr($line, $delimiter_position + strlen($delimiter)); + + // after some thinking, keeping the original names was a good idea + $parsed[$current_section][$kv_key] = $kv_value; + } } else if ($section_type == "lists") { $list = explode($delimiter, $line); if ($current_section == "Events") // saving the whole thing would take up too much space { - if (strpos($line, " ") === 0 || strpos($line, "_") === 0) continue; // skip storyboard details lines + if (mb_strpos($line, " ") === 0 || mb_strpos($line, "_") === 0) continue; // skip storyboard details lines list($event_type, $source_files) = self::gather_source_files($list); @@ -136,6 +142,10 @@ class osu_parser } unset($file); // remove the memory leak + $time_end = microtime(true); + $parsing_time = $time_end - $time_start; + $parsed["parsing_time"] = $parsing_time; + if (!$skip_cache) { $this->cacher->set_cache($path, $parsed); @@ -146,7 +156,7 @@ class osu_parser public static function gather_source_files(array $list) : array { - $list[0] = convert_event_type($list[0]); + $list[0] = self::convert_event_type($list[0]); $event_type = $list[0]; if (!in_array($event_type, [ "0", "1", "4", "5", "6" ])) diff --git a/main.php b/main.php index 58036e0..b542732 100644 --- a/main.php +++ b/main.php @@ -2,6 +2,7 @@ // todo: whitelist / blacklist // todo: repack osz file set_time_limit(300000); +ini_set('memory_limit', '1024M'); require_once "libraries/osu_library.php"; require_once "libraries/optimizer.php"; @@ -67,10 +68,10 @@ foreach ($lib->get_library() as $set) { foreach ($set["difficulties"] as $map) { - $proc_time += $map["process_time"]; + $proc_time += $map["parsing_time"] ?? 0; } } -echo "

Process time: " . $proc_time . " seconds

"; +echo "

Parse time: " . $proc_time . " seconds

"; // foreach ($lib->get_library() as $mapset) // { // echo '
'; @@ -80,8 +81,8 @@ echo "

Process time: " . $proc_time . " seconds

"; // echo ''; // foreach ($mapset["difficulties"] as $beatmap) // { - // $beatmap["format-2"] = substr($beatmap["format"] ?? "v1", 1); - // if (is_numeric(substr($beatmap["format"] ?? "v1", 1))) + // $beatmap["format-2"] = mb_substr($beatmap["format"] ?? "v1", 1); + // if (is_numeric(mb_substr($beatmap["format"] ?? "v1", 1))) // { // echo '
'; // echo '

Title: ' . $beatmap["title"]; diff --git a/resources/start.html b/resources/start.html index 267584f..cb608c9 100644 --- a/resources/start.html +++ b/resources/start.html @@ -2,5 +2,6 @@ osu! Optimizer by Thayol + \ No newline at end of file