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.
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 callingsetWorldSpecialPropertyEnabled/setBlurLevelclientside:Since the
setWorldSpecialPropertyEnabledcall 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
admin2refactored to call it serverside instead of proxying through a client event:setWorldSpecialPropertyEnabled(k, v)calls inadmin_proxy.luawith serversidesetWorldSpecialPropertyEnabled(player, k, v)calls (run wherever the admin action currently triggersEVENT_PROXY).PROXY_SPECIAL(and, withinPROXY_ALL, the special-property loop) client event plumbing that becomes unused once the call is serverside.This avoids triggering
OnPlayerChangesWorldSpecialPropertyfor 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.setPlayerBlurLevelexists serverside too, so the same change (setPlayerBlurLevel(player, data)instead ofsetBlurLevel(data), droppingPROXY_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
onPlayerChangesWorldSpecialPropertyto 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.