OSDN Git Service

先制対潜の判定を最新の検証結果に合わせる
[kancollesniffer/KancolleSniffer.git] / KancolleSniffer / NotificationManager.cs
index ee1431d..6c1ccd3 100644 (file)
@@ -16,7 +16,7 @@ using System;
 using System.Collections.Generic;\r
 using System.IO;\r
 using System.Linq;\r
-using System.Windows.Forms;\r
+using KancolleSniffer.Util;\r
 \r
 namespace KancolleSniffer\r
 {\r
@@ -24,28 +24,38 @@ namespace KancolleSniffer
     {\r
         private readonly NotificationQueue _notificationQueue;\r
 \r
+        private enum Mode\r
+        {\r
+            Normal,\r
+            Repeat,\r
+            Cont,\r
+            Preliminary\r
+        }\r
+\r
         private class Notification\r
         {\r
             public string Key { get; set; }\r
             public int Fleet { get; set; }\r
             public string Subject { get; set; }\r
             public int Repeat { get; set; }\r
+            public Mode Mode { get; set; }\r
             public DateTime Schedule { get; set; }\r
         }\r
 \r
-        public NotificationManager(Action<string, string, string> ring, ITimer timer = null)\r
+        public NotificationManager(Action<string, string, string> alarm, Func<DateTime> nowFunc = null)\r
         {\r
-            _notificationQueue = new NotificationQueue(ring, timer);\r
+            _notificationQueue = new NotificationQueue(alarm, nowFunc);\r
         }\r
 \r
-        public void Enqueue(string key, int fleet, string subject, int repeat = 0)\r
+        public void Enqueue(string key, int fleet, string subject, int repeat = 0, bool preliminary = false)\r
         {\r
             _notificationQueue.Enqueue(new Notification\r
             {\r
                 Key = key,\r
                 Fleet = fleet,\r
                 Subject = subject,\r
-                Repeat = repeat\r
+                Repeat = repeat,\r
+                Mode = preliminary ? Mode.Preliminary : Mode.Normal\r
             });\r
         }\r
 \r
@@ -54,14 +64,34 @@ namespace KancolleSniffer
             Enqueue(key, 0, subject, repeat);\r
         }\r
 \r
-        public void StopRepeat(string key)\r
+        public void Flash()\r
+        {\r
+            _notificationQueue.Flash();\r
+        }\r
+\r
+        public void StopRepeat(string key, bool cont = false)\r
+        {\r
+            _notificationQueue.StopRepeat(key, cont);\r
+        }\r
+\r
+        public void StopRepeat(string key, int fleet)\r
+        {\r
+            _notificationQueue.StopRepeat(key, fleet);\r
+        }\r
+\r
+        public void StopRepeat(string key, string subject)\r
         {\r
-            _notificationQueue.StopRepeat(key);\r
+            _notificationQueue.StopRepeat(key, subject);\r
         }\r
 \r
-        public void SuspendRepeat()\r
+        public void StopAllRepeat()\r
         {\r
-            _notificationQueue.SuspendRepeat();\r
+            _notificationQueue.StopAllRepeat();\r
+        }\r
+\r
+        public void SuspendRepeat(string exception = "")\r
+        {\r
+            _notificationQueue.SuspendRepeat(exception);\r
         }\r
 \r
         public void ResumeRepeat()\r
@@ -88,21 +118,21 @@ namespace KancolleSniffer
                     "遠征終了", new Message\r
                     {\r
                         Title = "遠征が終わりました",\r
-                        Body = "%s"\r
+                        Body = "%f艦隊 %s"\r
                     }\r
                 },\r
                 {\r
                     "入渠終了", new Message\r
                     {\r
                         Title = "入渠が終わりました",\r
-                        Body = "%s"\r
+                        Body = "%fドック %s"\r
                     }\r
                 },\r
                 {\r
                     "建造完了", new Message\r
                     {\r
                         Title = "建造が終わりました",\r
-                        Body = "%s"\r
+                        Body = "%fドック"\r
                     }\r
                 },\r
                 {\r
@@ -129,21 +159,21 @@ namespace KancolleSniffer
                 {\r
                     "泊地修理20分経過", new Message\r
                     {\r
-                        Title = "泊地修理 %f",\r
+                        Title = "泊地修理 %f艦隊",\r
                         Body = "20分経過しました。"\r
                     }\r
                 },\r
                 {\r
                     "泊地修理進行", new Message\r
                     {\r
-                        Title = "泊地修理 %f",\r
+                        Title = "泊地修理 %f艦隊",\r
                         Body = "修理進行:%s"\r
                     }\r
                 },\r
                 {\r
                     "泊地修理完了", new Message\r
                     {\r
-                        Title = "泊地修理 %f",\r
+                        Title = "泊地修理 %f艦隊",\r
                         Body = "修理完了:%s"\r
                     }\r
                 },\r
@@ -151,14 +181,21 @@ namespace KancolleSniffer
                     "疲労回復40", new Message\r
                     {\r
                         Title = "疲労が回復しました",\r
-                        Body = "%f 残り9分"\r
+                        Body = "%f艦隊 残り9分"\r
                     }\r
                 },\r
                 {\r
                     "疲労回復49", new Message\r
                     {\r
                         Title = "疲労が回復しました",\r
-                        Body = "%f"\r
+                        Body = "%f艦隊"\r
+                    }\r
+                },\r
+                {\r
+                    "任務達成", new Message\r
+                    {\r
+                        Title = "任務を達成しました",\r
+                        Body = "%s"\r
                     }\r
                 }\r
             };\r
@@ -195,10 +232,13 @@ namespace KancolleSniffer
             public Message GenerateMessage(Notification notification)\r
             {\r
                 LoadConfig();\r
-                var format = _config.TryGetValue(notification.Key, out Message value) ? value : _default[notification.Key];\r
+                var format = _config.TryGetValue(notification.Key, out Message value)\r
+                    ? value\r
+                    : _default[notification.Key];\r
+                var prefix = new[] {"", "[リピート] ", "[継続] ", "[予告] "}[(int)notification.Mode];\r
                 return new Message\r
                 {\r
-                    Title = ProcessFormatString(format.Title, notification.Fleet, notification.Subject),\r
+                    Title = prefix + ProcessFormatString(format.Title, notification.Fleet, notification.Subject),\r
                     Body = ProcessFormatString(format.Body, notification.Fleet, notification.Subject),\r
                     Name = KeyToName(notification.Key)\r
                 };\r
@@ -206,7 +246,7 @@ namespace KancolleSniffer
 \r
             private string ProcessFormatString(string format, int fleet, string subject)\r
             {\r
-                var fn = new[] {"第一艦隊", "第二艦隊", "第三艦隊", "第四艦隊"};\r
+                var fn = new[] {"第一", "第二", "第三", "第四"};\r
                 var result = "";\r
                 var percent = false;\r
                 foreach (var ch in format)\r
@@ -248,88 +288,71 @@ namespace KancolleSniffer
             }\r
         }\r
 \r
-        public interface ITimer\r
-        {\r
-            int Interval { get; set; }\r
-            bool Enabled { get; set; }\r
-            event EventHandler Tick;\r
-            void Start();\r
-            void Stop();\r
-            DateTime Now { get; }\r
-        }\r
-\r
-        public class TimerWrapper : ITimer\r
+        private class NotificationQueue\r
         {\r
-            private readonly Timer _timer = new Timer();\r
+            private readonly Action<string, string, string> _alarm;\r
+            private readonly List<Notification> _queue = new List<Notification>();\r
+            private readonly Func<DateTime> _nowFunc = () => DateTime.Now;\r
+            private readonly NotificationConfig _notificationConfig = new NotificationConfig();\r
+            private DateTime _lastAlarm;\r
+            private bool _suspend;\r
+            private string _suspendException;\r
 \r
-            public int Interval\r
+            public NotificationQueue(Action<string, string, string> alarm, Func<DateTime> nowFunc = null)\r
             {\r
-                get => _timer.Interval;\r
-                set => _timer.Interval = value;\r
+                _alarm = alarm;\r
+                if (nowFunc != null)\r
+                    _nowFunc = nowFunc;\r
             }\r
 \r
-            public bool Enabled\r
+            public void Enqueue(Notification notification)\r
             {\r
-                get => _timer.Enabled;\r
-                set => _timer.Enabled = value;\r
+                _queue.Add(notification);\r
             }\r
 \r
-            public event EventHandler Tick\r
+            public void Flash()\r
             {\r
-                add => _timer.Tick += value;\r
-                remove => _timer.Tick -= value;\r
+                Alarm();\r
             }\r
 \r
-            public void Start() => _timer.Start();\r
-\r
-            public void Stop() => _timer.Stop();\r
-\r
-            public DateTime Now => DateTime.Now;\r
-        }\r
-\r
-        private class NotificationQueue\r
-        {\r
-            private readonly Action<string, string, string> _ring;\r
-            private readonly List<Notification> _queue = new List<Notification>();\r
-            private readonly ITimer _timer;\r
-            private readonly NotificationConfig _notificationConfig = new NotificationConfig();\r
-            private DateTime _lastRing;\r
-            private bool _suspend;\r
-\r
-            public NotificationQueue(Action<string, string, string> ring, ITimer timer = null)\r
+            public void StopRepeat(string key, bool cont = false)\r
             {\r
-                _ring = ring;\r
-                _timer = timer ?? new TimerWrapper();\r
-                _timer.Interval = 1000;\r
-                _timer.Tick += TimerOnTick;\r
+                if (!cont)\r
+                {\r
+                    _queue.RemoveAll(n => IsMatch(n, key));\r
+                }\r
+                else\r
+                {\r
+                    foreach (var n in _queue.Where(n => IsMatch(n, key)))\r
+                    {\r
+                        n.Subject = "";\r
+                        n.Mode = Mode.Cont;\r
+                    }\r
+                }\r
             }\r
 \r
-            private void TimerOnTick(object obj, EventArgs e)\r
+            public void StopRepeat(string key, int fleet)\r
             {\r
-                if (_queue.Count == 0)\r
-                {\r
-                    _timer.Stop();\r
-                    return;\r
-                }\r
-                Ring();\r
+                _queue.RemoveAll(n => IsMatch(n, key) && n.Fleet == fleet);\r
             }\r
 \r
-            public void Enqueue(Notification notification)\r
+            public void StopRepeat(string key, string subject)\r
             {\r
-                _queue.Add(notification);\r
-                Ring();\r
-                if (_queue.Count > 0)\r
-                    _timer.Start();\r
+                _queue.RemoveAll(n => IsMatch(n, key) && n.Subject == subject);\r
             }\r
 \r
-            public void StopRepeat(string key)\r
+            private bool IsMatch(Notification n, string key) =>\r
+                n.Key.Substring(0, 4) == key.Substring(0, 4) && n.Schedule != default;\r
+\r
+            public void StopAllRepeat()\r
             {\r
-                _queue.RemoveAll(n => n.Key.Substring(0, 4) == key.Substring(0, 4) && n.Schedule != default);\r
+                _queue.RemoveAll(n => n.Schedule != default);\r
             }\r
 \r
-            public void SuspendRepeat()\r
+            public void SuspendRepeat(string exception = null)\r
             {\r
                 _suspend = true;\r
+                _suspendException = exception;\r
             }\r
 \r
             public void ResumeRepeat()\r
@@ -337,27 +360,35 @@ namespace KancolleSniffer
                 _suspend = false;\r
             }\r
 \r
-            private void Ring()\r
+            private void Alarm()\r
             {\r
-                var now = _timer.Now;\r
-                if (now - _lastRing < TimeSpan.FromSeconds(2))\r
+                var now = _nowFunc();\r
+                if (now - _lastAlarm < TimeSpan.FromSeconds(2))\r
                     return;\r
-                var notification = _queue.FirstOrDefault(n => n.Schedule.CompareTo(now) <= 0 &&\r
-                                                              !(_suspend && n.Schedule != default));\r
-                if (notification == null)\r
+                var first = _queue.FirstOrDefault(n => n.Schedule.CompareTo(now) <= 0 &&\r
+                                                       !(n.Schedule != default && _suspend && n.Key != _suspendException));\r
+                if (first == null)\r
                     return;\r
-                if (notification.Repeat == 0)\r
+                var message = _notificationConfig.GenerateMessage(first);\r
+                var similar = _queue.Where(n =>\r
+                        _notificationConfig.GenerateMessage(n).Name == message.Name && n.Schedule.CompareTo(now) <= 0)\r
+                    .ToArray();\r
+                var body = string.Join("\r\n", similar.Select(n => _notificationConfig.GenerateMessage(n).Body));\r
+                foreach (var n in similar)\r
                 {\r
-                    _queue.Remove(notification);\r
-                }\r
-                else\r
-                {\r
-                    notification.Schedule = _timer.Now + TimeSpan.FromSeconds(notification.Repeat);\r
+                    if (n.Repeat == 0)\r
+                    {\r
+                        _queue.Remove(n);\r
+                    }\r
+                    else\r
+                    {\r
+                        n.Schedule = now + TimeSpan.FromSeconds(n.Repeat);\r
+                        if (n.Mode == Mode.Normal)\r
+                            n.Mode = Mode.Repeat;\r
+                    }\r
                 }\r
-                var message =\r
-                    _notificationConfig.GenerateMessage(notification);\r
-                _ring(message.Title, message.Body, message.Name);\r
-                _lastRing = now;\r
+                _alarm(message.Title, body, message.Name);\r
+                _lastAlarm = now;\r
             }\r
         }\r
     }\r