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 1 commit 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.

int poolSize;
};

std::vector<SceneGraphPoolData> pools = {
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: WDYT about removing poolType from SceneGraphPoolData and defining pools not as vector but as unordered_map<eSceneGraphPool, SceneGraphPoolData>? Then we could index it with enum values without having to use static_cast or raw integers (i.e. pools[eSceneGraphPool::FW_ENTITY_CONTAINER].poolSize instead of current pools[0].poolSize).

static HookFunction hookFunction([]()
{
assert(pools[1].poolSize <= 64 && "The pool size of FW_FIXED_ENTITY_CONTAINER can't be greater than 64");
auto initPoolsLocation = hook::get_pattern("48 8D B3 ? ? ? ? 48 8B FB");
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: its probably better to use patter that points to the beginning of the function even tho its a bit longer: 48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 57 41 54 41 55 41 56 41 57 48 83 EC ? BA ? ? ? ? B9. This way we won't need to use negative offsets (like line 51) and I think it's a bit more maintainable (e.g. if I want to check if a function was modified - I will often try to search pattern that points to the beginning of it).

@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.

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.

2 participants