Add fishing bot-pattern telemetry
Some checks failed
build / Linux asan (push) Has been cancelled
build / Linux release (push) Has been cancelled
build / FreeBSD build (push) Has been cancelled

This commit is contained in:
server
2026-04-16 12:50:36 +02:00
parent bdfdef8411
commit 563e898942
3 changed files with 75 additions and 0 deletions

View File

@@ -144,6 +144,12 @@ void CHARACTER::Initialize()
m_iFishingWindowCount = 0;
m_lFishingStartX = 0;
m_lFishingStartY = 0;
m_dwFishingPatternWindowStart = 0;
m_iFishingPatternSampleCount = 0;
m_iFishingPatternMinReactionMs = 0;
m_iFishingPatternMaxReactionMs = 0;
m_iFishingPatternLastReactionMs = 0;
m_iFishingPatternTightSequence = 0;
m_dwMiningWindowStart = 0;
m_iMiningWindowCount = 0;

View File

@@ -2056,6 +2056,12 @@ class CHARACTER : public CEntity, public CFSM, public CHorseRider
int m_iFishingWindowCount;
long m_lFishingStartX;
long m_lFishingStartY;
DWORD m_dwFishingPatternWindowStart;
int m_iFishingPatternSampleCount;
int m_iFishingPatternMinReactionMs;
int m_iFishingPatternMaxReactionMs;
int m_iFishingPatternLastReactionMs;
int m_iFishingPatternTightSequence;
DWORD m_dwMiningWindowStart;
int m_iMiningWindowCount;
void ClearPMCounter(void) { m_iPMCounter = 0; }

View File

@@ -69,6 +69,68 @@ namespace fishing
FISHING_LIMIT_APPEAR,
};
namespace
{
constexpr DWORD kFishingPatternWindowMs = 12 * 60 * 1000;
constexpr int kFishingPatternMinSamples = 8;
constexpr int kFishingPatternMaxSpreadMs = 120;
constexpr int kFishingPatternTightDeltaMs = 80;
void ResetFishingPatternWindow(LPCHARACTER ch, DWORD now, int reactionMs)
{
ch->m_dwFishingPatternWindowStart = now;
ch->m_iFishingPatternSampleCount = 1;
ch->m_iFishingPatternMinReactionMs = reactionMs;
ch->m_iFishingPatternMaxReactionMs = reactionMs;
ch->m_iFishingPatternLastReactionMs = reactionMs;
ch->m_iFishingPatternTightSequence = 1;
}
void ObserveFishingReaction(LPCHARACTER ch, int reactionMs, bool success)
{
if (!ch || reactionMs <= 0 || reactionMs > 6000)
return;
const DWORD now = get_dword_time();
if (0 == ch->m_dwFishingPatternWindowStart || now - ch->m_dwFishingPatternWindowStart >= kFishingPatternWindowMs)
{
ResetFishingPatternWindow(ch, now, reactionMs);
return;
}
++ch->m_iFishingPatternSampleCount;
ch->m_iFishingPatternMinReactionMs = MIN(ch->m_iFishingPatternMinReactionMs, reactionMs);
ch->m_iFishingPatternMaxReactionMs = MAX(ch->m_iFishingPatternMaxReactionMs, reactionMs);
if (abs(reactionMs - ch->m_iFishingPatternLastReactionMs) <= kFishingPatternTightDeltaMs)
++ch->m_iFishingPatternTightSequence;
else
ch->m_iFishingPatternTightSequence = 1;
ch->m_iFishingPatternLastReactionMs = reactionMs;
const int spread = ch->m_iFishingPatternMaxReactionMs - ch->m_iFishingPatternMinReactionMs;
if (ch->m_iFishingPatternSampleCount < kFishingPatternMinSamples || spread > kFishingPatternMaxSpreadMs)
return;
char szDetail[160];
snprintf(szDetail,
sizeof(szDetail),
"samples=%d spread=%d last=%d tight_seq=%d success=%d",
ch->m_iFishingPatternSampleCount,
spread,
reactionMs,
ch->m_iFishingPatternTightSequence,
success ? 1 : 0);
ch->RecordAntiCheatViolation("FISHING_PATTERN",
ch->m_iFishingPatternTightSequence >= 5 ? 4 : 2,
szDetail,
spread <= 80);
ResetFishingPatternWindow(ch, now, reactionMs);
}
}
int aFishingTime[FISHING_TIME_COUNT][MAX_FISHING_TIME_COUNT] =
{
{ 0, 0, 0, 0, 0, 2, 4, 8, 12, 16, 20, 22, 25, 30, 50, 80, 50, 30, 25, 22, 20, 16, 12, 8, 4, 2, 0, 0, 0, 0, 0 },
@@ -618,6 +680,7 @@ void Take(fishing_event_info* info, LPCHARACTER ch)
long ms = (long) ((get_dword_time() - info->hang_time));
DWORD item_vnum = 0;
int ret = Compute(info->fish_id, ms, &item_vnum, GetFishingLevel(ch));
ObserveFishingReaction(ch, ms, ret == 0);
//if (test_server)
//ch->ChatPacket(CHAT_TYPE_INFO, "%d ms", ms);