New parser functional enough

This commit is contained in:
2020-12-26 12:21:42 +01:00
parent 984e4f0572
commit 51cb4508ac
6 changed files with 62 additions and 31 deletions
+13 -4
View File
@@ -8,6 +8,7 @@ class osu_cacher
{ {
$this->root = $root; $this->root = $root;
$this->cache_root = $cache_root; $this->cache_root = $cache_root;
if (!file_exists($cache_root)) mkdir($cache_root, 0777, true);
} }
public function get_root() : string public function get_root() : string
@@ -30,21 +31,29 @@ class osu_cacher
return file_exists($this->get_cached_path($path)); 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)); $raw = file_get_contents($this->get_cached_path($path));
$json = json_decode($raw, true); $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; return $json;
} }
public function set_cache(string $path, array $content) : void 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); $encoded = json_encode($content);
file_put_contents($this->get_cached_path($path), $encoded); file_put_contents($cache_path, $encoded);
} }
} }
+15 -5
View File
@@ -6,6 +6,7 @@ class osu_library
{ {
private static $song_library_folder = "Songs"; private static $song_library_folder = "Songs";
private static $db_file_location = "session/optimizer_data.json"; private static $db_file_location = "session/optimizer_data.json";
private static $cache_root = "session/cache";
private $db; private $db;
@@ -22,7 +23,11 @@ class osu_library
$this->set_root($root); // update db entry $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); $this->scan_add_folder($folder);
} }
@@ -30,11 +35,11 @@ class osu_library
public function rescan_library(string $root) : void public function rescan_library(string $root) : void
{ {
$this->clear_library_cache(); $this->clear_library();
$this->scan_library($root); $this->scan_library($root);
} }
private function clear_library_cache() : void private function clear_library() : void
{ {
unset($this->db["library"]); unset($this->db["library"]);
} }
@@ -50,9 +55,12 @@ class osu_library
$osb_glob = glob(utils::globsafe($folder) . "/*.osb"); $osb_glob = glob(utils::globsafe($folder) . "/*.osb");
$glob = array_merge($osu_glob, $osb_glob); $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) foreach ($glob as $file)
{ {
$difficulty = osu_parser::parse_osu_file_format($file); $difficulty = $parser->parse_osu_file_format($file);
$difficulty["key"] = basename($file); $difficulty["key"] = basename($file);
$difficulty["path"] = $file; $difficulty["path"] = $file;
@@ -71,7 +79,9 @@ class osu_library
// if (!isset($this->db["library"])) $this->db["library"] = array(); // 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; $this->db["library"][$key] = $entry;
} }
+7 -7
View File
@@ -20,7 +20,7 @@ class osu_old_parser
foreach ($file as $key => $line) 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); $current_section = str_replace([ "[", "]" ], "", $line);
if (!isset($osu[$current_section])) if (!isset($osu[$current_section]))
@@ -73,15 +73,15 @@ class osu_old_parser
if ($skip) continue; 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") 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)); $value = mb_substr($line, $delimiter_position + strlen($delimiter_position));
$osu[$current_section][substr($line, 0, $delimiter_position)] = $value; $osu[$current_section][mb_substr($line, 0, $delimiter_position)] = $value;
} }
else if ($section_type == "lists") else if ($section_type == "lists")
{ {
@@ -90,7 +90,7 @@ class osu_old_parser
// group events by type and start time // group events by type and start time
if ($current_section == "Events") 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 // event types: https://github.com/ppy/osu/blob/master/osu.Game/Beatmaps/Legacy/LegacyEventType.cs
$list[0] = str_replace( $list[0] = str_replace(
@@ -199,7 +199,7 @@ class osu_old_parser
$current_section = "UnofficialComments"; $current_section = "UnofficialComments";
foreach ($file as $key => $line) 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); $current_section = str_replace([ "[", "]" ], "", $line);
continue; continue;
+18 -8
View File
@@ -48,7 +48,7 @@ class osu_parser
$parsed = array(); $parsed = array();
// file format declaration // 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" // the ranker script had a bug where random "ZERO WIDTH NO-BREAK SPACE"
// characters were at beginning of the .osu files // characters were at beginning of the .osu files
@@ -61,17 +61,19 @@ class osu_parser
} }
$current_section = false; $current_section = false;
$section_type = false;
$delimiter = false;
$needed_sections = [ "General", "Metadata", "Difficulty", "Events" ]; $needed_sections = [ "General", "Metadata", "Difficulty", "Events" ];
foreach ($file as $key => $line) 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); list($current_section, $section_type, $delimiter) = self::parse_osu_file_section_header($line, $needed_sections);
continue; // this line has been analyzed 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) $section_type === false)
{ {
} }
@@ -80,20 +82,24 @@ class osu_parser
// init empty array // init empty array
if (!isset($parsed[$current_section])) $parsed[$current_section] = 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); // old maps had random lines and lines with different delimiters (why?)
$kv_value = substr($line, $delimiter_position + strlen($delimiter_position)); 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 // after some thinking, keeping the original names was a good idea
$parsed[$current_section][$kv_key] = $kv_value; $parsed[$current_section][$kv_key] = $kv_value;
} }
}
else if ($section_type == "lists") else if ($section_type == "lists")
{ {
$list = explode($delimiter, $line); $list = explode($delimiter, $line);
if ($current_section == "Events") // saving the whole thing would take up too much space 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); list($event_type, $source_files) = self::gather_source_files($list);
@@ -136,6 +142,10 @@ class osu_parser
} }
unset($file); // remove the memory leak unset($file); // remove the memory leak
$time_end = microtime(true);
$parsing_time = $time_end - $time_start;
$parsed["parsing_time"] = $parsing_time;
if (!$skip_cache) if (!$skip_cache)
{ {
$this->cacher->set_cache($path, $parsed); $this->cacher->set_cache($path, $parsed);
@@ -146,7 +156,7 @@ class osu_parser
public static function gather_source_files(array $list) : array 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]; $event_type = $list[0];
if (!in_array($event_type, [ "0", "1", "4", "5", "6" ])) if (!in_array($event_type, [ "0", "1", "4", "5", "6" ]))
+5 -4
View File
@@ -2,6 +2,7 @@
// todo: whitelist / blacklist // todo: whitelist / blacklist
// todo: repack osz file // todo: repack osz file
set_time_limit(300000); set_time_limit(300000);
ini_set('memory_limit', '1024M');
require_once "libraries/osu_library.php"; require_once "libraries/osu_library.php";
require_once "libraries/optimizer.php"; require_once "libraries/optimizer.php";
@@ -67,10 +68,10 @@ foreach ($lib->get_library() as $set)
{ {
foreach ($set["difficulties"] as $map) foreach ($set["difficulties"] as $map)
{ {
$proc_time += $map["process_time"]; $proc_time += $map["parsing_time"] ?? 0;
} }
} }
echo "<h3>Process time: " . $proc_time . " seconds</h3>"; echo "<h3>Parse time: " . $proc_time . " seconds</h3>";
// foreach ($lib->get_library() as $mapset) // foreach ($lib->get_library() as $mapset)
// { // {
// echo '<div class="beatmapset">'; // echo '<div class="beatmapset">';
@@ -80,8 +81,8 @@ echo "<h3>Process time: " . $proc_time . " seconds</h3>";
// echo '</h2>'; // echo '</h2>';
// foreach ($mapset["difficulties"] as $beatmap) // foreach ($mapset["difficulties"] as $beatmap)
// { // {
// $beatmap["format-2"] = substr($beatmap["format"] ?? "v1", 1); // $beatmap["format-2"] = mb_substr($beatmap["format"] ?? "v1", 1);
// if (is_numeric(substr($beatmap["format"] ?? "v1", 1))) // if (is_numeric(mb_substr($beatmap["format"] ?? "v1", 1)))
// { // {
// echo '<div class="beatmap">'; // echo '<div class="beatmap">';
// echo '<h3>Title: ' . $beatmap["title"]; // echo '<h3>Title: ' . $beatmap["title"];
+1
View File
@@ -2,5 +2,6 @@
<head> <head>
<title>osu! Optimizer by Thayol</title> <title>osu! Optimizer by Thayol</title>
<style>{{ STYLE }}</style> <style>{{ STYLE }}</style>
<meta charset="UTF-8">
</head> </head>
<body id="body"> <body id="body">