OSDN Git Service

先制対潜の判定を最新の検証結果に合わせる
[kancollesniffer/KancolleSniffer.git] / KancolleSniffer / Log / LogProcessor.cs
1 // Copyright (C) 2018 Kazuhiro Fujieda <fujieda@users.osdn.me>\r
2 //\r
3 // Licensed under the Apache License, Version 2.0 (the "License");\r
4 // you may not use this file except in compliance with the License.\r
5 // You may obtain a copy of the License at\r
6 //\r
7 //    http://www.apache.org/licenses/LICENSE-2.0\r
8 //\r
9 // Unless required by applicable law or agreed to in writing, software\r
10 // distributed under the License is distributed on an "AS IS" BASIS,\r
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
12 // See the License for the specific language governing permissions and\r
13 // limitations under the License.\r
14 \r
15 using System;\r
16 using System.Collections.Generic;\r
17 using System.Globalization;\r
18 using System.IO;\r
19 using System.Linq;\r
20 using KancolleSniffer.Model;\r
21 \r
22 namespace KancolleSniffer.Log\r
23 {\r
24     public class LogProcessor\r
25     {\r
26         private readonly MaterialCount[] _materialCount;\r
27         private readonly BattleLogProcessor _battleLogProcessor;\r
28 \r
29         public LogProcessor(MaterialCount[] materialCount = null, Dictionary<string, string> mapDictionary = null)\r
30         {\r
31             _materialCount = materialCount ?? new MaterialCount[0];\r
32             _battleLogProcessor = new BattleLogProcessor(mapDictionary);\r
33         }\r
34 \r
35         public IEnumerable<string> Process(IEnumerable<string> lines, string path, DateTime from, DateTime to,\r
36             bool number, DateTime now = default)\r
37         {\r
38             var fields = 0;\r
39             var battle = false;\r
40             var material = false;\r
41             switch (Path.GetFileNameWithoutExtension(path))\r
42             {\r
43                 case "遠征報告書":\r
44                     fields = 10;\r
45                     break;\r
46                 case "改修報告書":\r
47                     fields = 15;\r
48                     break;\r
49                 case "海戦・ドロップ報告書":\r
50                     fields = 40;\r
51                     battle = true;\r
52                     break;\r
53                 case "開発報告書":\r
54                     fields = 9;\r
55                     break;\r
56                 case "建造報告書":\r
57                     fields = 12;\r
58                     break;\r
59                 case "資材ログ":\r
60                     fields = 9;\r
61                     material = true;\r
62                     break;\r
63                 case "戦果":\r
64                     fields = 3;\r
65                     break;\r
66             }\r
67             var delimiter = "";\r
68             foreach (var line in lines)\r
69             {\r
70                 var data = line.Split(',');\r
71                 var date = ParseDateTime(data[0]);\r
72                 if (date == default)\r
73                     continue;\r
74                 if (to < date)\r
75                     yield break;\r
76                 if (date < from)\r
77                     continue;\r
78                 data[0] = Logger.FormatDateTime(date);\r
79                 var entries = data;\r
80                 if (material)\r
81                     entries = data.Take(fields).ToArray();\r
82                 if (battle)\r
83                     entries = _battleLogProcessor.Process(data);\r
84                 if (entries.Length != fields)\r
85                     continue;\r
86                 var result =\r
87                     number\r
88                         ? delimiter + "[" + JavaScriptTicks(date) + "," + string.Join(",", entries.Skip(1)) + "]"\r
89                         : delimiter + "[\"" + string.Join("\",\"", entries) + "\"]";\r
90                 delimiter = ",\n";\r
91                 yield return result;\r
92             }\r
93             if (material && !number) // 資材の現在値を出力する\r
94                 yield return delimiter + "[\"" + Logger.FormatDateTime(now) + "\",\"" +\r
95                              string.Join("\",\"", _materialCount.Select(c => c.Now)) + "\"]";\r
96         }\r
97 \r
98         private DateTime ParseDateTime(string dateTime)\r
99         {\r
100             if (DateTime.TryParseExact(dateTime, Logger.DateTimeFormat, CultureInfo.InvariantCulture,\r
101                 DateTimeStyles.AssumeLocal, out var date))\r
102             {\r
103                 return date;\r
104             }\r
105             // システムが和暦に設定されていて和暦が出力されてしまったケースを救う\r
106             if (dateTime[2] == '-')\r
107             {\r
108                 if (!int.TryParse(dateTime.Substring(0, 2), out var year))\r
109                     return default;\r
110                 dateTime = 1988 + year + dateTime.Substring(2);\r
111                 return DateTime.TryParseExact(dateTime, Logger.DateTimeFormat, CultureInfo.InvariantCulture,\r
112                     DateTimeStyles.AssumeLocal, out date)\r
113                     ? date\r
114                     : default;\r
115             }\r
116             return DateTime.TryParse(dateTime, CultureInfo.CurrentCulture, DateTimeStyles.AssumeLocal, out date)\r
117                 ? date\r
118                 : default;\r
119         }\r
120 \r
121         private long JavaScriptTicks(DateTime date) =>\r
122             (date.ToUniversalTime().Ticks - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks) /\r
123             TimeSpan.TicksPerMillisecond;\r
124     }\r
125 }