Skip to content

[admin2]: Use serverside setWorldSpecialPropertyEnabled instead of proxying the call through the client #731

Description

@brenodanyel

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

admin2's code applies "special world property" (and blur) changes by triggering a client event and calling setWorldSpecialPropertyEnabled / setBlurLevel clientside:

addEventHandler(
    EVENT_PROXY,
    root,
    function(action, data, value)
        if (action == PROXY_ALL) then
            setBlurLevel(data[PROXY_BLUR])
            for k, v in pairs(data[PROXY_SPECIAL]) do
                setWorldSpecialPropertyEnabled(k, v)
            end
        elseif (action == PROXY_BLUR) then
            setBlurLevel(data)
        elseif (action == PROXY_SPECIAL) then
            setWorldSpecialPropertyEnabled(data, value)
        end
    end
)

Since the setWorldSpecialPropertyEnabled call happens clientside, it fires onPlayerChangesWorldSpecialProperty exactly the same way a cheat/trainer forcing the property clientside would. Any server-side anti-cheat listening to that event has no way to distinguish "admin2 legitimately applied this" from "a client-side hack just toggled this", and is forced to add extra bookkeeping/allowlisting just to avoid flagging admin2's own actions.

Describe the solution you'd like

Since MTA 1.6.0 r22195, setWorldSpecialPropertyEnabled is also available as a serverside function. I'd like admin2 refactored to call it serverside instead of proxying through a client event:

  • Replace the clientside setWorldSpecialPropertyEnabled(k, v) calls in admin_proxy.lua with serverside setWorldSpecialPropertyEnabled(player, k, v) calls (run wherever the admin action currently triggers EVENT_PROXY).
  • Drop the PROXY_SPECIAL (and, within PROXY_ALL, the special-property loop) client event plumbing that becomes unused once the call is serverside.

This avoids triggering OnPlayerChangesWorldSpecialProperty for legitimate admin actions, removes a class of false positives, and lets resources that hook that event treat every clientside-originated change as suspect by default, without needing to special-case admin2.

Sidenote: the same proxy also sets blur via clientside setBlurLevel. setPlayerBlurLevel exists serverside too, so the same change (setPlayerBlurLevel(player, data) instead of setBlurLevel(data), dropping PROXY_BLUR) could be applied there for consistency, though it's not the main motivation for this issue.

Additional context

This came up while building an server ac that uses onPlayerChangesWorldSpecialProperty to detect clientside tampering with special world properties. admin2's own legitimate use of the clientside function is indistinguishable from a cheat doing the same thing, so refactoring admin2 to use the serverside function (added specifically to support this kind of use case) would let anti-cheat resources trust the event without extra validation logic for admin2's own actions.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions