1 // Copyright (C) 2017 Kazuhiro Fujieda <fujieda@users.osdn.me>
\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
7 // http://www.apache.org/licenses/LICENSE-2.0
\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
16 using System.Collections.Generic;
\r
18 using System.IO.Compression;
\r
21 using System.Text.RegularExpressions;
\r
22 using System.Windows.Forms;
\r
24 namespace KancolleSniffer
\r
26 public class BattleResultError : Exception
\r
30 public class ErrorLog
\r
32 private readonly Sniffer _sniffer;
\r
33 private BattleState _prevBattleState = BattleState.None;
\r
34 private readonly List<string[]> _battleApiLog = new List<string[]>();
\r
36 public ErrorLog(Sniffer sniffer)
\r
41 public void CheckBattleApi(string url, string request, string response)
\r
43 if (!url.EndsWith("api_port/port"))
\r
44 _battleApiLog.Add(new[] {url, request, response});
\r
47 if (_prevBattleState == BattleState.Result &&
\r
48 // battleresultのあとのship_deckかportでのみエラー判定する
\r
49 IsBattleResultError)
\r
51 throw new BattleResultError();
\r
56 _prevBattleState = _sniffer.Battle.BattleState;
\r
58 if (url.EndsWith("api_port/port"))
\r
59 _battleApiLog.Clear();
\r
62 private bool IsBattleResultError =>
\r
63 _sniffer.Battle.DisplayedResultRank.IsError || _sniffer.IsBattleResultStatusError;
\r
65 public string GenerateBattleErrorLog()
\r
67 foreach (var logs in _battleApiLog)
\r
68 RemoveUnwantedInformation(ref logs[1], ref logs[2]);
\r
69 var version = string.Join(".", Application.ProductVersion.Split('.').Take(2));
\r
70 var api = CompressApi(string.Join("\r\n",
\r
71 new[] {BattleStartSlots()}.Concat(_battleApiLog.SelectMany(logs => logs))));
\r
72 var rank = _sniffer.Battle.DisplayedResultRank;
\r
73 var status = string.Join("\r\n", new[]
\r
75 rank.IsError ? $"{rank.Assumed}->{rank.Actual}" : "",
\r
77 }.Where(s => !string.IsNullOrEmpty(s)));
\r
78 var result = $"{{{{{{\r\n{DateTime.Now:g} {version}\r\n{status}\r\n{api}\r\n}}}}}}";
\r
79 File.WriteAllText("error.log", result);
\r
83 private string BattleStartSlots()
\r
85 return JsonObject.CreateJsonObject((from ship in _sniffer.BattleStartStatus
\r
86 group ship by ship.Fleet
\r
90 select (from item in s.AllSlot select item.Spec.Id).ToArray()
\r
92 ).ToArray()).ToString();
\r
95 private string HpDiffLog() => string.Join(" ",
\r
96 from pair in _sniffer.BattleResultStatusDiff
\r
97 let assumed = pair.Assumed
\r
98 let actual = pair.Actual
\r
99 select $"({assumed.Fleet}-{assumed.DeckIndex}) {assumed.NowHp}->{actual.NowHp}");
\r
101 public string GenerateErrorLog(string url, string request, string response, string exception)
\r
103 RemoveUnwantedInformation(ref request, ref response);
\r
104 var version = string.Join(".", Application.ProductVersion.Split('.').Take(2));
\r
105 var api = CompressApi($"{url}\r\n{request}\r\n{response}");
\r
106 var result = $"{{{{{{\r\n{DateTime.Now:g} {version}\r\n{exception}\r\n{api}\r\n}}}}}}";
\r
107 File.WriteAllText("error.log", result);
\r
111 public static void RemoveUnwantedInformation(ref string request, ref string response)
\r
113 var token = new Regex(@"&api%5Ftoken=.+?(?=&|$)|api%5Ftoken=.+?(?:&|$)|api%5Fbtime=\d+&?");
\r
114 request = token.Replace(request, "");
\r
115 var id = new Regex(@"""api_member_id"":""?\d+""?,?|""api_nickname"":"".+?"",?|""api_nickname_id"":""\d+"",?|""api_name_id"":"".+?"",?|");
\r
116 response = id.Replace(response, "");
\r
117 var name = new Regex(@"""api_name"":"".+?""");
\r
118 response = name.Replace(response, @"""api_name"":""""");
\r
121 private string CompressApi(string api)
\r
123 var output = new MemoryStream();
\r
124 var gzip = new GZipStream(output, CompressionLevel.Optimal);
\r
125 var bytes = Encoding.UTF8.GetBytes(api);
\r
126 gzip.Write(bytes, 0, bytes.Length);
\r
128 var ascii85 = Ascii85.Encode(output.ToArray());
\r
129 var result = new List<string>();
\r
130 var rest = ascii85.Length;
\r
131 const int lineLength = 80;
\r
132 for (var i = 0; i < ascii85.Length; i += lineLength, rest -= lineLength)
\r
133 result.Add(ascii85.Substring(i, Math.Min(rest, lineLength)));
\r
134 return string.Join("\r\n", result);
\r