this provides some performance improvement (although it's difficult to measure because of cache).
this does mean that we read some garbage data during chunk reads, but it's less costly than hitting the disk twice.
I was unaware that fseek actually makes a syscall which is rather costly, which became painfully obvious during large world conversions on PM4.
On average this problem appeared to be adding about 5ms to the load time for a newly loaded region, which is insanely expensive.
In the old days, we used to try to correct this problem by adjusting the region header to match the
length found at the start of the chunk payload. However, this has a very good chance to cause corruption
of other chunks, since we can't do any fast overlap checks (an upsize might cause the chunk's alloocated
area to overlap into another one, causing corruption when either chunk's space gets written to).
This corruption risk has become more problematic since the
introduction of region garbage sector reuse, since a broken location
header could cause chunks to trash each others' saved data.
In addition, if there is a length mismatch, there's a good chance that the oversized chunk itself will
already be corrupted, so we'd just fail trying to decompress it later on.
So, instead of trying to fix this automatically, we bail and hope this doesn't occur often enough for
users to get upset, and allow external offline tools to attempt to repair the mess instead.
this caused some performance issues and silent bugs with the generator, notably that the generator would always think all chunks had been changed, causing them to be re-set back into the world 9 times.
previously a file with a 4-letter name ending in 'mca' in the region folder of a PMAnvil world would cause the world format to be unrecognized. This happens because strrpos() returns false when the substring isn't found, which gets coerced to 0 when used in addition.
PHPStan has no idea what is going on in this code because unpack() returns mixed[].
Possibly it might be a good idea to implement a dynamic return type extension for this.
non-class constants aren't stored during preloading phase and for some reason they aren't pre-resolved in opcode arrays. However, they are resolved by value when referenced by class constants, and class constants stick, so we can use those instead.
this bug became painfully obvious when testing bamboo. Detonating TNT near tall bamboo canes would result in bamboo canes not deleting themselves in some circumstances, because the non-destroyed parts of the cane would be updated before their supporting block was deleted, and subsequently would not be re-updated afterwards.
I think this bug should also reproduce with cacti, but I have not tested.
this is the biggest sector start that the location table can represent, due to the binary format. Larger values than this will overflow and cause corruption.
This provides an effective limit of 64 GB on region files.
we already have a region growth problem due to the lack of garbage collection, but this bug was making it worse. If the region already contained 1024 allocated chunks, 4MB of file space would get wasted before the next chunk would be appended to the file.