From cdd8e425872b94878babf7823cd12381d2db1a5c Mon Sep 17 00:00:00 2001 From: peterbell10 Date: Fri, 27 Jul 2018 00:12:41 +0100 Subject: cWorld: Manually bind deprecated broadcast functions (#4265) Ref: https://github.com/cuberite/cuberite/pull/4264#discussion_r204769193 --- src/Bindings/ManualBindings_World.cpp | 319 ++++++++++++++++++++++++++++------ 1 file changed, 266 insertions(+), 53 deletions(-) (limited to 'src/Bindings') diff --git a/src/Bindings/ManualBindings_World.cpp b/src/Bindings/ManualBindings_World.cpp index f5b846dde..9b51ab926 100644 --- a/src/Bindings/ManualBindings_World.cpp +++ b/src/Bindings/ManualBindings_World.cpp @@ -13,48 +13,258 @@ #include "LuaChunkStay.h" +/** Check that a Lua parameter is either a vector or 3 numbers in sequence +\param L The Lua state +\param a_VectorName name of the vector class e.g. "Vector3" +\param a_Index Index to the start of the vector in the parameter list +\param[out] a_NextIndex Index of the next parameter after the vector +\retval true if the parameter is a vector or 3 numbers */ +static bool CheckParamVectorOr3Numbers(cLuaState & L, const char * a_VectorName, int a_Index, int & a_NextIndex) +{ + if (L.IsParamUserType(a_Index, a_VectorName)) + { + a_NextIndex = a_Index + 1; + return L.CheckParamUserType(a_Index, a_VectorName); + } + + a_NextIndex = a_Index + 3; + return L.CheckParamNumber(a_Index, a_Index + 2); +} + + + + + +/** Get a vector from the stack, which may be represented in lua as either a `Vector3` or 3 numbers */ +template +static bool GetStackVectorOr3Numbers(cLuaState & L, int a_Index, Vector3 & a_Return) +{ + Vector3 * UserType; + if (L.GetStackValue(a_Index, UserType)) + { + a_Return = *UserType; + return true; + } + return L.GetStackValues(a_Index, a_Return.x, a_Return.y, a_Return.z); +} + + + + + +static int tolua_cWorld_BroadcastBlockAction(lua_State * tolua_S) +{ + /* Function signature: + void BroadcastBlockAction(number a_BlockX, number a_BlockY, number a_BlockZ, number a_number1, number a_number2, number a_BlockType, cClientHandle a_Exclude) + --or-- + void BroadcastBlockAction(Vector3 a_BlockPos, number a_Byte1, number a_Byte2, number a_BlockType, cClientHandle a_Exclude) + */ + + cLuaState L(tolua_S); + int Byte1Index; + if ( + !L.CheckParamSelf("cWorld") || + !CheckParamVectorOr3Numbers(L, "Vector3", 2, Byte1Index) || + !L.CheckParamNumber(Byte1Index, Byte1Index + 2) + ) + { + return 0; + } + + if (Byte1Index != 3) // Not the vector overload + { + L.LogStackTrace(); + LOGWARN("BroadcastBlockAction with 3 position arguments is deprecated, use vector-parametered version instead."); + } + + // Read the params: + cWorld * Self; + Vector3i BlockPos; + Byte Byte1, Byte2; + BLOCKTYPE BlockType; + const cClientHandle * Exclude = nullptr; + + if ( + !L.GetStackValues(1, Self) || + !GetStackVectorOr3Numbers(L, 2, BlockPos) || + !L.GetStackValues(Byte1Index, Byte1, Byte2, BlockType) + ) + { + return 0; + } + + // Optional param + L.GetStackValue(Byte1Index + 3, Exclude); + + Self->BroadcastBlockAction(BlockPos, Byte1, Byte2, BlockType, Exclude); + return 0; +} + + + + + +static int tolua_cWorld_BroadcastSoundEffect(lua_State * tolua_S) +{ + /* Function signature: + void BroadcastSoundEffect(string a_SoundName, number a_X, number a_Y, number a_Z, number a_Volume, number a_Pitch, [cClientHandle * a_Exclude]) + --or-- + void BroadcastSoundEffect(string a_SoundName, Vector3d, number a_Volume, number a_Pitch, [cClientHandle a_Exclude]) + */ + cLuaState L(tolua_S); + int VolumeIndex; + if ( + !L.CheckParamSelf("cWorld") || + !L.CheckParamString(2) || + !CheckParamVectorOr3Numbers(L, "Vector3", 3, VolumeIndex) || + !L.CheckParamNumber(VolumeIndex, VolumeIndex + 1) + ) + { + return 0; + } + + if (VolumeIndex != 4) // Not the vector overload + { + L.LogStackTrace(); + LOGWARN("BroadcastSoundEffect with 3 position arguments is deprecated, use vector-parametered version instead."); + } + + // Read the params: + cWorld * Self; + AString SoundName; + Vector3d BlockPos; + float Volume, Pitch; + const cClientHandle * Exclude = nullptr; + + if ( + !L.GetStackValues(1, Self, SoundName) || + !GetStackVectorOr3Numbers(L, 3, BlockPos) || + !L.GetStackValues(VolumeIndex, Volume, Pitch) + ) + { + return 0; + } + + // Optional param + L.GetStackValue(VolumeIndex + 2, Exclude); + + Self->BroadcastSoundEffect(SoundName, BlockPos, Volume, Pitch, Exclude); + return 0; +} + + + + + +static int tolua_cWorld_BroadcastSoundParticleEffect(lua_State * tolua_S) +{ + /* Function signature: + World:BroadcastSoundParticleEffect(EffectID a_EffectID, Vector3i a_SrcPos, number a_Data, [cClientHandle a_Exclude]) + --or-- + void BroadcastSoundParticleEffect(EffectID a_EffectID, number a_SrcX, number a_SrcY, number a_SrcZ, number a_Data, [cClientHandle a_Exclude]) + */ + cLuaState L(tolua_S); + int DataIndex; + if ( + !L.CheckParamSelf("cWorld") || + !L.CheckParamNumber(2) || + !CheckParamVectorOr3Numbers(L, "Vector3", 3, DataIndex) || + !L.CheckParamNumber(DataIndex) + ) + { + return 0; + } + + if (DataIndex != 4) // Not the vector overload + { + L.LogStackTrace(); + LOGWARN("BroadcastSoundParticleEffect with 3 position arguments is deprecated, use vector-parametered version instead."); + } + + // Read the params: + cWorld * World = nullptr; + Int32 EffectId; + Vector3i SrcPos; + int Data; + cClientHandle * ExcludeClient = nullptr; + + if ( + !L.GetStackValues(1, World, EffectId) || + !GetStackVectorOr3Numbers(L, 3, SrcPos) || + !L.GetStackValue(DataIndex, Data) + ) + { + return 0; + } + + // Optional param + L.GetStackValue(DataIndex + 1, ExcludeClient); + + World->BroadcastSoundParticleEffect(static_cast(EffectId), SrcPos, Data, ExcludeClient); + return 0; +} + + static int tolua_cWorld_BroadcastParticleEffect(lua_State * tolua_S) { /* Function signature: - World:BroadcastParticleEffect("Name", PosX, PosY, PosZ, OffX, OffY, OffZ, ParticleData, ParticleAmount, [ExcludeClient], [OptionalParam1], [OptionalParam2] + World:BroadcastParticleEffect("Name", PosX, PosY, PosZ, OffX, OffY, OffZ, ParticleData, ParticleAmount, [ExcludeClient], [OptionalParam1], [OptionalParam2]) + --or-- + World:BroadcastParticleEffect("Name", SrcPos, Offset, ParticleData, ParticleAmount, [ExcludeClient], [OptionalParam1], [OptionalParam2]) */ cLuaState L(tolua_S); + int OffsetIndex, ParticleDataIndex; if ( - !L.CheckParamUserType(1, "cWorld") || - !L.CheckParamString (2) || - !L.CheckParamNumber (3, 10) + !L.CheckParamSelf("cWorld") || + !L.CheckParamString(2) || + !CheckParamVectorOr3Numbers(L, "Vector3", 3, OffsetIndex) || + !CheckParamVectorOr3Numbers(L, "Vector3", OffsetIndex, ParticleDataIndex) ) { return 0; } + if ((OffsetIndex != 4) || (ParticleDataIndex != 5)) // Not the vector overload + { + L.LogStackTrace(); + LOGWARN("BroadcastParticleEffect with 3 position and 3 offset arguments is deprecated, use vector-parametered version instead."); + } + // Read the params: cWorld * World = nullptr; AString Name; - float PosX, PosY, PosZ, OffX, OffY, OffZ; + Vector3f SrcPos, Offset; float ParticleData; int ParticleAmount; cClientHandle * ExcludeClient = nullptr; - L.GetStackValues(1, World, Name, PosX, PosY, PosZ, OffX, OffY, OffZ, ParticleData, ParticleAmount, ExcludeClient); - if (World == nullptr) + + if ( + !L.GetStackValues(1, World, Name) || + !GetStackVectorOr3Numbers(L, 3, SrcPos) || + !GetStackVectorOr3Numbers(L, OffsetIndex, Offset) || + !L.GetStackValues(ParticleDataIndex, ParticleData, ParticleAmount) + ) { - LOGWARNING("World:BroadcastParticleEffect(): invalid world parameter"); - L.LogStackTrace(); return 0; } - // Read up to 2 more optional data params: - std::array data; - for (int i = 0; (i < 2) && L.IsParamNumber(11 + i); i++) - { - L.GetStackValue(11 + i, data[static_cast(i)]); - } + // Read up to 3 more optional params: + L.GetStackValue(ParticleDataIndex + 2, ExcludeClient); - World->BroadcastParticleEffect(Name, Vector3f(PosX, PosY, PosZ), Vector3f(OffX, OffY, OffZ), ParticleData, ParticleAmount, ExcludeClient); + std::array Data; + bool HasData = L.GetStackValues(ParticleDataIndex + 3, Data[0], Data[1]); + if (HasData) + { + World->BroadcastParticleEffect(Name, SrcPos, Offset, ParticleData, ParticleAmount, Data, ExcludeClient); + } + else + { + World->BroadcastParticleEffect(Name, SrcPos, Offset, ParticleData, ParticleAmount, ExcludeClient); + } return 0; } @@ -668,43 +878,46 @@ void cManualBindings::BindWorld(lua_State * tolua_S) { tolua_beginmodule(tolua_S, nullptr); tolua_beginmodule(tolua_S, "cWorld"); - tolua_function(tolua_S, "BroadcastParticleEffect", tolua_cWorld_BroadcastParticleEffect); - tolua_function(tolua_S, "ChunkStay", tolua_cWorld_ChunkStay); - tolua_function(tolua_S, "DoExplosionAt", tolua_cWorld_DoExplosionAt); - tolua_function(tolua_S, "DoWithBeaconAt", DoWithXYZ); - tolua_function(tolua_S, "DoWithBedAt", DoWithXYZ); - tolua_function(tolua_S, "DoWithBlockEntityAt", DoWithXYZ); - tolua_function(tolua_S, "DoWithBrewingstandAt", DoWithXYZ); - tolua_function(tolua_S, "DoWithChestAt", DoWithXYZ); - tolua_function(tolua_S, "DoWithCommandBlockAt", DoWithXYZ); - tolua_function(tolua_S, "DoWithDispenserAt", DoWithXYZ); - tolua_function(tolua_S, "DoWithDropSpenserAt", DoWithXYZ); - tolua_function(tolua_S, "DoWithDropperAt", DoWithXYZ); - tolua_function(tolua_S, "DoWithEntityByID", DoWithID< cWorld, cEntity, &cWorld::DoWithEntityByID>); - tolua_function(tolua_S, "DoWithFlowerPotAt", DoWithXYZ); - tolua_function(tolua_S, "DoWithFurnaceAt", DoWithXYZ); - tolua_function(tolua_S, "DoWithMobHeadAt", DoWithXYZ); - tolua_function(tolua_S, "DoWithNoteBlockAt", DoWithXYZ); - tolua_function(tolua_S, "DoWithPlayer", DoWith< cWorld, cPlayer, &cWorld::DoWithPlayer>); - tolua_function(tolua_S, "DoWithPlayerByUUID", tolua_cWorld_DoWithPlayerByUUID); - tolua_function(tolua_S, "FindAndDoWithPlayer", DoWith< cWorld, cPlayer, &cWorld::FindAndDoWithPlayer>); - tolua_function(tolua_S, "ForEachBlockEntityInChunk", ForEachInChunk); - tolua_function(tolua_S, "ForEachBrewingstandInChunk", ForEachInChunk); - tolua_function(tolua_S, "ForEachChestInChunk", ForEachInChunk); - tolua_function(tolua_S, "ForEachEntity", ForEach< cWorld, cEntity, &cWorld::ForEachEntity>); - tolua_function(tolua_S, "ForEachEntityInBox", ForEachInBox< cWorld, cEntity, &cWorld::ForEachEntityInBox>); - tolua_function(tolua_S, "ForEachEntityInChunk", ForEachInChunk); - tolua_function(tolua_S, "ForEachFurnaceInChunk", ForEachInChunk); - tolua_function(tolua_S, "ForEachLoadedChunk", tolua_cWorld_ForEachLoadedChunk); - tolua_function(tolua_S, "ForEachPlayer", ForEach< cWorld, cPlayer, &cWorld::ForEachPlayer>); - tolua_function(tolua_S, "GetBlockInfo", tolua_cWorld_GetBlockInfo); - tolua_function(tolua_S, "GetBlockTypeMeta", tolua_cWorld_GetBlockTypeMeta); - tolua_function(tolua_S, "GetSignLines", tolua_cWorld_GetSignLines); - tolua_function(tolua_S, "PrepareChunk", tolua_cWorld_PrepareChunk); - tolua_function(tolua_S, "QueueTask", tolua_cWorld_QueueTask); - tolua_function(tolua_S, "ScheduleTask", tolua_cWorld_ScheduleTask); - tolua_function(tolua_S, "SetSignLines", tolua_cWorld_SetSignLines); - tolua_function(tolua_S, "TryGetHeight", tolua_cWorld_TryGetHeight); + tolua_function(tolua_S, "BroadcastBlockAction", tolua_cWorld_BroadcastBlockAction); + tolua_function(tolua_S, "BroadcastSoundEffect", tolua_cWorld_BroadcastSoundEffect); + tolua_function(tolua_S, "BroadcastSoundParticleEffect", tolua_cWorld_BroadcastSoundParticleEffect); + tolua_function(tolua_S, "BroadcastParticleEffect", tolua_cWorld_BroadcastParticleEffect); + tolua_function(tolua_S, "ChunkStay", tolua_cWorld_ChunkStay); + tolua_function(tolua_S, "DoExplosionAt", tolua_cWorld_DoExplosionAt); + tolua_function(tolua_S, "DoWithBeaconAt", DoWithXYZ); + tolua_function(tolua_S, "DoWithBedAt", DoWithXYZ); + tolua_function(tolua_S, "DoWithBlockEntityAt", DoWithXYZ); + tolua_function(tolua_S, "DoWithBrewingstandAt", DoWithXYZ); + tolua_function(tolua_S, "DoWithChestAt", DoWithXYZ); + tolua_function(tolua_S, "DoWithCommandBlockAt", DoWithXYZ); + tolua_function(tolua_S, "DoWithDispenserAt", DoWithXYZ); + tolua_function(tolua_S, "DoWithDropSpenserAt", DoWithXYZ); + tolua_function(tolua_S, "DoWithDropperAt", DoWithXYZ); + tolua_function(tolua_S, "DoWithEntityByID", DoWithID< cWorld, cEntity, &cWorld::DoWithEntityByID>); + tolua_function(tolua_S, "DoWithFlowerPotAt", DoWithXYZ); + tolua_function(tolua_S, "DoWithFurnaceAt", DoWithXYZ); + tolua_function(tolua_S, "DoWithMobHeadAt", DoWithXYZ); + tolua_function(tolua_S, "DoWithNoteBlockAt", DoWithXYZ); + tolua_function(tolua_S, "DoWithPlayer", DoWith< cWorld, cPlayer, &cWorld::DoWithPlayer>); + tolua_function(tolua_S, "DoWithPlayerByUUID", tolua_cWorld_DoWithPlayerByUUID); + tolua_function(tolua_S, "FindAndDoWithPlayer", DoWith< cWorld, cPlayer, &cWorld::FindAndDoWithPlayer>); + tolua_function(tolua_S, "ForEachBlockEntityInChunk", ForEachInChunk); + tolua_function(tolua_S, "ForEachBrewingstandInChunk", ForEachInChunk); + tolua_function(tolua_S, "ForEachChestInChunk", ForEachInChunk); + tolua_function(tolua_S, "ForEachEntity", ForEach< cWorld, cEntity, &cWorld::ForEachEntity>); + tolua_function(tolua_S, "ForEachEntityInBox", ForEachInBox< cWorld, cEntity, &cWorld::ForEachEntityInBox>); + tolua_function(tolua_S, "ForEachEntityInChunk", ForEachInChunk); + tolua_function(tolua_S, "ForEachFurnaceInChunk", ForEachInChunk); + tolua_function(tolua_S, "ForEachLoadedChunk", tolua_cWorld_ForEachLoadedChunk); + tolua_function(tolua_S, "ForEachPlayer", ForEach< cWorld, cPlayer, &cWorld::ForEachPlayer>); + tolua_function(tolua_S, "GetBlockInfo", tolua_cWorld_GetBlockInfo); + tolua_function(tolua_S, "GetBlockTypeMeta", tolua_cWorld_GetBlockTypeMeta); + tolua_function(tolua_S, "GetSignLines", tolua_cWorld_GetSignLines); + tolua_function(tolua_S, "PrepareChunk", tolua_cWorld_PrepareChunk); + tolua_function(tolua_S, "QueueTask", tolua_cWorld_QueueTask); + tolua_function(tolua_S, "ScheduleTask", tolua_cWorld_ScheduleTask); + tolua_function(tolua_S, "SetSignLines", tolua_cWorld_SetSignLines); + tolua_function(tolua_S, "TryGetHeight", tolua_cWorld_TryGetHeight); tolua_endmodule(tolua_S); tolua_endmodule(tolua_S); } -- cgit v1.2.3