Make onPlayerWeaponFire cancellable (consistency with onWeaponFire)

Abierto
#5,133 0 comentarios 2 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 3 días

Nadie ha tomado este issue todavía.

  • #5115 de @QueryOfficial — cerrado sin fusionar

Evaluación

Dificultad
5/5
Tiempo estimado
Más de una semana
Aptitud para principiantes
35/100
Tipo de issue
Nueva funcionalidad
Claridad
Bastante claro
Estado de actividad
Tranquilo
Stack tecnológico
cpp, lua

Línea de trabajo

Start in Server/mods/deathmatch/logic/CGame.cpp at CGame::Packet_Bulletsync and compare the onWeaponFire path with onPlayerWeaponFire. Read CSimPlayerManager::HandleBulletSync and CNetAPI::ReadBulletsync to understand the sim-sync relay and client application. Done means cancellation suppresses the relay for every observer while preserving the fast path when no handler is attached, with relevant sync and event tests passing.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

enhancement
Is your feature request related to a problem? Please describe.

cancelEvent() inside onPlayerWeaponFire does nothing. A script can observe a bullet-sync shot server-side, but cannot stop it. Two things are in the way.

1. The return value is discarded. In CGame::Packet_Bulletsync:

player->CallEvent("onPlayerWeaponFire", args);
RelayNearbyPacket(packet);

CElement::CallEvent already returns !WasEventCancelled(). The custom-weapon path 26 lines below uses it (if (!weapon->CallEvent("onWeaponFire", args)) return;), so onWeaponFire is cancellable and onPlayerWeaponFire is not.

2. Sim sync relays the packet before Lua runs. CSimPlayerManager::HandleBulletSync broadcasts on the sync thread, and threadnet defaults to on. So just honouring the return value would cancel the shot only for observers sim sync did not cover — a zone-dependent partial cancel, which would be worse than today.

This is not cosmetic: receiving clients apply the shot and its damage from the relayed packet (CNetAPI::ReadBulletsync). Scripts validating a shot server-side today have to let it through and undo the damage afterwards, which players can see. onClientPlayerWeaponFire is not a substitute, since a server cannot rely on a client-side cancel.

Describe the solution you'd like

Make cancelEvent() in onPlayerWeaponFire suppress the relay for every observer, matching onWeaponFire.

That means bullets must not take the sim-sync fast path while a cancel is still possible. Proposal, and the part I would like feedback on: keep the fast path as the default, and bypass it for bullet sync only while a Lua handler for onPlayerWeaponFire is attached. Servers not using the event keep today's latency; servers using it pay one main-thread hop. There is precedent for gating work on handler presence (CMapEventManager::HasEvents()), though it is per-element and would need extending.

I am happy to write the PR — raising this first because it changes sync behaviour and I would rather agree on the approach up front.

Describe alternatives you've considered
  • Honour the return value only, leaving sim sync alone — smallest diff, but gives the partial cancel described above.
  • Drop the sim-sync fast path for bullets entirely — consistent, but costs latency on every server.
  • An explicit config/scripting toggle instead of inferring from handler presence — more predictable, more config surface.
Additional context

Verified on master (c3f1957a4007aefa8b2114028b298105a5e17934) with a local server and client build.

#852 asks for the same capability on the client-side event. I know #4989, #5115, #5116 and #4682 are open against this area; this request is about the scripting API contract rather than bullet-sync validation, and I am happy to rebase on top of them.

Security Policy
  • I have read and understood the Security Policy and this issue is not about a cheat or security vulnerability.
Lenguaje dominante
C++
Estrellas
1.9k
Forks
588
Merge medio
4 d 9 min
PR fusionados (30 d)
11

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de multitheftauto/mtasa-blue

Todos los issues de multitheftauto/mtasa-blue

Issues similares

Más issues de C++

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.