// See the License for the specific language governing permissions and\r
// limitations under the License.\r
\r
+using System.Collections.Generic;\r
using System.Linq;\r
using ExpressionToCodeLib;\r
using KancolleSniffer.Log;\r
input[37] = "制空権確保";\r
var result = new BattleLogProcessor().Process(input);\r
PAssert.That(() => result[5] == "T字有利");\r
- PAssert.That(() => result[23] == "龍鳳改(Lv97)・夕立改(Lv148)");\r
- PAssert.That(() => result[38] == "確保");\r
+ PAssert.That(() => result[37] == "確保");\r
+ PAssert.That(() => result[38] == "龍鳳改(Lv97)・夕立改(Lv148)");\r
}\r
\r
[TestMethod]\r
input[37] = "航空劣勢";\r
var result = new BattleLogProcessor().Process(input);\r
PAssert.That(() => result[6] == "第四警戒");\r
- PAssert.That(() => result[23] == "龍鳳改(Lv97)・夕立改(Lv148)");\r
- PAssert.That(() => result[38] == "劣勢");\r
+ PAssert.That(() => result[37] == "劣勢");\r
+ PAssert.That(() => result[38] == "龍鳳改(Lv97)・夕立改(Lv148)");\r
+\r
}\r
\r
[TestMethod]\r
input[13] = "・夕立改(Lv148)";\r
input[14] = "・5/36";\r
var result = new BattleLogProcessor().Process(input);\r
- PAssert.That(() => result[23] == "龍鳳改(Lv97)・夕立改(Lv148)");\r
+ PAssert.That(() => result[38] == "龍鳳改(Lv97)・夕立改(Lv148)");\r
}\r
\r
[TestMethod]\r
input[12] = "2/11";\r
var result = new BattleLogProcessor().Process(input);\r
PAssert.That(() => result[11] == "Luigi Torelli(Lv7)");\r
- PAssert.That(() => result[23] == "Luigi Torelli(Lv7)");\r
+ PAssert.That(() => result[38] == "Luigi Torelli(Lv7)");\r
}\r
\r
[TestMethod]\r
var result = new BattleLogProcessor().Process(input);\r
PAssert.That(() => result[21] == "潮改二(Lv94)・龍驤改二(Lv99)" &&\r
result[22] == "33/33・50/50");\r
- PAssert.That(() => result.Length == 39);\r
+ PAssert.That(() => result.Length == 40);\r
+ }\r
+\r
+ [TestMethod]\r
+ public void AddMapNumber()\r
+ {\r
+ var input = Enumerable.Repeat("", 38).ToArray();\r
+ input[1] = "サーモン海域";\r
+ var result = new BattleLogProcessor(new Dictionary<string, string> {{"サーモン海域", "5-4"}}).Process(input);\r
+ PAssert.That(() => result[39] == "5-4");\r
}\r
}\r
}
\ No newline at end of file
}\r
\r
/// <summary>\r
- /// 資材ログは最後に現在値を示すレコードを追加する\r
+ /// 海戦・ドロップ報告書を加工する\r
+ /// </summary>\r
+ [TestMethod]\r
+ public void BattleLog()\r
+ {\r
+ var processor = new LogProcessor(null, new Dictionary<string, string> {{"鎮守府正面海域", "1-1"}});\r
+ var log = new[]\r
+ {\r
+ "2018-09-08 11:28:01,鎮守府正面海域,3,ボス,A,同航戦,単縦陣,単縦陣,敵主力艦隊,駆逐艦,雷,浜波改(Lv78),32/32,涼風(Lv10),3/16,,,,,,,,,軽巡ホ級,0/33,駆逐イ級,0/20,駆逐イ級,7/20,,,,,,,0,0,"\r
+ };\r
+ var result = processor.Process(log, "海戦・ドロップ報告書.csv", DateTime.MinValue, DateTime.MaxValue, false);\r
+ PAssert.That(() =>\r
+ result.First() ==\r
+ "[\"2018-09-08 11:28:01\",\"鎮守府正面海域\",\"3\",\"ボス\",\"A\",\"同航戦\",\"単縦陣\",\"単縦陣\",\"敵主力艦隊\",\"駆逐艦\",\"雷\"," +\r
+ "\"浜波改(Lv78)\",\"32/32\",\"涼風(Lv10)\",\"3/16\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\"," +\r
+ "\"軽巡ホ級\",\"0/33\",\"駆逐イ級\",\"0/20\",\"駆逐イ級\",\"7/20\",\"\",\"\",\"\",\"\",\"\",\"\",\"0\",\"0\",\"\",\"涼風(Lv10)\",\"1-1\"]");\r
+ }\r
+\r
+ /// <summary>\r
+ /// 資材ログの最後に現在値を示すレコードを追加する\r
/// </summary>\r
[TestMethod]\r
public void MaterialLogWithCurrentRecord()\r
PAssert.That(() =>\r
"2017-01-01 00:00:00,カレー洋制圧戦,1,出撃,A,T字戦(有利),警戒陣,梯形陣,敵潜水教導艦隊,,," +\r
"隼鷹改二(Lv157),57/62,利根改二(Lv151),66/66,千代田航改二(Lv159),50/65,千歳航改二(Lv159),65/65,大井改二(Lv57),40/43,秋月改(Lv142),42/42," +\r
- "潜水ヨ級(elite),34/34,潜水ヨ級,5/24,潜水ヨ級,0/24,潜水カ級(elite),0/27,潜水カ級,0/19,潜水カ級,0/19,248~249,0,制空権確保|"\r
+ "潜水ヨ級(elite),34/34,潜水ヨ級,5/24,潜水ヨ級,0/24,潜水カ級(elite),0/27,潜水カ級,0/19,潜水カ級,0/19,248~249,0,制空権確保,4-2|"\r
== result);\r
}\r
\r
PAssert.That(() =>\r
"2017-01-01 00:00:00,台湾沖/ルソン島沖,5,出撃,S,同航戦,単縦陣,単縦陣,深海通商破部隊 前衛水雷戦隊,,," +\r
"あきつ丸改(Lv81),40/40,那智改二(Lv151),63/63,Roma改(Lv99),83/92,阿武隈改二(Lv98),40/45,霞改二(Lv96),13/31,潮改二(Lv94)・不知火改(Lv85),31/33・32/32," +\r
- "軽巡ホ級(flagship),0/53,駆逐ロ級後期型,0/37,駆逐ロ級後期型,0/37,駆逐ロ級後期型,0/37,駆逐イ級,0/20,駆逐イ級,0/20,317~318,0,制空権確保|"\r
+ "軽巡ホ級(flagship),0/53,駆逐ロ級後期型,0/37,駆逐ロ級後期型,0/37,駆逐ロ級後期型,0/37,駆逐イ級,0/20,駆逐イ級,0/20,317~318,0,制空権確保,40-2|"\r
== result);\r
}\r
\r
{\r
public class BattleLogProcessor\r
{\r
+ private readonly Dictionary<string, string> _mapDictionary;\r
+\r
+ public BattleLogProcessor(Dictionary<string, string> mapDictionary = null)\r
+ {\r
+ _mapDictionary = mapDictionary ?? new Dictionary<string, string>();\r
+ }\r
+\r
public string[] Process(string[] data)\r
{\r
- if (data.Length == 35)\r
- data = data.Concat(Enumerable.Repeat("", 3)).ToArray();\r
- if (data.Length == 40)\r
- {\r
- data = data.Take(21).Concat(new[] {data[21] + "・" + data[23], data[22] + "・" + data[24]})\r
- .Concat(data.Skip(25)).ToArray();\r
- }\r
- else if (data.Length != 38)\r
+ string map;\r
+ switch (data.Length)\r
{\r
- return data;\r
+ case 35:\r
+ data = data.Concat(Enumerable.Repeat("", 3)).ToArray();\r
+ goto case 38;\r
+ case 38:\r
+ map = _mapDictionary.TryGetValue(data[1], out var num) ? num : "";\r
+ break;\r
+ case 39:\r
+ map = data[38];\r
+ break;\r
+ case 40: // 七隻分のログが出力されている\r
+ data[21] = data[21] + "・" + data[23];\r
+ data[22] = data[22] + "・" + data[24];\r
+ Array.Copy(data, 24, data, 23, 15);\r
+ goto case 38;\r
+ default:\r
+ return data;\r
}\r
if (data[5] == "T字戦(有利)")\r
data[5] = "T字有利";\r
if (data[7].EndsWith("航行序列"))\r
data[7] = data[7].Substring(0, 4);\r
data[37] = ShortenAirBattleResult(data[37]);\r
- return AddDamagedShip(data);\r
+ var result = new string[40];\r
+ result[38] = GenerateDamagedShip(data);\r
+ result[39] = map;\r
+ Array.Copy(data, result, 38);\r
+ return result;\r
}\r
\r
private static string ShortenAirBattleResult(string result)\r
}\r
}\r
\r
- private static string[] AddDamagedShip(string[] data)\r
+ private static string GenerateDamagedShip(string[] data)\r
{\r
var damaged = new List<string>();\r
for (var i = 11; i < 11 + 12; i += 2)\r
}\r
catch (FormatException)\r
{\r
- return data;\r
+ return "";\r
}\r
}\r
- return data.Take(23).Concat(new[] {string.Join("・", damaged)}).Concat(data.Skip(23)).ToArray();\r
+ return string.Join("・", damaged);\r
}\r
\r
private static readonly Regex Kana = new Regex(@"\([^)]+\)\(", RegexOptions.Compiled);\r
private readonly MaterialCount[] _materialCount;\r
private readonly BattleLogProcessor _battleLogProcessor;\r
\r
- public LogProcessor(MaterialCount[] materialCount = null)\r
+ public LogProcessor(MaterialCount[] materialCount = null, Dictionary<string, string> mapDictionary = null)\r
{\r
_materialCount = materialCount ?? new MaterialCount[0];\r
- _battleLogProcessor = new BattleLogProcessor();\r
+ _battleLogProcessor = new BattleLogProcessor(mapDictionary);\r
}\r
\r
public IEnumerable<string> Process(IEnumerable<string> lines, string path, DateTime from, DateTime to,\r
fields = 15;\r
break;\r
case "海戦・ドロップ報告書":\r
- fields = 39;\r
+ fields = 40;\r
battle = true;\r
break;\r
case "開発報告書":\r
string.Join(",", fShips),\r
string.Join(",", eShips),\r
fPower, _battleInfo.EnemyFighterPower.AirCombat + _battleInfo.EnemyFighterPower.UnknownMark,\r
- AirControlLevelName(_battle)),\r
+ AirControlLevelName(_battle),\r
+ $"{(int)_map.api_maparea_id}-{(int)_map.api_mapinfo_no}"),\r
"日付,海域,マス,ボス,ランク,艦隊行動,味方陣形,敵陣形,敵艦隊,ドロップ艦種,ドロップ艦娘," +\r
"味方艦1,味方艦1HP,味方艦2,味方艦2HP,味方艦3,味方艦3HP,味方艦4,味方艦4HP,味方艦5,味方艦5HP,味方艦6,味方艦6HP," +\r
"敵艦1,敵艦1HP,敵艦2,敵艦2HP,敵艦3,敵艦3HP,敵艦4,敵艦4HP,敵艦5,敵艦5HP,敵艦6,敵艦6HP," +\r
- "味方制空値,敵制空値,制空状態"\r
+ "味方制空値,敵制空値,制空状態,マップ"\r
);\r
_map = _battle = null;\r
_start = false;\r
\r
public IRepeatingTimerController RepeatingTimerController { get; set; }\r
\r
+ public Dictionary<string, string> MapDictionary { get; } = new Dictionary<string, string>();\r
+\r
[Flags]\r
public enum Update\r
{\r
_itemInfo.InspectMaster(data);\r
_exMapInfo.ResetIfNeeded();\r
_miscTextInfo.InspectMaster(data);\r
+ SetMapDictionary(data.api_mst_mapinfo);\r
_start = true;\r
return Update.Start;\r
}\r
\r
+ private void SetMapDictionary(dynamic json)\r
+ {\r
+ foreach (var map in json)\r
+ MapDictionary[map.api_name] = $"{map.api_maparea_id}-{map.api_no}";\r
+ }\r
+\r
private Update ApiPort(dynamic data)\r
{\r
_itemInfo.InspectBasic(data.api_basic);\r
<script>
this.tables = [
-"<th>日付</th><th>海域</th><th>マス</th><th>ボス</th><th>ランク</th><th>ドロップ艦種</th><th>ドロップ艦娘", // ドロップ
-"<th>日付</th><th style=\"min-width: 3.2em;\">海域</th><th>マス</th><th>ボス</th><th>ランク</th><th>艦隊行動</th><th>味方陣形</th><th>敵陣形</th><th style=\"min-width: 3.2em;\">敵艦隊</th><th>味方艦1</th><th>味方艦1HP</th><th>味方艦2</th><th>味方艦2HP</th><th>味方艦3</th><th>味方艦3HP</th><th>味方艦4</th><th>味方艦4HP</th><th>味方艦5</th><th>味方艦5HP</th><th>味方艦6</th><th>味方艦6HP</th><th>大破艦</ht><th style=\"min-width: 2.2em;\">敵艦1</th><th>敵艦1HP</th><th style=\"min-width: 2.2em;\">敵艦2</th><th>敵艦2HP</th><th style=\"min-width: 2.2em;\">敵艦3</th><th>敵艦3HP</th><th style=\"min-width: 2.2em;\">敵艦4</th><th>敵艦4HP</th><th style=\"min-width: 2.2em;\">敵艦5</th><th>敵艦5HP</th><th style=\"min-width: 2.2em;\">敵艦6</th><th>敵艦6HP</th><th>味方制空値</th><th>敵制空値</th><th>制空状態</th>", // 海戦
+"<th>æ\97¥ä»\98</th><th>æµ·å\9f\9f</th><th>ã\83\9eã\83\83ã\83\97</th><th>ã\83\9eã\82¹</th><th>ã\83\9cã\82¹</th><th>ã\83©ã\83³ã\82¯</th><th>ã\83\89ã\83ã\83\83ã\83\97è\89¦ç¨®</th><th>ã\83\89ã\83ã\83\83ã\83\97è\89¦å¨\98", // ã\83\89ã\83ã\83\83ã\83\97
+"<th>æ\97¥ä»\98</th><th style=\"min-width: 3.2em;\">æµ·å\9f\9f</th><th>ã\83\9eã\83\83ã\83\97</th><th>ã\83\9eã\82¹</th><th>ã\83\9cã\82¹</th><th>ã\83©ã\83³ã\82¯</th><th>è\89¦é\9a\8aè¡\8cå\8b\95</th><th>å\91³æ\96¹é\99£å½¢</th><th>æ\95µé\99£å½¢</th><th style=\"min-width: 3.2em;\">æ\95µè\89¦é\9a\8a</th><th>å\91³æ\96¹è\89¦1</th><th>å\91³æ\96¹è\89¦1HP</th><th>å\91³æ\96¹è\89¦2</th><th>å\91³æ\96¹è\89¦2HP</th><th>å\91³æ\96¹è\89¦3</th><th>å\91³æ\96¹è\89¦3HP</th><th>å\91³æ\96¹è\89¦4</th><th>å\91³æ\96¹è\89¦4HP</th><th>å\91³æ\96¹è\89¦5</th><th>å\91³æ\96¹è\89¦5HP</th><th>å\91³æ\96¹è\89¦6</th><th>å\91³æ\96¹è\89¦6HP</th><th>å¤§ç ´è\89¦</ht><th style=\"min-width: 2.2em;\">æ\95µè\89¦1</th><th>æ\95µè\89¦1HP</th><th style=\"min-width: 2.2em;\">æ\95µè\89¦2</th><th>æ\95µè\89¦2HP</th><th style=\"min-width: 2.2em;\">æ\95µè\89¦3</th><th>æ\95µè\89¦3HP</th><th style=\"min-width: 2.2em;\">æ\95µè\89¦4</th><th>æ\95µè\89¦4HP</th><th style=\"min-width: 2.2em;\">æ\95µè\89¦5</th><th>æ\95µè\89¦5HP</th><th style=\"min-width: 2.2em;\">æ\95µè\89¦6</th><th>æ\95µè\89¦6HP</th><th>å\91³æ\96¹å\88¶ç©ºå\80¤</th><th>æ\95µå\88¶ç©ºå\80¤</th><th>å\88¶ç©ºç\8a¶æ\85\8b</th>", // æµ·æ\88¦
"<th>日付</th><th>結果</th><th>遠征</th><th>燃料</th><th>弾薬</th><th>鋼材</th><th>ボーキ</th><th>開発資材</th><th>高速修復材</th><th>高速建造材</th>", // 遠征
"<th>日付</th><th>開発装備</th><th>種別</th><th>燃料</th><th>弾薬</th><th>鋼材</th><th>ボーキ</th><th>秘書艦</th><th>司令部Lv</th>", // 開発
"<th>日付</th><th>種類</th><th>名前</th><th>艦種</th><th>燃料</th><th>弾薬</th><th>鋼材</th><th>ボーキ</th><th>開発資材</th><th>空きドック</th><th>秘書艦</th><th>司令部Lv</th>", // 建造
}
};
if (t === 0) {
- opts.columns = [{ data: 0 }, { data: 1 }, { data: 2 }, { data: 3 }, { data: 4 }, { data: 9 }, { data: 10 }];
+ opts.columns = [{data: 0}, {data: 1}, {data: 39}, {data: 2}, {data: 3}, {data: 4}, {data: 9}, {data: 10}];
} else if (t === 1) {
var entries = [];
- for (var i = 0; i < 39; i++) {
+ for (var i = 0; i < 38; i++) {
+ if (i === 2)
+ entries.push({data: 39});
if (i === 9 || i === 10)
continue;
- entries.push({ data: i });
+ if (i === 23)
+ entries.push({data: 38});
+ entries.push({data: i});
}
opts.columns = entries;
}
var isBoss = row[3].indexOf("ボス") !== -1;
var isStart = row[3].indexOf("出撃") !== -1;
var resR = 0;
- for (var j = 23; j < row.length; j++) {
+ for (var j = 22; j < row.length; j++) {
if (/^輸送/.test(row[j]) && /^0\x2f/.test(row[j + 1]))
resR++;
}