Files
2022-10-26 12:25:11 +08:00

210 lines
8.4 KiB
C++

#pragma once
#ifndef GAMESERVER_MOVEMENT_CHECKER_H
#define GAMESERVER_MOVEMENT_CHECKER_H
#include "SkillSystem/CSSyncTuner.h"
//==================================================================================================
// <MovementChecker>
//
class MovementChecker
{
public:
static const DWORD INTERVAL_LASTED_ACCEPT_SYN = 15; //ms
static const DWORD DELAY_MIN_MOVE_TRANSACTION = 200; //ms
static const DWORD DELAY_MIN_DIR_TRANSACTION = 100; //ms
static const DWORD DELAY_MIN_JUMP_TRANSACTION = 500; //ms
static const DWORD DELAY_DEFAULT_KBMOVE_SYN = 500; //ms
static const DWORD DELAY_MAX_PERMIT_LASTED_STATE = DELAY_DEFAULT_KBMOVE_SYN; //ms
enum eMOVE_TYPE
{
KEYBOARD_MOVE = 0,
KEYBOARD_JUMP ,
KEYBOARD_JUMP_STOP ,
MOUSE_MOVE ,
MOVE_STOP ,
};
enum eMOVE_CTRL
{
CANTACCEPTABLE = 0,
ACCEPT_STOP = 1,
ACCEPT_ALL = ACCEPT_STOP|2,
};
private:
static const DWORD TIMEOUT_BIT_PASS = 0x00000000;
static const DWORD TIMEOUT_BIT_I = 0x00000001;
static const DWORD TIMEOUT_BIT_K = 0x00000002; // 키보드 불허
static const DWORD TIMEOUT_BIT_J = 0x00000008; // 점프 불허
static const DWORD TIMEOUT_BIT_M = 0x00000010; // 마우스 불허
static const DWORD TIMEOUT_BIT_KJM = TIMEOUT_BIT_K | TIMEOUT_BIT_J | TIMEOUT_BIT_M; // JKM 모두 불허
static const DWORD INSTANCE_BIT_K = 0x00000200; // 키보드 허용
static const DWORD INSTANCE_BIT_J = 0x00000800; // 점프 허용
static const DWORD INSTANCE_BIT_M = 0x00001000; // 마우스 허용
static const DWORD INSTANCE_BIT_KJM = INSTANCE_BIT_K | INSTANCE_BIT_J | INSTANCE_BIT_M; // JKM 모두 사용 가능
private:
static float sfSYNC_HACK_DISTANCE2; // by SCRIPT DATA
static float sfSYNC_FAIL_DISTANCE2; // by SCRIPT DATA
static float sfSYNC_FAIL_DISTANCE_ACCEPT2; // by SCRIPT DATA+a
static float sfSYNC_WARN_DISTANCE2; // by SCRIPT DATA
static DWORD sdwFRAME_DELTA_TICK;
static DWORD sdwFRAME_POLE_TICK;
static WzVector sWzVectorZero;
//----------------------------------------------------------------------------------------------
//
public:
MovementChecker( Player* const pPlayer );
~MovementChecker();
void Reset();
// [1] : 클라이언트가 보낸, 또는 서버가 계산한 이동된 값
// [2] : 서버가 현재 보유한 위치값
BOOL AddMovement( WzVector& wvCurPos/*, WzVector* pwvPosOfPlayer = NULL*/ );
void AbusingNotify( RC::eSYNC_RESULT eRET, DWORD IN dwErrorLevel, float fDIST = .0f );
nsSync::CSSyncTuner* GetSyncTuner();
//----------------------------------------------------------------------------------------------
// FRAME 당 틱 갱신 시켜, 한번에 들어오는 경우에 대한 융통성 적용
static void Update( DWORD dwDeltaTick );
static BOOL PreCalcScript();
private:
inline static DWORD DeltaTick() { return sdwFRAME_POLE_TICK; }
private:
struct sPASSING_ARG;
//----------------------------------------------------------------------------------------------
// 계산용 기본 공통 로직
private:
eMOVE_CTRL CanStartAction( const eMOVE_TYPE mtTYPE, const WORD wAngle, const BYTE byMoveState, const BOOL bSpecial = FALSE );
inline BOOL IsFiniteVector( const WzVector& rVector );
inline BOOL IsFaultToleranceDifference( const BYTE byMoveState );
BOOL CheckSharedFault( FlowControl& INOUT flow );
//----------------------------------------------------------------------------------------------
// 클라 요청 엔트리
public:
RC::eSYNC_RESULT OnRecvCG_SYNC_KBMOVE_SYN( MSG_CG_SYNC_KBMOVE_SYN* pRecvMsg, DWORD& OUT rdwErrorLevel );
RC::eSYNC_RESULT OnRecvCG_SYNC_FAST_KBMOVE_SYN( MSG_CG_SYNC_FAST_KBMOVE_SYN* pRecvMsg, DWORD& OUT rdwErrorLevel );
RC::eSYNC_RESULT OnRecvCG_SYNC_STOP_SYN( MSG_CG_SYNC_STOP_SYN* pRecvMsg, DWORD& OUT rdwErrorLevel );
enum eJUMP_TYPE { JUMP_NORMAL, JUMP_STOP };
RC::eSYNC_RESULT OnRecvCG_SYNC_JUMP_SYN( MSG_CG_SYNC_JUMP_SYN* pRecvMsg, DWORD& OUT rdwErrorLevel, eJUMP_TYPE jumpType = JUMP_NORMAL );
RC::eSYNC_RESULT OnRecvCG_SYNC_JUMP_STOP_SYN( MSG_CG_SYNC_JUMP_STOP_SYN* pRecvMsg, DWORD& OUT rdwErrorLevel );
RC::eSYNC_RESULT OnRecvCG_SYNC_MOVE_SYN( MSG_CG_SYNC_MOVE_SYN* pRecvMsg, DWORD& OUT rdwErrorLevel );
RC::eSYNC_RESULT OnRecvCG_SYNC_TARGET_MOVE_SYN( MSG_CG_SYNC_TARGET_MOVE_SYN* pRecvMsg, DWORD& OUT rdwErrorLevel );
//----------------------------------------------------------------------------------------------
// 사례별 복합 계산 로직
#ifdef _NA_0_20110803_PLAYER_MOVEMENT_SYNC
private:
RC::eSYNC_RESULT do_fast_run(ushort angle, uchar fast_state);
RC::eSYNC_RESULT do_run(ushort angle, uchar keyboard_state);
RC::eSYNC_RESULT check_state_enable_move();
void send_move_fail(RC::eSYNC_RESULT result);
bool is_same_position(WzVector& client_position);
void apply_angle(ushort angle);
float angle_;
public:
void KeyBoard_Move(MSG_CG_SYNC_KBMOVE_SYN* recv_message);
void KeyBoard_Move(MSG_CG_SYNC_FAST_KBMOVE_SYN* recv_message);
void Move_Stop(MSG_CG_SYNC_STOP_SYN* recv_message);
bool Update_Moving_Turn(uint delta_tick);
#endif //_NA_0_20110803_PLAYER_MOVEMENT_SYNC
private:
RC::eSYNC_RESULT MoveCommon(
BOOL bIsTargetMove,
eCHAR_MOVE_STATE eState, // CMS_RUN, ... 이동 상태
WzVector& IN OUT wvCurPosR, // 현재 좌표
WzVector& IN OUT wvDestPosR, // 이동할 좌표
INT iNumRoute, // PathRoute 개수
TILEINDEX* piRoute, // PathRoute 배열
DWORD& OUT rdwErrorLevel
);
RC::eSYNC_RESULT KBMoveCommonCHECK(
WzVector& wvCurPos,
BYTE IN byMoveState, // 이동 상태 (전/후진, 좌우진, 조합 이동 등등...)
BOOL& OUT bNeedMoveCalc, // 방향만 바꿨는지, 실제 이동 계산이 요구되는지...
DWORD& OUT rdwErrorLevel
);
void KBMoveCommonDIR(
WzVector& OUT wvDirection, // 결과, 이동 방향 벡터 설정
WORD IN wAngle, // 이동하려는 각도
BOOL IN bFastMove, // FastMove 설정 여부
BYTE IN byMoveState // 이동 상태 (/후진, 좌우진, 조합 이동 등등...)
);
inline BOOL KBMoveCommonDIST(
WzVector& OUT wvDirection // 결과, 이동 방향 벡터 설정
);
RC::eSYNC_RESULT KBMoveCommonUPDATE( Player* pPlayer, WzVector& wvCurPos );
private:
Player* m_pPlayer; // 검사 대상
BOOL m_bFirst; // 검사 시작 여부 설정
// 단위 시간 내 수신된 메시지 평가 필드
public:
struct sMSG_TIMER_INFO
{
ITimeout AcceptTimer;
DWORD ReceivedCount;
inline void Reset();
inline DWORD Increase();
};
// 이동 평가 필드
public:
struct sPATH_INFO
{
DWORD LatestAcceptTick; // 가장 최근 갱신된 시각
WzVector LatestAcceptPosition; // 가장 최근 갱신된 위치
float fAccumulatedDistance; // 누적 오차
BOOL SetupLatestState(
MovementChecker* pChecker, //
float fDistOfCS, // 서버와 클라이언트 위치 오차
BYTE byMoveState, // 이동 상태
WzVector& wvCurPos, // 서버가 인식하는 현재 좌표
WzVector& wvPos // 클라가 요청한 현재 좌표
);
};
inline sPATH_INFO* GetServerPathExpUpdate() { return &PATH_EXP; }
private:
sMSG_TIMER_INFO INTERNAL; // JUMP
sMSG_TIMER_INFO MOVEKEYBOARD; // 방향키, FASTMOVE
WORD MOVEKEYBOARD_ANGLE;
BYTE MOVEKEYBOARD_STATE; // 방향이 다를 경우 ACCEPT
sMSG_TIMER_INFO MOVEKEYBOARDJ; // JUMP
sMSG_TIMER_INFO MOVEMOUSE; // 마우스, TARGET MOVE
sPATH_INFO PATH_EXP;
//_NA000000_SPEED_HACK_PREVENTION_SUPPORT
nsSync::CSSyncTuner sync_tuner_;
//----------------------------------------------------------------------------------------------
friend struct sPATH_INFO;
__DISABLE_COPY(MovementChecker);
};
//==================================================================================================
inline nsSync::CSSyncTuner* MovementChecker::GetSyncTuner() {
return &sync_tuner_;
};
#endif //GAMESERVER_MOVEMENT_CHECKER_H