OSDN Git Service

MainFormからViewと関係のないコードをMainに分離する
authorKazuhiro Fujieda <fujieda@users.osdn.me>
Fri, 1 May 2020 04:31:21 +0000 (13:31 +0900)
committerKazuhiro Fujieda <fujieda@users.osdn.me>
Sun, 30 Aug 2020 05:58:21 +0000 (14:58 +0900)
13 files changed:
KancolleSniffer.Test/PrivacyTest.cs
KancolleSniffer/ConfigDialog.cs
KancolleSniffer/ErrorLog.cs
KancolleSniffer/KancolleSniffer.csproj
KancolleSniffer/ListForm.cs
KancolleSniffer/Main.cs [new file with mode: 0644]
KancolleSniffer/MainForm.Designer.cs
KancolleSniffer/MainForm.cs
KancolleSniffer/MainForm.resx
KancolleSniffer/Net/ProxyManager.cs
KancolleSniffer/Privacy.cs
KancolleSniffer/Program.cs
KancolleSniffer/Util/SoundPlayer.cs [new file with mode: 0644]

index 5abcbbf..d159b85 100644 (file)
@@ -74,14 +74,14 @@ namespace KancolleSniffer.Test
 \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
index 120a3c8..a0b1e99 100644 (file)
@@ -19,13 +19,14 @@ using System.Drawing;
 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
@@ -38,7 +39,7 @@ namespace KancolleSniffer
         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
@@ -292,7 +293,7 @@ namespace KancolleSniffer
 \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
index 165aff2..cc6ca73 100644 (file)
@@ -33,14 +33,14 @@ namespace KancolleSniffer
     {\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
@@ -99,7 +99,7 @@ namespace KancolleSniffer
             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
index 0d3ac7d..6a5f5f0 100644 (file)
@@ -60,6 +60,7 @@
   </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
@@ -85,6 +86,7 @@
     <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
index 75d5969..0068758 100644 (file)
@@ -384,7 +384,7 @@ namespace KancolleSniffer
             {\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
diff --git a/KancolleSniffer/Main.cs b/KancolleSniffer/Main.cs
new file mode 100644 (file)
index 0000000..27f6282
--- /dev/null
@@ -0,0 +1,373 @@
+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
index f43c2ca..d00e68b 100644 (file)
@@ -51,7 +51,6 @@ namespace KancolleSniffer
             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
@@ -138,12 +137,6 @@ namespace KancolleSniffer
             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
@@ -298,6 +291,7 @@ namespace KancolleSniffer
             // \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
@@ -526,7 +520,6 @@ namespace KancolleSniffer
         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
index db75565..3197aa0 100644 (file)
 // 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
@@ -100,9 +80,9 @@ namespace KancolleSniffer
             _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
@@ -122,161 +102,20 @@ namespace KancolleSniffer
             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
@@ -305,42 +144,7 @@ namespace KancolleSniffer
                 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
@@ -355,12 +159,8 @@ namespace KancolleSniffer
                 }\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
@@ -434,12 +234,7 @@ namespace KancolleSniffer
 \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
@@ -454,9 +249,8 @@ namespace KancolleSniffer
             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
@@ -489,36 +283,12 @@ namespace KancolleSniffer
                 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
@@ -529,55 +299,6 @@ namespace KancolleSniffer
             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
@@ -585,10 +306,10 @@ namespace KancolleSniffer
             _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
@@ -598,7 +319,7 @@ namespace KancolleSniffer
         {\r
             shipInfoPanel.SetCurrentFleet();\r
             shipInfoPanel.Update();\r
-            _notifier.NotifyDamagedShip();\r
+            Notifier.NotifyDamagedShip();\r
             UpdateChargeInfo();\r
             UpdateRepairList();\r
             UpdateMissionLabels();\r
@@ -669,11 +390,10 @@ namespace KancolleSniffer
             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
@@ -686,7 +406,7 @@ namespace KancolleSniffer
         {\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
@@ -699,32 +419,14 @@ namespace KancolleSniffer
             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
@@ -790,7 +492,10 @@ namespace KancolleSniffer
 \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
@@ -832,12 +537,6 @@ namespace KancolleSniffer
             });\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
@@ -902,17 +601,7 @@ namespace KancolleSniffer
 \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
index 91a332c..a5ddaef 100644 (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
index 1258544..a4665f6 100644 (file)
@@ -32,10 +32,10 @@ namespace KancolleSniffer.Net
         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
index 2dddd8a..7197a47 100644 (file)
@@ -18,13 +18,13 @@ namespace KancolleSniffer
 {\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
@@ -42,7 +42,7 @@ namespace KancolleSniffer
             @"""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
index a11506e..c756028 100644 (file)
@@ -25,11 +25,11 @@ namespace KancolleSniffer
         {\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
diff --git a/KancolleSniffer/Util/SoundPlayer.cs b/KancolleSniffer/Util/SoundPlayer.cs
new file mode 100644 (file)
index 0000000..ff05fa5
--- /dev/null
@@ -0,0 +1,39 @@
+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