Open Seadragon91 opened 3 years ago
I think this happens for any position related function.
I thought about having a check in the Vector3 constructor but this isn't user friendly in case someone is doing calculations. I think we have to manually add checks.
I'm moving my discussion here.
To summarise #5395, there are also crashes when:
These are both due to GetBlockTypeMeta
being called
The discussion in #5194 suggests we should do these checks before calling GetBlockTypeMeta
. The alternative would be adding a void block and an additional check in cChunkMap::GetBlockTypeMeta
and if IsValidHeight
is false, return false and set the void block.
I think it's best for the calling methods to check IsValidHeight
to keep things clean (and maybe performant too, as although GetBlockTypeMeta
isn't called much GetBlock
and GetBlockMeta
seem to be called very often).
Hi, @KingCol13, I'm interested in trying to fix this issue and the related issues (stuff happening below y=0). Are there still things to fix? It looks like #5194 fixes some of these issues, and was merged last year. Has there been any more recent progress on these types of issues I should know about?
Hi @hle0
an easy way would be to change GetBlockTypeMeta
in a way that it returns air if a non-valid position is passed. Maybe add a comment to the function to explain this behaviour
And there is no progress. Usually the development takes place publicly in the PR.
And GetBlock
, GetMeta
, GetBlockTypeMeta
will get replaced with one method in the block state PR
Hi @hle0
an easy way would be to change
GetBlockTypeMeta
in a way that it returns air if a non-valid position is passed. Maybe add a comment to the function to explain this behaviour
This would work for a lot but there might be some cases (like pistons https://github.com/cuberite/cuberite/issues/5395#issuecomment-1075616950) where we don't want void blocks to behave like air blocks. Also we were considering not putting checks in those functions for performance: https://github.com/cuberite/cuberite/pull/5194#issuecomment-877851697. I think the long term solution would be a separate void block but it's probably fine until blockstate gets merged if we make a note.
Another intermediate solution could be more manual bindings.
an easy way would be to change GetBlockTypeMeta in a way that it returns air if a non-valid position is passed. Maybe add a comment to the function to explain this behaviour
Another thing we could do is return false
if the height is invalid. cChunkMap::GetBlockTypeMeta
already returns false
if the chunk is invalid. Unfortunately, it looks like a lot of the code that indirectly calls cChunkMap::GetBlockTypeMeta
doesn't pay attention to this return value. I think it would make more sense (be more maintainable, and maybe more performant) if we fixed those invocations so that they actually do check the return value.
Here's an example of code that doesn't pay attention to the return value:
bool cBlockPistonHandler::CanPushBlock(
const Vector3i & a_BlockPos, cWorld & a_World, bool a_RequirePushable,
Vector3iSet & a_BlocksPushed, const Vector3i & a_PushDir
)
{
const static std::array<Vector3i, 6> pushingDirs =
{
{
Vector3i(-1, 0, 0), Vector3i(1, 0, 0),
Vector3i( 0, -1, 0), Vector3i(0, 1, 0),
Vector3i( 0, 0, -1), Vector3i(0, 0, 1)
}
};
BLOCKTYPE currBlock;
NIBBLETYPE currMeta;
a_World.GetBlockTypeMeta(a_BlockPos, currBlock, currMeta);
if (!cChunkDef::IsValidHeight(a_BlockPos.y))
{
return !a_RequirePushable;
}
...
Here's an example of code that doesn't pay attention to the return value:
Yea that's one I fixed in #5396, maybe it makes more sense to do it as you suggested.
Yea that's one I fixed in https://github.com/cuberite/cuberite/pull/5396, maybe it makes more sense to do it as you suggested.
I can work on adding checks to everything that needs it, and then I'll make it a PR. It looks like there are a lot of things; for example, if you try to light the void on fire (with a flint and steel on the side of a block at y=0), it'll crash because of GetBlock
, not GetBlockTypeMeta
, I think. So that whole family of functions should probably be fixed.
Server OS: Linux Cuberite Commit id: ce8d8388d630fa936500e6843496afe113ad8bc5
Actual behavior
Server crashes.
Steps to reproduce the behavior
Call this code from a plugin:
cRoot:Get():GetDefaultWorld():GrowTreeFromSapling(Vector3d(0, 1000, 0))
The chunk has to be loaded, join the server and teleport to
0 1000 0
.Negative y position also crashes the server (Moved over from #5191):
Stack trace