遊戲伺服器之防加速器
阿新 • • 發佈:2018-12-31
加速器是網頁類遊戲常使用的通過修改前端幀頻率來達到加速操作目的的工具,常用的有遊戲瀏覽器等。所以前端的時間會變得很快或者很慢(跟後端的比較)。
防加速器設計上:
在閘道器伺服器裡限制連線發來(客戶端發來)的移動系統裡的角色移動訊息,
根據訊息的時間戳跟伺服器的時間相比,時間相差較大就踢掉.前後端需要在一定時間內同步一次
時間上,每60秒同步一次後端時間到前端,設定為加速不超過9秒(9/60 ,即加速15%),減速不超過15秒(15/60,即減速25%,因為有網路延時,所以減速的會放寬些)。
本文程式碼內容如下:
閘道器連線處理客戶端的移動訊息
bool gateway_session::msgParse(const MSG::base_msg *ptNull, const unsigned int msglen) { ... case MOVE_USERCMD://移動指令 { if (!testRunState(gateway_session::RunState_Play)) { return true; } PRINT_MSG_LOG(ptrMsg, 0); switch (ptrMsg->second) { case USERMOVE_MOVE_USERCMD_PARA_C: { if(msglen != sizeof(stplayerMoveUpMoveplayerCmd)) { g_log->error("訊息長度有誤:%u,%u",this->id,msglen); return false; } MSG::stplayerMoveUpMoveplayerCmd send = *(MSG::stplayerMoveUpMoveplayerCmd*) ptrMsg; int timeDiff = int((int)send.dwTimestamp - (int)main_logic_thread::currentTime.sec()); if (timeDiff > 9 || timeDiff < -15)//相差時間過大則斷開閘道器的客戶端連線(單位秒) { error_log("加速器:時間相差過大(%u,%llu),(帳號%s,角色(%u,%s),ip:%s)", send.dwTimestamp,main_logic_thread::currentTime.sec(), account,pplayer->id,pplayer->name,getIP()); TerminateWait(); return false; } return forwardScene(&send, sizeof(send)); } break; ... } ... } ... }
前後端需要在一定時間內同步一次
//傳送同步時間訊息 struct gateway_session_time_sync: public callback<gateway_session> { bool invoke(gateway_session *entry) { MSG::stGameTimeTimerplayerCmd cmd; cmd.qwGameTime = (uint32)(main_logic_thread::currentTime.sec()); entry->sendmsg(&cmd,sizeof(cmd)); return true; } }timesync;
主執行緒迴圈定時同步後端時間到所有連線的前端
void main_logic_thread::run() { while(!isFinal()) { setRunning(); main_logic_thread::currentTime.now(); thread_base::msleep(50); g_server.handle_msg(); if(_one_sec(main_logic_thread::currentTime)) { g_gateway_session_manager.invoke_all_task(timeout); if(_one_min(main_logic_thread::currentTime)) { g_gateway_session_manager.invoke_all_task(timesync); } ... }