• R/O
  • HTTP
  • SSH
  • HTTPS

提交

标签
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Commit MetaInfo

修订版115aef624d0834edd743922da2cf8a6bb5575b57 (tree)
时间2020-08-30 14:58:21
作者Kazuhiro Fujieda <fujieda@user...>
CommiterKazuhiro Fujieda

Log Message

通知周りをMainWindowからNotifierに移す

更改概述

差异

--- a/KancolleSniffer/KancolleSniffer.csproj
+++ b/KancolleSniffer/KancolleSniffer.csproj
@@ -69,6 +69,7 @@
6969 <Compile Include="Model\QuestCountList.cs" />
7070 <Compile Include="Model\QuestSpec.cs" />
7171 <Compile Include="Notification\Formatter.cs" />
72+ <Compile Include="Notification\Notifier.cs" />
7273 <Compile Include="Privacy.cs" />
7374 <Compile Include="Log\LogProcessor.cs" />
7475 <Compile Include="Model\Achievement.cs" />
--- a/KancolleSniffer/MainForm.cs
+++ b/KancolleSniffer/MainForm.cs
@@ -48,7 +48,7 @@ namespace KancolleSniffer
4848 private readonly ResizableToolTip _tooltipCopy = new ResizableToolTip {ShowAlways = false, AutomaticDelay = 0};
4949 private readonly ListFormGroup _listFormGroup;
5050
51- private readonly Scheduler _notificationScheduler;
51+ private readonly Notifier _notifier;
5252 private bool _started;
5353 private bool _timerEnabled;
5454 private string _debugLogFile;
@@ -63,12 +63,6 @@ namespace KancolleSniffer
6363 public Sniffer Sniffer { get; } = new Sniffer();
6464 public Config Config { get; } = new Config();
6565
66- public interface INotifySubmitter
67- {
68- void Flash();
69- void Enqueue(string key, string subject);
70- }
71-
7266 public MainForm()
7367 {
7468 InitializeComponent();
@@ -76,13 +70,13 @@ namespace KancolleSniffer
7670 Config.Load();
7771 _configDialog = new ConfigDialog(this);
7872 _listFormGroup = new ListFormGroup(this);
79- _notificationScheduler = new Scheduler(Alarm);
73+ _notifier = new Notifier(FlashWindow, ShowTaster, PlaySound);
8074 SetupView();
8175 _proxyManager = new ProxyManager(this);
8276 _proxyManager.UpdatePacFile();
8377 _errorLog = new ErrorLog(Sniffer);
8478 LoadData();
85- Sniffer.RepeatingTimerController = new RepeatingTimerController(this);
79+ Sniffer.RepeatingTimerController = _notifier;
8680 }
8781
8882 private void SetupView()
@@ -105,9 +99,9 @@ namespace KancolleSniffer
10599 _updateable = new IUpdateContext[]
106100 {
107101 hqPanel, missionPanel, kdockPanel, ndockPanel, materialHistoryPanel, shipInfoPanel, chargeStatus1,
108- chargeStatus2, chargeStatus3, chargeStatus4
102+ chargeStatus2, chargeStatus3, chargeStatus4, _notifier
109103 };
110- var context = new UpdateContext(Sniffer, Config, new NotifySubmitter(_notificationScheduler), () => _now);
104+ var context = new UpdateContext(Sniffer, Config, () => _now, () => _prev);
111105 foreach (var updateable in _updateable)
112106 updateable.Context = context;
113107 _timers = new IUpdateTimers[] {missionPanel, kdockPanel, ndockPanel, shipInfoPanel};
@@ -127,26 +121,6 @@ namespace KancolleSniffer
127121 Height += questPanel.Height - prevHeight;
128122 }
129123
130- private class NotifySubmitter : INotifySubmitter
131- {
132- private readonly Scheduler _manager;
133-
134- public NotifySubmitter(Scheduler manager)
135- {
136- _manager = manager;
137- }
138-
139- public void Flash()
140- {
141- _manager.Flush();
142- }
143-
144- public void Enqueue(string key, string subject)
145- {
146- _manager.Enqueue(key, subject);
147- }
148- }
149-
150124 private readonly FileSystemWatcher _watcher = new FileSystemWatcher
151125 {
152126 Path = AppDomain.CurrentDomain.BaseDirectory,
@@ -182,31 +156,6 @@ namespace KancolleSniffer
182156 _watcher.EnableRaisingEvents = true;
183157 }
184158
185- private class RepeatingTimerController : Sniffer.IRepeatingTimerController
186- {
187- private readonly Scheduler _manager;
188- private readonly Config _config;
189-
190- public RepeatingTimerController(MainForm main)
191- {
192- _manager = main._notificationScheduler;
193- _config = main.Config;
194- }
195-
196- public void Stop(string key)
197- {
198- _manager.StopRepeat(key,
199- (key == "入渠終了" || key == "遠征終了") &&
200- (_config.Notifications[key].Flags & NotificationType.Cont) != 0);
201- }
202-
203- public void Stop(string key, int fleet) => _manager.StopRepeat(key, fleet);
204-
205- public void Suspend(string exception = null) => _manager.SuspendRepeat(exception);
206-
207- public void Resume() => _manager.ResumeRepeat();
208- }
209-
210159 private void HttpProxy_AfterSessionComplete(HttpProxy.Session session)
211160 {
212161 BeginInvoke(new Action<HttpProxy.Session>(ProcessRequest), session);
@@ -301,7 +250,7 @@ namespace KancolleSniffer
301250 hqPanel.Login.Visible = false;
302251 shipInfoPanel.Guide.Visible = false;
303252 _started = true;
304- _notificationScheduler.StopAllRepeat();
253+ _notifier.StopAllRepeat();
305254 return;
306255 }
307256 if (!_started)
@@ -469,16 +418,10 @@ namespace KancolleSniffer
469418 {
470419 Config.Save();
471420 ApplyConfig();
472- StopRepeatingTimer(_configDialog.RepeatSettingsChanged);
421+ _notifier.StopRepeatingTimer(_configDialog.RepeatSettingsChanged);
473422 }
474423 }
475424
476- private void StopRepeatingTimer(IEnumerable<string> names)
477- {
478- foreach (var name in names)
479- _notificationScheduler.StopRepeat(name);
480- }
481-
482425 private void PerformZoom()
483426 {
484427 if (Config.Zoom == 100)
@@ -533,6 +476,7 @@ namespace KancolleSniffer
533476 Sniffer.ShipCounter.Margin = Config.MarginShips;
534477 Sniffer.ItemCounter.Margin = Config.MarginEquips;
535478 hqPanel.Update();
479+ _notifier.NotifyShipItemCount();
536480 Sniffer.Achievement.ResetHours = Config.ResetHours;
537481 labelAkashiRepair.Visible = labelAkashiRepairTimer.Visible = Config.UsePresetAkashi;
538482 Sniffer.WarnBadDamageWithDameCon = Config.WarnBadDamageWithDameCon;
@@ -573,7 +517,7 @@ namespace KancolleSniffer
573517 {
574518 _now = DateTime.Now;
575519 UpdateTimers();
576- NotifyTimers();
520+ _notifier.NotifyTimers();
577521 _prev = _now;
578522 }
579523 catch (Exception ex)
@@ -624,6 +568,7 @@ namespace KancolleSniffer
624568 private void UpdateItemInfo()
625569 {
626570 hqPanel.Update();
571+ _notifier.NotifyShipItemCount();
627572 materialHistoryPanel.Update();
628573 if (_listFormGroup.Visible)
629574 _listFormGroup.UpdateList();
@@ -633,7 +578,7 @@ namespace KancolleSniffer
633578 {
634579 shipInfoPanel.SetCurrentFleet();
635580 shipInfoPanel.Update();
636- NotifyDamagedShip();
581+ _notifier.NotifyDamagedShip();
637582 UpdateChargeInfo();
638583 UpdateRepairList();
639584 UpdateMissionLabels();
@@ -673,15 +618,6 @@ namespace KancolleSniffer
673618 }
674619 }
675620
676- private void NotifyDamagedShip()
677- {
678- _notificationScheduler.StopRepeat("大破警告");
679- if (!Sniffer.BadlyDamagedShips.Any())
680- return;
681- SetNotification("大破警告", string.Join(" ", Sniffer.BadlyDamagedShips));
682- _notificationScheduler.Flush();
683- }
684-
685621 private void UpdateBattleInfo()
686622 {
687623 _listFormGroup.UpdateBattleResult();
@@ -720,119 +656,6 @@ namespace KancolleSniffer
720656 _timerEnabled = true;
721657 }
722658
723- private void NotifyTimers()
724- {
725- for (var i = 0; i < Sniffer.Missions.Length; i++)
726- {
727- var entry = Sniffer.Missions[i];
728- if (entry.Name == "前衛支援任務" || entry.Name == "艦隊決戦支援任務")
729- continue;
730- CheckAlarm("遠征終了", entry.Timer, i + 1, entry.Name);
731- }
732- for (var i = 0; i < Sniffer.NDock.Length; i++)
733- {
734- var entry = Sniffer.NDock[i];
735- CheckAlarm("入渠終了", entry.Timer, i, entry.Name);
736- }
737- for (var i = 0; i < Sniffer.KDock.Length; i++)
738- {
739- var timer = Sniffer.KDock[i];
740- CheckAlarm("建造完了", timer, i, "");
741- }
742- NotifyCondTimers();
743- NotifyAkashiTimer();
744- _notificationScheduler.Flush();
745- }
746-
747- private void CheckAlarm(string key, AlarmTimer timer, int fleet, string subject)
748- {
749- if (timer.CheckAlarm(_prev, _now))
750- {
751- SetNotification(key, fleet, subject);
752- return;
753- }
754- var pre = TimeSpan.FromSeconds(Config.Notifications[key].PreliminaryPeriod);
755- if (pre == TimeSpan.Zero)
756- return;
757- if (timer.CheckAlarm(_prev + pre, _now + pre))
758- SetPreNotification(key, fleet, subject);
759- }
760-
761- private void NotifyCondTimers()
762- {
763- var notice = Sniffer.GetConditionNotice(_prev, _now);
764- var pre = TimeSpan.FromSeconds(Config.Notifications["疲労回復"].PreliminaryPeriod);
765- var preNotice = pre == TimeSpan.Zero
766- ? new int[ShipInfo.FleetCount]
767- : Sniffer.GetConditionNotice(_prev + pre, _now + pre);
768- for (var i = 0; i < ShipInfo.FleetCount; i++)
769- {
770- if (Config.NotifyConditions.Contains(notice[i]))
771- {
772- SetNotification("疲労回復" + notice[i], i, "cond" + notice[i]);
773- }
774- else if (Config.NotifyConditions.Contains(preNotice[i]))
775- {
776- SetPreNotification("疲労回復" + preNotice[i], i, "cond" + notice[i]);
777- }
778- }
779- }
780-
781- private void NotifyAkashiTimer()
782- {
783- var akashi = Sniffer.AkashiTimer;
784- var msgs = akashi.GetNotice(_prev, _now);
785- if (msgs.Length == 0)
786- {
787- _notificationScheduler.StopRepeat("泊地修理");
788- return;
789- }
790- if (!akashi.CheckRepairing(_now) && !(akashi.CheckPresetRepairing() && Config.UsePresetAkashi))
791- {
792- _notificationScheduler.StopRepeat("泊地修理");
793- return;
794- }
795- var skipPreliminary = false;
796- if (msgs[0].Proceeded == "20分経過しました。")
797- {
798- SetNotification("泊地修理20分経過", msgs[0].Proceeded);
799- msgs[0].Proceeded = "";
800- skipPreliminary = true;
801- // 修理完了がいるかもしれないので続ける
802- }
803- for (var i = 0; i < ShipInfo.FleetCount; i++)
804- {
805- if (msgs[i].Proceeded != "")
806- SetNotification("泊地修理進行", i, msgs[i].Proceeded);
807- if (msgs[i].Completed != "")
808- SetNotification("泊地修理完了", i, msgs[i].Completed);
809- }
810- var pre = TimeSpan.FromSeconds(Config.Notifications["泊地修理20分経過"].PreliminaryPeriod);
811- if (skipPreliminary || pre == TimeSpan.Zero)
812- return;
813- if ((msgs = akashi.GetNotice(_prev + pre, _now + pre))[0].Proceeded == "20分経過しました。")
814- SetPreNotification("泊地修理20分経過", 0, msgs[0].Proceeded);
815- }
816-
817- private void SetNotification(string key, string subject)
818- {
819- SetNotification(key, 0, subject);
820- }
821-
822- private void SetNotification(string key, int fleet, string subject)
823- {
824- var spec = Config.Notifications[_notificationScheduler.KeyToName(key)];
825- _notificationScheduler.Enqueue(key, fleet, subject,
826- (spec.Flags & Config.NotificationFlags & NotificationType.Repeat) == 0 ? 0 : spec.RepeatInterval);
827- }
828-
829- private void SetPreNotification(string key, int fleet, string subject)
830- {
831- var spec = Config.Notifications[_notificationScheduler.KeyToName(key)];
832- if ((spec.Flags & NotificationType.Preliminary) != 0)
833- _notificationScheduler.Enqueue(key, fleet, subject, 0, true);
834- }
835-
836659 private void UpdateRepairList()
837660 {
838661 panelRepairList.SetRepairList(Sniffer.RepairList);
@@ -843,44 +666,17 @@ namespace KancolleSniffer
843666 {
844667 questPanel.Update(Sniffer.Quests);
845668 labelQuestCount.Text = Sniffer.Quests.Length.ToString();
846- SetQuestNotification();
669+ _notifier.NotifyQuestComplete();
847670 }
848671
849- private void SetQuestNotification()
672+ private void FlashWindow()
850673 {
851- Sniffer.GetQuestNotifications(out var notify, out var stop);
852- foreach (var questName in notify)
853- SetNotification("任務達成", 0, questName);
854- foreach (var questName in stop)
855- _notificationScheduler.StopRepeat("任務達成", questName);
856- _notificationScheduler.Flush();
674+ Win32API.FlashWindow(Handle);
857675 }
858676
859- private void Alarm(string balloonTitle, string balloonMessage, string name)
677+ private void ShowTaster(string title, string message)
860678 {
861- var flags = Config.Notifications[name].Flags;
862- var effective = Config.NotificationFlags & Config.Notifications[name].Flags;
863- if ((effective & NotificationType.FlashWindow) != 0)
864- Win32API.FlashWindow(Handle);
865- if ((effective & NotificationType.ShowBaloonTip) != 0)
866- notifyIconMain.ShowBalloonTip(20000, balloonTitle, balloonMessage, ToolTipIcon.Info);
867- if ((effective & NotificationType.PlaySound) != 0)
868- PlaySound(Config.Sounds[name], Config.Sounds.Volume);
869- if (Config.Pushbullet.On && (flags & NotificationType.Push) != 0)
870- {
871- Task.Run(() =>
872- {
873- PushNotification.PushToPushbullet(Config.Pushbullet.Token, balloonTitle, balloonMessage);
874- });
875- }
876- if (Config.Pushover.On && (flags & NotificationType.Push) != 0)
877- {
878- Task.Run(() =>
879- {
880- PushNotification.PushToPushover(Config.Pushover.ApiKey, Config.Pushover.UserKey,
881- balloonTitle, balloonMessage);
882- });
883- }
679+ notifyIconMain.ShowBalloonTip(20000, title, message, ToolTipIcon.Info);
884680 }
885681
886682 [DllImport("winmm.dll")]
--- /dev/null
+++ b/KancolleSniffer/Notification/Notifier.cs
@@ -0,0 +1,276 @@
1+// Copyright (C) 2020 Kazuhiro Fujieda <fujieda@users.osdn.me>
2+//
3+// Licensed under the Apache License, Version 2.0 (the "License");
4+// you may not use this file except in compliance with the License.
5+// You may obtain a copy of the License at
6+//
7+// http://www.apache.org/licenses/LICENSE-2.0
8+//
9+// Unless required by applicable law or agreed to in writing, software
10+// distributed under the License is distributed on an "AS IS" BASIS,
11+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+// See the License for the specific language governing permissions and
13+// limitations under the License.
14+
15+using System;
16+using System.Collections.Generic;
17+using System.Linq;
18+using System.Threading.Tasks;
19+using KancolleSniffer.Model;
20+using KancolleSniffer.Net;
21+using KancolleSniffer.View;
22+
23+namespace KancolleSniffer.Notification
24+{
25+ public class Notifier : IUpdateContext, Sniffer.IRepeatingTimerController
26+ {
27+ private readonly Scheduler _scheduler;
28+ private readonly Method _method;
29+
30+ private class Method
31+ {
32+ public Action FlashWindow;
33+ public Action<string, string> ShowToaster;
34+ public Action<string, int> PlaySound;
35+ }
36+
37+ public UpdateContext Context { get; set; }
38+
39+ private DateTime Now => Context.GetNow();
40+
41+ private DateTime Prev => Context.GetPrev();
42+
43+ private NotificationConfig Notifications => Context.Config.Notifications;
44+
45+ public Notifier(Action flashWindow, Action<string, string> showToaster, Action<string, int> playSound)
46+ {
47+ _method = new Method
48+ {
49+ FlashWindow = flashWindow,
50+ ShowToaster = showToaster,
51+ PlaySound = playSound,
52+ };
53+ _scheduler = new Scheduler(Alarm);
54+ }
55+
56+ public void Stop(string key)
57+ {
58+ _scheduler.StopRepeat(key,
59+ (key == "入渠終了" || key == "遠征終了") &&
60+ (Context.Config.Notifications[key].Flags & NotificationType.Cont) != 0);
61+ }
62+
63+ public void Stop(string key, int fleet) => _scheduler.StopRepeat(key, fleet);
64+
65+ public void Suspend(string exception = null) => _scheduler.SuspendRepeat(exception);
66+
67+ public void Resume() => _scheduler.ResumeRepeat();
68+
69+ public void StopAllRepeat() => _scheduler.StopAllRepeat();
70+
71+ public void StopRepeatingTimer(IEnumerable<string> names)
72+ {
73+ foreach (var name in names)
74+ _scheduler.StopRepeat(name);
75+ }
76+
77+ public void NotifyShipItemCount()
78+ {
79+ var ship = Context.Sniffer.ShipCounter;
80+ if (ship.Alarm)
81+ {
82+ var message = $"残り{ship.Rest:D}隻";
83+ _scheduler.Enqueue("艦娘数超過", message);
84+ ship.Alarm = false;
85+ }
86+ var item = Context.Sniffer.ItemCounter;
87+ if (item.Alarm)
88+ {
89+ var message = $"残り{item.Rest:D}個";
90+ _scheduler.Enqueue("装備数超過", message);
91+ item.Alarm = false;
92+ }
93+ _scheduler.Flush();
94+ }
95+
96+ public void NotifyDamagedShip()
97+ {
98+ _scheduler.StopRepeat("大破警告");
99+ if (!Context.Sniffer.BadlyDamagedShips.Any())
100+ return;
101+ SetNotification("大破警告", string.Join(" ", Context.Sniffer.BadlyDamagedShips));
102+ _scheduler.Flush();
103+ }
104+
105+ public void NotifyTimers()
106+ {
107+ for (var i = 0; i < Context.Sniffer.Missions.Length; i++)
108+ {
109+ var entry = Context.Sniffer.Missions[i];
110+ if (entry.Name == "前衛支援任務" || entry.Name == "艦隊決戦支援任務")
111+ continue;
112+ CheckAlarm("遠征終了", entry.Timer, i + 1, entry.Name);
113+ }
114+ for (var i = 0; i < Context.Sniffer.NDock.Length; i++)
115+ {
116+ var entry = Context.Sniffer.NDock[i];
117+ CheckAlarm("入渠終了", entry.Timer, i, entry.Name);
118+ }
119+ for (var i = 0; i < Context.Sniffer.KDock.Length; i++)
120+ {
121+ var timer = Context.Sniffer.KDock[i];
122+ CheckAlarm("建造完了", timer, i, "");
123+ }
124+ NotifyCondTimers();
125+ NotifyAkashiTimer();
126+ _scheduler.Flush();
127+ }
128+
129+ private void CheckAlarm(string key, AlarmTimer timer, int fleet, string subject)
130+ {
131+ if (timer.CheckAlarm(Prev, Now))
132+ {
133+ SetNotification(key, fleet, subject);
134+ return;
135+ }
136+ var pre = TimeSpan.FromSeconds(Notifications[key].PreliminaryPeriod);
137+ if (pre == TimeSpan.Zero)
138+ return;
139+ if (timer.CheckAlarm(Prev + pre, Now + pre))
140+ SetPreNotification(key, fleet, subject);
141+ }
142+
143+ private void NotifyCondTimers()
144+ {
145+ var notice = Context.Sniffer.GetConditionNotice(Prev, Now);
146+ var pre = TimeSpan.FromSeconds(Notifications["疲労回復"].PreliminaryPeriod);
147+ var preNotice = pre == TimeSpan.Zero
148+ ? new int[ShipInfo.FleetCount]
149+ : Context.Sniffer.GetConditionNotice(Prev + pre, Now + pre);
150+ var conditions = Context.Config.NotifyConditions;
151+ for (var i = 0; i < ShipInfo.FleetCount; i++)
152+ {
153+ if (conditions.Contains(notice[i]))
154+ {
155+ SetNotification("疲労回復" + notice[i], i, "cond" + notice[i]);
156+ }
157+ else if (conditions.Contains(preNotice[i]))
158+ {
159+ SetPreNotification("疲労回復" + preNotice[i], i, "cond" + notice[i]);
160+ }
161+ }
162+ }
163+
164+ private void NotifyAkashiTimer()
165+ {
166+ var akashi = Context.Sniffer.AkashiTimer;
167+ var msgs = akashi.GetNotice(Prev, Now);
168+ if (msgs.Length == 0)
169+ {
170+ _scheduler.StopRepeat("泊地修理");
171+ return;
172+ }
173+ if (!akashi.CheckRepairing(Context.GetNow()) && !(akashi.CheckPresetRepairing() && Context.Config.UsePresetAkashi))
174+ {
175+ _scheduler.StopRepeat("泊地修理");
176+ return;
177+ }
178+ var skipPreliminary = false;
179+ if (msgs[0].Proceeded == "20分経過しました。")
180+ {
181+ SetNotification("泊地修理20分経過", msgs[0].Proceeded);
182+ msgs[0].Proceeded = "";
183+ skipPreliminary = true;
184+ // 修理完了がいるかもしれないので続ける
185+ }
186+ for (var i = 0; i < ShipInfo.FleetCount; i++)
187+ {
188+ if (msgs[i].Proceeded != "")
189+ SetNotification("泊地修理進行", i, msgs[i].Proceeded);
190+ if (msgs[i].Completed != "")
191+ SetNotification("泊地修理完了", i, msgs[i].Completed);
192+ }
193+ var pre = TimeSpan.FromSeconds(Notifications["泊地修理20分経過"].PreliminaryPeriod);
194+ if (skipPreliminary || pre == TimeSpan.Zero)
195+ return;
196+ if ((msgs = akashi.GetNotice(Prev + pre, Now + pre))[0].Proceeded == "20分経過しました。")
197+ SetPreNotification("泊地修理20分経過", 0, msgs[0].Proceeded);
198+ }
199+
200+ public void NotifyQuestComplete()
201+ {
202+ Context.Sniffer.GetQuestNotifications(out var notify, out var stop);
203+ foreach (var questName in notify)
204+ SetNotification("任務達成", 0, questName);
205+ foreach (var questName in stop)
206+ _scheduler.StopRepeat("任務達成", questName);
207+ _scheduler.Flush();
208+ }
209+
210+ private void SetNotification(string key, string subject)
211+ {
212+ SetNotification(key, 0, subject);
213+ }
214+
215+ private void SetNotification(string key, int fleet, string subject)
216+ {
217+ var spec = Spec(key);
218+ _scheduler.Enqueue(key, fleet, subject,
219+ (spec.Flags & Context.Config.NotificationFlags & NotificationType.Repeat) == 0
220+ ? 0
221+ : spec.RepeatInterval);
222+ }
223+
224+ private void SetPreNotification(string key, int fleet, string subject)
225+ {
226+ if ((Spec(key).Flags & NotificationType.Preliminary) != 0)
227+ _scheduler.Enqueue(key, fleet, subject, 0, true);
228+ }
229+
230+ private NotificationSpec Spec(string key)
231+ {
232+ return Notifications[_scheduler.KeyToName(key)];
233+ }
234+
235+ private void Alarm(string balloonTitle, string balloonMessage, string name)
236+ {
237+ if (Check(name, NotificationType.FlashWindow))
238+ _method.FlashWindow();
239+ if (Check(name, NotificationType.ShowBaloonTip))
240+ _method.ShowToaster(balloonTitle, balloonMessage);
241+ if (Check(name, NotificationType.PlaySound))
242+ _method.PlaySound(Context.Config.Sounds[name], Context.Config.Sounds.Volume);
243+ if (Context.Config.Pushbullet.On && CheckPush(name))
244+ {
245+ Task.Run(() =>
246+ {
247+ PushNotification.PushToPushbullet(Context.Config.Pushbullet.Token, balloonTitle,
248+ balloonMessage);
249+ });
250+ }
251+ if (Context.Config.Pushover.On && CheckPush(name))
252+ {
253+ Task.Run(() =>
254+ {
255+ PushNotification.PushToPushover(Context.Config.Pushover.ApiKey, Context.Config.Pushover.UserKey,
256+ balloonTitle, balloonMessage);
257+ });
258+ }
259+ }
260+
261+ private bool Check(string name, NotificationType type)
262+ {
263+ return (Flags(name) & type) != 0;
264+ }
265+
266+ private NotificationType Flags(string name)
267+ {
268+ return Context.Config.NotificationFlags & Notifications[name].Flags;
269+ }
270+
271+ private bool CheckPush(string name)
272+ {
273+ return (Notifications[name].Flags & NotificationType.Push) != 0;
274+ }
275+ }
276+}
\ No newline at end of file
--- a/KancolleSniffer/View/HqPanel.cs
+++ b/KancolleSniffer/View/HqPanel.cs
@@ -124,7 +124,6 @@ namespace KancolleSniffer.View
124124 {
125125 UpdateNumOfShips();
126126 UpdateNumOfEquips();
127- Context.Submitter.Flash();
128127 UpdateNumOfBuckets();
129128 UpdateBucketHistory();
130129 UpdateAchievement();
@@ -151,12 +150,6 @@ namespace KancolleSniffer.View
151150 var ship = Context.Sniffer.ShipCounter;
152151 _numOfShips.Text = $"{ship.Now:D}/{ship.Max:D}";
153152 _numOfShips.ForeColor = ship.TooMany ? CUDColors.Red : Color.Black;
154- if (ship.Alarm)
155- {
156- var message = $"残り{ship.Rest:D}隻";
157- Context.Submitter.Enqueue("艦娘数超過", message);
158- ship.Alarm = false;
159- }
160153 }
161154
162155 private void UpdateNumOfEquips()
@@ -164,12 +157,6 @@ namespace KancolleSniffer.View
164157 var item = Context.Sniffer.ItemCounter;
165158 _numOfEquips.Text = $"{item.Now:D}/{item.Max:D}";
166159 _numOfEquips.ForeColor = item.TooMany ? CUDColors.Red : Color.Black;
167- if (item.Alarm)
168- {
169- var message = $"残り{item.Rest:D}個";
170- Context.Submitter.Enqueue("装備数超過", message);
171- item.Alarm = false;
172- }
173160 }
174161
175162 private void UpdateBucketHistory()
--- a/KancolleSniffer/View/UpdateContext.cs
+++ b/KancolleSniffer/View/UpdateContext.cs
@@ -20,15 +20,15 @@ namespace KancolleSniffer.View
2020 {
2121 public Sniffer Sniffer { get; }
2222 public Config Config { get; }
23- public MainForm.INotifySubmitter Submitter { get; }
2423 public Func<DateTime> GetNow { get; }
24+ public Func<DateTime> GetPrev { get; }
2525
26- public UpdateContext(Sniffer sniffer, Config config, MainForm.INotifySubmitter submitter, Func<DateTime> getNow)
26+ public UpdateContext(Sniffer sniffer, Config config, Func<DateTime> getNow, Func<DateTime> getPrev)
2727 {
2828 Sniffer = sniffer;
2929 Config = config;
30- Submitter = submitter;
3130 GetNow = getNow;
31+ GetPrev = getPrev;
3232 }
3333 }
3434 }
\ No newline at end of file