otland / forgottenserver

A free and open-source MMORPG server emulator written in C++
https://otland.net
GNU General Public License v2.0
1.56k stars 1.04k forks source link

Fix classicAttackSpeed makes server lag (#4676) #4677

Closed gesior closed 2 months ago

gesior commented 2 months ago

classicAttackSpeed algorithm is bugged and may generate infinite number of scheduler (dispatcher) events.

  1. TFS calls Player::doAttacking every second for every player.
  2. It creates new event g_scheduler.addEvent(task);, which calls Player::doAttacking again with getAttackSpeed() delay. So there is repeating event every 0.2 sec (with attack speed 200) and TFS still calls Player::doAttacking every second creating new event. That way server can create infinite number of events for 1 player. 1 new event every second.

Often it all stops on if ((OTSYS_TIME() - lastAttack) >= getAttackSpeed()) { - player cannot attack as fast as these events execute, so if there is more than 1 dispatcher event for given player, it won't re-create it after execution (addEvent is inside that IF). But if player uses melee weapon and his target is not within 1 sqm, his attack will never execute and lastAttack will never update, so it will be able to re-create events, even if there is more than 1 running in same time.

Fixed code limits number of scheduled doAttacking events to 1 per player.