How Long to Wait Mta Use Again
GTA Online. Infamous for its dull loading times. Having picked up the game over again to cease some of the newer heists I was shocked (/s) to notice that it withal loads just as slow as the day it was released seven years ago.
It was time. Time to get to the lesser of this.
Recon
Commencement I wanted to check if someone had already solved this problem. Most of the results I found pointed towards anecdata about how the game is so sophisticated that it needs to load so long, stories on how the p2p network architecture is rubbish (non maxim that it isn't), some elaborate means of loading into story mode and a solo session after that and a couple of mods that immune skipping the startup R* logo video. Some more reading told me we could salvage a whopping 10-30 seconds with these combined!
Meanwhile on my PC…
Criterion
i | Story style load time: ~1m 10s |
I know my setup is dated but what on earth could accept 6x longer to load into online way? I couldn't measure whatsoever difference using the story-to-online loading technique as others accept found before me. Even if it did work the results would be downwards in the racket.
I Am (Non) Alone
If this poll is to exist trusted then the issue is widespread enough to mildly annoy more than lxxx% of the role player base. Information technology's been 7 years R*!
Looking effectually a bit to find who are the lucky ~20% that get sub 3 infinitesimal load times I came across a few benchmarks with loftier-terminate gaming PCs and an online way load fourth dimension of about 2 minutes. I would kill hack for a ii infinitesimal load time! Information technology does seem to be hardware-dependent but something doesn't add up here…
How come their story mode notwithstanding takes near a minute to load? (The Thou.two one didn't count the startup logos btw.) Likewise, loading story to online takes them only a minute more while I'1000 getting most 5 more. I know that their hardware specs are a lot meliorate but surely non 5x better.
Highly accurate measurements
Armed with such powerful tools as the Task Manager I began to investigate what resources could exist the clogging.
Subsequently taking a minute to load the mutual resources used for both story and online modes (which is almost on par with high-end PCs) GTA decides to max out a single core on my machine for 4 minutes and do nothing else.
Deejay usage? None! Network usage? There's a flake, simply it drops basically to zippo after a few seconds (apart from loading the rotating info banners). GPU usage? Naught. Memory usage? Completely flat…
What, is it mining crypto or something? I smell code. Actually bad code.
Single thread-bound
While my old AMD CPU has 8 cores and information technology does pack a punch, it was made in the olden days. Back when AMD's single-thread performance was fashion backside Intel's. This might not explain all of the load time differences but it should explain near of information technology.
What's odd is that it's using upwardly just the CPU. I was expecting vast amounts of disk reads loading upwards resources or loads of network requests trying to negotiate a session in the p2p network. But this? This is probably a bug.
Profiling
Profilers are a great way of finding CPU bottlenecks. There's only one problem - most of them rely on instrumenting the source lawmaking to go a perfect picture of what's happening in the process. And I don't have the source code. Nor exercise I need microsecond-perfect readings - I have 4 minutes' worth of a bottleneck.
Enter stack sampling: for closed source applications at that place's only one option. Dump the running procedure' stack and current didactics pointer's location to build a calling tree in set up intervals. Then add them up to go statistics on what'due south going on. In that location's only one profiler that I know of (might be ignorant here) that can do this on Windows. And information technology hasn't been updated in over 10 years. It's Luke Stackwalker! Someone, please give this project some love :)
Normally Luke would group the aforementioned functions together but since I don't have debugging symbols I had to eyeball nearby addresses to guess if it's the same identify. And what do we see? Non one bottleneck but two of them!
Down the rabbit hole
Having borrowed my friend's completely legitimate re-create of the industry-standard disassembler (no, I really tin't afford the affair… gonna acquire to ghidra one of these days) I went to take GTA apart.
That doesn't look correct at all. Nearly high-contour games come up with built-in protection confronting reverse engineering to keep away pirates, cheaters, and modders. Not that it has e'er stopped them.
In that location seems to be some sort of an obfuscation/encryption at play hither that has replaced almost instructions with gibberish. Not to worry, we simply demand to dump the game's retention while it's executing the part we desire to await at. The instructions have to be de-obfuscated before running one fashion or another. I had Procedure Dump lying around, then I used that, but there are plenty of other tools available to practise this sort of thing.
Trouble one: It's… strlen?!
Disassembling the now-less-obfuscated dump reveals that i of the addresses has a label pulled out of somewhere! It's strlen? Going down the telephone call stack the next one is labeled vscan_fn and after that the labels end, tho I'g fairly confident it's sscanf.
It's parsing something. Parsing what? Untangling the disassembly would take forever and then I decided to dump some samples from the running process using x64dbg. Some debug-stepping later it turns out it's… JSON! They're parsing JSON. A whopping 10 megabytes worth of JSON with some 63k item entries.
one | ..., |
What is information technology? It appears to be data for a "net shop catalog" according to some references. I assume it contains a list of all the possible items and upgrades you can buy in GTA Online.
Clearing up some confusion: I beleive these are in-game money purchasable items, not direct linked with microtransactions.
Simply 10 megs? That'southward nothing! And using sscanf may not be optimal only surely it'southward not that bad? Well…
Yes, that'south gonna accept a while… To exist off-white I had no thought most sscanf implementations chosen strlen so I can't arraign the developer who wrote this. I would assume it only scanned byte by byte and could stop on a Nada.
Problem ii: Let'due south use a Hash- … Array?
Turns out the 2d offender is called correct side by side to the first i. They're both fifty-fifty called in the same if statement as seen in this ugly decompilation:
All labels are mine, no idea what the functions/parameters are actually called.
The 2d problem? Correct after parsing an particular, information technology's stored in an array (or an inlined C++ list? not certain). Each entry looks something like this:
i | struct { |
But before it's stored? It checks the entire array, ane past one, comparing the hash of the item to see if it's in the list or non. With ~63k entries that'southward (northward^two+n)/2 = (63000^ii+63000)/2 = 1984531500 checks if my math is right. Most of them useless. You lot have unique hashes why not use a hash map.
I named information technology hashmap while reversing but it's clearly not_a_hashmap. And it gets even better. The hash-array-list-thing is empty earlier loading the JSON. And all of the items in the JSON are unique! They don't even need to check if information technology's in the list or not! They fifty-fifty have a function to directly insert the items! Just use that! Srsly, WAT!?
PoC
Now that's squeamish and all, but no 1 is going to have me seriously unless I test this so I can write a clickbait title for the post.
The plan? Write a .dll, inject it in GTA, hook some functions, ???, profit.
The JSON problem is hairy, I can't realistically supercede their parser. Replacing sscanf with one that doesn't depend on strlen would be more realistic. But at that place's an even easier fashion.
- hook strlen
- wait for a long cord
- "enshroud" the outset and length of it
- if information technology's called again within the string's range, render buried value
Something like:
i | size_t strlen_cacher (char* str) |
And as for the hash-array problem, it's more than straightforward - just skip the duplicate checks entirely and insert the items directly since we know the values are unique.
one | char __fastcall netcat_insert_dedupe_hooked (uint64_t itemize, uint64_t* cardinal, uint64_t* item) |
Total source of PoC hither.
Results
Well, did it work then?
1 | Original online mode load time: ~6m apartment |
Hell yes, it did! :))
Most probable, this won't solve everyone'southward load times - there might be other bottlenecks on different systems, but it's such a gaping hole that I accept no thought how R* has missed it all these years.
tl;dr
- There'due south a single thread CPU clogging while starting up GTA Online
- It turns out GTA struggles to parse a 10MB JSON file
- The JSON parser itself is poorly built / naive and
- After parsing there's a irksome item de-duplication routine
R* please set
If this somehow reaches Rockstar: the problems shouldn't take more than a mean solar day for a single dev to solve. Delight exercise something most information technology :<
Yous could either switch to a hashmap for the de-duplication or completely skip it on startup every bit a faster set. For the JSON parser - just swap out the library for a more performant one. I don't think there'due south any easier way out.
ty <3
Modest update
I was expecting to get some attention but nowhere almost this much! After reaching the pinnacle of HN this postal service has spread like wildfire! Thank you for the overwhelming response :)
I'll practise more writing if something interesting comes forth, but don't await annihilation of this calibration soon - there was a lot of luck involved.
A few people suggested spamming this mail to Rockstar's support - please don't! I'm sure they've seen this past now. Continuing would just bog downwardly support tickets for everyone else. Social media is off-white game in my book tho.
Several HN comments suggested I add a donate button, as they would similar to buy me a beer (give thanks y'all!) then I'm placing a link in the footer.
Thank yous for reading and all the support :)
Update 2021-03-15
- Got confirmation from R* that this is getting a set before long
- Just got awarded $10k through their H1 in-game bounty as an exception :)) (unremarkably merely for security issues)
- Trying to figure out what's a W8 and how to fill it (lol)
- I did try asking for more technical details but they couldn't say anything
- Will do another benchmark on my same quondam setup as before long as the update is out, I'm sure their engineers won't disappoint :)
Update 2021-03-16
R* released the update! Downloaded information technology and got my start run results - aforementioned hardware, same measurement - from R* logo to fully online.
Fully stock-still! t0st approves!
Thanks once more for all the coffees, and thanks to R* for taking the fourth dimension to look into this and the generous bounty!
hamiltonainal1983.blogspot.com
Source: https://nee.lv/2021/02/28/How-I-cut-GTA-Online-loading-times-by-70/
0 Response to "How Long to Wait Mta Use Again"
Postar um comentário