using System.Globalization;\r
using System.IO;\r
using System.Linq;\r
-using System.Net.Sockets;\r
using System.Runtime.InteropServices;\r
using System.Text;\r
using System.Text.RegularExpressions;\r
using System.Threading.Tasks;\r
using System.Windows.Forms;\r
using Microsoft.CSharp.RuntimeBinder;\r
-using Microsoft.Win32;\r
using static System.Math;\r
-using Timer = System.Windows.Forms.Timer;\r
\r
namespace KancolleSniffer\r
{\r
private readonly Sniffer _sniffer = new Sniffer();\r
private readonly Config _config = new Config();\r
private readonly ConfigDialog _configDialog;\r
+ private readonly ProxyManager _proxyManager;\r
private int _currentFleet;\r
private bool _combinedFleet;\r
private readonly Label[] _labelCheckFleets;\r
private readonly ShipLabels _shipLabels;\r
private readonly ListForm _listForm;\r
- private readonly NoticeQueue _noticeQueue;\r
+ private readonly NotificationManager _notificationManager;\r
private bool _started;\r
private string _debugLogFile;\r
private IEnumerator<string> _playLog;\r
- private int _prevProxyPort;\r
- private readonly SystemProxy _systemProxy = new SystemProxy();\r
+\r
private readonly ErrorDialog _errorDialog = new ErrorDialog();\r
private bool _missionFinishTimeMode;\r
private bool _ndockFinishTimeMode;\r
panelRepairList.CreateLabels(panelRepairList_Click);\r
labelPresetAkashiTimer.BackColor = ShipLabels.ColumnColors[1];\r
_listForm = new ListForm(_sniffer, _config) {Owner = this};\r
- _noticeQueue = new NoticeQueue(Ring);\r
+ _notificationManager = new NotificationManager(Ring);\r
_config.Load();\r
+ _proxyManager = new ProxyManager(_config, this);\r
PerformZoom();\r
_shipLabels.AdjustAkashiTimers();\r
_sniffer.LoadState();\r
ApplyDebugLogSetting();\r
ApplyLogSetting();\r
ApplyProxySetting();\r
- SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;\r
if (_config.KancolleDb.On)\r
_kancolleDb.Start(_config.KancolleDb.Token);\r
}\r
\r
- private void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e)\r
- {\r
- if (e.Mode != PowerModes.Resume || !_config.Proxy.Auto)\r
- return;\r
- SystemProxy.Refresh();\r
- }\r
-\r
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)\r
{\r
+ using (var dialog = new ConfirmDialog())\r
+ {\r
+ if (dialog.ShowDialog(this) != DialogResult.Yes)\r
+ {\r
+ e.Cancel = true;\r
+ return;\r
+ }\r
+ }\r
e.Cancel = false;\r
_sniffer.FlashLog();\r
_config.Location = (WindowState == FormWindowState.Normal ? Bounds : RestoreBounds).Location;\r
_config.Save();\r
- Task.Run(() => ShutdownProxy());\r
- if (_config.Proxy.Auto)\r
- _systemProxy.RestoreSettings();\r
- SystemEvents.PowerModeChanged -= SystemEvents_PowerModeChanged;\r
+ _proxyManager.Shutdown();\r
_kancolleDb.Stop();\r
}\r
\r
- private void ShutdownProxy()\r
- {\r
- HttpProxy.Shutdown();\r
- }\r
-\r
private void MainForm_Resize(object sender, EventArgs e)\r
{\r
ShowInTaskbar = !(_config.HideOnMinimized && WindowState == FormWindowState.Minimized);\r
\r
public bool ApplyProxySetting()\r
{\r
- if (!_config.Proxy.Auto)\r
- _systemProxy.RestoreSettings();\r
- if (_config.Proxy.UseUpstream)\r
- {\r
- HttpProxy.UpstreamProxyHost = "127.0.0.1";\r
- HttpProxy.UpstreamProxyPort = _config.Proxy.UpstreamPort;\r
- }\r
- HttpProxy.IsEnableUpstreamProxy = _config.Proxy.UseUpstream;\r
- var result = true;\r
- if (!HttpProxy.IsInListening || _config.Proxy.Listen != _prevProxyPort)\r
- {\r
- ShutdownProxy();\r
- result = StartProxy();\r
- }\r
- if (_config.Proxy.Auto && result)\r
- {\r
- _systemProxy.SetAutoProxyUrl($"http://localhost:{_config.Proxy.Listen}/proxy.pac");\r
- }\r
- _prevProxyPort = _config.Proxy.Listen;\r
- return result;\r
- }\r
-\r
- private bool StartProxy()\r
- {\r
- try\r
- {\r
- HttpProxy.Startup(_config.Proxy.Listen, false, false);\r
- }\r
- catch (SocketException e)\r
- {\r
- if (e.SocketErrorCode != SocketError.AddressAlreadyInUse)\r
- throw;\r
- if (WarnConflictPortNumber("プロキシサーバー", _config.Proxy.Listen, _config.Proxy.Auto) == DialogResult.No ||\r
- !_config.Proxy.Auto)\r
- {\r
- _systemProxy.RestoreSettings();\r
- return false;\r
- }\r
- HttpProxy.Startup(0, false, false);\r
- _config.Proxy.Listen = HttpProxy.LocalPort;\r
- }\r
- return true;\r
- }\r
-\r
- private DialogResult WarnConflictPortNumber(string name, int port, bool auto)\r
- {\r
- var msg = $"{name}のポート番号{port}は他のアプリケーションが使用中です。";\r
- var cap = "ポート番号の衝突";\r
- return auto\r
- ? MessageBox.Show(this, msg + "自動的に別の番号を割り当てますか?", cap,\r
- MessageBoxButtons.YesNo, MessageBoxIcon.Question)\r
- : MessageBox.Show(this, msg + "設定ダイアログでポート番号を変更してください。", cap,\r
- MessageBoxButtons.OK, MessageBoxIcon.Exclamation);\r
+ return _proxyManager.ApplyConfig();\r
}\r
\r
public void ApplyLogSetting()\r
if (item.RingShips)\r
{\r
var message = $"残り{_sniffer.Item.MaxShips - _sniffer.Item.NowShips:D}隻";\r
- _noticeQueue.Enqueue("艦娘が多すぎます", message, "艦娘数超過");\r
+ _notificationManager.Enqueue("艦娘数超過", message);\r
item.RingShips = false;\r
}\r
}\r
if (item.RingEquips)\r
{\r
var message = $"残り{_sniffer.Item.MaxEquips - _sniffer.Item.NowEquips:D}個";\r
- _noticeQueue.Enqueue("装備が多すぎます", message, "装備数超過");\r
+ _notificationManager.Enqueue("装備数超過", message);\r
item.RingEquips = false;\r
}\r
}\r
private void NotifyDamagedShip()\r
{\r
if (_sniffer.BadlyDamagedShips.Any())\r
- _noticeQueue.Enqueue("大破した艦娘がいます", string.Join(" ", _sniffer.BadlyDamagedShips), "大破警告");\r
+ _notificationManager.Enqueue("大破警告", string.Join(" ", _sniffer.BadlyDamagedShips));\r
}\r
\r
private void NotifyAkashiTimer()\r
return;\r
if (msgs[0].Proceeded == "20分経過しました。")\r
{\r
- _noticeQueue.Enqueue("泊地修理", msgs[0].Proceeded, "泊地修理20分経過");\r
+ _notificationManager.Enqueue("泊地修理20分経過", msgs[0].Proceeded);\r
msgs[0].Proceeded = "";\r
// 修理完了がいるかもしれないので続ける\r
}\r
- var fn = new[] {"第一艦隊", "第二艦隊", "第三艦隊", "第四艦隊"};\r
- for (var i = 0; i < fn.Length; i++)\r
+ for (var i = 0; i < ShipInfo.FleetCount; i++)\r
{\r
if (msgs[i].Proceeded != "")\r
- _noticeQueue.Enqueue("泊地修理 " + fn[i], "修理進行:" + msgs[i].Proceeded, "泊地修理進行");\r
+ _notificationManager.Enqueue("泊地修理進行", i, msgs[i].Proceeded);\r
if (msgs[i].Completed != "")\r
- _noticeQueue.Enqueue("泊地修理 " + fn[i], "修理完了:" + msgs[i].Completed, "泊地修理完了");\r
+ _notificationManager.Enqueue("泊地修理完了", i, msgs[i].Completed);\r
}\r
}\r
\r
entry.label.Text = entry.Timer.ToString(_missionFinishTimeMode);\r
if (!entry.Timer.NeedRing)\r
continue;\r
- _noticeQueue.Enqueue("遠征が終わりました", entry.Name, "遠征終了");\r
+ _notificationManager.Enqueue("遠征終了", entry.Name);\r
entry.Timer.NeedRing = false;\r
}\r
for (var i = 0; i < _sniffer.NDock.Length; i++)\r
_shipLabels.SetNDockTimer(i, entry.Timer, _ndockFinishTimeMode);\r
if (!entry.Timer.NeedRing)\r
continue;\r
- _noticeQueue.Enqueue("入渠が終わりました", entry.Name, "入渠終了");\r
+ _notificationManager.Enqueue("入渠終了", entry.Name);\r
entry.Timer.NeedRing = false;\r
}\r
var kdock = new[] {labelConstruct1, labelConstruct2, labelConstruct3, labelConstruct4};\r
kdock[i].Text = timer.EndTime == DateTime.MinValue ? "" : timer.Rest.ToString(@"hh\:mm\:ss");\r
if (!timer.NeedRing)\r
continue;\r
- _noticeQueue.Enqueue("建造が終わりました", $"第{i + 1:D}ドック", "建造完了");\r
+ _notificationManager.Enqueue("建造完了", $"第{i + 1:D}ドック");\r
timer.NeedRing = false;\r
}\r
UpdateCondTimers();\r
var notice = _sniffer.GetConditionNotice();\r
if (notice == null)\r
return;\r
- var fn = new[] {"第一艦隊", "第二艦隊", "第三艦隊", "第四艦隊"};\r
- for (var i = 0; i < fn.Length; i++)\r
+ for (var i = 0; i < ShipInfo.FleetCount; i++)\r
{\r
if (!_config.NotifyConditions.Contains(notice[i]))\r
return;\r
- _noticeQueue.Enqueue("疲労が回復しました", fn[i] + " cond" + notice[i].ToString("D"), "疲労回復");\r
+ _notificationManager.Enqueue("疲労回復" + notice[i], i, "cond" + notice[i]);\r
}\r
}\r
\r
}\r
}\r
\r
- private class NoticeQueue\r
- {\r
- private readonly Action<string, string, string> _ring;\r
- private readonly Queue<Tuple<string, string, string>> _queue = new Queue<Tuple<string, string, string>>();\r
- private readonly Timer _timer = new Timer {Interval = 2000};\r
-\r
- public NoticeQueue(Action<string, string, string> ring)\r
- {\r
- _ring = ring;\r
- _timer.Tick += TimerOnTick;\r
- }\r
-\r
- private void TimerOnTick(object obj, EventArgs e)\r
- {\r
- if (_queue.Count == 0)\r
- {\r
- _timer.Stop();\r
- return;\r
- }\r
- var notice = _queue.Dequeue();\r
- _ring(notice.Item1, notice.Item2, notice.Item3);\r
- }\r
-\r
- public void Enqueue(string title, string message, string name)\r
- {\r
- if (_timer.Enabled)\r
- {\r
- _queue.Enqueue(new Tuple<string, string, string>(title, message, name));\r
- }\r
- else\r
- {\r
- _ring(title, message, name);\r
- _timer.Start();\r
- }\r
- }\r
- }\r
-\r
- private void Ring(string baloonTitle, string baloonMessage, string name)\r
+ private void Ring(string balloonTitle, string balloonMessage, string name)\r
{\r
if (_config.FlashWindow && (_config.Notifications[name] & NotificationType.FlashWindow) != 0)\r
Win32API.FlashWindow(Handle);\r
if (_config.ShowBaloonTip && (_config.Notifications[name] & NotificationType.ShowBaloonTip) != 0)\r
- notifyIconMain.ShowBalloonTip(20000, baloonTitle, baloonMessage, ToolTipIcon.Info);\r
+ notifyIconMain.ShowBalloonTip(20000, balloonTitle, balloonMessage, ToolTipIcon.Info);\r
if (_config.PlaySound && (_config.Notifications[name] & NotificationType.PlaySound) != 0)\r
PlaySound(_config.Sounds[name], _config.Sounds.Volume);\r
+ if (_config.Pushbullet.On && (_config.Notifications[name] & NotificationType.Pushbullet) != 0)\r
+ {\r
+ Task.Run(() =>\r
+ {\r
+ PushBullet.PushNote(_config.Pushbullet.Token, balloonTitle, balloonMessage);\r
+ });\r
+ }\r
}\r
\r
[DllImport("winmm.dll")]\r