OSDN Git Service

[feature]スコアDBのdead_placeカラムに死亡場所を記録する
[hengband/web.git] / score / dump_file.inc
index e0a85f8..72ec4c6 100644 (file)
@@ -3,6 +3,7 @@ class DumpFile
 {
     public function __construct($score_id) {
         $this->score_id = $score_id;
+        $this->dump_lines = NULL;
     }
 
 
@@ -34,7 +35,7 @@ class DumpFile
         header("Etag: ".$etag);
         header("Content-Type: ".$content_type);
 
-        if ($content_encoding !== FALSE) {
+        if ($content_encoding !== NULL) {
             header("Content-Encoding: ".$content_encoding);
             echo $contents;
         } else {
@@ -45,7 +46,7 @@ class DumpFile
 
     public function save($dir, $ext, $contents)
     {
-        if ($outputs === FALSE) return;
+        if ($contents === FALSE) return;
 
         umask(2); // Group書き込み権限許可
 
@@ -77,20 +78,41 @@ class DumpFile
 
 
     /**
+     * キャラクタダンプを配列に読み込む
+     * 読み込んだ配列はメンバ変数dump_linesに格納
+     *
+     * @return boolean 読み込みに成功した場合TRUE、失敗した場合FALSE
+     */
+    private function readlines()
+    {
+        if ($this->dump_lines !== NULL) {
+            return TRUE;
+        }
+
+        $lines = gzfile($this->get_filename('dumps', 'txt'));
+        if ($lines !== FALSE) {
+            $this->dump_lines = $lines;
+            return TRUE;
+        }
+
+        return FALSE;
+    }
+
+
+    /**
      * キャラクタダンプの死ぬ直前のメッセージもしくは勝利メッセージを取得する
      *
      * @return array 死ぬ直前のメッセージもしくは勝利メッセージを1行1要素にした文字列の配列
      */
     public function get_last_message()
     {
-        $zp = gzopen($this->get_filename('dumps', 'txt'), 'r');
-        if ($zp === FALSE) return [];
+        if ($this->readlines() === FALSE) {
+            return [];
+        }
 
         $in_message = FALSE;
         $result = [];
-        while (!gzeof($zp)) {
-            $line = gzgets($zp);
-
+        foreach ($this->dump_lines as $line) {
             if (preg_match('/^\s*\[(.*)\]\s*$/u', $line, $matches)) {
                 if ($matches[1] == '*勝利*メッセージ' ||
                     $matches[1] == '死ぬ直前のメッセージ') {
@@ -109,6 +131,57 @@ class DumpFile
         return $result;
     }
 
+
+    /**
+     * キャラクタダンプから死因の詳細を得る
+     *
+     * @return string 死因の詳細を表す文字列
+     */
+    public function get_death_reason_detail()
+    {
+        if ($this->readlines() === FALSE) {
+            return FALSE;
+        }
+
+        $death_reason_lines = array_slice($this->dump_lines, 30, 3);
+        $death_reason = implode("", array_map('trim', $death_reason_lines));
+
+        if (preg_match("/^…あなたは、?(.+)。/u", $death_reason, $matches)) {
+            return $matches[1];
+        } else {
+            return FALSE;
+        }
+    }
+
+
+    /**
+     * キャラクタダンプから死んだ場所を得る
+     *
+     * @return string|FALSE 死んだ場所を表す文字列。
+     *                死んだ場所が得られなかった場合FALSE。
+     */
+    public function get_dead_place()
+    {
+
+        $death_reason_detail = $this->get_death_reason_detail();
+        if ($death_reason_detail === FALSE) {
+            return FALSE;
+        }
+        $places = implode("|", [
+            "階", "荒野", "地上", "街",
+            "辺境の地", "モリバント", "アングウィル", "テルモラ", "ズル",
+            "クエスト「.+」", "クエスト",
+        ]);
+
+        if (preg_match("/^(.*(?:{$places})\s*)で.+$/u",
+                        $death_reason_detail, $matches)) {
+            return $matches[1];
+        } else {
+            return FALSE;
+        }
+    }
+
+
     private static function browser_accept_encodings()
     {
         $accept_encoding = filter_input(INPUT_SERVER, 'HTTP_ACCEPT_ENCODING');
@@ -124,8 +197,7 @@ class DumpFile
             self::browser_accept_encodings(),
             ['gzip', 'x-gzip']);
 
-        return count($supported_gzip_encodings) > 0 ?
-            $supported_gzip_encodings[0] : FALSE;
+        return array_shift($supported_gzip_encodings);
     }
 
 }