MMO Player Movement hacking

Post here your questions about the Unity / .Net / Mono / Windows 8 / Windows Phone 8 API for SFS2X

Moderators: Lapo, Bax

OhMyOhmit
Posts: 18
Joined: 24 Apr 2018, 12:25

MMO Player Movement hacking

Postby OhMyOhmit » 11 Sep 2018, 16:30

Hey guys. I'm here again with another question. Thanks for a previous replies, they helped me a lot and I have a great progress in creating my game.

So, the problem I've faced right now is a player movement in the MMO Room. Right now it is very easy to hack as I have no movement-checks on the server side, so cheaters could change character's speed on the client or even teleport to another place. The idea I have at the moment is to move player on the client and on server-unity-client with the same script and contain player speed variable on server, so if players taps W, for example, to move forward, he will move forward on client with velocity that is on client, and on server with velocity that is on server (normally they should be same). And if the player will change his speed on the client, then there will appear a difference between his position on client and server, which means that he was hacking.
But in theory, the problem I could face is a player's bad connection that will cause lags. And if he will move 10 meters on the client having a big ping, on the server he moved only for 2 meters for example because the request to move weren't sending from the client.


Fairly saying I'm not even sure if that can really happen, because I don't have an experience in such things and can't test it yet.
Hope you'll understand the idea and could help me.
User avatar
Lapo
Site Admin
Posts: 20390
Joined: 21 Mar 2005, 09:50
Location: Italy

Re: MMO Player Movement hacking

Postby Lapo » 12 Sep 2018, 07:45

Hi,
usually the best option is to have some input validation at the server side. For example a speed check would be useful to verify that the client isn't cheating by increasing his movement speed beyond the game's limits.

You can still initiate the movement on client side and when the request gets to the server Extension you can validate it. If it's out of bounds you should probably disconnect the player.

Hope it helps
Lapo
--
gotoAndPlay()
...addicted to flash games
OhMyOhmit
Posts: 18
Joined: 24 Apr 2018, 12:25

Re: MMO Player Movement hacking

Postby OhMyOhmit » 12 Sep 2018, 09:04

Well, that looks like a simple solution, but how should I realise this?
I see 2 options:
1. Like in a MMORoomDemo, when my variable MovementDirty equals true, which means that player is actually moving, send a request to server extension, but adding a velocity to this. But as far as I know (I'm not really sure in it, as I said, because have no experience in such things, but I've heard that) cheaters can change the values that are sent by packets, so he could have a cheated velocity on his client but still send a normal value to server. Is it true or am I wrong?
2. Server should write the time and coordinates of every player on a server everytime server gets "move-request" from some client, so when server gets next player's move, it will check the distance player moved in a given amount of time. Like V=S/t. And if it's more then it should be, then player will get disconnected. But here's also a problem that I have different type of velocities. When player moves forward, his speed is, for example 4. When he moves backwards his speed is 2. When he sprints forward his speed is 6. And there's also a things like knockbacks when player is moving with a higher speed. So he could simulate a sprint speed, giving him a velocity as 6 that will give him ulimited fastness. :?
User avatar
Lapo
Site Admin
Posts: 20390
Joined: 21 Mar 2005, 09:50
Location: Italy

Re: MMO Player Movement hacking

Postby Lapo » 13 Sep 2018, 17:46

OhMyOhmit wrote:1. Like in a MMORoomDemo, when my variable MovementDirty equals true, which means that player is actually moving, send a request to server extension, but adding a velocity to this. But as far as I know (I'm not really sure in it, as I said, because have no experience in such things, but I've heard that) cheaters can change the values that are sent by packets, so he could have a cheated velocity on his client but still send a normal value to server. Is it true or am I wrong?

Depends, is the velocity variable? Or fixed?
If it's variable you initialize it from server side (so the server knows the initial state) and when the player changes it the server must validate it.

2. Server should write the time and coordinates of every player on a server everytime server gets "move-request" from some client, so when server gets next player's move, it will check the distance player moved in a given amount of time. Like V=S/t. And if it's more then it should be, then player will get disconnected.

Yes, it could work.
If you keep a server side state of your players (e.g. movement vector) you should have everything under control. If a client sends weird data that contradicts the server side player's state you probably have a cheater.

This is for example what we do in the SpaceWar game/demo example. Have you taken a look?
http://docs2x.smartfoxserver.com/ExamplesUnity/spacewar

Cheers
Lapo

--

gotoAndPlay()

...addicted to flash games
OhMyOhmit
Posts: 18
Joined: 24 Apr 2018, 12:25

Re: MMO Player Movement hacking

Postby OhMyOhmit » 14 Sep 2018, 16:48

I think I've found some useful information in this example. Thank you for your help once again! :)
OhMyOhmit
Posts: 18
Joined: 24 Apr 2018, 12:25

Re: MMO Player Movement hacking

Postby OhMyOhmit » 25 Oct 2018, 19:26

Hey guys. I am here again with the same trouble. It has looked clear to me in theory, but when it came to practice - I've stucked.
I've read this article (http://www.gabrielgambetta.com/client-s ... cture.html) nearly 10 times and understood everything, but I can't add to my project. And I'm not sure if I need the timestamps, but the question is not about it.
My plan right now is:
1. Player presses W in his client. Client translates player infront of his rotation and sends a packet to server that says "Player on coordinates X and Z is now going forward with rotation RRR":
PlayerController:

Code: Select all

void Update () {
      float translation = Input.GetAxis("Vertical");
      if (translation != 0) {
            if (translation > 0)
            {
                movestate = 1;
                this.transform.Translate(0, 0, 1 * Time.deltaTime * forwardSpeed);
            }
            else
            {
                movestate = 2;
                this.transform.Translate(0, 0, -1 * Time.deltaTime * backwardSpeed);
            }
            MovementDirty = true;
      }
        else if(movestate != 0)
        {
            movestate = 0;
            MovementDirty = true;
        }
       


GameManager:

Code: Select all

void FixedUpdate()
{
  if (sfs != null)
  {
    sfs.ProcessEvents();
         
    if (localPlayer != null && localPlayerController != null && localPlayerController.MovementDirty)
    {
                ISFSObject info = new SFSObject();
                info.PutInt("movestate", localPlayer.GetComponent<PlayerController>().movestate);
                info.PutDouble("x", (double)localPlayer.transform.position.x);
                info.PutDouble("z", (double)localPlayer.transform.position.z);
                info.PutDouble("rot", (double)localPlayer.transform.rotation.eulerAngles.y);
                sfs.Send(new ExtensionRequest("MovePlayer", info, sfs.LastJoinedRoom));
      localPlayerController.MovementDirty = false;
    }
  }
}

2. Server gets the packet and moves it to my UnityServerClient which is responsible for physics on the server-side.

Code: Select all

@Override
public void handleClientRequest(User sender, ISFSObject params)
{
      //HERE I SEND IT TO MY UNITYSERVERCLIENT
      ISFSObject info = new SFSObject();
      info.putUtfString("name", sender.getName());
      info.putInt("movestate", params.getInt("movestate"));
      info.putDouble("rot", params.getDouble("rot"));
      send("MovePlayer", info, ExtensionRequestHandler.extension.getApi().getUserByName("UNITYSERVERCLIENT"));      
}

After that, my plan was to move player in my UnityServerClient, get the result position, compare it to position that client has achieved and if everything is ok, set this position with

Code: Select all

      MMORoomDemoExtension.mmoApi.setUserPosition(sender, new Vec3D(params.getDouble("x").floatValue(), 1, params.getDouble("z").floatValue()), player);

The problem is that when I move my player in this UnityServerClient, my coordinates differ from client's coordinates. And as more I keep moving forward, more they differ.
It is absolutely the same code:

Code: Select all

//GET PACKET FROM SERVER
public void OnExtensionResponse(BaseEvent evt)
    {
        if (cmd == "MovePlayer")
        {
            ISFSObject pars = (SFSObject)evt.Params["params"];
            remotePlayers[pars.GetUtfString("name")].transform.rotation = Quaternion.Euler(0, (float)pars.GetDouble("rot"), 0);
            remotePlayers[pars.GetUtfString("name")].GetComponent<PlayerController>().movestate = pars.GetInt("movestate");
        }
    }
   
    //MOVE PLAYER
    if (movestate == 1)
         this.transform.Translate(0, 0, 1 * Time.deltaTime * forwardSpeed);
        else if (movestate == 2)
            this.transform.Translate(0, 0, -1 * Time.deltaTime * backwardSpeed);

I really hope someone will help me, cause I've wasted so much time trying to understand this synchronization things.

I've even counted how much does player's client send packets to server, how much packets server gets and then sends to UnityServerClient and how much does UnityServerClient get - absolutely same amount everywhere :? .
OhMyOhmit
Posts: 18
Joined: 24 Apr 2018, 12:25

Re: MMO Player Movement hacking

Postby OhMyOhmit » 27 Oct 2018, 18:54

Alright, I've solved this problem with different coordinates by comparing, but still remains a question with lagging people(bad connection). I believe it is not about smartfox anymore, but more about networking itself.

Return to “SFS2X C# API”

Who is online

Users browsing this forum: No registered users and 5 guests