Jump to content

ZeusDev

Members
  • Posts

    3
  • Joined

  • Last visited

Details

  • Gang
    LockCode Systems
  • Location
    0x000000
  • Occupation
    Solutions Architect & Reverse Engineer
  • Interests
    Software Protection, VM Architecture, High-Performance Computing

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

ZeusDev's Achievements

I ordered some spaghetti with marinara sauce and I got egg noodles and ketchup. I'm an average nobody.

I ordered some spaghetti with marinara sauce and I got egg noodles and ketchup. I'm an average nobody. (2/54)

2

Reputation

  1. ZeusDev

    Hydra Speed

    Vehicle handling doesn't affect aircraft top speed because MTA has a separate velocity cap specifically for flying vehicles. This is controlled by setAircraftMaxVelocity. The default value is 1.5, which roughly translates to that 270 km/h limit you're hitting. To increase it: setAircraftMaxVelocity(3.0) The parameter is a multiplier, not an actual speed value. Some reference points: - 1.5 = default (~270 km/h) - 2.0 = ~360 km/h - 3.0 = ~540 km/h - 5.0 = ~900 km/h There's no documented maximum limit for this value, but extremely high values may cause physics instability or unexpected behavior. Keep in mind this applies to all aircraft globally, not per-vehicle. If you need to check the current value, use getAircraftMaxVelocity. local currentMax = getAircraftMaxVelocity() outputChatBox("Current aircraft speed cap: " .. tostring(currentMax)) So yeah, handling is for ground vehicle physics. Aircraft speed limits are a separate system entirely.
  2. ZeusDev

    MTA UI Editor

    Really cool project! It's nice to see someone putting effort into tooling for MTA. The community really lacks this kind of stuff and it's a shame these posts don't get more attention. I'm actually working on something similar myself, a direct converter for developers that goes from Figma to MTA. You design your UI in Figma, tag your layers with suffixes like _checkbox, _image, _button, etc., and it exports the whole thing ready to use. Different approach but same goal: making UI development less painful. Good luck with the project, hope it gets the traction it deserves.
  3. Unfortunately that's not how MTA's damage system works. The official Wiki explicitly states: So onPlayerDamage server-side is not authoritative at all. If a cheater cancels onClientPlayerDamage on their client, the server never receives onPlayerDamage because the damage was prevented client-side before synchronization even happens. The player becomes invincible and your server sees absolutely nothing. The phrase "never trust the client" is correct, but in this case MTA's architecture forces the client to be trusted for damage events. That's the core problem here. A Real Approach: Server-Side Health Validation Since you can't rely on damage events arriving, you need to validate expected damage against actual health changes using data you CAN trust server-side: local playerHealthCache = {} local HEALTH_DISCREPANCY_THRESHOLD = 50 addEventHandler("onPlayerSpawn", root, function() playerHealthCache[source] = getElementHealth(source) end) addEventHandler("onPlayerWeaponFire", root, function(weapon, _, _, _, _, _, target) if not target or not isElement(target) or getElementType(target) ~= "player" then return end local expectedDamage = getWeaponDamage(weapon) local currentHealth = playerHealthCache[target] or getElementHealth(target) local expectedHealth = math.max(0, currentHealth - expectedDamage) setTimer(function() if not isElement(target) then return end local actualHealth = getElementHealth(target) local discrepancy = actualHealth - expectedHealth if discrepancy > HEALTH_DISCREPANCY_THRESHOLD then flagSuspiciousPlayer(target, "GODMODE_SUSPECTED", discrepancy) end playerHealthCache[target] = actualHealth end, 150, 1) end) function getWeaponDamage(weaponID) local damageTable = { [22] = 8.25, [23] = 13.2, [24] = 46.2, [25] = 49.5, [26] = 49.5, [27] = 39.6, [28] = 6.6, [29] = 8.25, [30] = 9.9, [31] = 9.9, [32] = 46.2, [33] = 75, [34] = 75, [38] = 46.2 } return damageTable[weaponID] or 25 end function flagSuspiciousPlayer(player, reason, data) local serial = getPlayerSerial(player) outputDebugString(("[AC] %s flagged: %s (data: %s)"):format(getPlayerName(player), reason, tostring(data))) end addEventHandler("onPlayerQuit", root, function() playerHealthCache[source] = nil end) The idea is simple: when someone fires a weapon at a player, you know the expected damage. Then you check if their health actually dropped by that amount. If they keep taking hits but health never goes down, something's wrong. Also worth noting that wasEventCancelled() on client won't help for anti-cheat since the cheater controls that environment entirely. They can just patch out the detection or spoof the result.
×
×
  • Create New...