Merge pull request 'Remove naive hack checks, fix quest error format string' (#38) from nightly into master
Reviewed-on: #38
This commit is contained in:
commit
7ee9c84bd3
@ -1243,258 +1243,6 @@ void CInputMain::Position(LPCHARACTER ch, const char * data)
|
||||
}
|
||||
}
|
||||
|
||||
static const int ComboSequenceBySkillLevel[3][8] =
|
||||
{
|
||||
// 0 1 2 3 4 5 6 7
|
||||
{ 14, 15, 16, 17, 0, 0, 0, 0 },
|
||||
{ 14, 15, 16, 18, 20, 0, 0, 0 },
|
||||
{ 14, 15, 16, 18, 19, 17, 0, 0 },
|
||||
};
|
||||
|
||||
#define COMBO_HACK_ALLOWABLE_MS 100
|
||||
|
||||
// [2013 09 11 CYH]
|
||||
DWORD ClacValidComboInterval( LPCHARACTER ch, BYTE bArg )
|
||||
{
|
||||
int nInterval = 300;
|
||||
float fAdjustNum = 1.5f; // 일반 유저가 speed hack 에 걸리는 것을 막기 위해. 2013.09.10 CYH
|
||||
|
||||
if( !ch )
|
||||
{
|
||||
SPDLOG_ERROR("ClacValidComboInterval() ch is NULL");
|
||||
return nInterval;
|
||||
}
|
||||
|
||||
if( bArg == 13 )
|
||||
{
|
||||
float normalAttackDuration = CMotionManager::instance().GetNormalAttackDuration(ch->GetRaceNum());
|
||||
nInterval = (int) (normalAttackDuration / (((float) ch->GetPoint(POINT_ATT_SPEED) / 100.f) * 900.f) + fAdjustNum );
|
||||
}
|
||||
else if( bArg == 14 )
|
||||
{
|
||||
nInterval = (int)(ani_combo_speed(ch, 1 ) / ((ch->GetPoint(POINT_ATT_SPEED) / 100.f) + fAdjustNum) );
|
||||
}
|
||||
else if( bArg > 14 && bArg << 22 )
|
||||
{
|
||||
nInterval = (int)(ani_combo_speed(ch, bArg - 13 ) / ((ch->GetPoint(POINT_ATT_SPEED) / 100.f) + fAdjustNum) );
|
||||
}
|
||||
else
|
||||
{
|
||||
SPDLOG_ERROR("ClacValidComboInterval() Invalid bArg({}) ch({})", bArg, ch->GetName() );
|
||||
}
|
||||
|
||||
return nInterval;
|
||||
}
|
||||
|
||||
bool CheckComboHack(LPCHARACTER ch, BYTE bArg, DWORD dwTime, bool CheckSpeedHack)
|
||||
{
|
||||
// 죽거나 기절 상태에서는 공격할 수 없으므로, skip한다.
|
||||
// 이렇게 하지 말고, CHRACTER::CanMove()에
|
||||
// if (IsStun() || IsDead()) return false;
|
||||
// 를 추가하는게 맞다고 생각하나,
|
||||
// 이미 다른 부분에서 CanMove()는 IsStun(), IsDead()과
|
||||
// 독립적으로 체크하고 있기 때문에 수정에 의한 영향을
|
||||
// 최소화하기 위해 이렇게 땜빵 코드를 써놓는다.
|
||||
if (ch->IsStun() || ch->IsDead())
|
||||
return false;
|
||||
int ComboInterval = dwTime - ch->GetLastComboTime();
|
||||
int HackScalar = 0; // 기본 스칼라 단위 1
|
||||
|
||||
// [2013 09 11 CYH] debugging log
|
||||
/*SPDLOG_DEBUG("COMBO_TEST_LOG: {} arg:{} interval:{} valid:{} atkspd:{} riding:{}",
|
||||
ch->GetName(),
|
||||
bArg,
|
||||
ComboInterval,
|
||||
ch->GetValidComboInterval(),
|
||||
ch->GetPoint(POINT_ATT_SPEED),
|
||||
ch->IsRiding() ? "yes" : "no");*/
|
||||
|
||||
#if 0
|
||||
SPDLOG_DEBUG("COMBO: {} arg:{} seq:{} delta:{} checkspeedhack:{}",
|
||||
ch->GetName(), bArg, ch->GetComboSequence(), ComboInterval - ch->GetValidComboInterval(), CheckSpeedHack);
|
||||
#endif
|
||||
// bArg 14 ~ 21번 까지 총 8콤보 가능
|
||||
// 1. 첫 콤보(14)는 일정 시간 이후에 반복 가능
|
||||
// 2. 15 ~ 21번은 반복 불가능
|
||||
// 3. 차례대로 증가한다.
|
||||
if (bArg == 14)
|
||||
{
|
||||
if (CheckSpeedHack && ComboInterval > 0 && ComboInterval < ch->GetValidComboInterval() - COMBO_HACK_ALLOWABLE_MS)
|
||||
{
|
||||
// FIXME 첫번째 콤보는 이상하게 빨리 올 수가 있어서 300으로 나눔 -_-;
|
||||
// 다수의 몬스터에 의해 다운되는 상황에서 공격을 하면
|
||||
// 첫번째 콤보가 매우 적은 인터벌로 들어오는 상황 발생.
|
||||
// 이로 인해 콤보핵으로 튕기는 경우가 있어 다음 코드 비 활성화.
|
||||
//HackScalar = 1 + (ch->GetValidComboInterval() - ComboInterval) / 300;
|
||||
|
||||
//SPDLOG_WARN("COMBO_HACK: 2 {} arg:{} interval:{} valid:{} atkspd:{} riding:{}",
|
||||
// ch->GetName(),
|
||||
// bArg,
|
||||
// ComboInterval,
|
||||
// ch->GetValidComboInterval(),
|
||||
// ch->GetPoint(POINT_ATT_SPEED),
|
||||
// ch->IsRiding() ? "yes" : "no");
|
||||
}
|
||||
|
||||
ch->SetComboSequence(1);
|
||||
// 2013 09 11 CYH edited
|
||||
//ch->SetValidComboInterval((int) (ani_combo_speed(ch, 1) / (ch->GetPoint(POINT_ATT_SPEED) / 100.f)));
|
||||
ch->SetValidComboInterval( ClacValidComboInterval(ch, bArg) );
|
||||
ch->SetLastComboTime(dwTime);
|
||||
}
|
||||
else if (bArg > 14 && bArg < 22)
|
||||
{
|
||||
int idx = std::min<int>(2, ch->GetComboIndex());
|
||||
|
||||
if (ch->GetComboSequence() > 5) // 현재 6콤보 이상은 없다.
|
||||
{
|
||||
HackScalar = 1;
|
||||
ch->SetValidComboInterval(300);
|
||||
SPDLOG_WARN("COMBO_HACK: 5 {} combo_seq:{}", ch->GetName(), ch->GetComboSequence());
|
||||
}
|
||||
// 자객 쌍수 콤보 예외처리
|
||||
else if (bArg == 21 &&
|
||||
idx == 2 &&
|
||||
ch->GetComboSequence() == 5 &&
|
||||
ch->GetJob() == JOB_ASSASSIN &&
|
||||
ch->GetWear(WEAR_WEAPON) &&
|
||||
ch->GetWear(WEAR_WEAPON)->GetSubType() == WEAPON_DAGGER)
|
||||
ch->SetValidComboInterval(300);
|
||||
else if (ComboSequenceBySkillLevel[idx][ch->GetComboSequence()] != bArg)
|
||||
{
|
||||
HackScalar = 1;
|
||||
ch->SetValidComboInterval(300);
|
||||
|
||||
SPDLOG_WARN("COMBO_HACK: 3 {} arg:{} valid:{} combo_idx:{} combo_seq:{}",
|
||||
ch->GetName(),
|
||||
bArg,
|
||||
ComboSequenceBySkillLevel[idx][ch->GetComboSequence()],
|
||||
idx,
|
||||
ch->GetComboSequence());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (CheckSpeedHack && ComboInterval < ch->GetValidComboInterval() - COMBO_HACK_ALLOWABLE_MS)
|
||||
{
|
||||
HackScalar = 1 + (ch->GetValidComboInterval() - ComboInterval) / 100;
|
||||
|
||||
SPDLOG_WARN("COMBO_HACK: 2 {} arg:{} interval:{} valid:{} atkspd:{} riding:{}",
|
||||
ch->GetName(),
|
||||
bArg,
|
||||
ComboInterval,
|
||||
ch->GetValidComboInterval(),
|
||||
ch->GetPoint(POINT_ATT_SPEED),
|
||||
ch->IsRiding() ? "yes" : "no");
|
||||
}
|
||||
|
||||
// 말을 탔을 때는 15번 ~ 16번을 반복한다
|
||||
//if (ch->IsHorseRiding())
|
||||
if (ch->IsRiding())
|
||||
ch->SetComboSequence(ch->GetComboSequence() == 1 ? 2 : 1);
|
||||
else
|
||||
ch->SetComboSequence(ch->GetComboSequence() + 1);
|
||||
|
||||
// 2013 09 11 CYH edited
|
||||
//ch->SetValidComboInterval((int) (ani_combo_speed(ch, bArg - 13) / (ch->GetPoint(POINT_ATT_SPEED) / 100.f)));
|
||||
ch->SetValidComboInterval( ClacValidComboInterval(ch, bArg) );
|
||||
ch->SetLastComboTime(dwTime);
|
||||
}
|
||||
}
|
||||
else if (bArg == 13) // 기본 공격 (둔갑(Polymorph)했을 때 온다)
|
||||
{
|
||||
if (CheckSpeedHack && ComboInterval > 0 && ComboInterval < ch->GetValidComboInterval() - COMBO_HACK_ALLOWABLE_MS)
|
||||
{
|
||||
// 다수의 몬스터에 의해 다운되는 상황에서 공격을 하면
|
||||
// 첫번째 콤보가 매우 적은 인터벌로 들어오는 상황 발생.
|
||||
// 이로 인해 콤보핵으로 튕기는 경우가 있어 다음 코드 비 활성화.
|
||||
//HackScalar = 1 + (ch->GetValidComboInterval() - ComboInterval) / 100;
|
||||
|
||||
//SPDLOG_WARN("COMBO_HACK: 6 {} arg:{} interval:{} valid:{} atkspd:{}",
|
||||
// ch->GetName(),
|
||||
// bArg,
|
||||
// ComboInterval,
|
||||
// ch->GetValidComboInterval(),
|
||||
// ch->GetPoint(POINT_ATT_SPEED));
|
||||
}
|
||||
|
||||
if (ch->GetRaceNum() >= MAIN_RACE_MAX_NUM)
|
||||
{
|
||||
// POLYMORPH_BUG_FIX
|
||||
|
||||
// DELETEME
|
||||
/*
|
||||
const CMotion * pkMotion = CMotionManager::instance().GetMotion(ch->GetRaceNum(), MAKE_MOTION_KEY(MOTION_MODE_GENERAL, MOTION_NORMAL_ATTACK));
|
||||
|
||||
if (!pkMotion)
|
||||
SPDLOG_ERROR("cannot find motion by race {}", ch->GetRaceNum());
|
||||
else
|
||||
{
|
||||
// 정상적 계산이라면 1000.f를 곱해야 하지만 클라이언트가 애니메이션 속도의 90%에서
|
||||
// 다음 애니메이션 블렌딩을 허용하므로 900.f를 곱한다.
|
||||
int k = (int) (pkMotion->GetDuration() / ((float) ch->GetPoint(POINT_ATT_SPEED) / 100.f) * 900.f);
|
||||
ch->SetValidComboInterval(k);
|
||||
ch->SetLastComboTime(dwTime);
|
||||
}
|
||||
*/
|
||||
|
||||
// 2013 09 11 CYH edited
|
||||
//float normalAttackDuration = CMotionManager::instance().GetNormalAttackDuration(ch->GetRaceNum());
|
||||
//int k = (int) (normalAttackDuration / ((float) ch->GetPoint(POINT_ATT_SPEED) / 100.f) * 900.f);
|
||||
//ch->SetValidComboInterval(k);
|
||||
ch->SetValidComboInterval( ClacValidComboInterval(ch, bArg) );
|
||||
ch->SetLastComboTime(dwTime);
|
||||
// END_OF_POLYMORPH_BUG_FIX
|
||||
}
|
||||
else
|
||||
{
|
||||
// 말이 안되는 콤보가 왔다 해커일 가능성?
|
||||
//if (ch->GetDesc()->DelayedDisconnect(Random::get(2, 9)))
|
||||
//{
|
||||
// LogManager::instance().HackLog("Hacker", ch);
|
||||
// SPDLOG_WARN("HACKER: {} arg {}", ch->GetName(), bArg);
|
||||
//}
|
||||
|
||||
// 위 코드로 인해, 폴리모프를 푸는 중에 공격 하면,
|
||||
// 가끔 핵으로 인식하는 경우가 있다.
|
||||
|
||||
// 자세히 말혀면,
|
||||
// 서버에서 poly 0를 처리했지만,
|
||||
// 클라에서 그 패킷을 받기 전에, 몹을 공격. <- 즉, 몹인 상태에서 공격.
|
||||
//
|
||||
// 그러면 클라에서는 서버에 몹 상태로 공격했다는 커맨드를 보내고 (arg == 13)
|
||||
//
|
||||
// 서버에서는 race는 인간인데 공격형태는 몹인 놈이다! 라고 하여 핵체크를 했다.
|
||||
|
||||
// 사실 공격 패턴에 대한 것은 클라이언트에서 판단해서 보낼 것이 아니라,
|
||||
// 서버에서 판단해야 할 것인데... 왜 이렇게 해놨을까...
|
||||
// by rtsummit
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 말이 안되는 콤보가 왔다 해커일 가능성?
|
||||
if (ch->GetDesc()->DelayedDisconnect(Random::get(2, 9)))
|
||||
{
|
||||
LogManager::instance().HackLog("Hacker", ch);
|
||||
SPDLOG_WARN("HACKER: {} arg {}", ch->GetName(), bArg);
|
||||
}
|
||||
|
||||
HackScalar = 10;
|
||||
ch->SetValidComboInterval(300);
|
||||
}
|
||||
|
||||
if (HackScalar)
|
||||
{
|
||||
// 말에 타거나 내렸을 때 1.5초간 공격은 핵으로 간주하지 않되 공격력은 없게 하는 처리
|
||||
if (get_dword_time() - ch->GetLastMountTime() > 1500)
|
||||
ch->IncreaseComboHackCount(1 + HackScalar);
|
||||
|
||||
ch->SkipComboAttackByTime(ch->GetValidComboInterval());
|
||||
}
|
||||
|
||||
return HackScalar;
|
||||
}
|
||||
|
||||
void CInputMain::Move(LPCHARACTER ch, const char * data)
|
||||
{
|
||||
if (!ch->CanMove())
|
||||
@ -1508,68 +1256,16 @@ void CInputMain::Move(LPCHARACTER ch, const char * data)
|
||||
return;
|
||||
}
|
||||
|
||||
//enum EMoveFuncType
|
||||
//{
|
||||
// FUNC_WAIT,
|
||||
// FUNC_MOVE,
|
||||
// FUNC_ATTACK,
|
||||
// FUNC_COMBO,
|
||||
// FUNC_MOB_SKILL,
|
||||
// _FUNC_SKILL,
|
||||
// FUNC_MAX_NUM,
|
||||
// FUNC_SKILL = 0x80,
|
||||
//};
|
||||
// Check for teleportation hacks
|
||||
const float fDist = DISTANCE_SQRT((ch->GetX() - pinfo->lX) / 100, (ch->GetY() - pinfo->lY) / 100);
|
||||
|
||||
// 텔레포트 핵 체크
|
||||
|
||||
// if (!test_server) //2012.05.15 김용욱 : 테섭에서 (무적상태로) 다수 몬스터 상대로 다운되면서 공격시 콤보핵으로 죽는 문제가 있었다.
|
||||
if (((false == ch->IsRiding() && fDist > 25) || fDist > 40) && OXEVENT_MAP_INDEX != ch->GetMapIndex())
|
||||
{
|
||||
const float fDist = DISTANCE_SQRT((ch->GetX() - pinfo->lX) / 100, (ch->GetY() - pinfo->lY) / 100);
|
||||
SPDLOG_WARN("MOVE: {} trying to move too far (dist: {:.1f}m) Riding({})", ch->GetName(), fDist, ch->IsRiding());
|
||||
|
||||
if (((false == ch->IsRiding() && fDist > 25) || fDist > 40) && OXEVENT_MAP_INDEX != ch->GetMapIndex())
|
||||
{
|
||||
SPDLOG_WARN("MOVE: {} trying to move too far (dist: {:.1f}m) Riding({})", ch->GetName(), fDist, ch->IsRiding());
|
||||
|
||||
ch->Show(ch->GetMapIndex(), ch->GetX(), ch->GetY(), ch->GetZ());
|
||||
ch->Stop();
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// 스피드핵(SPEEDHACK) Check
|
||||
//
|
||||
DWORD dwCurTime = get_dword_time();
|
||||
// 시간을 Sync하고 7초 후 부터 검사한다. (20090702 이전엔 5초였음)
|
||||
bool CheckSpeedHack = (false == ch->GetDesc()->IsHandshaking() && dwCurTime - ch->GetDesc()->GetClientTime() > 7000);
|
||||
|
||||
if (CheckSpeedHack)
|
||||
{
|
||||
int iDelta = (int) (pinfo->dwTime - ch->GetDesc()->GetClientTime());
|
||||
int iServerDelta = (int) (dwCurTime - ch->GetDesc()->GetClientTime());
|
||||
|
||||
iDelta = (int) (dwCurTime - pinfo->dwTime);
|
||||
|
||||
// 시간이 늦게간다. 일단 로그만 해둔다. 진짜 이런 사람들이 많은지 체크해야함. TODO
|
||||
if (iDelta >= 30000)
|
||||
{
|
||||
SPDLOG_WARN("SPEEDHACK: slow timer name {} delta {}", ch->GetName(), iDelta);
|
||||
ch->GetDesc()->DelayedDisconnect(3);
|
||||
}
|
||||
// 1초에 20msec 빨리 가는거 까지는 이해한다.
|
||||
else if (iDelta < -(iServerDelta / 50))
|
||||
{
|
||||
SPDLOG_WARN("SPEEDHACK: DETECTED! {} (delta {} {})", ch->GetName(), iDelta, iServerDelta);
|
||||
ch->GetDesc()->DelayedDisconnect(3);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// 콤보핵 및 스피드핵 체크
|
||||
//
|
||||
if (pinfo->bFunc == FUNC_COMBO && g_bCheckMultiHack)
|
||||
{
|
||||
CheckComboHack(ch, pinfo->bArg, pinfo->dwTime, CheckSpeedHack); // 콤보 체크
|
||||
}
|
||||
ch->Show(ch->GetMapIndex(), ch->GetX(), ch->GetY(), ch->GetZ());
|
||||
ch->Stop();
|
||||
return;
|
||||
}
|
||||
|
||||
if (pinfo->bFunc == FUNC_MOVE)
|
||||
@ -1637,30 +1333,17 @@ void CInputMain::Move(LPCHARACTER ch, const char * data)
|
||||
pack.dwDuration = (pinfo->bFunc == FUNC_MOVE) ? ch->GetCurrentMoveDuration() : 0;
|
||||
|
||||
ch->PacketAround(&pack, sizeof(TPacketGCMove), ch);
|
||||
/*
|
||||
if (pinfo->dwTime == 10653691) // 디버거 발견
|
||||
{
|
||||
if (ch->GetDesc()->DelayedDisconnect(Random::get(15, 30)))
|
||||
LogManager::instance().HackLog("Debugger", ch);
|
||||
|
||||
}
|
||||
else if (pinfo->dwTime == 10653971) // Softice 발견
|
||||
{
|
||||
if (ch->GetDesc()->DelayedDisconnect(Random::get(15, 30)))
|
||||
LogManager::instance().HackLog("Softice", ch);
|
||||
}
|
||||
*/
|
||||
/*
|
||||
SPDLOG_TRACE(
|
||||
"MOVE: {} Func:{} Arg:{} Pos:{}x{} Time:{} Dist:{:.1f}",
|
||||
ch->GetName(),
|
||||
pinfo->bFunc,
|
||||
pinfo->bArg,
|
||||
pinfo->lX / 100,
|
||||
pinfo->lY / 100,
|
||||
pinfo->dwTime,
|
||||
fDist);
|
||||
*/
|
||||
"MOVE: {} Func:{} Arg:{} Pos:{}x{} Time:{} Dist:{:.1f}",
|
||||
ch->GetName(),
|
||||
pinfo->bFunc,
|
||||
pinfo->bArg,
|
||||
pinfo->lX / 100,
|
||||
pinfo->lY / 100,
|
||||
pinfo->dwTime,
|
||||
fDist
|
||||
);
|
||||
}
|
||||
|
||||
void CInputMain::Attack(LPCHARACTER ch, const BYTE header, const char* data)
|
||||
|
@ -1640,7 +1640,7 @@ namespace quest
|
||||
vsnprintf(szMsg, sizeof(szMsg), fmt, args);
|
||||
va_end(args);
|
||||
|
||||
SPDLOG_ERROR("Quest error occurred in [{}:{}}]: {}", func, line, szMsg);
|
||||
SPDLOG_ERROR("Quest error occurred in [{}:{}]: {}", func, line, szMsg);
|
||||
if (test_server)
|
||||
{
|
||||
LPCHARACTER ch = GetCurrentCharacterPtr();
|
||||
|
Loading…
x
Reference in New Issue
Block a user