OSDN Git Service

95ee961ce324f117b3481c39cbcfa0e376432d45
[kancollesniffer/KancolleSniffer.git] / KancolleSniffer / ProxyManager.cs
1 // Copyright (C) 2017 Kazuhiro Fujieda <fujieda@users.osdn.me>\r
2 //\r
3 // Licensed under the Apache License, Version 2.0 (the "License");\r
4 // you may not use this file except in compliance with the License.\r
5 // You may obtain a copy of the License at\r
6 //\r
7 //    http://www.apache.org/licenses/LICENSE-2.0\r
8 //\r
9 // Unless required by applicable law or agreed to in writing, software\r
10 // distributed under the License is distributed on an "AS IS" BASIS,\r
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
12 // See the License for the specific language governing permissions and\r
13 // limitations under the License.\r
14 \r
15 using System.Net.Sockets;\r
16 using System.Threading.Tasks;\r
17 using System.Windows.Forms;\r
18 using Microsoft.Win32;\r
19 \r
20 namespace KancolleSniffer\r
21 {\r
22     public class ProxyManager\r
23     {\r
24         private readonly Config _config;\r
25         private readonly Control _parent;\r
26         private readonly SystemProxy _systemProxy = new SystemProxy();\r
27         private int _prevProxyPort;\r
28 \r
29         public ProxyManager(Config config, Control parent)\r
30         {\r
31             _config = config;\r
32             _parent = parent;\r
33             SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;\r
34         }\r
35 \r
36         public bool ApplyConfig()\r
37         {\r
38             if (!_config.Proxy.Auto)\r
39                 _systemProxy.RestoreSettings();\r
40             if (_config.Proxy.UseUpstream)\r
41             {\r
42                 HttpProxy.UpstreamProxyHost = "127.0.0.1";\r
43                 HttpProxy.UpstreamProxyPort = _config.Proxy.UpstreamPort;\r
44             }\r
45             HttpProxy.IsEnableUpstreamProxy = _config.Proxy.UseUpstream;\r
46             var result = true;\r
47             if (!HttpProxy.IsInListening || _config.Proxy.Listen != _prevProxyPort)\r
48             {\r
49                 ShutdownProxy();\r
50                 result = StartProxy();\r
51             }\r
52             if (_config.Proxy.Auto && result)\r
53             {\r
54                 _systemProxy.SetAutoProxyUrl($"http://localhost:{_config.Proxy.Listen}/proxy.pac");\r
55             }\r
56             _prevProxyPort = _config.Proxy.Listen;\r
57             return result;\r
58         }\r
59 \r
60         private bool StartProxy()\r
61         {\r
62             try\r
63             {\r
64                 HttpProxy.Startup(_config.Proxy.Listen, false, false);\r
65             }\r
66             catch (SocketException e)\r
67             {\r
68                 if (e.SocketErrorCode != SocketError.AddressAlreadyInUse)\r
69                     throw;\r
70                 if (WarnConflictPortNumber("プロキシサーバー", _config.Proxy.Listen, _config.Proxy.Auto) == DialogResult.No ||\r
71                     !_config.Proxy.Auto)\r
72                 {\r
73                     _systemProxy.RestoreSettings();\r
74                     return false;\r
75                 }\r
76                 HttpProxy.Startup(0, false, false);\r
77                 _config.Proxy.Listen = HttpProxy.LocalPort;\r
78             }\r
79             return true;\r
80         }\r
81 \r
82         private DialogResult WarnConflictPortNumber(string name, int port, bool auto)\r
83         {\r
84             var msg = $"{name}のポート番号{port}は他のアプリケーションが使用中です。";\r
85             var cap = "ポート番号の衝突";\r
86             return auto\r
87                 ? MessageBox.Show(_parent, msg + "自動的に別の番号を割り当てますか?", cap,\r
88                     MessageBoxButtons.YesNo, MessageBoxIcon.Question)\r
89                 : MessageBox.Show(_parent, msg + "設定ダイアログでポート番号を変更してください。", cap,\r
90                     MessageBoxButtons.OK, MessageBoxIcon.Exclamation);\r
91         }\r
92 \r
93         private void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e)\r
94         {\r
95             if (e.Mode != PowerModes.Resume || !_config.Proxy.Auto)\r
96                 return;\r
97             SystemProxy.Refresh();\r
98         }\r
99 \r
100         public void Shutdown()\r
101         {\r
102             Task.Run(() => ShutdownProxy());\r
103             if (_config.Proxy.Auto)\r
104                 _systemProxy.RestoreSettings();\r
105             SystemEvents.PowerModeChanged -= SystemEvents_PowerModeChanged;\r
106 \r
107         }\r
108 \r
109         private void ShutdownProxy()\r
110         {\r
111             HttpProxy.Shutdown();\r
112         }\r
113     }\r
114 }