O que é VDM?
Vehicle Deathmatch (VDM) refere-se ao ato de usar um veículo como arma para intencionalmente atropelar, matar ou ferir outros jogadores sem justificativa adequada para o RPG. Em servidores de RPG FiveM, o VDM viola regras fundamentais do servidor e interrompe a experiência de roleplay que os jogadores buscam.
Por que o VDM é importante
Os servidores de RPG operam com base no princípio da interação realista. Quando um jogador deliberadamente bate seu veículo em outros jogadores sem contexto de RPG, isso:
- Quebra a imersão para todos os participantes
- Impede o desenvolvimento significativo da história
- Cria vantagens de jogo injustas
- Leva à frustração do jogador e ao declínio da população do servidor
Cenários comuns de VDM
Limpar violações do VDM:
- Dirigir nas calçadas para atropelar pedestres
- Atropelar veículos parados em semáforos
- Uso de veículos para bloquear entradas de hospitais
- Causar colisões frontais intencionalmente
Áreas cinzentas que exigem contexto:
- Manobras policiais durante perseguições
- Ataques de veículos relacionados a gangues com interpretação prévia
- Colisões acidentais durante corridas
- Respostas de veículos de emergência
Implementação Técnica: Sistemas Anti-VDM
Script de detecção do lado do servidor
-- resources/anti-vdm/server.lua
local vdmWarnings = {}
local VDM_THRESHOLD = 3
local DAMAGE_THRESHOLD = 50
RegisterServerEvent('vdm:checkCollision')
AddEventHandler('vdm:checkCollision', function(targetId, damage, speed)
local source = source
-- Validar entrada
if not targetId or not damage or not speed then return end
-- Verificar se dano e velocidade excedem limites
if damage > DAMAGE_THRESHOLD and speed > 30 then
local identifier = GetPlayerIdentifier(source, 0)
-- Inicializar contagem de avisos
if not vdmWarnings[identifier] then
vdmWarnings[identifier] = 0
end
vdmWarnings[identifier] = vdmWarnings[identifier] + 1
-- Registrar incidente
local logData = {
attacker = GetPlayerName(source),
victim = GetPlayerName(targetId),
damage = damage,
speed = speed,
timestamp = os.time()
}
TriggerEvent('vdm:logIncident', logData)
-- Agir com base nos avisos
if vdmWarnings[identifier] >= VDM_THRESHOLD then
DropPlayer(source, 'Expulso por violações de VDM')
vdmWarnings[identifier] = 0
else
TriggerClientEvent('chat:addMessage', source, {
args = {'^1[AVISO]', 'VDM detectado. Aviso ' ..
vdmWarnings[identifier] .. '/' .. VDM_THRESHOLD}
})
end
end
end)
Monitoramento do lado do cliente
-- resources/anti-vdm/client.lua
local lastCollision = 0
local COLLISION_COOLDOWN = 5000 -- 5 segundos
Citizen.CreateThread(function()
while true do
Citizen.Wait(0)
local playerPed = PlayerPedId()
if IsPedInAnyVehicle(playerPed, false) then
local vehicle = GetVehiclePedIsIn(playerPed, false)
if GetPedInVehicleSeat(vehicle, -1) == playerPed then
if HasEntityCollidedWithAnything(vehicle) then
local currentTime = GetGameTimer()
if currentTime - lastCollision > COLLISION_COOLDOWN then
local speed = GetEntitySpeed(vehicle) * 3.6 -- Converter para km/h
-- Verificar colisão com pedestre
local coords = GetEntityCoords(vehicle)
local closestPed = GetClosestPed(coords.x, coords.y, coords.z,
5.0, 1, 0, 0, 0, -1)
if DoesEntityExist(closestPed) and IsEntityAPed(closestPed) then
local targetPlayer = NetworkGetPlayerIndexFromPed(closestPed)
if targetPlayer ~= -1 then
local damage = GetEntityHealth(closestPed)
TriggerServerEvent('vdm:checkCollision',
GetPlayerServerId(targetPlayer),
damage, speed)
end
end
lastCollision = currentTime
end
end
end
end
end
end)
Configuração do servidor
Adições ao servidor FiveM server.cfg:
# Configuração Anti-VDM definir vdm_enabled true definir vdm_max_warnings 3 definir vdm_damage_threshold 50 definir vdm_speed_threshold 30 definir vdm_log_incidents true definir vdm_webhook "https://discord.com/api/webhooks/SEU_WEBHOOK_AQUI" # Garantir que o recurso anti-VDM seja iniciado garantir que o anti-VDM
Melhores práticas para administradores de servidor
1. Definição clara da regra
Crie regras VDM específicas na documentação do seu servidor:
Regra 2.1 - Vehicle Deathmatch (VDM) - É proibido usar qualquer veículo como arma - Exceções: Táticas policiais autorizadas, eventos sancionados - Punição: 1ª infração - Advertência, 2ª - Banimento por 24 horas, 3ª - Banimento permanente
2. Protocolo de Treinamento de Pessoal
Treinar moderadores para identificar VDM:
- Revisar registros de danos
- Verifique a velocidade do jogador no momento do impacto
- Verifique se o contexto do RPG existe
- Documentar evidências (clipes, capturas de tela)
3. Sistema de Relatórios de Jogadores
-- Simple reporting command
RegisterCommand('reportvdm', function(source, args, rawCommand)
local targetId = tonumber(args[1])
local reason = table.concat(args, ' ', 2)
if not targetId or not reason then
TriggerClientEvent('chat:addMessage', source, {
args = {'^1[ERROR]', 'Usage: /reportvdm [player_id] [reason]'}
})
return
end
-- Create report ticket
local report = {
reporter = GetPlayerName(source),
reported = GetPlayerName(targetId),
reason = reason,
timestamp = os.date('%Y-%m-%d %H:%M:%S'),
status = 'pending'
}
-- Store in database or send to Discord
TriggerEvent('vdm:createReport', report)
end, false)
Desafios comuns de implementação
Falsos Positivos
- Detecção de colisão induzida por atraso
- Dessincronização entre jogadores
- Acidentes legítimos
Solução: Implementar períodos de carência e verificação de contexto:
-- Verificar se os jogadores estão em um cenário ativo local function isInActiveRP(playerId) -- Verificar banco de dados para cenários ativos -- Retornar verdadeiro se o jogador estiver em perseguição policial, corrida, etc. end
Impacto no desempenho
Monitorar o uso de recursos de script:
-- Adicionar a fxmanifest.lua resource_monitor_mode 'yes'
Integração com Frameworks Populares
Estrutura ESX
ESX = nil
TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end)
-- Adicionar violações de VDM ao registro do jogador
RegisterServerEvent('vdm:recordViolation')
AddEventHandler('vdm:recordViolation', function(targetId)
local xPlayer = ESX.GetPlayerFromId(source)
MySQL.Async.execute('INSERT INTO vdm_violations SET identifier = @identifier, timestamp = @timestamp',
{
['@identifier'] = xPlayer.identifier,
['@timestamp'] = os.time()
})
end)
Estrutura QBCore
local QBCore = exports['qb-core']:GetCoreObject()
-- Integração com o menu de administração
QBCore.Commands.Add('checkvdm', 'Verificar histórico de VDM do jogador', {{name = 'id', help = 'ID do jogador'}}, true, function(source, args)
local Player = QBCore.Functions.GetPlayer(tonumber(args[1]))
if Player then
-- Buscar histórico de VDM
MySQL.Async.fetchAll('SELECT * FROM vdm_logs WHERE citizenid = @citizenid', {
['@citizenid'] = Player.PlayerData.citizenid
}, function(result)
TriggerClientEvent('qb-admin:client:showVDMHistory', source, result)
end)
end
end, 'admin')
Testando seu sistema anti-VDM
Conjunto de testes automatizados
-- tests/vdm_test.lua
local function testVDMDetection()
-- Simular evento de colisão
local mockData = {
attacker = 1,
victim = 2,
damage = 75,
speed = 45
}
TriggerEvent('vdm:checkCollision', mockData.victim, mockData.damage, mockData.speed)
-- Verificar se o aviso foi emitido
-- Verificar se o registro foi criado
-- Confirmar se o webhook foi acionado
end
Métricas de desempenho
Eficácia do sistema de rastreamento:
-- Esquema do banco de dados CREATE TABLE vdm_metrics ( id INT AUTO_INCREMENT PRIMARY KEY, date DATE, total_incidents INT, warnings_issued INT, players_kicked INT, false_positives INT );
Conclusão
A prevenção de VDM requer implementação técnica, regras claras e aplicação consistente para manter ambientes de simulação de qualidade em servidores FiveM.