Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stop element sync on demand #3245

Open
1 task done
haron4igg opened this issue Nov 18, 2023 · 22 comments
Open
1 task done

Stop element sync on demand #3245

haron4igg opened this issue Nov 18, 2023 · 22 comments
Labels
enhancement New feature or request

Comments

@haron4igg
Copy link

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

In respond to total disaster with WH/ESP cheating this days,
i think there is actually a solution, which will cure this issue for competitive servers for like 80% of cheat use-cases.

Describe the solution you'd like

If it would be possible to pause player/vehicle/ped synchronization for particular players on demand - we would actually prevent
cheat-makers and cheaters from knowing 'long-distance' situation in game world.

There would be no-way for cheat-makers to bypass it since client will have limited data.

lets say we have method:
setPositionSyncEnabled(emement, forPlayer, state)

So for server side, we may write a script, that for every 100-300 ms, enables sync of elements that are in range of N meters to player and removes position sync for elements that are offside of this range.

If server disables sync of some element, this element should become 'non-streamable' for client. or at least hidden to some technical dimension / or sent to some outside of map location, until sync is re-enabled.

Describe alternatives you've considered

No response

Additional context

No response

Security Policy

  • I have read and understood the Security Policy and this issue is not about a cheat or security vulnerability.
@haron4igg haron4igg added the enhancement New feature or request label Nov 18, 2023
@Zangomangu
Copy link
Contributor

This is achievable using dimensions

@haron4igg
Copy link
Author

haron4igg commented Nov 19, 2023

This is achievable using dimensions

2 of most used cheats that i know bypassing dimensions already.

@CrosRoad95
Copy link

setPositionSyncEnabled(emement, forPlayer, state)

this function sounds like most dumbest thing i have ever seen. I know that recently cheaters count increased but solutions like your should never be accepted.

When i have been working on bullet physics, my idea was to use it in deathmatch server so server know what player sees and what should be synced, that way you won't ever know even enemy rotation if he is outside eye sight

@haron4igg
Copy link
Author

setPositionSyncEnabled(emement, forPlayer, state)

this function sounds like most dumbest thing i have ever seen. I know that recently cheaters count increased but solutions like your should never be accepted.

When i have been working on bullet physics, my idea was to use it in deathmatch server so server know what player sees and what should be synced, that way you won't ever know even enemy rotation if he is outside eye sight

Its just a tool which you may or may not to use depends on situation. For me its not improtant if player knows what is rotation/position of enemy in 1000 meters, but it is crucial that cheater is not aware of gameplay situation in 1000 meters.

In my server - cheaters using ESP to observe where 'big fights' are happens, or observe if some lonely player visiting some 'profitable' location. so they can come there and get 'easy profits'. This is what i'm trying to stop, and i can do nothing with this using current toolset.

On other hand - so far i have banlist of 140 players only for this year, who been caught using known cheats, using features which i'm able to detect. I can't imagine how much more people using this undetectable ESP, but at the end i'm having numerous of complains and people stopping play just because they don't feel confident that we can handle this issue.

@haron4igg
Copy link
Author

haron4igg commented Nov 19, 2023

At the moment few admins of similar project as mine, (me as well) having solution, to 'hide' player/vehicle from render so cheats are being confused and not able to render it. This is literraly the same idea as 'setPositionSyncEnabled' - but it's client-side solution and could be easly bypased in any time by cheat-devs.
And this was the last thing with current tool-set we were able to oppose them...

@ffsPLASMA
Copy link
Contributor

ffsPLASMA commented Nov 19, 2023

This is achievable using dimensions

Working with dimensions on a large or specific way is either annoying or impossible.
Disabling sync of one element for a specific player or group of players could be very useful.

something like that I have in mind:

syncElement(element, player/table, bSync)

  • element: the element to sync or not sync
  • a player element or a table of player elements to sync to
  • bool to let it sync or not

@Zangomangu
Copy link
Contributor

From haron's description it sounds like he needs a cutoff based on distance.

So we could have an opt-in setting to disable sync updates over a certain distance between players
One solution could be to allow disabling lightsync entirely (gotta investigate to see if this is feasible)

@haron4igg
Copy link
Author

haron4igg commented Nov 19, 2023

From haron's description it sounds like he needs a cutoff based on distance.

So we could have an opt-in setting to disable sync updates over a certain distance between players One solution could be to allow disabling lightsync entirely (gotta investigate to see if this is feasible)

I prefer still to choose who should receive updates, and who not.
For example - team-mates should be able to see each other, or car-owners should see their cars on GPS/Map at any distance.

As of my understanding of light-sync, this should be already feaseble, because current light-sync evaluates distances for each player individually. And my proposal just needs one more extra flag on each syncable element, to filter it out for particular player.

@Zangomangu
Copy link
Contributor

Those are some good examples

My concern with a scripting function like this is that it gets mismanaged by scripters

There have been many reports from server owners claiming an issue with MTA when it's their own bad scripting allowing clients to abuse their server. So it's hard to see these people making proper use of a function like this.

But considering that anti-cheat is the job of server owners there should also be the necessary tools available. So overall i'm in favor of adding a function like this, as I don't see an alternative to countering ESP cheats

@Dutchman101
Copy link
Member

I don't agree with the concerns, and i support implementing this suggestion, good idea.

@T-MaxWiese-T
Copy link

T-MaxWiese-T commented Jul 22, 2024

something like that I have in mind:

syncElement(element, player/table, bSync)

  • element: the element to sync or not sync
  • a player element or a table of player elements to sync to
  • bool to let it sync or not

That's what we need. Currently, only vehicles, peds and players are synchronized. But we are also working on object synchronization: #3405 . What I am currently missing with vehicles and peds is that if you set the synced parameter to false, you can no longer set it to true. This means you are forced to create a new element if synchronization is desired and set the parameter to true.
Players are also elements there would be the question whether you should be able to deactivate the synchronization there. This might be fun for cheaters.

@T-MaxWiese-T
Copy link

T-MaxWiese-T commented Jul 22, 2024

So I see some inconsistencies with the deactivated synchronization of the different server-side elements.
So you have to ask yourself the question: What exactly does no synchronization mean?
I would say no synchronization means that all player actions are not synchronized between the clients, i.e. the values from the server cannot be modified by clients. This means that there is no exchange between the server and the clients.
Then there is the question if a sync is deactivated for an server-side element, should the position and rotation be synchronized by the server as for example with createVehicle?
I would say yes, that should be an additional argument.
And then there is the question of whether server-side elements should behave like client-side elements if only the position and rotation is synchronized by the server?
I would say no because otherwise it would look strange if a player moves a vehicle and then it is synchronized by a player and the vehicle is suddenly somewhere else. This means that the server-side elements should be static as defined by the server so that every player sees the same thing.
You could possibly use other arguments such as whether the element health should be synchronized.

@Fernando-A-Rocha
Copy link
Contributor

Peds and vehicles with "sync=false" are not synchronized by any clients, meaning that if they move somehow, the server won't receive or will ignore any updates, right?

we would actually prevent cheat-makers and cheaters from knowing 'long-distance' situation in game world.

Regarding this core issue, haven't we solved it already?

Image

With these 2 server settings, we can determine the distance within which peds and vehicles will be synced to clients, no?

@haron4igg
Copy link
Author

Peds and vehicles with "sync=false" are not synchronized by any clients, meaning that if they move somehow, the server won't receive or will ignore any updates, right?

we would actually prevent cheat-makers and cheaters from knowing 'long-distance' situation in game world.

Regarding this core issue, haven't we solved it already?

Image

With these 2 server settings, we can determine the distance within which peds and vehicles will be synced to clients, no?

this two parameters will stop client, from syncing position updates to unoccupied cars and peds.
this still doesn't help if car is occupied, or for players it self :D

Also answering @T-MaxWiese-T questions:

i will note, that we are now speaking about possibility, to customize element sync behavior, for particular client.
What sync types could be and what does it means (i also added one more type, in example bellow, could be useful):

  • SYNCED - element is normaly synced to client, same as now.

  • NO_POSITION_SYNC - 'existance', element data and state updates are synced with chosen client (as it is now with light sync),
    but element become 'unstreamable' and gets position data anonymized. So it means that particular client, is not receiving position updates,
    and render engine must exclude element from streaming 'tree'.
    If you see the car, and server decides to stop sync - car should just dissapear for you, but should still exist in memory, without position information (or at least with outdate one, until sync would be re-inabled).
    what it mean for server, before issuing a position data update to client, server need to check if this client who gonna receive the info update, is allowed to receive it, and if not - do nothing, or exclude position information from state sync packet.
    but other people who allowed to see the car - should still receive an update as it is with SYNCED type.

  • UNSYNCED - the element existance is not communicated to particular client at all. Here if element existed on client side previosly,
    it gets 'onClientElementDestroy' notification.
    This could be also used to hide some elements, which should not be visible to client (some edf definitions, custom utility elements)
    and if element is then again switched to SYNCED or NO_POSITION_SYNC type, it gets retranslated back to user, with last known server state.


How we are using it:

We have a server side 'pusle' logic, which is triggered from time to time, and for EACH Client - evaluates
visibility of elements around him (on server side). If condition of visibility for particular element are met on server side - server will toggle full sync, if they are not met - server will limit it, or stop sync at all.

Some pseudo-code example:


local players = getElementsByType("player")
for i, p in ipairs(players) do
    local x,y,z = getElementPosition(p)

    local syncedElements = ... <getElementsSyncedByPlayer(player, "SYNCED")> -- new function to fetch elements, having custom setting for player, filtered by type of sync

    for j, el in ipairs(syncedElements ) do
          if getDistanceBetweenElements(player, el) > 150 then
              setElementSyncType(el, p, "NO_POSITION_SYNC") -- or "UNSYNCED", depends on usecase
          end
    end

    local elements = getElementsWithinRange(x,y,z,150, "") -- all streamable elements
    for j, el in ipairs(elements) do
          setElementSyncType(el, p, "SYNCED") -- sync all elements in 'visibility'range
    end
end

@FileEX
Copy link
Contributor

FileEX commented Dec 15, 2024

My proposal includes slightly simpler syntax:

bool setElementSyncable(element theElement, element/table player, bool syncable [, bool positionSync = true])

Allows enabling or disabling synchronization of a specific element with certain players or all players (root).

The syncable argument would refer to data such as player state, HP, element data, etc., while the positionSync argument would refer to position and rotation.
If syncable is set to true and positionSync to false, data like element data, HP, water state, fire state, etc., would be synchronized, but without position and rotation.

bool synced, bool positionSync isElementSyncable(element theElement [, element target = root])

As for handling something like "disappearing of unsynchronized elements," it would be simplest to leave this to scripters. Using Lua scripts, they could hide such players or move them to another dimension.

Contrary to appearances, introducing such functions would not be very difficult.

@samr46
Copy link
Contributor

samr46 commented Dec 15, 2024

Contrary to appearances, introducing such functions would not be very difficult.

It's partially true. There are 8 edge cases that I'm aware of that will have to be handled carefully. I'm not going to go into details because I don't think that proposed solution should be implemented in MTA. I'm talking from experience here (it's already possible to do what is proposed here for the purpose OP mentioned and it doesn't require modifications to existing codebase).

Generally I wouldn't recommend messing with sync too much (for example selective disabling of sync for players and vehicles is a terrible idea). There are some issues that are not that obvious (I had to deal with this and fixed it but overall optimized solution is tricky and good solutions have to be designed for particular gamemode behavior). It may look really easy at first before you switch to wide testing with heavy and complicated gamemodes. Also current sync packet handling is optimized for efficiency and not ideal for selective disabling.

Anyway, since it's already possible to do what is proposed here (in a different way) I don't think that anyone should waste time on this. It's not really needed and potentially will create more issues than it will resolve even if you implement it as server config setting.

@haron4igg
Copy link
Author

Contrary to appearances, introducing such functions would not be very difficult.

It's partially true. There are 8 edge cases that I'm aware of that will have to be handled carefully. I'm not going to go into details because I don't think that proposed solution should be implemented in MTA. I'm talking from experience here (it's already possible to do what is proposed here for the purpose OP mentioned and it doesn't require modifications to existing codebase).

Generally I wouldn't recommend messing with sync too much (for example selective disabling of sync for players and vehicles is a terrible idea). There are some issues that are not that obvious (I had to deal with this and fixed it but overall optimized solution is tricky and good solutions have to be designed for particular gamemode behavior). It may look really easy at first before you switch to wide testing with heavy and complicated gamemodes. Also current sync packet handling is optimized for efficiency and not ideal for selective disabling.

Anyway, since it's already possible to do what is proposed here (in a different way) I don't think that anyone should waste time on this. It's not really needed and potentially will create more issues than it will resolve even if you implement it as server config setting.

I assume you referring to client-side solution, manipulating position data for invisible elements after sync.

If such approach would be highly adopted by many servers, cheat-devs would find a way to baypass it, because position data is still exchanged, so available for them.

@samr46
Copy link
Contributor

samr46 commented Dec 15, 2024

I assume you referring to client-side solution, manipulating position data for invisible elements after sync.

If such approach would be highly adopted by many servers, cheat-devs would find a way to baypass it, because position data is still exchanged, so available for them.

I'm not gonna share any details for obvious reasons. But no, they can't bypass it (real sync data is not available to them in my case).

@FileEX
Copy link
Contributor

FileEX commented Dec 15, 2024

I assume you referring to client-side solution, manipulating position data for invisible elements after sync.
If such approach would be highly adopted by many servers, cheat-devs would find a way to baypass it, because position data is still exchanged, so available for them.

I'm not gonna share any details for obvious reasons. But no, they can't bypass it (real sync data is not available to them in my case).

Could you explain specifically what you mean and what side effects you foresee? If you don't want to do it here for obvious reasons, maybe we can discuss it via DM on Discord or some other way? I believe such functions would be useful, and I don't think they would break anything in any way. You know, if someone manages synchronization irresponsibly, that's their problem, not ours.

Such functions would be particularly useful for vehicles and peds created with the 'sync' argument set to false, allowing this parameter to be changed without needing to recreate the ped or vehicle

@samr46
Copy link
Contributor

samr46 commented Dec 15, 2024

Such functions would be particularly useful for vehicles and peds created with the 'sync' argument set to false, allowing this parameter to be changed without needing to recreate the ped or vehicle

You can add function to handle this. It will not create any issues if you just want to modify existing 'sync' argument. It should take only few lines of code (call SetSyncable for peds and similar method for vehicles). I guess it might be useful for someone.

Issues and edge cases are related to more deeper modification of sync (like proposed by OP). It's not worth it because like I mentioned it's already possible to do what OP wants without any modifications to existing codebase (and this other solution can be even more convenient / efficient).

maybe we can discuss it via DM on Discord or some other way

I can DM you when I get time if you want to know more about potential edge cases and issues of what OP proposed. It's not going to be easily noticeable on basic gamemodes like freeroam which will make testing tricky.

You know, if someone manages synchronization irresponsibly, that's their problem, not ours.

Normally I would agree with this but it's not a good policy in this particular case.

@Dutchman101
Copy link
Member

Dutchman101 commented Dec 16, 2024

You can go ahead with the implementation of this feature (@FileEX wants to do it). Even though opinions differ, it will simply be up to the server owner/scripter to choose if they use it. For those that don't like or want to use it: no gain no harm. It'll be useful for servers that want to develop advanced syncing systems, and it's their responsibility to use it (and clean up) properly.

From here onwards please stay on-topic in regards to how it should be implemented/further ideas for the feature. There's been enough feedback that seeks to block it, just not with anything but vague explanations. It has now been greenlighted, thanks for understanding

@TheNormalnij
Copy link
Member

bool synced, bool positionSync isElementSyncable(element theElement [, element target = root])

It feels wrong. Functions that started with "is" should return one boolean value.
I would prefer something like setElementSyncFlags(element, player/table, flags...) / flags... = setElementSyncFlags
Flags may be a table: { position = false, hp = true, weapon = false }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

10 participants