summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattes D <github@xoft.cz>2015-04-29 15:14:22 +0200
committerMattes D <github@xoft.cz>2015-04-29 15:14:22 +0200
commitfc95501f68b28f2fc595eb574546500c2713ef96 (patch)
tree4201e7e773b152aea800f1024bc0ea4bca28eeda
parentFix explosions trying to write to unread blockarea (diff)
downloadcuberite-fc95501f68b28f2fc595eb574546500c2713ef96.tar
cuberite-fc95501f68b28f2fc595eb574546500c2713ef96.tar.gz
cuberite-fc95501f68b28f2fc595eb574546500c2713ef96.tar.bz2
cuberite-fc95501f68b28f2fc595eb574546500c2713ef96.tar.lz
cuberite-fc95501f68b28f2fc595eb574546500c2713ef96.tar.xz
cuberite-fc95501f68b28f2fc595eb574546500c2713ef96.tar.zst
cuberite-fc95501f68b28f2fc595eb574546500c2713ef96.zip
-rw-r--r--src/Bindings/LuaState.cpp32
-rw-r--r--src/Bindings/LuaState.h4
-rw-r--r--src/Bindings/ManualBindings.cpp39
-rw-r--r--src/BlockArea.cpp67
-rw-r--r--src/BlockArea.h5
5 files changed, 146 insertions, 1 deletions
diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp
index 38e008b2a..ed31e678f 100644
--- a/src/Bindings/LuaState.cpp
+++ b/src/Bindings/LuaState.cpp
@@ -937,6 +937,18 @@ void cLuaState::GetStackValue(int a_StackPos, AString & a_Value)
+void cLuaState::GetStackValue(int a_StackPos, BLOCKTYPE & a_ReturnedVal)
+{
+ if (lua_isnumber(m_LuaState, a_StackPos))
+ {
+ a_ReturnedVal = static_cast<BLOCKTYPE>(tolua_tonumber(m_LuaState, a_StackPos, a_ReturnedVal));
+ }
+}
+
+
+
+
+
void cLuaState::GetStackValue(int a_StackPos, bool & a_ReturnedVal)
{
a_ReturnedVal = (tolua_toboolean(m_LuaState, a_StackPos, a_ReturnedVal ? 1 : 0) > 0);
@@ -995,6 +1007,24 @@ void cLuaState::GetStackValue(int a_StackPos, int & a_ReturnedVal)
+void cLuaState::GetStackValue(int a_StackPos, pBlockArea & a_ReturnedVal)
+{
+ if (lua_isnil(m_LuaState, a_StackPos))
+ {
+ a_ReturnedVal = nullptr;
+ return;
+ }
+ tolua_Error err;
+ if (tolua_isusertype(m_LuaState, a_StackPos, "cBlockArea", false, &err))
+ {
+ a_ReturnedVal = *(reinterpret_cast<cBlockArea **>(lua_touserdata(m_LuaState, a_StackPos)));
+ }
+}
+
+
+
+
+
void cLuaState::GetStackValue(int a_StackPos, pBoundingBox & a_ReturnedVal)
{
if (lua_isnil(m_LuaState, a_StackPos))
@@ -1005,7 +1035,7 @@ void cLuaState::GetStackValue(int a_StackPos, pBoundingBox & a_ReturnedVal)
tolua_Error err;
if (tolua_isusertype(m_LuaState, a_StackPos, "cBoundingBox", false, &err))
{
- a_ReturnedVal = *((cBoundingBox **)lua_touserdata(m_LuaState, a_StackPos));
+ a_ReturnedVal = *(reinterpret_cast<cBoundingBox **>(lua_touserdata(m_LuaState, a_StackPos)));
}
}
diff --git a/src/Bindings/LuaState.h b/src/Bindings/LuaState.h
index a6e121eb7..6bedbf5ec 100644
--- a/src/Bindings/LuaState.h
+++ b/src/Bindings/LuaState.h
@@ -37,6 +37,7 @@ extern "C"
+class cBlockArea;
class cBlockEntity;
class cBoundingBox;
class cChunkDesc;
@@ -68,6 +69,7 @@ struct HTTPRequest;
struct HTTPTemplateRequest;
struct TakeDamageInfo;
+typedef cBlockArea * pBlockArea;
typedef cBoundingBox * pBoundingBox;
typedef cMapManager * pMapManager;
typedef cPluginManager * pPluginManager;
@@ -244,11 +246,13 @@ public:
// GetStackValue() retrieves the value at a_StackPos, if it is a valid type. If not, a_Value is unchanged.
// Enum values are clamped to their allowed range.
void GetStackValue(int a_StackPos, AString & a_Value);
+ void GetStackValue(int a_StackPos, BLOCKTYPE & a_Value);
void GetStackValue(int a_StackPos, bool & a_Value);
void GetStackValue(int a_StackPos, cRef & a_Ref);
void GetStackValue(int a_StackPos, double & a_Value);
void GetStackValue(int a_StackPos, eWeather & a_Value);
void GetStackValue(int a_StackPos, int & a_Value);
+ void GetStackValue(int a_StackPos, pBlockArea & a_Value);
void GetStackValue(int a_StackPos, pBoundingBox & a_Value);
void GetStackValue(int a_StackPos, pMapManager & a_Value);
void GetStackValue(int a_StackPos, pPluginManager & a_Value);
diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp
index c4b12aa84..8e909827c 100644
--- a/src/Bindings/ManualBindings.cpp
+++ b/src/Bindings/ManualBindings.cpp
@@ -3187,6 +3187,44 @@ static int tolua_cBlockArea_GetOrigin(lua_State * tolua_S)
+static int tolua_cBlockArea_GetNonAirCropRelCoords(lua_State * tolua_S)
+{
+ // function cBlockArea::GetNonAirCropRelCoords()
+ // Exported manually because tolua would generate extra input params for the outputs
+
+ cLuaState L(tolua_S);
+ if (!L.CheckParamUserType(1, "cBlockArea"))
+ {
+ return 0;
+ }
+
+ cBlockArea * self = nullptr;
+ BLOCKTYPE IgnoreBlockType = E_BLOCK_AIR;
+ L.GetStackValues(1, self, IgnoreBlockType);
+ if (self == nullptr)
+ {
+ tolua_error(tolua_S, "invalid 'self' in function 'cBlockArea:GetNonAirCropRelCoords'", nullptr);
+ return 0;
+ }
+
+ // Calculate the crop coords:
+ int MinRelX, MinRelY, MinRelZ, MaxRelX, MaxRelY, MaxRelZ;
+ self->GetNonAirCropRelCoords(MinRelX, MinRelY, MinRelZ, MaxRelX, MaxRelY, MaxRelZ, IgnoreBlockType);
+
+ // Push the six crop coords:
+ L.Push(MinRelX);
+ L.Push(MinRelY);
+ L.Push(MinRelZ);
+ L.Push(MaxRelX);
+ L.Push(MaxRelY);
+ L.Push(MaxRelZ);
+ return 6;
+}
+
+
+
+
+
static int tolua_cBlockArea_GetRelBlockTypeMeta(lua_State * tolua_S)
{
// function cBlockArea::GetRelBlockTypeMeta()
@@ -3687,6 +3725,7 @@ void ManualBindings::Bind(lua_State * tolua_S)
tolua_function(tolua_S, "GetBlockTypeMeta", tolua_cBlockArea_GetBlockTypeMeta);
tolua_function(tolua_S, "GetCoordRange", tolua_cBlockArea_GetCoordRange);
tolua_function(tolua_S, "GetOrigin", tolua_cBlockArea_GetOrigin);
+ tolua_function(tolua_S, "GetNonAirCropRelCoords", tolua_cBlockArea_GetNonAirCropRelCoords);
tolua_function(tolua_S, "GetRelBlockTypeMeta", tolua_cBlockArea_GetRelBlockTypeMeta);
tolua_function(tolua_S, "GetSize", tolua_cBlockArea_GetSize);
tolua_function(tolua_S, "LoadFromSchematicFile", tolua_cBlockArea_LoadFromSchematicFile);
diff --git a/src/BlockArea.cpp b/src/BlockArea.cpp
index 4c3da0535..7526e1c32 100644
--- a/src/BlockArea.cpp
+++ b/src/BlockArea.cpp
@@ -1614,6 +1614,73 @@ void cBlockArea::GetRelBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTY
+void cBlockArea::GetNonAirCropRelCoords(int & a_MinRelX, int & a_MinRelY, int & a_MinRelZ, int & a_MaxRelX, int & a_MaxRelY, int & a_MaxRelZ, BLOCKTYPE a_IgnoreBlockType)
+{
+ // Check if blocktypes are valid:
+ if (m_BlockTypes == nullptr)
+ {
+ LOGWARNING("%s: BlockTypes have not been read!", __FUNCTION__);
+ a_MinRelX = 1;
+ a_MaxRelX = 0;
+ return;
+ }
+
+ // Walk all the blocks and find the min and max coords for the non-ignored ones:
+ int MaxX = 0, MinX = m_Size.x - 1;
+ int MaxY = 0, MinY = m_Size.y - 1;
+ int MaxZ = 0, MinZ = m_Size.z - 1;
+ for (int y = 0; y < m_Size.y; y++)
+ {
+ for (int z = 0; z < m_Size.z; z++)
+ {
+ for (int x = 0; x < m_Size.x; x++)
+ {
+ if (m_BlockTypes[MakeIndex(x, y, z)] == a_IgnoreBlockType)
+ {
+ continue;
+ }
+ // The block is not ignored, update any coords that need updating:
+ if (x < MinX)
+ {
+ MinX = x;
+ }
+ if (x > MaxX)
+ {
+ MaxX = x;
+ }
+ if (y < MinY)
+ {
+ MinY = y;
+ }
+ if (y > MaxY)
+ {
+ MaxY = y;
+ }
+ if (z < MinZ)
+ {
+ MinZ = z;
+ }
+ if (z > MaxZ)
+ {
+ MaxZ = z;
+ }
+ } // for x
+ } // for z
+ } // for y
+
+ // Assign to the output:
+ a_MinRelX = MinX;
+ a_MinRelY = MinY;
+ a_MinRelZ = MinZ;
+ a_MaxRelX = MaxX;
+ a_MaxRelY = MaxY;
+ a_MaxRelZ = MaxZ;
+}
+
+
+
+
+
int cBlockArea::GetDataTypes(void) const
{
int res = 0;
diff --git a/src/BlockArea.h b/src/BlockArea.h
index 348e960dd..6b8b30443 100644
--- a/src/BlockArea.h
+++ b/src/BlockArea.h
@@ -288,6 +288,11 @@ public:
bool HasBlockSkyLights(void) const { return (m_BlockSkyLight != nullptr); }
// tolua_end
+
+ /** Returns the minimum and maximum coords in each direction for the first non-ignored block in each direction.
+ If there are no non-ignored blocks within the area, or blocktypes are not present, the returned values are reverse-ranges (MinX <- m_RangeX, MaxX <- 0 etc.)
+ Exported to Lua in ManualBindings.cpp. */
+ void GetNonAirCropRelCoords(int & a_MinRelX, int & a_MinRelY, int & a_MinRelZ, int & a_MaxRelX, int & a_MaxRelY, int & a_MaxRelZ, BLOCKTYPE a_IgnoreBlockType = E_BLOCK_AIR);
// Clients can use these for faster access to all blocktypes. Be careful though!
/** Returns the internal pointer to the block types */