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

feat(gta-streaming-five): allow to edit scene graph pools #3136

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

DaniGP17
Copy link
Contributor

@DaniGP17 DaniGP17 commented Feb 6, 2025

Goal of this PR

Allow editing of most SceneGraphNodes pools, the increase of fwPortalSceneGraphNode was suggested in the forum.
Recently it was attempted to add the pool fwPortalSceneGraphNode to the gameconfig(#2695) but as prikolium said they are allocated from another precomputed heap and should be looked for in fwSceneGraph::InitPools.
This was already done by blattersturm here but 2 days later they reverted his change due to Potential cause for 'missing doors after a while'. What they did was hook the PortalSceneGraphPool constructor to multiply the size and allocate the memory elsewhere.
I don't know if this is the approach that you want to take in order to increase the sizes of these pools.

How is this PR achieving the goal

First of all, I have defined a list of pools so that their sizes can be easily edited.

v0 = Allocate(214473LL, 16LL);
qword_7FF6B50437F8 = v0;
AssignStorage(v0, 210864LL);
v1 = (unsigned int)dword_7FF6B5043808 + v0;
v2 = v1 + 800;
v3 = v1;
v4 = v1 + 802;
v5 = v1 + 1802;
v6 = v1 + 1803;
v7 = v1 + 2803;
v8 = v7 + 406;

As you can see in the code, by default the game allocates 214473 in memory which is the sum of the pool storage sizes and the pool flag sizes and in AssignStorageMemory the pool flag sizes are sent. Both values ​​are calculated with the data from the pools table and set in both arguments.
The memory displacement offsets are modified for each pool (v2, v4, v5, v6, etc.)
Later the value of all poolSizes is changed in each pool constructor.
And finally, other memory offsets of the AssignStorage function are changed.

This PR applies to the following area(s)

FiveM

Successfully tested on

Game builds: 1604, 2060, 2189, 3095, 3258, 3407(My tests have been to join the server and have a test hook to see the arguments that are sent to the pool constructor and they seemed correct.)

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.

@github-actions github-actions bot added the invalid Requires changes before it's considered valid and can be (re)triaged label Feb 6, 2025
@Nobelium-cfx Nobelium-cfx self-requested a review February 9, 2025 20:23
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 the effort. This looks like a great start! I have some comments, let me know WDYT.

  1. It seems that there are more places where those sizes are used and therefore probably should be updated as well. E.g. in this function: 4C 8B C1 0F B6 49 ? 85 C9. But there is seems to be plenty. I didn't check it too deep, so idk if its feasible to track and update them all.
  2. This is less of a priority that the 1st point and can be done later. I think it would make sense to move this code into PoolManagement.cpp and conditionally increase as we do with other pools based on fx::PoolSizeManager::GetIncreaseRequest().
  3. Left some style nits related to this code.

@DaniGP17
Copy link
Contributor Author

DaniGP17 commented Feb 9, 2025

Thank you very much for the review, about the way I'm changing all the values making many hook::put is it okay? It seems to me that I am using it a lot and I don't know if there would be another better way.

@Nobelium-cfx
Copy link
Contributor

Thank you very much for the review, about the way I'm changing all the values making many hook::put is it okay? It seems to me that I am using it a lot and I don't know if there would be another better way.

I think hook::put ok. Idk any better way to do it and to me it look good as it is.

Change the initPoolsLocation at the top of the function.
Index the pools by eSceneGraphPool instead raw index
Change memory offsets in other functions(computeSceneNode, assignScratch, clearVisData)
@DaniGP17
Copy link
Contributor Author

  1. It seems that there are more places where those sizes are used and therefore probably should be updated as well. E.g. in this function: 4C 8B C1 0F B6 49 ? 85 C9. But there is seems to be plenty. I didn't check it too deep, so idk if its feasible to track and update them all.

I've added new locations to change the pool sizes, but I'm stil looking for new locations cause as you said there're a lot of places.

  1. This is less of a priority that the 1st point and can be done later. I think it would make sense to move this code into PoolManagement.cpp and conditionally increase as we do with other pools based on fx::PoolSizeManager::GetIncreaseRequest().

I'll check that after finding all the locations.

  1. Left some style nits related to this code.

Done

Copy link
Contributor

@iridium-cfx iridium-cfx left a comment

Choose a reason for hiding this comment

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

We have also investigated this internally.
There is at least one other place that needs patching - the function at 83 B9 ? ? ? ? ? 4C 8B CA 4C 8B C1, which also then indexes into a fixed-size bitset based on the node index.

@DaniGP17
Copy link
Contributor Author

Sorry for the requested review, miss click.

We have also investigated this internally. There is at least one other place that needs patching - the function at 83 B9 ? ? ? ? ? 4C 8B CA 4C 8B C1, which also then indexes into a fixed-size bitset based on the node index.

Ok, I'll check that thanks.

Changed the first pattern to the begin of the function.
Added the GetGbufScreenQuadPair function patch
Changed the value of the FIRST_ROOM_SCENE_NODE_INDEX(FW_EXTERIOR_SCENE_GRAPH_NODE + FW_STREAMED_SCENE_GRAPH_NODE + FW_INTERIOR_SCENE_GRAPH_NODE - 1)
As Iridium said the at `83 B9 ? ? ? ? ? 4C 8B CA 4C 8B C1` function needed to be patched because the size of the skyPortalFlags was the size of the FW_PORTAL_SCENE_GRAPH_NODE pool. Since we doubled it(800) that size was not updated.
I created a function that returns the address of the new skyPortalFlag with its correct size based on the address of the class self, so if there is another instance of the same class it will have a different skyPortalFlags.
I patched the AddSkyPortal function to use the new SkyPortalFlag array and the same with the SetIsSkyPortalVisInterior.
Fixed the offset of the pool size constructor of FW_FIXED_ENTITY_CONTAINER.
Changed r8 register to match the original(r8d)
Changed the value that take r8d to `(pools[eSceneGraphPool::FW_PORTAL_SCENE_GRAPH_NODE].poolSize + 7) / 8`
Add original missing code `mov(dword_ptr[rcx+0x378], r9d)`
Copy link
Contributor

@iridium-cfx iridium-cfx left a comment

Choose a reason for hiding this comment

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

I've added a couple others to review this as well.
It's quite a large change, so I'm not sure if it would be better to put it on a few branch for a while.

xor(edx, edx);
mov(dword_ptr[rcx+0x378], r9d);
mov(r8d, static_cast<size_t>((pools[eSceneGraphPool::FW_PORTAL_SCENE_GRAPH_NODE].poolSize + 7) / 8));
add(rcx, 0x37C);
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this instruction still needs to be removed.

@DaniGP17
Copy link
Contributor Author

It's quite a large change, so I'm not sure if it would be better to put it on a few branch for a while.

Honestly, at first I had in mind only increasing the size of a pool (#3121), I saw that I could increase the others but then new locations to patch began to appear and now it is a big change, yes, I don't know if you have any suggestions on this subject

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