-
Notifications
You must be signed in to change notification settings - Fork 27
/
Copy pathConfigFileManager.hpp
109 lines (97 loc) · 2.81 KB
/
ConfigFileManager.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/*
* Copyright (C) 2020 Richard Yu <[email protected]>
*
* This file is part of ClashXW.
*
* ClashXW is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ClashXW is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with ClashXW. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
void CopySampleConfigIfNeed()
{
constexpr auto sampleConfig = R"(port: 7890
socks-port: 7891
allow-lan: false
mode: Rule
log-level: info
external-controller: 127.0.0.1:9090
external-ui: Dashboard
Proxy:
Proxy Group:
Rule:
- DOMAIN-SUFFIX,google.com,DIRECT
- DOMAIN-KEYWORD,google,DIRECT
- DOMAIN,google.com,DIRECT
- DOMAIN-SUFFIX,ad.com,REJECT
- GEOIP,CN,DIRECT
- MATCH,DIRECT
)";
auto fileName = g_configPath / CLASH_DEF_CONFIG_NAME;
if (!fs::exists(fileName))
{
wil::unique_file file;
_wfopen_s(&file, fileName.c_str(), L"wb");
THROW_HR_IF_NULL(E_ACCESSDENIED, file);
fputs(sampleConfig, file.get());
}
}
void SetupDataDirectory()
{
try
{
CreateDirectoryIgnoreExist(g_configPath.c_str());
CopySampleConfigIfNeed();
}
CATCH_LOG();
}
std::vector<fs::path> GetConfigFilesList()
{
std::vector<fs::path> list;
for (auto& f : fs::directory_iterator(g_configPath))
{
if (f.is_regular_file() && f.path().extension().native() == L".yaml")
list.emplace_back(f.path().filename());
}
return list;
}
wil::unique_folder_change_reader reader = nullptr;
wil::unique_threadpool_timer timer = nullptr;
bool pause = false;
void WatchConfigFile()
{
timer.reset(CreateThreadpoolTimer([](PTP_CALLBACK_INSTANCE, PVOID, PTP_TIMER) {
PostMessageW(g_hWnd, WM_CONFIGCHANGEDETECT, 0, 0);
pause = false;
}, nullptr, nullptr));
THROW_LAST_ERROR_IF_NULL(timer);
reader = wil::make_folder_change_reader(g_configPath.c_str(), false,
wil::FolderChangeEvents::FileName | wil::FolderChangeEvents::LastWriteTime,
[](wil::FolderChangeEvent event, PCWSTR fileName) {
if (!pause && (event == wil::FolderChangeEvent::Added ||
event == wil::FolderChangeEvent::Modified ||
event == wil::FolderChangeEvent::RenameNewName) &&
g_settings.configFile == fileName)
{
pause = true;
constexpr winrt::Windows::Foundation::TimeSpan latency = 300ms;
int64_t relative_count = -latency.count();
SetThreadpoolTimer(timer.get(), reinterpret_cast<PFILETIME>(&relative_count), 0, 0);
}
});
}
void StopWatchConfigFile()
{
reader.reset();
timer.reset();
pause = false;
}