Bullet sync may be broken
Closed this issue · 14 comments
Describe the bug
@Nico8340 I think #4381 (or the changes Dutchman made after you) have broken bullet sync, not entirely broken it, but I have updated the server to the newest 1.6 nightly which has the changes and players are reporting players randomly aren't taking gun fire damage, no clear steps to reproduce it yet.
I also witnessed an incident where there were 5 players on my screen in combat, all aiming their guns but no bullets were being fired, this lasted a few seconds. This was inside an interior and dimension on mapped objects so may be related.
I see that a load of new checks have been added like validating trajectory, how about when aborting, add some logging of these aborted shots as that'd be quite a quick way to find out which of these checks is causing all these legit bullets to not be sent.
I asked codex for some theories:
Steps to reproduce
Unknown as of now.
Version
MTA:SA Server v1.6-release-23368
Multi Theft Auto v1.6-release-23324 - I notice some client side changes have been made, do clients need updating? If so then that's a problem because newest nightly is unstable and also max min/recommended client version needs updating.
Additional context
A video someone uploaded of them shooting someone loads and no bullets seemed to do anything: https://www.youtube.com/watch?v=MxG-1z5xsZI
Relevant log output
Security Policy
- I have read and understood the Security Policy and this issue is not security related.
#4381 was thoroughly tested with multiple players before it was merged, and we didn't run into issues like this
There are 2 more videos here and comments are saying that it only happens on mapped and or crowded areas: https://cit.gg/index.php?topic=407823.0
Did you test it on mapped objects though?
Did you test it on mapped objects though?
I was one of the people who helped Nico test it. We used a default freeroam gamemode, so no, but I don't see how that could make a difference
I was going to test a theory, and found that onPlayerWeaponFire doesn't trigger at all when firing weapons now.
srun addEventHandler ("onPlayerWeaponFire", root, function (weapon, endX, endY, endZ, hitElement, startX, startY, startZ) outputChatBox("source is: "..inspect(source)) end)
In 23329:
source is: elem:player[[CIT]Arran]
In 23368:
Nothing.
I was going to test a theory, and found that onPlayerWeaponFire doesn't trigger at all when firing weapons now.
That can only happen if one of the bullet sync checks are invalid. Everything was working great when we tested it, so I have no clue what's happening
I have tested newest nightly on local default server to confirm no scripts were interfering and onPlayerWeaponFire is still non functional, I am firing an M4 at the ground and vehicles, nothing.
Maybe the version you tested didn't have the additional changes that Dutchman did after that PR.
Changes in 7004014
- Only peds and vehicles receive damage.
// Check element type is valid for damage
auto elementType = pElement->GetType();
if (elementType != CElement::PLAYER &&
elementType != CElement::PED &&
elementType != CElement::VEHICLE)
{
ResetDamageData();
return false;
}- It’s also worth mentioning that outside the map, bulletsync doesn’t work either.
bool CBulletsyncPacket::ValidateVectorBounds(const CVector& vec) const noexcept
{
if (vec.fX < -MAX_WORLD_COORD || vec.fX > MAX_WORLD_COORD)
return false;
if (vec.fY < -MAX_WORLD_COORD || vec.fY > MAX_WORLD_COORD)
return false;
if (vec.fZ < -MAX_WORLD_COORD || vec.fZ > MAX_WORLD_COORD)
return false;
return true;
}- Strange coding practices?
if (!stream.Read(reinterpret_cast<char*>(&m_start), sizeof(CVector)))
return false;
if (!stream.Read(reinterpret_cast<char*>(&m_end), sizeof(CVector)))
return false;Overall, I understand Dutchman’s intentions and I know he meant well. Bulletsync and weapons are among the most commonly exploited entry points for cheaters to cause various strange crashes.
However, putting aside coding guidelines, code quality, and readability.. since those can always be improved - the important point here is the actual logic changes, which alter the behavior and fundamental operation of bulletsync.
I will fix this today, dw
Additionally, from #4381, Codex’s suggestions are correct. The ammo-in-clip check should be removed, because under heavier network load there’s no guarantee that the packet updating ammo in clip (I think that’s player puresync?) will reach the server before the bulletsync. This means the condition can often result in false positives, especially if the server uses a custom interval for puresync. Testing with 5 players won’t yield the same results as with 50 players, so I think this was overlooked.
Checking total ammo is completely sufficient.
I was going to test a theory, and found that onPlayerWeaponFire doesn't trigger at all when firing weapons now.
srun addEventHandler ("onPlayerWeaponFire", root, function (weapon, endX, endY, endZ, hitElement, startX, startY, startZ) outputChatBox("source is: "..inspect(source)) end)
In 23329:
source is: elem:player[[CIT]Arran]
In 23368:
Nothing.
I have been having reports of my anticheat bullet tracking system not working correctly, so yeah I can confirm this happens outside of CIT.
Needed changes overall but I will have to revert to a previous nightly.
I just tested #4430 and onPlayerWeaponFire doesn't seem to be triggering still. I'm shooting at the ground, vehicles, ped. Nothing. In the video it shows it working shooting a player, I don't know if shooting at the ground was tested.
#4430'u az önce denedim ve onPlayerWeaponFire hala tetiklenmiyor gibi görünüyor. Yere, araçlara, yayalara ateş ediyorum. Hiçbir şey. Videoda bir oyuncuyu vururken çalıştığı görülüyor, yere ateş etmenin test edilip edilmediğini bilmiyorum.
pPlayer->GetWeaponTotalAmmo function requires the weapon's slot, so it was returning 0. If it is updated this way, it will work without any problems.
#include "CWeaponNames.h"
// Check if weapon has ammo
const auto type = static_cast<std::uint8_t>(m_weapon);
const auto slot = CWeaponNames::GetSlotFromWeapon(type);
if (pPlayer->GetWeaponTotalAmmo(slot) <= 0)
return false;
onPlayerWeaponFire now works correctly in newest 1.7 nightly.
Though won't know for sure if bullet sync is working correctly without a bigger test.