\r
private string RemoveToken(string query)\r
{\r
- var s = new MainForm.Session(query, null, null);\r
+ var s = new Main.Session(query, null, null);\r
Privacy.Remove(s);\r
return s.Url;\r
}\r
\r
private string RemoveName(string response)\r
{\r
- var s = new MainForm.Session(null, null, response);\r
+ var s = new Main.Session(null, null, response);\r
Privacy.Remove(s);\r
return s.Response;\r
}\r
using System.IO;\r
using System.Windows.Forms;\r
using KancolleSniffer.Net;\r
+using KancolleSniffer.Util;\r
using KancolleSniffer.View;\r
\r
namespace KancolleSniffer\r
{\r
public partial class ConfigDialog : Form\r
{\r
- private readonly MainForm _main;\r
+ private readonly Main _main;\r
private readonly Config _config;\r
\r
private readonly Dictionary<string, NotificationSpec> _notificationSettings =\r
public List<string> RepeatSettingsChanged { get; } = new List<string>();\r
public Notification.ConfigDialog NotificationConfigDialog { get; }\r
\r
- public ConfigDialog(MainForm main)\r
+ public ConfigDialog(Main main)\r
{\r
InitializeComponent();\r
_main = main;\r
\r
private void buttonPlay_Click(object sender, EventArgs e)\r
{\r
- _main.PlaySound(_soundSettings[(string)listBoxSoundFile.SelectedItem], (int)numericUpDownSoundVolume.Value);\r
+ SoundPlayer.PlaySound(Handle, _soundSettings[(string)listBoxSoundFile.SelectedItem], (int)numericUpDownSoundVolume.Value);\r
}\r
\r
private void buttonResetAchievement_Click(object sender, EventArgs e)\r
{\r
private readonly Sniffer _sniffer;\r
private BattleState _prevBattleState = BattleState.None;\r
- private readonly List<MainForm.Session> _battleApiLog = new List<MainForm.Session>();\r
+ private readonly List<Main.Session> _battleApiLog = new List<Main.Session>();\r
\r
public ErrorLog(Sniffer sniffer)\r
{\r
_sniffer = sniffer;\r
}\r
\r
- public void CheckBattleApi(MainForm.Session session)\r
+ public void CheckBattleApi(Main.Session session)\r
{\r
if (_prevBattleState == BattleState.None)\r
_battleApiLog.Clear();\r
let actual = pair.Actual\r
select $"({actual.Fleet.Number}-{actual.DeckIndex}) {assumed.NowHp}->{actual.NowHp}");\r
\r
- public string GenerateErrorLog(MainForm.Session s, string exception)\r
+ public string GenerateErrorLog(Main.Session s, string exception)\r
{\r
Privacy.Remove(s);\r
var version = string.Join(".", Application.ProductVersion.Split('.').Take(2));\r
</ItemGroup>\r
<ItemGroup>\r
<Compile Include="Log\BattleLogger.cs" />\r
+ <Compile Include="Main.cs" />\r
<Compile Include="MainForm.ListFormGroup.cs">\r
<SubType>Form</SubType>\r
</Compile>\r
<Compile Include="Log\BattleLogProcessor.cs" />\r
<Compile Include="Model\Range.cs" />\r
<Compile Include="Util\Clipboard.cs" />\r
+ <Compile Include="Util\SoundPlayer.cs" />\r
<Compile Include="Util\TimeStep.cs" />\r
<Compile Include="View\ChargeStatus.cs">\r
<SubType>Component</SubType>\r
{\r
if (WindowState == FormWindowState.Minimized)\r
{\r
- Application.DoEvents();\r
+ System.Windows.Forms.Application.DoEvents();\r
if (_config.HideOnMinimized)\r
ShowInTaskbar = true;\r
WindowState = FormWindowState.Normal;\r
--- /dev/null
+using System;\r
+using System.Collections.Generic;\r
+using System.ComponentModel;\r
+using System.Diagnostics;\r
+using System.Globalization;\r
+using System.IO;\r
+using System.Linq;\r
+using System.Net;\r
+using System.Text.RegularExpressions;\r
+using System.Windows.Forms;\r
+using DynaJson;\r
+using KancolleSniffer.Log;\r
+using KancolleSniffer.Net;\r
+using KancolleSniffer.Notification;\r
+using KancolleSniffer.Util;\r
+using Microsoft.CSharp.RuntimeBinder;\r
+\r
+namespace KancolleSniffer\r
+{\r
+ public interface IMainForm\r
+ {\r
+ Label PlayLogSign { get; }\r
+ Notifier Notifier { get; }\r
+ void UpdateTimers();\r
+ void UpdateItemInfo();\r
+ void UpdateInfo(Sniffer.Update update);\r
+ void ApplyConfig();\r
+ }\r
+\r
+ public class Main\r
+ {\r
+ private ProxyManager _proxyManager;\r
+ private Form _form;\r
+ private IMainForm _mainForm;\r
+ private readonly ErrorDialog _errorDialog = new ErrorDialog();\r
+ private ConfigDialog _configDialog;\r
+ private ErrorLog _errorLog;\r
+ private IEnumerator<string> _playLog;\r
+ private string _debugLogFile;\r
+ private bool _timerEnabled;\r
+ private readonly Timer _mainTimer = new Timer {Interval = 1000, Enabled = true};\r
+\r
+ public TimeStep Step { get; } = new TimeStep();\r
+\r
+ public Config Config { get; } = new Config();\r
+ public Sniffer Sniffer { get; } = new Sniffer();\r
+\r
+ public static void Run()\r
+ {\r
+ new Main().RunInternal();\r
+ }\r
+\r
+ private void RunInternal()\r
+ {\r
+ Config.Load();\r
+ _configDialog = new ConfigDialog(this);\r
+ var form = new MainForm(this);\r
+ _form = form;\r
+ _mainForm = form;\r
+ _proxyManager = new ProxyManager(_form, Config);\r
+ _proxyManager.UpdatePacFile();\r
+ _errorLog = new ErrorLog(Sniffer);\r
+ Sniffer.RepeatingTimerController = _mainForm.Notifier;\r
+ LoadData();\r
+ ApplyConfig();\r
+ ApplySettings();\r
+ HttpProxy.AfterSessionComplete += HttpProxy_AfterSessionComplete;\r
+ _mainTimer.Tick += TimerTick;\r
+ Application.Run(_form);\r
+ Terminate();\r
+ }\r
+\r
+ public void CheckVersionUpMain(LinkLabel guide)\r
+ {\r
+ CheckVersionUp((current, latest) =>\r
+ {\r
+ if (latest == current)\r
+ return;\r
+ guide.Text = $"バージョン{latest}があります。";\r
+ guide.LinkArea = new LinkArea(0, guide.Text.Length);\r
+ guide.Click += (obj, ev) => { Process.Start("https://ja.osdn.net/rel/kancollesniffer/" + latest); };\r
+ });\r
+ }\r
+\r
+ private readonly FileSystemWatcher _watcher = new FileSystemWatcher\r
+ {\r
+ Path = AppDomain.CurrentDomain.BaseDirectory,\r
+ NotifyFilter = NotifyFilters.LastWrite\r
+ };\r
+\r
+ private readonly Timer _watcherTimer = new Timer {Interval = 1000};\r
+\r
+ private void LoadData()\r
+ {\r
+ var target = "";\r
+ Sniffer.LoadState();\r
+ _watcher.SynchronizingObject = _form;\r
+ _watcherTimer.Tick += (sender, ev) =>\r
+ {\r
+ _watcherTimer.Stop();\r
+ switch (target)\r
+ {\r
+ case "status.xml":\r
+ Sniffer.LoadState();\r
+ break;\r
+ case "TP.csv":\r
+ Sniffer.AdditionalData.LoadTpSpec();\r
+ break;\r
+ }\r
+ };\r
+ _watcher.Changed += (sender, ev) =>\r
+ {\r
+ target = ev.Name;\r
+ _watcherTimer.Stop();\r
+ _watcherTimer.Start();\r
+ };\r
+ _watcher.EnableRaisingEvents = true;\r
+ }\r
+\r
+ private void HttpProxy_AfterSessionComplete(HttpProxy.Session session)\r
+ {\r
+ _form.BeginInvoke(new Action<HttpProxy.Session>(ProcessRequest), session);\r
+ }\r
+\r
+ public class Session\r
+ {\r
+ public string Url { get; set; }\r
+ public string Request { get; set; }\r
+ public string Response { get; set; }\r
+\r
+ public Session(string url, string request, string response)\r
+ {\r
+ Url = url;\r
+ Request = request;\r
+ Response = response;\r
+ }\r
+\r
+ public string[] Lines => new[] {Url, Request, Response};\r
+ }\r
+\r
+ private void ProcessRequest(HttpProxy.Session session)\r
+ {\r
+ var url = session.Request.PathAndQuery;\r
+ if (!url.Contains("kcsapi/"))\r
+ return;\r
+ var s = new Session(url, session.Request.BodyAsString, session.Response.BodyAsString);\r
+ Privacy.Remove(s);\r
+ if (s.Response == null || !s.Response.StartsWith("svdata="))\r
+ {\r
+ WriteDebugLog(s);\r
+ return;\r
+ }\r
+ s.Response = UnEscapeString(s.Response.Remove(0, "svdata=".Length));\r
+ WriteDebugLog(s);\r
+ ProcessRequestMain(s);\r
+ }\r
+\r
+ private void ProcessRequestMain(Session s)\r
+ {\r
+ try\r
+ {\r
+ var update = (Sniffer.Update)Sniffer.Sniff(s.Url, s.Request, JsonObject.Parse(s.Response));\r
+ _mainForm.UpdateInfo(update);\r
+ if ((update & Sniffer.Update.Timer) != 0)\r
+ _timerEnabled = true;\r
+ _errorLog.CheckBattleApi(s);\r
+ }\r
+\r
+ catch (RuntimeBinderException e)\r
+ {\r
+ if (_errorDialog.ShowDialog(_form,\r
+ "艦これに仕様変更があったか、受信内容が壊れています。",\r
+ _errorLog.GenerateErrorLog(s, e.ToString())) == DialogResult.Abort)\r
+ Exit();\r
+ }\r
+ catch (LogIOException e)\r
+ {\r
+ // ReSharper disable once PossibleNullReferenceException\r
+ if (_errorDialog.ShowDialog(_form, e.Message, e.InnerException.ToString()) == DialogResult.Abort)\r
+ Exit();\r
+ }\r
+ catch (BattleResultError)\r
+ {\r
+ if (_errorDialog.ShowDialog(_form, "戦闘結果の計算に誤りがあります。",\r
+ _errorLog.GenerateBattleErrorLog()) == DialogResult.Abort)\r
+ Exit();\r
+ }\r
+ catch (Exception e)\r
+ {\r
+ if (_errorDialog.ShowDialog(_form, "エラーが発生しました。",\r
+ _errorLog.GenerateErrorLog(s, e.ToString())) == DialogResult.Abort)\r
+ Exit();\r
+ }\r
+ }\r
+\r
+ private void Exit()\r
+ {\r
+ _proxyManager.Shutdown();\r
+ Environment.Exit(1);\r
+ }\r
+\r
+ private void WriteDebugLog(Session s)\r
+ {\r
+ if (_debugLogFile != null)\r
+ {\r
+ File.AppendAllText(_debugLogFile,\r
+ $"date: {DateTime.Now:g}\nurl: {s.Url}\nrequest: {s.Request}\nresponse: {s.Response ?? "(null)"}\n");\r
+ }\r
+ }\r
+\r
+ private string UnEscapeString(string s)\r
+ {\r
+ try\r
+ {\r
+ var rx = new Regex(@"\\[uU]([0-9A-Fa-f]{4})");\r
+ return rx.Replace(s,\r
+ match => ((char)int.Parse(match.Value.Substring(2), NumberStyles.HexNumber)).ToString());\r
+ }\r
+ catch (ArgumentException)\r
+ {\r
+ return s;\r
+ }\r
+ }\r
+\r
+ public async void CheckVersionUp(Action<string, string> action)\r
+ {\r
+ var current = string.Join(".", Application.ProductVersion.Split('.').Take(2));\r
+ try\r
+ {\r
+ var latest = (await new WebClient().DownloadStringTaskAsync("http://kancollesniffer.osdn.jp/version"))\r
+ .TrimEnd();\r
+ try\r
+ {\r
+ action(current, latest);\r
+ }\r
+ catch (InvalidOperationException)\r
+ {\r
+ }\r
+ }\r
+ catch (WebException)\r
+ {\r
+ }\r
+ }\r
+\r
+ private void ApplySettings()\r
+ {\r
+ ApplyDebugLogSetting();\r
+ ApplyLogSetting();\r
+ ApplyProxySetting();\r
+ }\r
+\r
+ public void ApplyDebugLogSetting()\r
+ {\r
+ _debugLogFile = Config.DebugLogging ? Config.DebugLogFile : null;\r
+ }\r
+\r
+ public bool ApplyProxySetting()\r
+ {\r
+ return _proxyManager.ApplyConfig();\r
+ }\r
+\r
+ public void ApplyLogSetting()\r
+ {\r
+ LogServer.OutputDir = Config.Log.OutputDir;\r
+ LogServer.LogProcessor = new LogProcessor(Sniffer.Material.MaterialHistory, Sniffer.MapDictionary);\r
+ Sniffer.EnableLog(Config.Log.On ? LogType.All : LogType.None);\r
+ Sniffer.MaterialLogInterval = Config.Log.MaterialLogInterval;\r
+ Sniffer.LogOutputDir = Config.Log.OutputDir;\r
+ }\r
+\r
+ public void SetPlayLog(string file)\r
+ {\r
+ _playLog = File.ReadLines(file).GetEnumerator();\r
+ }\r
+\r
+ private void TimerTick(object sender, EventArgs ev)\r
+ {\r
+ if (_timerEnabled)\r
+ {\r
+ try\r
+ {\r
+ Step.SetNow();\r
+ _mainForm.UpdateTimers();\r
+ _mainForm.Notifier.NotifyTimers();\r
+ Step.SetPrev();\r
+ }\r
+ catch (Exception ex)\r
+ {\r
+ if (_errorDialog.ShowDialog(_form, "エラーが発生しました。", ex.ToString()) == DialogResult.Abort)\r
+ Exit();\r
+ }\r
+ }\r
+ if (_playLog == null || _configDialog.Visible)\r
+ {\r
+ _mainForm.PlayLogSign.Visible = false;\r
+ return;\r
+ }\r
+ PlayLog();\r
+ }\r
+\r
+ public void ResetAchievement()\r
+ {\r
+ Sniffer.Achievement.Reset();\r
+ _mainForm.UpdateItemInfo();\r
+ }\r
+\r
+ private void PlayLog()\r
+ {\r
+ var lines = new List<string>();\r
+ var sign = _mainForm.PlayLogSign;\r
+ foreach (var s in new[] {"url: ", "request: ", "response: "})\r
+ {\r
+ do\r
+ {\r
+ if (!_playLog.MoveNext() || _playLog.Current == null)\r
+ {\r
+ sign.Visible = false;\r
+ return;\r
+ }\r
+ } while (!_playLog.Current.StartsWith(s));\r
+ lines.Add(_playLog.Current.Substring(s.Length));\r
+ }\r
+ sign.Visible = !sign.Visible;\r
+ ProcessRequestMain(new Session(lines[0], lines[1], lines[2]));\r
+ }\r
+\r
+ public void ShowConfigDialog()\r
+ {\r
+ if (_configDialog.ShowDialog(_form) == DialogResult.OK)\r
+ {\r
+ Config.Save();\r
+ ApplyConfig();\r
+ _mainForm.Notifier.StopRepeatingTimer(_configDialog.RepeatSettingsChanged);\r
+ }\r
+ }\r
+\r
+ private void ApplyConfig()\r
+ {\r
+ Sniffer.ShipCounter.Margin = Config.MarginShips;\r
+ Sniffer.ItemCounter.Margin = Config.MarginEquips;\r
+ _mainForm.Notifier.NotifyShipItemCount();\r
+ Sniffer.Achievement.ResetHours = Config.ResetHours;\r
+ Sniffer.WarnBadDamageWithDameCon = Config.WarnBadDamageWithDameCon;\r
+ _mainForm.ApplyConfig();\r
+ }\r
+\r
+ public IEnumerable<Control> Controls =>\r
+ new Control[] {_errorDialog, _configDialog, _configDialog.NotificationConfigDialog};\r
+\r
+ private void Terminate()\r
+ {\r
+ _proxyManager.Shutdown();\r
+ Config.Save();\r
+ Sniffer.FlashLog();\r
+ Sniffer.SaveState();\r
+ }\r
+\r
+ public void StartCapture()\r
+ {\r
+ try\r
+ {\r
+ var proc = new ProcessStartInfo("BurageSnap.exe") {WorkingDirectory = "Capture"};\r
+ Process.Start(proc);\r
+ }\r
+ catch (FileNotFoundException)\r
+ {\r
+ }\r
+ catch (Win32Exception)\r
+ {\r
+ }\r
+ }\r
+ }\r
+}
\ No newline at end of file
this.labelConstruct = new System.Windows.Forms.Label();\r
this.labelQuest = new System.Windows.Forms.Label();\r
this.labelMissionCaption = new System.Windows.Forms.Label();\r
- this.timerMain = new System.Windows.Forms.Timer(this.components);\r
this.notifyIconMain = new System.Windows.Forms.NotifyIcon(this.components);\r
this.contextMenuStripNotifyIcon = new System.Windows.Forms.ContextMenuStrip(this.components);\r
this.NotifyIconOpenToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\r
this.labelMissionCaption.TabIndex = 10;\r
this.labelMissionCaption.Text = "遠征";\r
// \r
- // timerMain\r
- // \r
- this.timerMain.Enabled = true;\r
- this.timerMain.Interval = 1000;\r
- this.timerMain.Tick += new System.EventHandler(this.timerMain_Tick);\r
- // \r
// notifyIconMain\r
// \r
this.notifyIconMain.ContextMenuStrip = this.contextMenuStripNotifyIcon;\r
// \r
// dropDownButtonRepairList\r
// \r
+ this.dropDownButtonRepairList.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;\r
this.dropDownButtonRepairList.Location = new System.Drawing.Point(121, 193);\r
this.dropDownButtonRepairList.Name = "dropDownButtonRepairList";\r
this.dropDownButtonRepairList.Size = new System.Drawing.Size(14, 14);\r
private System.Windows.Forms.Label labelConstruct;\r
private System.Windows.Forms.Label labelQuest;\r
private System.Windows.Forms.Label labelMissionCaption;\r
- private System.Windows.Forms.Timer timerMain;\r
private System.Windows.Forms.NotifyIcon notifyIconMain;\r
private System.Windows.Forms.ContextMenuStrip contextMenuStripMain;\r
private System.Windows.Forms.ToolStripMenuItem ConfigToolStripMenuItem;\r
// limitations under the License.\r
\r
using System;\r
-using System.Collections;\r
using System.Collections.Generic;\r
-using System.ComponentModel;\r
using System.Diagnostics;\r
using System.Drawing;\r
-using System.Globalization;\r
-using System.IO;\r
using System.Linq;\r
-using System.Net;\r
-using System.Runtime.InteropServices;\r
-using System.Text;\r
-using System.Text.RegularExpressions;\r
using System.Threading;\r
using System.Threading.Tasks;\r
using System.Windows.Forms;\r
-using DynaJson;\r
-using KancolleSniffer.Log;\r
using KancolleSniffer.Model;\r
-using KancolleSniffer.Net;\r
using KancolleSniffer.Notification;\r
using KancolleSniffer.Util;\r
using KancolleSniffer.View;\r
-using Microsoft.CSharp.RuntimeBinder;\r
using Clipboard = KancolleSniffer.Util.Clipboard;\r
-using Timer = System.Windows.Forms.Timer;\r
\r
namespace KancolleSniffer\r
{\r
- public partial class MainForm : Form\r
+ public partial class MainForm : Form, IMainForm\r
{\r
- private readonly ConfigDialog _configDialog;\r
- private readonly ProxyManager _proxyManager;\r
private readonly ResizableToolTip _toolTip = new ResizableToolTip();\r
private readonly ResizableToolTip _tooltipCopy = new ResizableToolTip {ShowAlways = false, AutomaticDelay = 0};\r
private readonly ListFormGroup _listFormGroup;\r
-\r
- private readonly Notifier _notifier;\r
private bool _started;\r
- private bool _timerEnabled;\r
- private string _debugLogFile;\r
- private IEnumerator<string> _playLog;\r
- private readonly TimeStep _step = new TimeStep();\r
+\r
private IEnumerable<IUpdateContext> _updateable;\r
private IEnumerable<IUpdateTimers> _timers;\r
+ private Main _main;\r
\r
- private readonly ErrorDialog _errorDialog = new ErrorDialog();\r
- private readonly ErrorLog _errorLog;\r
-\r
- public Sniffer Sniffer { get; } = new Sniffer();\r
- public Config Config { get; } = new Config();\r
+ public Sniffer Sniffer { get; private set; }\r
+ public Config Config { get; private set; }\r
+ public Label PlayLogSign => hqPanel.PlayLog;\r
+ public Notifier Notifier { get; }\r
\r
- public MainForm()\r
+ public MainForm(Main main)\r
{\r
InitializeComponent();\r
- HttpProxy.AfterSessionComplete += HttpProxy_AfterSessionComplete;\r
- Config.Load();\r
- _configDialog = new ConfigDialog(this);\r
+ SetupMain(main);\r
_listFormGroup = new ListFormGroup(this);\r
- _notifier = new Notifier(FlashWindow, ShowTaster, PlaySound);\r
+ Notifier = new Notifier(FlashWindow, ShowTaster, PlaySound);\r
SetupView();\r
- _proxyManager = new ProxyManager(this);\r
- _proxyManager.UpdatePacFile();\r
- _errorLog = new ErrorLog(Sniffer);\r
- LoadData();\r
- Sniffer.RepeatingTimerController = _notifier;\r
+ }\r
+\r
+ private void SetupMain(Main main)\r
+ {\r
+ _main = main;\r
+ Config = main.Config;\r
+ Sniffer = main.Sniffer;\r
}\r
\r
private void SetupView()\r
_updateable = new IUpdateContext[]\r
{\r
hqPanel, missionPanel, kdockPanel, ndockPanel, materialHistoryPanel, shipInfoPanel, chargeStatus1,\r
- chargeStatus2, chargeStatus3, chargeStatus4, _notifier\r
+ chargeStatus2, chargeStatus3, chargeStatus4, Notifier\r
};\r
- var context = new UpdateContext(Sniffer, Config, () => _step);\r
+ var context = new UpdateContext(Sniffer, Config, () => _main.Step);\r
foreach (var updateable in _updateable)\r
updateable.Context = context;\r
_timers = new IUpdateTimers[] {missionPanel, kdockPanel, ndockPanel, shipInfoPanel};\r
Height += questPanel.Height - prevHeight;\r
}\r
\r
- private readonly FileSystemWatcher _watcher = new FileSystemWatcher\r
- {\r
- Path = AppDomain.CurrentDomain.BaseDirectory,\r
- NotifyFilter = NotifyFilters.LastWrite\r
- };\r
-\r
- private readonly Timer _watcherTimer = new Timer {Interval = 1000};\r
-\r
- private void LoadData()\r
- {\r
- var target = "";\r
- Sniffer.LoadState();\r
- _watcher.SynchronizingObject = this;\r
- _watcherTimer.Tick += (sender, ev) =>\r
- {\r
- _watcherTimer.Stop();\r
- switch (target)\r
- {\r
- case "status.xml":\r
- Sniffer.LoadState();\r
- break;\r
- case "TP.csv":\r
- Sniffer.AdditionalData.LoadTpSpec();\r
- break;\r
- }\r
- };\r
- _watcher.Changed += (sender, ev) =>\r
- {\r
- target = ev.Name;\r
- _watcherTimer.Stop();\r
- _watcherTimer.Start();\r
- };\r
- _watcher.EnableRaisingEvents = true;\r
- }\r
-\r
- private void HttpProxy_AfterSessionComplete(HttpProxy.Session session)\r
- {\r
- BeginInvoke(new Action<HttpProxy.Session>(ProcessRequest), session);\r
- }\r
-\r
- public class Session\r
- {\r
- public string Url { get; set; }\r
- public string Request { get; set; }\r
- public string Response { get; set; }\r
-\r
- public Session()\r
- {\r
- }\r
-\r
- public Session(string url, string request, string response)\r
- {\r
- Url = url;\r
- Request = request;\r
- Response = response;\r
- }\r
-\r
- public string[] Lines => new[] {Url, Request, Response};\r
- }\r
-\r
- private void ProcessRequest(HttpProxy.Session session)\r
- {\r
- var url = session.Request.PathAndQuery;\r
- if (!url.Contains("kcsapi/"))\r
- return;\r
- var s = new Session(url, session.Request.BodyAsString, session.Response.BodyAsString);\r
- Privacy.Remove(s);\r
- if (s.Response == null || !s.Response.StartsWith("svdata="))\r
- {\r
- WriteDebugLog(s);\r
- return;\r
- }\r
- s.Response = UnEscapeString(s.Response.Remove(0, "svdata=".Length));\r
- WriteDebugLog(s);\r
- ProcessRequestMain(s);\r
- }\r
-\r
- private void ProcessRequestMain(Session s)\r
- {\r
- try\r
- {\r
- UpdateInfo(Sniffer.Sniff(s.Url, s.Request, JsonObject.Parse(s.Response)));\r
- _errorLog.CheckBattleApi(s);\r
- }\r
-\r
- catch (RuntimeBinderException e)\r
- {\r
- if (_errorDialog.ShowDialog(this,\r
- "艦これに仕様変更があったか、受信内容が壊れています。",\r
- _errorLog.GenerateErrorLog(s, e.ToString())) == DialogResult.Abort)\r
- Exit();\r
- }\r
- catch (LogIOException e)\r
- {\r
- // ReSharper disable once PossibleNullReferenceException\r
- if (_errorDialog.ShowDialog(this, e.Message, e.InnerException.ToString()) == DialogResult.Abort)\r
- Exit();\r
- }\r
- catch (BattleResultError)\r
- {\r
- if (_errorDialog.ShowDialog(this, "戦闘結果の計算に誤りがあります。",\r
- _errorLog.GenerateBattleErrorLog()) == DialogResult.Abort)\r
- Exit();\r
- }\r
- catch (Exception e)\r
- {\r
- if (_errorDialog.ShowDialog(this, "エラーが発生しました。",\r
- _errorLog.GenerateErrorLog(s, e.ToString())) == DialogResult.Abort)\r
- Exit();\r
- }\r
- }\r
-\r
- private void Exit()\r
- {\r
- _proxyManager.Shutdown();\r
- Environment.Exit(1);\r
- }\r
-\r
- private void WriteDebugLog(Session s)\r
- {\r
- if (_debugLogFile != null)\r
- {\r
- File.AppendAllText(_debugLogFile,\r
- $"date: {DateTime.Now:g}\nurl: {s.Url}\nrequest: {s.Request}\nresponse: {s.Response ?? "(null)"}\n");\r
- }\r
- }\r
-\r
- private string UnEscapeString(string s)\r
- {\r
- try\r
- {\r
- var rx = new Regex(@"\\[uU]([0-9A-Fa-f]{4})");\r
- return rx.Replace(s,\r
- match => ((char)int.Parse(match.Value.Substring(2), NumberStyles.HexNumber)).ToString());\r
- }\r
- catch (ArgumentException)\r
- {\r
- return s;\r
- }\r
- }\r
-\r
- private void UpdateInfo(Sniffer.Update update)\r
+ public void UpdateInfo(Sniffer.Update update)\r
{\r
if (update == Sniffer.Update.Start)\r
{\r
hqPanel.Login.Visible = false;\r
shipInfoPanel.Guide.Visible = false;\r
_started = true;\r
- _notifier.StopAllRepeat();\r
+ Notifier.StopAllRepeat();\r
return;\r
}\r
if (!_started)\r
return;\r
- if (_step.Now == DateTime.MinValue)\r
- _step.SetNow();\r
+ if (_main.Step.Now == DateTime.MinValue)\r
+ _main.Step.SetNow();\r
if ((update & Sniffer.Update.Item) != 0)\r
UpdateItemInfo();\r
if ((update & Sniffer.Update.Timer) != 0)\r
shipInfoPanel.ToggleHpPercent();\r
if (Config.ShipList.Visible)\r
_listFormGroup.Show();\r
- ApplyConfig();\r
- ApplyDebugLogSetting();\r
- ApplyLogSetting();\r
- ApplyProxySetting();\r
- CheckVersionUp((current, latest) =>\r
- {\r
- if (latest == current)\r
- return;\r
- var guide = shipInfoPanel.Guide;\r
- guide.Text = $"バージョン{latest}があります。";\r
- guide.LinkArea = new LinkArea(0, guide.Text.Length);\r
- guide.Click += (obj, ev) =>\r
- {\r
- Process.Start("https://ja.osdn.net/rel/kancollesniffer/" + latest);\r
- };\r
- });\r
- }\r
-\r
- public async void CheckVersionUp(Action<string, string> action)\r
- {\r
- var current = string.Join(".", Application.ProductVersion.Split('.').Take(2));\r
- try\r
- {\r
- var latest = (await new WebClient().DownloadStringTaskAsync("http://kancollesniffer.osdn.jp/version"))\r
- .TrimEnd();\r
- try\r
- {\r
- action(current, latest);\r
- }\r
- catch (InvalidOperationException)\r
- {\r
- }\r
- }\r
- catch (WebException)\r
- {\r
- }\r
+ _main.CheckVersionUpMain(shipInfoPanel.Guide);\r
}\r
\r
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)\r
}\r
}\r
_listFormGroup.Close();\r
- Sniffer.FlashLog();\r
Config.Location = (WindowState == FormWindowState.Normal ? Bounds : RestoreBounds).Location;\r
Config.ShowHpInPercent = shipInfoPanel.ShowHpInPercent;\r
- Config.Save();\r
- Sniffer.SaveState();\r
- _proxyManager.Shutdown();\r
}\r
\r
private void MainForm_Resize(object sender, EventArgs e)\r
\r
private void ConfigToolStripMenuItem_Click(object sender, EventArgs e)\r
{\r
- if (_configDialog.ShowDialog(this) == DialogResult.OK)\r
- {\r
- Config.Save();\r
- ApplyConfig();\r
- _notifier.StopRepeatingTimer(_configDialog.RepeatSettingsChanged);\r
- }\r
+ _main.ShowConfigDialog();\r
}\r
\r
private void PerformZoom()\r
foreach (var control in new Control[]\r
{\r
this, shipInfoPanel.Guide, hqPanel.Login,\r
- _configDialog, _configDialog.NotificationConfigDialog,\r
- contextMenuStripMain, _errorDialog\r
- })\r
+ contextMenuStripMain\r
+ }.Concat(_main.Controls))\r
{\r
control.Font = ZoomFont(control.Font);\r
}\r
Location = Config.Location;\r
}\r
\r
- private void ApplyConfig()\r
+ public void ApplyConfig()\r
{\r
if (TopMost != Config.TopMost)\r
TopMost = _listFormGroup.TopMost = Config.TopMost;\r
- Sniffer.ShipCounter.Margin = Config.MarginShips;\r
- Sniffer.ItemCounter.Margin = Config.MarginEquips;\r
hqPanel.Update();\r
- _notifier.NotifyShipItemCount();\r
- Sniffer.Achievement.ResetHours = Config.ResetHours;\r
labelAkashiRepair.Visible = labelAkashiRepairTimer.Visible = Config.UsePresetAkashi;\r
- Sniffer.WarnBadDamageWithDameCon = Config.WarnBadDamageWithDameCon;\r
- }\r
-\r
- public void ApplyDebugLogSetting()\r
- {\r
- _debugLogFile = Config.DebugLogging ? Config.DebugLogFile : null;\r
- }\r
-\r
- public bool ApplyProxySetting()\r
- {\r
- return _proxyManager.ApplyConfig();\r
- }\r
-\r
- public void ApplyLogSetting()\r
- {\r
- LogServer.OutputDir = Config.Log.OutputDir;\r
- LogServer.LogProcessor = new LogProcessor(Sniffer.Material.MaterialHistory, Sniffer.MapDictionary);\r
- Sniffer.EnableLog(Config.Log.On ? LogType.All : LogType.None);\r
- Sniffer.MaterialLogInterval = Config.Log.MaterialLogInterval;\r
- Sniffer.LogOutputDir = Config.Log.OutputDir;\r
}\r
\r
public static bool IsTitleBarOnAnyScreen(Point location)\r
return Screen.AllScreens.Any(screen => screen.WorkingArea.Contains(rect));\r
}\r
\r
- private void timerMain_Tick(object sender, EventArgs e)\r
- {\r
- if (_timerEnabled)\r
- {\r
- try\r
- {\r
- _step.SetNow();\r
- UpdateTimers();\r
- _notifier.NotifyTimers();\r
- _step.SetPrev();\r
- }\r
- catch (Exception ex)\r
- {\r
- if (_errorDialog.ShowDialog(this, "エラーが発生しました。", ex.ToString()) == DialogResult.Abort)\r
- Exit();\r
- }\r
- }\r
- if (_playLog == null || _configDialog.Visible)\r
- {\r
- hqPanel.PlayLog.Visible = false;\r
- return;\r
- }\r
- PlayLog();\r
- }\r
-\r
- public void SetPlayLog(string file)\r
- {\r
- _playLog = File.ReadLines(file).GetEnumerator();\r
- }\r
-\r
- private void PlayLog()\r
- {\r
- var lines = new List<string>();\r
- foreach (var s in new[] {"url: ", "request: ", "response: "})\r
- {\r
- do\r
- {\r
- if (!_playLog.MoveNext() || _playLog.Current == null)\r
- {\r
- hqPanel.PlayLog.Visible = false;\r
- return;\r
- }\r
- } while (!_playLog.Current.StartsWith(s));\r
- lines.Add(_playLog.Current.Substring(s.Length));\r
- }\r
- hqPanel.PlayLog.Visible = !hqPanel.PlayLog.Visible;\r
- ProcessRequestMain(new Session(lines[0], lines[1], lines[2]));\r
- }\r
-\r
private void ShowShipOnShipList(int id)\r
{\r
if (!_listFormGroup.Visible)\r
_listFormGroup.ShowShip(id);\r
}\r
\r
- private void UpdateItemInfo()\r
+ public void UpdateItemInfo()\r
{\r
hqPanel.Update();\r
- _notifier.NotifyShipItemCount();\r
+ Notifier.NotifyShipItemCount();\r
materialHistoryPanel.Update();\r
if (_listFormGroup.Visible)\r
_listFormGroup.UpdateList();\r
{\r
shipInfoPanel.SetCurrentFleet();\r
shipInfoPanel.Update();\r
- _notifier.NotifyDamagedShip();\r
+ Notifier.NotifyDamagedShip();\r
UpdateChargeInfo();\r
UpdateRepairList();\r
UpdateMissionLabels();\r
missionPanel.Update();\r
}\r
\r
- private void UpdateTimers()\r
+ public void UpdateTimers()\r
{\r
foreach (var timer in _timers)\r
timer.UpdateTimers();\r
- _timerEnabled = true;\r
}\r
\r
private void UpdateRepairList()\r
{\r
questPanel.Update(Sniffer.Quests);\r
labelQuestCount.Text = Sniffer.Quests.Length.ToString();\r
- _notifier.NotifyQuestComplete();\r
+ Notifier.NotifyQuestComplete();\r
}\r
\r
private void FlashWindow()\r
notifyIconMain.ShowBalloonTip(20000, title, message, ToolTipIcon.Info);\r
}\r
\r
- [DllImport("winmm.dll")]\r
- private static extern int mciSendString(String command,\r
- StringBuilder buffer, int bufferSize, IntPtr hWndCallback);\r
-\r
-// ReSharper disable InconsistentNaming\r
- // ReSharper disable once IdentifierTypo\r
- private const int MM_MCINOTIFY = 0x3B9;\r
-\r
- private const int MCI_NOTIFY_SUCCESSFUL = 1;\r
-// ReSharper restore InconsistentNaming\r
-\r
- public void PlaySound(string file, int volume)\r
+ private void PlaySound(string file, int volume)\r
{\r
- if (!File.Exists(file))\r
- return;\r
- mciSendString("close sound", null, 0, IntPtr.Zero);\r
- if (mciSendString("open \"" + file + "\" type mpegvideo alias sound", null, 0, IntPtr.Zero) != 0)\r
- return;\r
- mciSendString("setaudio sound volume to " + volume * 10, null, 0, IntPtr.Zero);\r
- mciSendString("play sound notify", null, 0, Handle);\r
+ SoundPlayer.PlaySound(Handle, file, volume);\r
}\r
\r
protected override void WndProc(ref Message m)\r
{\r
- if (m.Msg == MM_MCINOTIFY && (int)m.WParam == MCI_NOTIFY_SUCCESSFUL)\r
- mciSendString("close sound", null, 0, IntPtr.Zero);\r
+ SoundPlayer.CloseSound(m);\r
base.WndProc(ref m);\r
}\r
\r
\r
private void labelFleet1_MouseHover(object sender, EventArgs e)\r
{\r
- labelFleet1.Text = shipInfoPanel.CurrentFleet == 0 && Sniffer.IsCombinedFleet && !shipInfoPanel.CombinedFleet ? "連合" : "第一";\r
+ labelFleet1.Text =\r
+ shipInfoPanel.CurrentFleet == 0 && Sniffer.IsCombinedFleet && !shipInfoPanel.CombinedFleet\r
+ ? "連合"\r
+ : "第一";\r
}\r
\r
private void labelFleet1_MouseLeave(object sender, EventArgs e)\r
});\r
}\r
\r
- public void ResetAchievement()\r
- {\r
- Sniffer.Achievement.Reset();\r
- UpdateItemInfo();\r
- }\r
-\r
private void labelRepairListButton_Click(object sender, EventArgs e)\r
{\r
if (panelRepairList.Visible)\r
\r
private void CaptureToolStripMenuItem_Click(object sender, EventArgs e)\r
{\r
- try\r
- {\r
- var proc = new ProcessStartInfo("BurageSnap.exe") {WorkingDirectory = "Capture"};\r
- Process.Start(proc);\r
- }\r
- catch (FileNotFoundException)\r
- {\r
- }\r
- catch (Win32Exception)\r
- {\r
- }\r
+ _main.StartCapture();\r
}\r
}\r
}
\ No newline at end of file
<resheader name="writer">\r
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r
</resheader>\r
- <metadata name="timerMain.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">\r
- <value>17, 17</value>\r
- </metadata>\r
<metadata name="notifyIconMain.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">\r
<value>129, 17</value>\r
</metadata>\r
private bool _initiated;\r
private DateTime _pacFileTime;\r
\r
- public ProxyManager(MainForm main)\r
+ public ProxyManager(Control parent, Config config)\r
{\r
- _parent = main;\r
- _config = main.Config;\r
+ _parent = parent;\r
+ _config = config;\r
SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;\r
_timer.Tick += CheckProxy;\r
}\r
{\r
public static class Privacy\r
{\r
- public static void Remove(MainForm.Session s)\r
+ public static void Remove(Main.Session s)\r
{\r
RemoveToken(s);\r
RemoveName(s);\r
}\r
\r
- private static void RemoveToken(MainForm.Session s)\r
+ private static void RemoveToken(Main.Session s)\r
{\r
s.Url = RemoveToken(s.Url);\r
s.Request = RemoveToken(s.Request);\r
@"""api_member_id"":""?\d*""?,|""api_(?:nick)?name"":""(?:[^\""]|\\.)*"",""api_(?:nick)?name_id"":""\d*"",",\r
RegexOptions.Compiled);\r
\r
- private static void RemoveName(MainForm.Session s)\r
+ private static void RemoveName(Main.Session s)\r
{\r
if (s.Response != null && !(s.Url != null && s.Url.Contains("start2")))\r
s.Response = NameRegex.Replace(s.Response, "");\r
{\r
if (Win32API.ProcessAlreadyExists())\r
return;\r
- Application.EnableVisualStyles();\r
- Application.SetCompatibleTextRenderingDefault(false);\r
+ System.Windows.Forms.Application.EnableVisualStyles();\r
+ System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(false);\r
try\r
{\r
- Application.Run(new MainForm());\r
+ KancolleSniffer.Main.Run();\r
}\r
catch (Exception ex)\r
{\r
--- /dev/null
+using System;\r
+using System.IO;\r
+using System.Runtime.InteropServices;\r
+using System.Text;\r
+using System.Windows.Forms;\r
+\r
+namespace KancolleSniffer.Util\r
+{\r
+ public static class SoundPlayer\r
+ {\r
+ [DllImport("winmm.dll")]\r
+ private static extern int mciSendString(String command,\r
+ StringBuilder buffer, int bufferSize, IntPtr hWndCallback);\r
+\r
+// ReSharper disable InconsistentNaming\r
+ // ReSharper disable once IdentifierTypo\r
+ private const int MM_MCINOTIFY = 0x3B9;\r
+\r
+ private const int MCI_NOTIFY_SUCCESSFUL = 1;\r
+// ReSharper restore InconsistentNaming\r
+\r
+ public static void PlaySound(IntPtr handle, string file, int volume)\r
+ {\r
+ if (!File.Exists(file))\r
+ return;\r
+ mciSendString("close sound", null, 0, IntPtr.Zero);\r
+ if (mciSendString("open \"" + file + "\" type mpegvideo alias sound", null, 0, IntPtr.Zero) != 0)\r
+ return;\r
+ mciSendString("setaudio sound volume to " + volume * 10, null, 0, IntPtr.Zero);\r
+ mciSendString("play sound notify", null, 0, handle);\r
+ }\r
+\r
+ public static void CloseSound(Message m)\r
+ {\r
+ if (m.Msg == MM_MCINOTIFY && (int)m.WParam == MCI_NOTIFY_SUCCESSFUL)\r
+ mciSendString("close sound", null, 0, IntPtr.Zero);\r
+ }\r
+ }\r
+}
\ No newline at end of file