style: Format source code and support grouping client

This commit is contained in:
yuanyuanxiang
2025-10-15 04:32:59 +08:00
parent 77087d2e06
commit 6b81ad1f81
244 changed files with 43052 additions and 42562 deletions

View File

@@ -24,16 +24,16 @@
#pragma comment(lib, "wininet.lib")
#pragma comment(lib, "Iphlpapi.lib")
inline void splitIpPort(const std::string& input, std::string& ip, std::string& port) {
size_t pos = input.find(':');
if (pos != std::string::npos) {
ip = input.substr(0, pos);
port = input.substr(pos + 1);
}
else {
ip = input;
port = "";
}
inline void splitIpPort(const std::string& input, std::string& ip, std::string& port)
{
size_t pos = input.find(':');
if (pos != std::string::npos) {
ip = input.substr(0, pos);
port = input.substr(pos + 1);
} else {
ip = input;
port = "";
}
}
/**
@@ -43,205 +43,210 @@ inline void splitIpPort(const std::string& input, std::string& ip, std::string&
class IPConverter
{
public:
std::string IPtoAddress(const std::string& ip) { return "implement me"; }
std::string IPtoAddress(const std::string& ip)
{
return "implement me";
}
/**
* <20>жϸ<D0B6><CFB8><EFBFBD><EFBFBD><EFBFBD> IP <20><>ַ<EFBFBD>Ƿ<EFBFBD><C7B7>Ǿ<EFBFBD><C7BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>IP
* @param ipAddress IP <20><>ַ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> "192.168.1.1"<22><>
* @return <20><><EFBFBD><EFBFBD><EFBFBD>Ǿ<EFBFBD><C7BE><EFBFBD><EFBFBD><EFBFBD> IP<49><50><EFBFBD><EFBFBD><EFBFBD><EFBFBD> true; <20><><EFBFBD>򷵻<EFBFBD> false
*/
bool IsPrivateIP(const std::string& ipAddress) {
// <20><> IP <20><>ַ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>ת<EFBFBD><D7AA>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD>Ƹ<EFBFBD>ʽ
in_addr addr;
if (inet_pton(AF_INET, ipAddress.c_str(), &addr) != 1) {
Mprintf("Invalid IP address: %s\n", ipAddress.c_str());
return false;
}
/**
* <20>жϸ<D0B6><CFB8><EFBFBD><EFBFBD><EFBFBD> IP <20><>ַ<EFBFBD>Ƿ<EFBFBD><C7B7>Ǿ<EFBFBD><C7BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>IP
* @param ipAddress IP <20><>ַ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> "192.168.1.1"<22><>
* @return <20><><EFBFBD><EFBFBD><EFBFBD>Ǿ<EFBFBD><C7BE><EFBFBD><EFBFBD><EFBFBD> IP<49><50><EFBFBD><EFBFBD><EFBFBD><EFBFBD> true; <20><><EFBFBD>򷵻<EFBFBD> false
*/
bool IsPrivateIP(const std::string& ipAddress)
{
// <20><> IP <20><>ַ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>ת<EFBFBD><D7AA>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD>Ƹ<EFBFBD>ʽ
in_addr addr;
if (inet_pton(AF_INET, ipAddress.c_str(), &addr) != 1) {
Mprintf("Invalid IP address: %s\n", ipAddress.c_str());
return false;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> IP <20><>ַת<D6B7><D7AA>Ϊ<EFBFBD>޷<EFBFBD><DEB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
unsigned long ip = ntohl(addr.s_addr);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> IP <20><>ַת<D6B7><D7AA>Ϊ<EFBFBD>޷<EFBFBD><DEB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
unsigned long ip = ntohl(addr.s_addr);
// <20><><EFBFBD><EFBFBD> IP <20><>ַ<EFBFBD>Ƿ<EFBFBD><C7B7>ھ<EFBFBD><DABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Χ<EFBFBD><CEA7>
if ((ip >= 0x0A000000 && ip <= 0x0AFFFFFF) || // 10.0.0.0/8
(ip >= 0xAC100000 && ip <= 0xAC1FFFFF) || // 172.16.0.0/12
(ip >= 0xC0A80000 && ip <= 0xC0A8FFFF) || // 192.168.0.0/16
(ip >= 0x7F000000 && ip <= 0x7FFFFFFF)) { // 127.0.0.0/8
return true;
}
// <20><><EFBFBD><EFBFBD> IP <20><>ַ<EFBFBD>Ƿ<EFBFBD><C7B7>ھ<EFBFBD><DABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Χ<EFBFBD><CEA7>
if ((ip >= 0x0A000000 && ip <= 0x0AFFFFFF) || // 10.0.0.0/8
(ip >= 0xAC100000 && ip <= 0xAC1FFFFF) || // 172.16.0.0/12
(ip >= 0xC0A80000 && ip <= 0xC0A8FFFF) || // 192.168.0.0/16
(ip >= 0x7F000000 && ip <= 0x7FFFFFFF)) { // 127.0.0.0/8
return true;
}
return false;
}
return false;
}
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>
std::string GetLocalLocation() {
return GetGeoLocation(getPublicIP());
}
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>
std::string GetLocalLocation()
{
return GetGeoLocation(getPublicIP());
}
// <20><>ȡ IP <20><>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>(<28><><EFBFBD><EFBFBD>[ipinfo.io])
std::string GetGeoLocation(const std::string& IP) {
if (IP.empty()) return "";
// <20><>ȡ IP <20><>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>(<28><><EFBFBD><EFBFBD>[ipinfo.io])
std::string GetGeoLocation(const std::string& IP)
{
if (IP.empty()) return "";
std::string ip = IP;
if (isLocalIP(ip)) {
ip = getPublicIP();
if (ip.empty())
return "";
}
std::string ip = IP;
if (isLocalIP(ip)) {
ip = getPublicIP();
if (ip.empty())
return "";
}
HINTERNET hInternet, hConnect;
DWORD bytesRead;
std::string readBuffer;
HINTERNET hInternet, hConnect;
DWORD bytesRead;
std::string readBuffer;
// <20><>ʼ<EFBFBD><CABC> WinINet
hInternet = InternetOpen("IP Geolocation", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
if (hInternet == NULL) {
Mprintf("InternetOpen failed! %d\n", GetLastError());
return "";
}
// <20><>ʼ<EFBFBD><CABC> WinINet
hInternet = InternetOpen("IP Geolocation", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
if (hInternet == NULL) {
Mprintf("InternetOpen failed! %d\n", GetLastError());
return "";
}
// <20><><EFBFBD><EFBFBD> HTTP <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
std::string url = "http://ipinfo.io/" + ip + "/json";
hConnect = InternetOpenUrlA(hInternet, url.c_str(), NULL, 0, INTERNET_FLAG_RELOAD, 0);
if (hConnect == NULL) {
Mprintf("InternetOpenUrlA failed! %d\n", GetLastError());
InternetCloseHandle(hInternet);
return "";
}
// <20><><EFBFBD><EFBFBD> HTTP <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
std::string url = "http://ipinfo.io/" + ip + "/json";
hConnect = InternetOpenUrlA(hInternet, url.c_str(), NULL, 0, INTERNET_FLAG_RELOAD, 0);
if (hConnect == NULL) {
Mprintf("InternetOpenUrlA failed! %d\n", GetLastError());
InternetCloseHandle(hInternet);
return "";
}
// <20><>ȡ<EFBFBD><C8A1><EFBFBD>ص<EFBFBD><D8B5><EFBFBD><EFBFBD><EFBFBD>
char buffer[4096];
while (InternetReadFile(hConnect, buffer, sizeof(buffer), &bytesRead) && bytesRead > 0) {
readBuffer.append(buffer, bytesRead);
}
// <20><>ȡ<EFBFBD><C8A1><EFBFBD>ص<EFBFBD><D8B5><EFBFBD><EFBFBD><EFBFBD>
char buffer[4096];
while (InternetReadFile(hConnect, buffer, sizeof(buffer), &bytesRead) && bytesRead > 0) {
readBuffer.append(buffer, bytesRead);
}
// <20><><EFBFBD><EFBFBD> JSON <20><>Ӧ
Json::Value jsonData;
Json::Reader jsonReader;
std::string location;
// <20><><EFBFBD><EFBFBD> JSON <20><>Ӧ
Json::Value jsonData;
Json::Reader jsonReader;
std::string location;
if (jsonReader.parse(readBuffer, jsonData)) {
std::string country = jsonData["country"].asString();
std::string city = jsonData["city"].asString();
std::string loc = jsonData["loc"].asString(); // <20><>γ<EFBFBD><CEB3><EFBFBD><EFBFBD>Ϣ
if (city.empty() && country.empty()) {
}
else if (city.empty()) {
location = country;
}
else if (country.empty()) {
location = city;
}
else {
location = city + ", " + country;
}
if (location.empty() && IsPrivateIP(ip)) {
location = "Local Area Network";
}
}
else {
Mprintf("Failed to parse JSON response: %s.\n", readBuffer.c_str());
}
if (jsonReader.parse(readBuffer, jsonData)) {
std::string country = jsonData["country"].asString();
std::string city = jsonData["city"].asString();
std::string loc = jsonData["loc"].asString(); // <20><>γ<EFBFBD><CEB3><EFBFBD><EFBFBD>Ϣ
if (city.empty() && country.empty()) {
} else if (city.empty()) {
location = country;
} else if (country.empty()) {
location = city;
} else {
location = city + ", " + country;
}
if (location.empty() && IsPrivateIP(ip)) {
location = "Local Area Network";
}
} else {
Mprintf("Failed to parse JSON response: %s.\n", readBuffer.c_str());
}
// <20>رվ<D8B1><D5BE><EFBFBD>
InternetCloseHandle(hConnect);
InternetCloseHandle(hInternet);
// <20>رվ<D8B1><D5BE><EFBFBD>
InternetCloseHandle(hConnect);
InternetCloseHandle(hInternet);
return location;
}
return location;
}
bool isLoopbackAddress(const std::string& ip) {
return (ip == "127.0.0.1" || ip == "::1");
}
bool isLoopbackAddress(const std::string& ip)
{
return (ip == "127.0.0.1" || ip == "::1");
}
bool isLocalIP(const std::string& ip) {
if (isLoopbackAddress(ip)) return true; // <20>ȼ<EFBFBD><C8BC><EFBFBD><EFBFBD>ػ<EFBFBD><D8BB><EFBFBD>ַ
bool isLocalIP(const std::string& ip)
{
if (isLoopbackAddress(ip)) return true; // <20>ȼ<EFBFBD><C8BC><EFBFBD><EFBFBD>ػ<EFBFBD><D8BB><EFBFBD>ַ
ULONG outBufLen = 15000;
IP_ADAPTER_ADDRESSES* pAddresses = (IP_ADAPTER_ADDRESSES*)malloc(outBufLen);
if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, nullptr, pAddresses, &outBufLen) == ERROR_BUFFER_OVERFLOW) {
free(pAddresses);
pAddresses = (IP_ADAPTER_ADDRESSES*)malloc(outBufLen);
}
ULONG outBufLen = 15000;
IP_ADAPTER_ADDRESSES* pAddresses = (IP_ADAPTER_ADDRESSES*)malloc(outBufLen);
if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, nullptr, pAddresses, &outBufLen) == ERROR_BUFFER_OVERFLOW) {
free(pAddresses);
pAddresses = (IP_ADAPTER_ADDRESSES*)malloc(outBufLen);
}
if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, nullptr, pAddresses, &outBufLen) == NO_ERROR) {
for (IP_ADAPTER_ADDRESSES* pCurrAddresses = pAddresses; pCurrAddresses; pCurrAddresses = pCurrAddresses->Next) {
for (IP_ADAPTER_UNICAST_ADDRESS* pUnicast = pCurrAddresses->FirstUnicastAddress; pUnicast; pUnicast = pUnicast->Next) {
char addressBuffer[INET6_ADDRSTRLEN] = { 0 };
getnameinfo(pUnicast->Address.lpSockaddr, pUnicast->Address.iSockaddrLength, addressBuffer, sizeof(addressBuffer), nullptr, 0, NI_NUMERICHOST);
if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, nullptr, pAddresses, &outBufLen) == NO_ERROR) {
for (IP_ADAPTER_ADDRESSES* pCurrAddresses = pAddresses; pCurrAddresses; pCurrAddresses = pCurrAddresses->Next) {
for (IP_ADAPTER_UNICAST_ADDRESS* pUnicast = pCurrAddresses->FirstUnicastAddress; pUnicast; pUnicast = pUnicast->Next) {
char addressBuffer[INET6_ADDRSTRLEN] = { 0 };
getnameinfo(pUnicast->Address.lpSockaddr, pUnicast->Address.iSockaddrLength, addressBuffer, sizeof(addressBuffer), nullptr, 0, NI_NUMERICHOST);
if (ip == addressBuffer) {
free(pAddresses);
return true;
}
}
}
}
if (ip == addressBuffer) {
free(pAddresses);
return true;
}
}
}
}
free(pAddresses);
return false;
}
free(pAddresses);
return false;
}
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>IP, <20><>ȡʧ<C8A1>ܷ<EFBFBD><DCB7>ؿ<EFBFBD>
std::string getPublicIP() {
clock_t t = clock();
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>IP, <20><>ȡʧ<C8A1>ܷ<EFBFBD><DCB7>ؿ<EFBFBD>
std::string getPublicIP()
{
clock_t t = clock();
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD><D1A1>ѯԴ
static const std::vector<std::string> urls = {
"https://checkip.amazonaws.com", // ȫ<><C8AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
"https://api.ipify.org", // <20><><EFBFBD><EFBFBD><EFBFBD>߿<EFBFBD><DFBF><EFBFBD>
"https://ipinfo.io/ip", // <20><><EFBFBD>÷<EFBFBD><C3B7><EFBFBD>
"https://icanhazip.com", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
"https://ifconfig.me/ip" // ĩλ<C4A9><CEBB><EFBFBD><EFBFBD>
};
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD><D1A1>ѯԴ
static const std::vector<std::string> urls = {
"https://checkip.amazonaws.com", // ȫ<><C8AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
"https://api.ipify.org", // <20><><EFBFBD><EFBFBD><EFBFBD>߿<EFBFBD><DFBF><EFBFBD>
"https://ipinfo.io/ip", // <20><><EFBFBD>÷<EFBFBD><C3B7><EFBFBD>
"https://icanhazip.com", // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
"https://ifconfig.me/ip" // ĩλ<C4A9><CEBB><EFBFBD><EFBFBD>
};
// <20><><EFBFBD><EFBFBD> WinINet <20>
HINTERNET hInternet = InternetOpenA("Mozilla/5.0", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
if (!hInternet) {
Mprintf("InternetOpen failed. cost %d ms.\n", clock() - t);
return "";
}
// <20><><EFBFBD><EFBFBD> WinINet <20>
HINTERNET hInternet = InternetOpenA("Mozilla/5.0", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
if (!hInternet) {
Mprintf("InternetOpen failed. cost %d ms.\n", clock() - t);
return "";
}
// <20><><EFBFBD>ó<EFBFBD>ʱ (<28><><EFBFBD><EFBFBD>)
DWORD timeout = 3000; // 3 <20><>
InternetSetOptionA(hInternet, INTERNET_OPTION_CONNECT_TIMEOUT, &timeout, sizeof(timeout));
InternetSetOptionA(hInternet, INTERNET_OPTION_SEND_TIMEOUT, &timeout, sizeof(timeout));
InternetSetOptionA(hInternet, INTERNET_OPTION_RECEIVE_TIMEOUT, &timeout, sizeof(timeout));
// <20><><EFBFBD>ó<EFBFBD>ʱ (<28><><EFBFBD><EFBFBD>)
DWORD timeout = 3000; // 3 <20><>
InternetSetOptionA(hInternet, INTERNET_OPTION_CONNECT_TIMEOUT, &timeout, sizeof(timeout));
InternetSetOptionA(hInternet, INTERNET_OPTION_SEND_TIMEOUT, &timeout, sizeof(timeout));
InternetSetOptionA(hInternet, INTERNET_OPTION_RECEIVE_TIMEOUT, &timeout, sizeof(timeout));
std::string result;
char buffer[2048];
DWORD bytesRead = 0;
std::string result;
char buffer[2048];
DWORD bytesRead = 0;
// <20><>ѯ<EFBFBD><D1AF>ͬ IP <20><>ѯԴ
for (const auto& url : urls) {
HINTERNET hConnect = InternetOpenUrlA(
hInternet, url.c_str(), NULL, 0,
INTERNET_FLAG_RELOAD | INTERNET_FLAG_SECURE | INTERNET_FLAG_NO_CACHE_WRITE,
0
);
// <20><>ѯ<EFBFBD><D1AF>ͬ IP <20><>ѯԴ
for (const auto& url : urls) {
HINTERNET hConnect = InternetOpenUrlA(
hInternet, url.c_str(), NULL, 0,
INTERNET_FLAG_RELOAD | INTERNET_FLAG_SECURE | INTERNET_FLAG_NO_CACHE_WRITE,
0
);
if (!hConnect) {
continue; // <20><>ǰԴʧ<D4B4>ܣ<EFBFBD><DCA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>
}
if (!hConnect) {
continue; // <20><>ǰԴʧ<D4B4>ܣ<EFBFBD><DCA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>
}
memset(buffer, 0, sizeof(buffer));
if (InternetReadFile(hConnect, buffer, sizeof(buffer) - 1, &bytesRead) && bytesRead > 0) {
result.assign(buffer, bytesRead);
memset(buffer, 0, sizeof(buffer));
if (InternetReadFile(hConnect, buffer, sizeof(buffer) - 1, &bytesRead) && bytesRead > 0) {
result.assign(buffer, bytesRead);
// ȥ<><C8A5><EFBFBD><EFBFBD><EFBFBD>з<EFBFBD><D0B7>Ϳո<CDBF>
while (!result.empty() && (result.back() == '\n' || result.back() == '\r' || result.back() == ' '))
result.pop_back();
// ȥ<><C8A5><EFBFBD><EFBFBD><EFBFBD>з<EFBFBD><D0B7>Ϳո<CDBF>
while (!result.empty() && (result.back() == '\n' || result.back() == '\r' || result.back() == ' '))
result.pop_back();
InternetCloseHandle(hConnect);
break; // <20>ɹ<EFBFBD><C9B9><EFBFBD>ȡ<EFBFBD><C8A1>ֹͣ<CDA3><D6B9><EFBFBD><EFBFBD>
}
InternetCloseHandle(hConnect);
break; // <20>ɹ<EFBFBD><C9B9><EFBFBD>ȡ<EFBFBD><C8A1>ֹͣ<CDA3><D6B9><EFBFBD><EFBFBD>
}
InternetCloseHandle(hConnect);
}
InternetCloseHandle(hConnect);
}
InternetCloseHandle(hInternet);
InternetCloseHandle(hInternet);
Mprintf("getPublicIP %s cost %d ms.\n", result.empty() ? "failed" : "succeed", clock() - t);
Mprintf("getPublicIP %s cost %d ms.\n", result.empty() ? "failed" : "succeed", clock() - t);
return result;
}
return result;
}
};