5.4 KiB
Server time, SunMoon phase, và đồng hồ minimap (PC → Unity)
Tài liệu tóm tắt luồng thời gian server, SetTimeOfTheDay, đồng bộ main thread, và hiển thị canh giờ trên minimap — đối chiếu CElementClient (C++) với perfect-world-unity (C#).
1. CECGame::SetServerTime (PC — EC_Game.cpp)
m_iTimeError = iSevTime - time(NULL)— lệch giây giữa Unix server và máy client.m_iTimeZoneBias— bias múi giờ theo phút (ví dụ Bắc Kinh thường -480).GetServerLocalTime()(không tham số):
serverTime = GetServerGMTTime()(=time(NULL) + m_iTimeError), rồi
serverTime -= m_iTimeZoneBias * 60, sau đógmtime— tức “giờ địa phương server” dùng để lấytm_hour/tm_min/tm_sec.- SunMoon:
nTimeInDay = hour*3600 + min*60 + sec,
SetTimeOfTheDay(nTimeInDay / (4.0f * 3600.0f))— cùng công thức đã port sang Unity. - Lưu ý thiết kế PC: chia
(4*3600)+ chuẩn hóa[0,1)làm nhiều mốc giờ thật có thể trùng cùng một phase (đã phân tích trong phiên làm việc); phần UI canh giờ trên PC lại dùngGetTimeOfTheDay()(không dùng trực tiếptm_hourcho chuỗi minimap).
2. Unity — EC_Game.Time.cs (partial EC_Game)
SetServerTime(int iSevTime, int iTimeZoneBias)- Đồng bộ offset, tính phase giống PC (
iSevTime - bias*60→ giờ trong ngày →/ (4f*3600f)), gọiSetTimeOfTheDay.
- Đồng bộ offset, tính phase giống PC (
SetTimeOfTheDay(float vTime)— forward tớiCECSunMoon.Instance.SetTimeOfTheDay.SyncSunMoonTimeOfDayFromServerClock()— giống cuốiCECGameRun::CreateWorld/CECWorld::InitNatureObjects: lấyGetServerGMTTime()rồi áp dụng cùng công thức phase (helper nội bộ).- Log debug có thể dùng tiền tố
[Cuong]theo convention dự án.
3. Nơi gọi (đối chiếu PC)
| Nguồn (PC) | Unity đã nối |
|---|---|
Gói SERVER_TIME → PostMessage(MSG_SERVERTIME) → SetServerTime |
GameSession.cs — CommandID.SERVER_TIME: parse cmd_server_time, PostToUnityContext → EC_Game.SetServerTime + EC_ManMessage.PostMessage (queue không thread-safe). |
Cuối CECGameRun::CreateWorld — set lại phase theo GetServerLocalTime |
LoginScreenUI.OnEnterWorldComplete — gọi EC_Game.SyncSunMoonTimeOfDayFromServerClock(). |
Lý do PostToUnityContext: NetworkManager nhận socket trong Task.Run; gọi trực tiếp SetServerTime / CECSunMoon / FindFirstObjectByType trên luồng đó là không an toàn với Unity API và race với EC_ManMessage queue.
4. CECSunMoon (Unity)
SetTimeOfTheDay: chuẩn hóa[0,1), gánm_vTimeOfTheDay, gọiRefreshDayNightFactorsFromPhase().Update: tăng phase theoTIME_SCALE(giống hướng PC), sau đóRefreshDayNightFactorsFromPhase().RefreshDayNightFactorsFromPhase: port khốim_fDNFactor/m_fDNFactorDesttừEC_SunMoon::UpdateWithTime(PC), phục vụ logic minimap (ngày / sáng / hoàng hôn / đêm).- Getter:
GetTimeOfTheDay(),GetDNFactor(),GetDNFactorDest().
5. Minimap — chuỗi canh giờ giống PC (DlgMiniMap.cpp)
Trên PC (trong Render), hint đồng hồ:
nTimeIndex = (int)(12 * GetTimeOfTheDay() + 0.5) % 12GetStringFromTable(1330 + nTimeIndex)— tên canh địa (mười nhị canh).int(GetTimeOfTheDay() * 24)— số “giờ” hiển thị (theo phase game, không phảitm_hourserver).Format(GetStringFromTable(604), ...)— template chuỗi (thường dạng%s+%d/ tương đương).FixFrame(nTimeItem)— icon theofDNFactor/fDNFactorDest: TIME_DAY (0), TIME_MORNING (1), TIME_DUSK (2), TIME_NIGHT (3).
Unity — CDlgMiniMap.cs:
UpdateSystemClockFromPcMiniMapLogic()mỗiUpdate, cùng công thức trên.- SerializeField:
_txtSystemTime(TMP),_imgSystemTime+_systemTimeSprites(4 sprite đúng thứ tự enum PC). - Nếu chưa có
CECGameUIMan/ thiếu string: fallback tên 子…亥 và format{0}({1}时).
Editor: gán TMP / Image / sprites trên prefab minimap để thấy chữ và icon; không gán thì không crash, chỉ không cập nhật UI tương ứng.
6. File chính liên quan
| Vai trò | Đường dẫn (Unity) |
|---|---|
| Thời gian server + phase | Assets/PerfectWorld/Scripts/MainFiles/EC_Game.Time.cs |
| SunMoon + DN factor | Assets/PerfectWorld/Scripts/World/CECSunMoon.cs |
Nhận SERVER_TIME (main thread) |
Assets/PerfectWorld/Scripts/Network/CSNetwork/GameSession.cs |
| Vào world — sync lại phase | Assets/PerfectWorld/Scripts/UI/Login/LoginScreenUI.cs (OnEnterWorldComplete) |
| UI canh giờ minimap | Assets/PerfectWorld/Scripts/UI/MiniMap/CDlgMiniMap.cs |
PC tham chiếu: EC_Game.cpp (SetServerTime, GetServerLocalTime), EC_GameRun.cpp (MSG_SERVERTIME, cuối CreateWorld), Network/EC_GameDataPrtc.cpp (SERVER_TIME), DlgMiniMap.cpp (đoạn GetTimeOfTheDay / string 604 / 1330), EC_SunMoon.cpp (UpdateWithTime — phần DN factor).
Tài liệu được tạo để handoff nhanh; cập nhật khi đổi protocol bias (phút vs giây) hoặc khi marshal toàn bộ HandleServerDataSend lên main thread.