OSDN Git Service

耐久のラベルのテキストを2回設定しているのを直す
[kancollesniffer/KancolleSniffer.git] / KancolleSniffer / MainForm.cs
1 // Copyright (C) 2013, 2014 Kazuhiro Fujieda <fujieda@users.sourceforge.jp>\r
2 // \r
3 // This program is part of KancolleSniffer.\r
4 //\r
5 // KancolleSniffer is free software: you can redistribute it and/or modify\r
6 // it under the terms of the GNU General Public License as published by\r
7 // the Free Software Foundation, either version 3 of the License, or\r
8 // (at your option) any later version.\r
9 //\r
10 // This program is distributed in the hope that it will be useful,\r
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13 // GNU General Public License for more details.\r
14 //\r
15 // You should have received a copy of the GNU General Public License\r
16 // along with this program; if not, see <http://www.gnu.org/licenses/>.\r
17 \r
18 using System;\r
19 using System.Drawing;\r
20 using System.IO;\r
21 using System.Linq;\r
22 using System.Windows.Forms;\r
23 using Codeplex.Data;\r
24 using Fiddler;\r
25 \r
26 namespace KancolleSniffer\r
27 {\r
28     public partial class MainForm : Form\r
29     {\r
30         private readonly Sniffer _sniffer = new Sniffer();\r
31         private readonly dynamic _wmp = Activator.CreateInstance(Type.GetTypeFromProgID("WMPlayer.OCX.7"));\r
32         private readonly Config _config = new Config();\r
33         private readonly ConfigDialog _configDialog = new ConfigDialog();\r
34         private readonly int _labelRightDistance;\r
35 \r
36         public MainForm()\r
37         {\r
38             InitializeComponent();\r
39             FiddlerApplication.AfterSessionComplete += FiddlerApplication_AfterSessionComplete;\r
40             _wmp.PlayStateChange += new EventHandler(_wmp_PlayStateChange);\r
41             _configDialog.Tag = _config;\r
42             _labelRightDistance = labelHP1.Parent.Width - labelHP1.Right;\r
43         }\r
44 \r
45         private void FiddlerApplication_AfterSessionComplete(Session oSession)\r
46         {\r
47             if (!oSession.bHasResponse || !oSession.uriContains("/kcsapi/api_"))\r
48                 return;\r
49             var response = oSession.GetResponseBodyAsString();\r
50             if (!response.StartsWith("svdata="))\r
51                 return;\r
52             response = response.Remove(0, "svdata=".Length);\r
53             var json = DynamicJson.Parse(response);\r
54             if (!json.IsDefined("api_data"))\r
55                 return;\r
56             json = json.api_data;\r
57             UpdateInfo update = _sniffer.Sniff(oSession.url, json);\r
58             if ((update & UpdateInfo.Item) != 0)\r
59                 Invoke(new Action(UpdateItemInfo));\r
60             if ((update & UpdateInfo.Mission) != 0)\r
61                 Invoke(new Action(UpdateMissionLabels));\r
62             if ((update & UpdateInfo.NDock) != 0)\r
63                 Invoke(new Action(UpdateNDocLabels));\r
64             if ((update & UpdateInfo.Ship) != 0)\r
65                 Invoke(new Action(UpdateShipInfo));\r
66             if ((update & UpdateInfo.Quest) != 0)\r
67                 Invoke(new Action(UpdateQuestList));\r
68             if ((update & UpdateInfo.Charge) != 0)\r
69                 Invoke(new Action(UpdateChargeInfo));\r
70         }\r
71 \r
72         private void MainForm_Load(object sender, EventArgs e)\r
73         {\r
74             _sniffer.LoadMaster();\r
75             _config.Load();\r
76             ApplyConfig();\r
77             FiddlerApplication.Startup(0, FiddlerCoreStartupFlags.RegisterAsSystemProxy);\r
78         }\r
79 \r
80         private void MainForm_FormClosing(object sender, FormClosingEventArgs e)\r
81         {\r
82             FiddlerApplication.Shutdown();\r
83             _sniffer.SaveMaster();\r
84             _config.Save();\r
85         }\r
86 \r
87         private void labelHP_SizeChanged(object sender, EventArgs e)\r
88         {\r
89             var label = (Label)sender;\r
90             label.Location = new Point(label.Parent.Width - _labelRightDistance - label.Width, label.Top);\r
91         }\r
92 \r
93         private void notifyIconMain_MouseDoubleClick(object sender, MouseEventArgs e)\r
94         {\r
95             if (WindowState == FormWindowState.Minimized)\r
96                 WindowState = FormWindowState.Normal;\r
97             Activate();\r
98         }\r
99 \r
100         private void ExitToolStripMenuItem_Click(object sender, EventArgs e)\r
101         {\r
102             Application.Exit();\r
103         }\r
104 \r
105 \r
106         private void ConfigToolStripMenuItem_Click(object sender, EventArgs e)\r
107         {\r
108             if (_configDialog.ShowDialog(this) == DialogResult.OK)\r
109                 ApplyConfig();\r
110         }\r
111 \r
112         private void ApplyConfig()\r
113         {\r
114             TopMost = _config.TopMost;\r
115             _wmp.settings.volume = _config.SoundVolume;\r
116             _sniffer.Item.MarginShips = _config.MarginShips;\r
117         }\r
118 \r
119         private void timerMain_Tick(object sender, EventArgs e)\r
120         {\r
121             UpdateTimers();\r
122         }\r
123 \r
124         private void UpdateItemInfo()\r
125         {\r
126             var item = _sniffer.Item;\r
127             labelNumOfShips.Text = string.Format("{0:D}/{1:D}", item.NowShips, item.MaxShips);\r
128             labelNumOfShips.ForeColor = item.TooManyShips ? Color.Red : Color.Black;\r
129             if (item.NeedRing)\r
130             {\r
131                 var message = string.Format("残り{0:D}隻", _sniffer.Item.MaxShips - _sniffer.Item.NowShips);\r
132                 Ring("艦娘が多すぎます", message, _config.MaxShipsSoundFile);\r
133                 item.NeedRing = false;\r
134             }\r
135             labelNumOfEquips.Text = string.Format("{0:D}/{1:D}", item.NowItems, item.MaxItems);\r
136             labelNumOfBuckets.Text = item.NumBuckets.ToString("D");\r
137         }\r
138 \r
139         private void UpdateMissionLabels()\r
140         {\r
141             foreach (var entry in\r
142                 new[] {labelMissionName1, labelMissionName2, labelMissionName3}.Zip(_sniffer.Missions,\r
143                     (label, mission) => new {label, mission.Name}))\r
144                 entry.label.Text = entry.Name;\r
145         }\r
146 \r
147         private void UpdateNDocLabels()\r
148         {\r
149             foreach (var entry in\r
150                 new[] {labelRepairShip1, labelRepairShip2, labelRepairShip3, labelRepairShip4}.Zip(_sniffer.NDock,\r
151                     (label, ndock) => new {label, ndock.Name}))\r
152                 entry.label.Text = entry.Name;\r
153         }\r
154 \r
155         private void UpdateShipInfo()\r
156         {\r
157             var name = new[] {labelShip1, labelShip2, labelShip3, labelShip4, labelShip5, labelShip6};\r
158             var lv = new[] {labelLv1, labelLv2, labelLv3, labelLv4, labelLv5, labelLv6};\r
159             var hp = new[] {labelHP1, labelHP2, labelHP3, labelHP4, labelHP5, labelHP6};\r
160             var cond = new[] {labelCond1, labelCond2, labelCond3, labelCond4, labelCond5, labelCond6};\r
161             var next = new[] {labelNextLv1, labelNextLv2, labelNextLv3, labelNextLv4, labelNextLv5, labelNextLv6};\r
162 \r
163             for (var i = 0; i < name.Length; i++)\r
164             {\r
165                 var stat = _sniffer.ShipStatuses[i];\r
166                 name[i].Text = stat.Name;\r
167                 lv[i].Text = stat.Level.ToString("D");\r
168                 SetHpLavel(hp[i], stat.NowHp, stat.MaxHp);\r
169                 SetCondLabel(cond[i], stat.Cond);\r
170                 next[i].Text = stat.ExpToNext.ToString("D");\r
171             }\r
172         }\r
173 \r
174         private void UpdateChargeInfo()\r
175         {\r
176             var fuel = new[] {labelFuel1, labelFuel2, labelFuel3, labelFuel4};\r
177             var bull = new[] {labelBull1, labelBull2, labelBull3, labelBull4};\r
178 \r
179             for (var i = 0; i < fuel.Length; i++)\r
180             {\r
181                 var stat = _sniffer.ChargeStatuses[i];\r
182                 fuel[i].ImageIndex = stat.Fuel;\r
183                 bull[i].ImageIndex = stat.Bull;\r
184             }\r
185         }\r
186 \r
187         private void SetHpLavel(Label label, int now, int max)\r
188         {\r
189             label.Text = string.Format("{0:D}/{1:D}", now, max);\r
190             var damage = max == 0 ? 1 : (double)now / max;\r
191             label.BackColor = damage > 0.5 ? DefaultBackColor : damage > 0.25 ? Color.Orange : Color.Red;\r
192         }\r
193 \r
194         private void SetCondLabel(Label label, int cond)\r
195         {\r
196             label.Text = cond.ToString("D");\r
197             label.BackColor = cond >= 50\r
198                 ? Color.Yellow\r
199                 : cond >= 30 || cond == 0\r
200                     ? DefaultBackColor\r
201                     : cond >= 20 ? Color.Orange : Color.Red;\r
202         }\r
203 \r
204         private void UpdateTimers()\r
205         {\r
206             foreach (var entry in\r
207                 new[] {labelMission1, labelMission2, labelMission3}.Zip(_sniffer.Missions,\r
208                     (label, mission) => new {label, mission.Name, mission.Timer}))\r
209             {\r
210                 entry.Timer.Update();\r
211                 SetTimerLabel(entry.label, entry.Timer);\r
212                 if (!entry.Timer.NeedRing)\r
213                     continue;\r
214                 Ring("遠征が終わりました", entry.Name, _config.MissionSoundFile);\r
215                 entry.Timer.NeedRing = false;\r
216             }\r
217             foreach (var entry in\r
218                 new[] {labelRepair1, labelRepair2, labelRepair3, labelRepair4}.Zip(_sniffer.NDock,\r
219                     (label, ndock) => new {label, ndock.Name, ndock.Timer}))\r
220             {\r
221                 entry.Timer.Update();\r
222                 SetTimerLabel(entry.label, entry.Timer);\r
223                 if (!entry.Timer.NeedRing)\r
224                     continue;\r
225                 Ring("入渠が終わりました", entry.Name, _config.NDockSoundFile);\r
226                 entry.Timer.NeedRing = false;\r
227             }\r
228             var kdock = new[] {labelConstruct1, labelConstruct2, labelConstruct3, labelConstruct4};\r
229             for (var i = 0; i < kdock.Length; i++)\r
230             {\r
231                 var timer = _sniffer.KDock[i];\r
232                 timer.Update();\r
233                 SetTimerLabel(kdock[i], timer);\r
234                 if (!timer.NeedRing)\r
235                     continue;\r
236                 Ring("建造が終わりました", string.Format("第{0:D}ドック", i + 1), _config.KDockSoundFile);\r
237                 timer.NeedRing = false;\r
238             }\r
239             UpdateCondTimers();\r
240         }\r
241 \r
242         private void SetTimerLabel(Label label, RingTimer timer)\r
243         {\r
244             if (timer.NeedRing)\r
245                 label.ForeColor = Color.Red;\r
246             if (!timer.IsSet)\r
247                 label.ForeColor = Color.Black;\r
248             label.Text = timer.ToString();\r
249         }\r
250 \r
251         private void UpdateCondTimers()\r
252         {\r
253             var now = DateTime.Now;\r
254             foreach (var entry in\r
255                 new[] {labelCondTimer1, labelCondTimer2, labelCondTimer3}.Zip(_sniffer.RecoveryTimes,\r
256                     (label, time) => new {label, time}))\r
257                 entry.label.Text = entry.time > now ? (entry.time - now).ToString(@"mm\:ss") : "00:00";\r
258         }\r
259 \r
260         private void UpdateQuestList()\r
261         {\r
262             var name = new[] {labelQuest1, labelQuest2, labelQuest3, labelQuest4, labelQuest5};\r
263             var progress = new[] {labelProgress1, labelProgress2, labelProgress3, labelProgress4, labelProgress5};\r
264 \r
265             for (var i = 0; i < name.Length; i++)\r
266             {\r
267                 if (i < _sniffer.Quests.Length)\r
268                 {\r
269                     name[i].Text = _sniffer.Quests[i].Name;\r
270                     progress[i].Text = string.Format("{0:D}%", _sniffer.Quests[i].Progress);\r
271                 }\r
272                 else\r
273                 {\r
274                     name[i].Text = progress[i].Text = "";\r
275                 }\r
276             }\r
277         }\r
278 \r
279         private void Ring(string baloonTitle, string baloonMessage, string soundFile)\r
280         {\r
281             if (_config.FlashWindow)\r
282                 Win32API.FlashWindow(Handle);\r
283             if (_config.ShowBaloonTip)\r
284                 notifyIconMain.ShowBalloonTip(20000, baloonTitle, baloonMessage, ToolTipIcon.Info);\r
285             if (_config.PlaySound && File.Exists(soundFile))\r
286             {\r
287                 _wmp.URL = soundFile;\r
288                 _wmp.controls.play();\r
289             }\r
290         }\r
291 \r
292         private void _wmp_PlayStateChange(object sender, EventArgs e)\r
293         {\r
294             if (_wmp.playState == 8) // MediaEnded\r
295                 _wmp.URL = ""; // 再生したファイルが差し替えできなくなるのを防ぐ。\r
296         }\r
297     }\r
298 }