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
{\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
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 SuspendRepeat(string exception = "")\r
+ {\r
+ _notificationQueue.SuspendRepeat(exception);\r
+ }\r
+\r
+ public void ResumeRepeat()\r
{\r
- _notificationQueue.StopRepeat(key);\r
+ _notificationQueue.ResumeRepeat();\r
}\r
\r
public string KeyToName(string key) => NotificationConfig.KeyToName(key);\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ドック %s"\r
}\r
},\r
{\r
"建造完了", new Message\r
{\r
Title = "建造が終わりました",\r
- Body = "%s"\r
+ Body = "%fドック"\r
}\r
},\r
{\r
{\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
"疲労回復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
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
\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
}\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
-\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
+ private bool IsMatch(Notification n, string key) =>\r
+ n.Key.Substring(0, 4) == key.Substring(0, 4) && n.Schedule != default;\r
+\r
+ public void SuspendRepeat(string exception = null)\r
{\r
- _queue.Add(notification);\r
- Ring();\r
- if (_queue.Count > 0)\r
- _timer.Start();\r
+ _suspend = true;\r
+ _suspendException = exception;\r
}\r
\r
- public void StopRepeat(string key)\r
+ public void ResumeRepeat()\r
{\r
- _queue.RemoveAll(n => n.Key.Substring(0, 4) == key.Substring(0, 4) && n.Schedule != default);\r
+ _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
- 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
- {\r
- _queue.Remove(notification);\r
- }\r
- else\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
- 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