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

fix(net/five): correct train track node on ownership change #2911

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Ehbw
Copy link
Contributor

@Ehbw Ehbw commented Nov 5, 2024

Goal of this PR

Fixes scenarios where a train becomes owned by the server (orphan natives) and upon a player re-entering the trains scope and becoming owner of the train, The train resets to the node 0 of the track it is currently on

How is this PR achieving the goal

By forcing the train to find its current track node based on the trains current position, only upon ownership change to a player from a server and if the new client has no knowledge of the trains current track node.

This PR applies to the following area(s)

FiveM

Successfully tested on

Game builds: 1604, 2372, 2545, 2802, 3258

Platforms: Windows

Checklist

  • Code compiles and has been tested successfully.
  • Code explains itself well and/or is documented.
  • My commit message explains what the changes do and what they are for.
  • No extra compilation warnings are added by these changes.

Fixes issues

@github-actions github-actions bot added the invalid Requires changes before it's considered valid and can be (re)triaged label Nov 5, 2024
@Legacy-TacticalGamingInteractive

Excellent

Copy link
Contributor

@Nobelium-cfx Nobelium-cfx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your contribution! It looks like a really valuable change. Left some minor comments.

But also, do you have a good way to reproduce/test it? I tried to play with it locally:

  • Put one player in a carriage of a train. Make sure that this player is the owner.
  • Get second player on the train as well.
  • See netObjectMgrBase__ChangeOwner being called, but the code never reaches the CTrain__SetTrainCoord(train, -1, -1); part. Seems like (CTrain__IsCarriageEngine(train) && *(int*)((char*)train + TrainTrackNodeIndexOffset) == 0) check is always false in my case.
  • Disconnect the first player.
  • After some time train disappears even tho second player in in a carriage.

Do I misunderstand the use case or this? Am I doing something wrong?

code/components/gta-net-five/src/CloneObjectManager.cpp Outdated Show resolved Hide resolved
code/components/gta-net-five/src/CloneObjectManager.cpp Outdated Show resolved Hide resolved
// Make sure that this is a train and that we are now the new owner of it
if (object->objectType == (uint16_t)NetObjEntityType::Train && targetPlayer->physicalPlayerIndex() == rage::GetLocalPlayer()->physicalPlayerIndex())
{
// Ensure that the vehicle isn't a nullptr
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: This comment is redundant. It's clear whats going on without it.

code/components/gta-net-five/src/CloneObjectManager.cpp Outdated Show resolved Hide resolved
code/components/gta-net-five/src/CloneObjectManager.cpp Outdated Show resolved Hide resolved
code/components/gta-net-five/src/CloneObjectManager.cpp Outdated Show resolved Hide resolved
@Ehbw
Copy link
Contributor Author

Ehbw commented Nov 8, 2024

Thank you for your contribution! It looks like a really valuable change. Left some minor comments.

But also, do you have a good way to reproduce/test it? I tried to play with it locally:

  • Put one player in a carriage of a train. Make sure that this player is the owner.
  • Get second player on the train as well.
  • See netObjectMgrBase__ChangeOwner being called, but the code never reaches the CTrain__SetTrainCoord(train, -1, -1); part. Seems like (CTrain__IsCarriageEngine(train) && *(int*)((char*)train + TrainTrackNodeIndexOffset) == 0) check is always false in my case.
  • Disconnect the first player.
  • After some time train disappears even tho second player in in a carriage.

Do I misunderstand the use case or this? Am I doing something wrong?

This issue isn't related to ownership changing between players as in most (if not all cases) the client becoming owner should already have knowledge of the track node the train is located on. However, in cases where the server was the previous owner (in cases where no player is in the trains scope to have ownership over the train) the client becoming owner will have no knowledge of the trains current track node. Causing the train to reset to node 0 regardless of where it actually is.
The issue resolved with this PR can be replicated with 1 player.

  • Create a train doesn't matter the track location or train config. Applying the server-native SET_ENTITY_ORPHAN_MODE on the engine and all of it's carriages (this is simplified in Minor fixes for trains, use IsEntityValid for other calls checking if the entity exists #2902)
  • Once the train begins moving, move the player far enough away from the train to where the player leaves the trains scope (trains have a much larger scope then normal entities, the entity culling natives can be used here to make the scope smaller and make it easier to repro)
  • When re-entering the trains scope. Without this patch the train will begin calculating its next position from node 0 of the track it is on (usually 0 for metro lines, 3 for main train tracks) causing the train to teleport to node 0. With this patch, the train will continuing moving along based on the current track node it is located at.

I've also attached the repro resource i used to test this. (find a train track, do /train on the client to create a train. Leave the scope and return)
trainnode-repro.zip

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
invalid Requires changes before it's considered valid and can be (re)triaged
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants