How do I prevent exploiters from manipulating this

  1. What do you want to achieve? Keep it simple and clear!
    I’m trying to prevent exploiters from being able to manipulate a model that’s parented to a character and is owned by the player that owns the character.

  2. What is the issue?
    The issue is that currently exploiters are able to manipulate the position of an attachment and it goes serverside. The ability model has it’s network ownership set to the player and I can’t change that because it’s important that the ability stays behind the player smoothly rather than being laggy.

  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    Continously setting the position of the attachment on server side, as expected didn’t work.

Context:
[Video showcasing the issue: the ability is behind the player in the left window]

The ability models have been entirely client side (model wasn’t on the serverside, each client made it’s own copy) before but it’s a headache to do certain things when it’s this way so I decided to make it so the model is server side. To make it smooth this way I needed to give network ownership to the player who owns the ability and this introduced this issue. There are also some other issues. A perfect solution would be giving the player as little control over the model as possible with this solution.
What I think would work is make it so the server simulates the model by itself and each player simulates it by themselves as well, but I do not know if that’s possible to achieve. (Basically the server network owns the model but each client acts as if it was network owned by them and simulates the physics)
I already prevented removal of anything from the model with connections which kill the player if anything is removed.

I know this is somehow possible because I’m 99% sure other big games based on the same source material have these ability models present on server side and don’t seem to have this issue.

1 Like

I’m assuming that the position of the attachment is also replicated to the server here. Because the player has network ownership of the model, or whatever.

You could have a script on the server that constantly calculates what the attachment’s position is supposed to be. And then if the attachment’s position relative to the part that it’s attached to isn’t what it thought it was supposed to be, then you know that it’s position has been manipulated. You could then to a whole lot of things. Ban them. Kick them. Kill them. Or reset the attachments position in the right location. It’s a bad idea to ban or kick them, because if there was a bug in the script, it could potentially improperly calculate the position of the attachment, and then potentially falsely ban them.

Edit: The way you could calculate the attachment depends entirely on your game’s design. If the attachment’s position relative to the part that it’s attached to is static (never changes), then you could just loop through every attachment in the model right when the model is cloned / parented, and store it’s position relative to the object it’s attached to, and then constantly check to see if the coordinates are the same. Like this:

local model = model
-- Code that spawns the model or whatever
local relativeCoordinates = {}
for i, v in pairs(model:GetDescendants()) do
      if v:IsA("Attachment") then
          relativeCoordinates[v] = v.Position -- Position is already in LocalSpace
      end
  end

while true do
    task.wait(1)
    for i, v in pairs(model:GetDescendants()) do
        if v:IsA("Attachment") then
            if v.Position ~= relativeCoordinates[v] then
                print("Attachment has been tampered with")
            end
        end
    end
end

There is probably a better way of doing this than using a while true do loop, but I think you understand what I mean now.

Another Edit:

Just in case the attachment’s positions aren’t replicated to the server, you could run this code right here instead:

-- Run this code right after the model is spawned, and right after it has been positioned right behind the player
local correctPosition = player.HumanoidRootPart.CFrame:ToObjectSpace(model.PrimaryPart.CFrame)
-- Only set the network ownership of the model after the correctPosition variable has been created, because if you don't, a hacker could (theoretically) change the position of the model right before the server calculates the value of the correctPosition variable, and then it will not be calculated correctly.
while true do
    task.wait(1)
    if player.HumanoidRootPart.CFrame:ToObjectSpace(model.PrimaryPart.CFrame) ~= correctPosition then
        print("Something has been tampered with")
    end
end

What this new block of code is doing, is it’s calculating what the position of the model should be relative to the player, and then a while true do loop calculates the current position of the model relative to the player’s humanoid root part, and if that position isn’t equal to what the server thought it should be, then the player is probably tampering with the position of the attachment.

Also, in this case, the “model” variable is that model that is attached to the player.
@mayoozzzz