From b688ba9be8da66c2df428f0842be4b73092baa81 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 3 Aug 2013 20:05:07 +0200 Subject: Removed the unused BlockY parameter from cChunkDef::BlockToChunk() --- source/BlockEntities/ChestEntity.cpp | 2 +- source/BlockEntities/HopperEntity.cpp | 2 +- source/ChunkDef.h | 5 ++--- source/ChunkMap.cpp | 26 +++++++++++++------------- 4 files changed, 17 insertions(+), 18 deletions(-) diff --git a/source/BlockEntities/ChestEntity.cpp b/source/BlockEntities/ChestEntity.cpp index 24d2aef11..d5cd076be 100644 --- a/source/BlockEntities/ChestEntity.cpp +++ b/source/BlockEntities/ChestEntity.cpp @@ -123,7 +123,7 @@ void cChestEntity::UsedBy(cPlayer * a_Player) // We cannot properly detect contents change, but such a change doesn't happen without a player opening the chest first. // The few false positives aren't much to worry about int ChunkX, ChunkZ; - cChunkDef::BlockToChunk(m_PosX, m_PosY, m_PosZ, ChunkX, ChunkZ); + cChunkDef::BlockToChunk(m_PosX, m_PosZ, ChunkX, ChunkZ); m_World->MarkChunkDirty(ChunkX, ChunkZ); } diff --git a/source/BlockEntities/HopperEntity.cpp b/source/BlockEntities/HopperEntity.cpp index 23e4b8096..591db7b4d 100644 --- a/source/BlockEntities/HopperEntity.cpp +++ b/source/BlockEntities/HopperEntity.cpp @@ -125,7 +125,7 @@ void cHopperEntity::UsedBy(cPlayer * a_Player) // We cannot properly detect contents change, but such a change doesn't happen without a player opening the chest first. // The few false positives aren't much to worry about int ChunkX, ChunkZ; - cChunkDef::BlockToChunk(m_PosX, m_PosY, m_PosZ, ChunkX, ChunkZ); + cChunkDef::BlockToChunk(m_PosX, m_PosZ, ChunkX, ChunkZ); m_World->MarkChunkDirty(ChunkX, ChunkZ); } diff --git a/source/ChunkDef.h b/source/ChunkDef.h index 7f9c0ca98..3e78b59b1 100644 --- a/source/ChunkDef.h +++ b/source/ChunkDef.h @@ -137,7 +137,7 @@ public: /// Converts absolute block coords into relative (chunk + block) coords: inline static void AbsoluteToRelative(/* in-out */ int & a_X, int & a_Y, int & a_Z, /* out */ int & a_ChunkX, int & a_ChunkZ ) { - BlockToChunk(a_X, a_Y, a_Z, a_ChunkX, a_ChunkZ); + BlockToChunk(a_X, a_Z, a_ChunkX, a_ChunkZ); a_X = a_X - a_ChunkX * Width; a_Z = a_Z - a_ChunkZ * Width; @@ -145,9 +145,8 @@ public: /// Converts absolute block coords to chunk coords: - inline static void BlockToChunk( int a_X, int a_Y, int a_Z, int & a_ChunkX, int & a_ChunkZ ) + inline static void BlockToChunk(int a_X, int a_Z, int & a_ChunkX, int & a_ChunkZ) { - (void)a_Y; a_ChunkX = a_X / Width; if ((a_X < 0) && (a_X % Width != 0)) { diff --git a/source/ChunkMap.cpp b/source/ChunkMap.cpp index 0db4b898a..9a9e0dcf6 100644 --- a/source/ChunkMap.cpp +++ b/source/ChunkMap.cpp @@ -345,7 +345,7 @@ void cChunkMap::BroadcastBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, c x = a_BlockX; y = a_BlockY; z = a_BlockZ; - cChunkDef::BlockToChunk(x, y, z, ChunkX, ChunkZ); + cChunkDef::BlockToChunk(x, z, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ); if (Chunk == NULL) { @@ -364,7 +364,7 @@ void cChunkMap::BroadcastBlockBreakAnimation(int a_entityID, int a_blockX, int a cCSLock Lock(m_CSLayers); int ChunkX, ChunkZ; - cChunkDef::BlockToChunk(a_blockX, a_blockY, a_blockZ, ChunkX, ChunkZ); + cChunkDef::BlockToChunk(a_blockX, a_blockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, 0, ChunkZ); if (Chunk == NULL) { @@ -382,7 +382,7 @@ void cChunkMap::BroadcastBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, c { cCSLock Lock(m_CSLayers); int ChunkX, ChunkZ; - cChunkDef::BlockToChunk(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); + cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, 0, ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { @@ -592,7 +592,7 @@ void cChunkMap::BroadcastSoundEffect(const AString & a_SoundName, int a_SrcX, in cCSLock Lock(m_CSLayers); int ChunkX, ChunkZ; - cChunkDef::BlockToChunk(a_SrcX / 8, a_SrcY / 8, a_SrcZ / 8, ChunkX, ChunkZ); + cChunkDef::BlockToChunk(a_SrcX / 8, a_SrcZ / 8, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, 0, ChunkZ); if (Chunk == NULL) { @@ -611,7 +611,7 @@ void cChunkMap::BroadcastSoundParticleEffect(int a_EffectID, int a_SrcX, int a_S cCSLock Lock(m_CSLayers); int ChunkX, ChunkZ; - cChunkDef::BlockToChunk(a_SrcX / 8, a_SrcY / 8, a_SrcZ / 8, ChunkX, ChunkZ); + cChunkDef::BlockToChunk(a_SrcX / 8, a_SrcZ / 8, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, 0, ChunkZ); if (Chunk == NULL) { @@ -645,7 +645,7 @@ void cChunkMap::BroadcastThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ, c { cCSLock Lock(m_CSLayers); int ChunkX, ChunkZ; - cChunkDef::BlockToChunk(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); + cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, 0, ChunkZ); if (Chunk == NULL) { @@ -664,7 +664,7 @@ void cChunkMap::BroadcastUseBed(const cEntity & a_Entity, int a_BlockX, int a_Bl cCSLock Lock(m_CSLayers); int ChunkX, ChunkZ; - cChunkDef::BlockToChunk(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); + cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, 0, ChunkZ); if (Chunk == NULL) { @@ -682,7 +682,7 @@ void cChunkMap::SendBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cClien { cCSLock Lock(m_CSLayers); int ChunkX, ChunkZ; - cChunkDef::BlockToChunk(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); + cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, 0, ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { @@ -700,7 +700,7 @@ void cChunkMap::UseBlockEntity(cPlayer * a_Player, int a_BlockX, int a_BlockY, i // a_Player rclked block entity at the coords specified, handle it cCSLock Lock(m_CSLayers); int ChunkX, ChunkZ; - cChunkDef::BlockToChunk(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); + cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, 0, ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { @@ -717,7 +717,7 @@ void cChunkMap::WakeUpSimulators(int a_BlockX, int a_BlockY, int a_BlockZ) { cCSLock Lock(m_CSLayers); int ChunkX, ChunkZ; - cChunkDef::BlockToChunk(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); + cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, 0, ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { @@ -735,8 +735,8 @@ void cChunkMap::WakeUpSimulatorsInArea(int a_MinBlockX, int a_MaxBlockX, int a_M { cSimulatorManager * SimMgr = m_World->GetSimulatorManager(); int MinChunkX, MinChunkZ, MaxChunkX, MaxChunkZ; - cChunkDef::BlockToChunk(a_MinBlockX, ZERO_CHUNK_Y, a_MinBlockZ, MinChunkX, MinChunkZ); - cChunkDef::BlockToChunk(a_MaxBlockX, ZERO_CHUNK_Y, a_MaxBlockZ, MaxChunkX, MaxChunkZ); + cChunkDef::BlockToChunk(a_MinBlockX, a_MinBlockZ, MinChunkX, MinChunkZ); + cChunkDef::BlockToChunk(a_MaxBlockX, a_MaxBlockZ, MaxChunkX, MaxChunkZ); for (int z = MinChunkZ; z <= MaxChunkZ; z++) { int MinZ = std::max(a_MinBlockZ, z * cChunkDef::Width); @@ -1903,7 +1903,7 @@ bool cChunkMap::SetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, const ASt { cCSLock Lock(m_CSLayers); int ChunkX, ChunkZ; - cChunkDef::BlockToChunk(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); + cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { -- cgit v1.2.3 From 4f26f11dc77ab032feec8c746fc6ddaa1ea44057 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 3 Aug 2013 20:26:50 +0200 Subject: Added cWorld::DoWithChunk() function. This will be used by the blocktracers to gain direct access to chunk data. --- source/ChunkMap.cpp | 15 +++++++++++++++ source/ChunkMap.h | 4 ++++ source/World.cpp | 9 +++++++++ source/World.h | 3 +++ 4 files changed, 31 insertions(+) diff --git a/source/ChunkMap.cpp b/source/ChunkMap.cpp index 9a9e0dcf6..0d49ce9c4 100644 --- a/source/ChunkMap.cpp +++ b/source/ChunkMap.cpp @@ -713,6 +713,21 @@ void cChunkMap::UseBlockEntity(cPlayer * a_Player, int a_BlockX, int a_BlockY, i +bool cChunkMap::DoWithChunk(int a_ChunkX, int a_ChunkZ, cChunkCallback & a_Callback) +{ + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ); + if (Chunk == NULL) + { + return false; + } + return a_Callback.Item(Chunk); +} + + + + + void cChunkMap::WakeUpSimulators(int a_BlockX, int a_BlockY, int a_BlockZ) { cCSLock Lock(m_CSLayers); diff --git a/source/ChunkMap.h b/source/ChunkMap.h index 899f290c5..183031808 100644 --- a/source/ChunkMap.h +++ b/source/ChunkMap.h @@ -35,6 +35,7 @@ typedef cItemCallback cDispenserCallback; typedef cItemCallback cDropperCallback; typedef cItemCallback cDropSpenserCallback; typedef cItemCallback cFurnaceCallback; +typedef cItemCallback cChunkCallback; @@ -79,6 +80,9 @@ public: /// a_Player rclked block entity at the coords specified, handle it void UseBlockEntity(cPlayer * a_Player, int a_X, int a_Y, int a_Z); + /// Calls the callback for the chunk specified, with ChunkMapCS locked; returns false if the chunk doesn't exist, otherwise returns the same value as the callback + bool DoWithChunk(int a_ChunkX, int a_ChunkZ, cChunkCallback & a_Callback); + /// Wakes up simulators for the specified block void WakeUpSimulators(int a_BlockX, int a_BlockY, int a_BlockZ); diff --git a/source/World.cpp b/source/World.cpp index 880f6e5b2..03e086148 100644 --- a/source/World.cpp +++ b/source/World.cpp @@ -832,6 +832,15 @@ bool cWorld::GetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_ +bool cWorld::DoWithChunk(int a_ChunkX, int a_ChunkZ, cChunkCallback & a_Callback) +{ + return m_ChunkMap->DoWithChunk(a_ChunkX, a_ChunkZ, a_Callback); +} + + + + + void cWorld::GrowTree(int a_X, int a_Y, int a_Z) { if (GetBlock(a_X, a_Y, a_Z) == E_BLOCK_SAPLING) diff --git a/source/World.h b/source/World.h index 9de00ceec..52d634769 100644 --- a/source/World.h +++ b/source/World.h @@ -404,6 +404,9 @@ public: /// a_Player is using block entity at [x, y, z], handle that: void UseBlockEntity(cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) {m_ChunkMap->UseBlockEntity(a_Player, a_BlockX, a_BlockY, a_BlockZ); } + + /// Calls the callback for the chunk specified, with ChunkMapCS locked; returns false if the chunk doesn't exist, otherwise returns the same value as the callback + bool DoWithChunk(int a_ChunkX, int a_ChunkZ, cChunkCallback & a_Callback); void GrowTree (int a_BlockX, int a_BlockY, int a_BlockZ); // tolua_export void GrowTreeFromSapling(int a_BlockX, int a_BlockY, int a_BlockZ, char a_SaplingMeta); // tolua_export -- cgit v1.2.3 From 5fe7008966f70de2af53cce7fc13014c220ab721 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 4 Aug 2013 13:25:48 +0200 Subject: First attempt at implementing a cLineBlockTracer class Not yet tested, will probably have lots of bugs, if it is at all usable. --- VC2008/MCServer.vcproj | 14 ++- source/BlockTracer.h | 104 ++++++++++++++++++ source/LineBlockTracer.cpp | 258 +++++++++++++++++++++++++++++++++++++++++++++ source/LineBlockTracer.h | 84 +++++++++++++++ 4 files changed, 459 insertions(+), 1 deletion(-) create mode 100644 source/BlockTracer.h create mode 100644 source/LineBlockTracer.cpp create mode 100644 source/LineBlockTracer.h diff --git a/VC2008/MCServer.vcproj b/VC2008/MCServer.vcproj index 6fcd55388..54a694f19 100644 --- a/VC2008/MCServer.vcproj +++ b/VC2008/MCServer.vcproj @@ -1,4 +1,4 @@ - + + + @@ -545,6 +549,14 @@ RelativePath="..\source\LinearUpscale.h" > + + + + diff --git a/source/BlockTracer.h b/source/BlockTracer.h new file mode 100644 index 000000000..4adc61f00 --- /dev/null +++ b/source/BlockTracer.h @@ -0,0 +1,104 @@ + +// BlockTracer.h + +// Declares the classes common for all blocktracers + + + + + +#pragma once + + + + + +// fwd: World.h +class cWorld; + + + + + +class cBlockTracer abstract +{ +public: + /** The callback class is used to notify the caller of individual events that are being traced. + */ + class cCallbacks abstract + { + public: + /** Called on each block encountered along the path, including the first block (path start) + When this callback returns true, the tracing is aborted. + */ + virtual bool OnNextBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) = 0; + + /** Called on each block encountered along the path, including the first block (path start), if chunk data is not loaded + When this callback returns true, the tracing is aborted. + */ + virtual bool OnNextBlockNoData(int a_BlockX, int a_BlockY, int a_BlockZ) {} + + /** Called when the path goes out of world, either below (a_BlockY < 0) or above (a_BlockY >= cChunkDef::Height) + The coords specify the exact point at which the path exited the world. + If this callback returns true, the tracing is aborted. + Note that some paths can go out of the world and come back again (parabola), + in such a case this callback is followed by OnIntoWorld() and further OnNextBlock() calls + */ + virtual bool OnOutOfWorld(double a_BlockX, double a_BlockY, double a_BlockZ) {} + + /** Called when the path goes into the world, from either below (a_BlockY < 0) or above (a_BlockY >= cChunkDef::Height) + The coords specify the exact point at which the path entered the world. + If this callback returns true, the tracing is aborted. + Note that some paths can go out of the world and come back again (parabola), + in such a case this callback is followed by further OnNextBlock() calls + */ + virtual bool OnIntoWorld(double a_BlockX, double a_BlockY, double a_BlockZ) {} + + /** Called when the path is sure not to hit any more blocks. + Note that for some shapes this might never happen (line with constant Y) + */ + virtual void OnNoMoreHits(void) {} + + /** Called when the block tracing walks into a chunk that is not allocated. + This usually means that the tracing is aborted. + */ + virtual void OnNoChunk(void) {} + } ; + + + /// Creates the BlockTracer parent with the specified callbacks + cBlockTracer(cWorld & a_World, cCallbacks & a_Callbacks) : + m_World(&a_World), + m_Callbacks(&a_Callbacks) + { + } + + + /// Sets new world, returns the old one. Note that both need to be valid + cWorld & SetWorld(cWorld & a_World) + { + cWorld & Old = *m_World; + m_World = &a_World; + return Old; + } + + + /// Sets new callbacks, returns the old ones. Note that both need to be valid + cCallbacks & SetCallbacks(cCallbacks & a_NewCallbacks) + { + cCallbacks & Old = *m_Callbacks; + m_Callbacks = &a_NewCallbacks; + return Old; + } + +protected: + /// The world upon which to operate + cWorld * m_World; + + /// The callback to use for reporting + cCallbacks * m_Callbacks; +} ; + + + + diff --git a/source/LineBlockTracer.cpp b/source/LineBlockTracer.cpp new file mode 100644 index 000000000..c5939cb78 --- /dev/null +++ b/source/LineBlockTracer.cpp @@ -0,0 +1,258 @@ + +// LineBlockTracer.cpp + +// Implements the cLineBlockTracer class representing a cBlockTracer that traces along a straight line between two points + +#include "Globals.h" +#include "LineBlockTracer.h" +#include "Vector3d.h" +#include "World.h" +#include "Chunk.h" + + + + + + +cLineBlockTracer::cLineBlockTracer(cWorld & a_World, cCallbacks & a_Callbacks) : + super(a_World, a_Callbacks) +{ +} + + + + + +bool cLineBlockTracer::Trace(cWorld & a_World, cBlockTracer::cCallbacks & a_Callbacks, const Vector3d & a_Start, const Vector3d & a_End) +{ + cLineBlockTracer Tracer(a_World, a_Callbacks); + return Tracer.Trace(a_Start.x, a_Start.y, a_Start.z, a_End.x, a_End.y, a_End.z); +} + + + + + +bool cLineBlockTracer::Trace(cWorld & a_World, cBlockTracer::cCallbacks &a_Callbacks, double a_StartX, double a_StartY, double a_StartZ, double a_EndX, double a_EndY, double a_EndZ) +{ + cLineBlockTracer Tracer(a_World, a_Callbacks); + return Tracer.Trace(a_StartX, a_StartY, a_StartZ, a_EndX, a_EndY, a_EndZ); +} + + + + + +bool cLineBlockTracer::Trace(double a_StartX, double a_StartY, double a_StartZ, double a_EndX, double a_EndY, double a_EndZ) +{ + // Initialize the member veriables: + m_StartX = a_StartX; + m_StartY = a_StartY; + m_StartZ = a_StartZ; + m_EndX = a_EndX; + m_EndY = a_EndY; + m_EndZ = a_EndZ; + m_DirX = (m_StartX < m_EndX) ? 1 : -1; + m_DirY = (m_StartY < m_EndY) ? 1 : -1; + m_DirZ = (m_StartZ < m_EndZ) ? 1 : -1; + + // Check the start coords, adjust into the world: + if (m_StartY < 0) + { + if (m_EndY < 0) + { + // Nothing to trace + m_Callbacks->OnNoMoreHits(); + return true; + } + FixStartBelowWorld(); + m_Callbacks->OnIntoWorld(m_StartX, m_StartY, m_StartZ); + } + else if (m_StartY >= cChunkDef::Height) + { + if (m_EndY >= cChunkDef::Height) + { + m_Callbacks->OnNoMoreHits(); + return true; + } + FixStartAboveWorld(); + m_Callbacks->OnIntoWorld(m_StartX, m_StartY, m_StartZ); + } + + m_CurrentX = (int)floor(m_StartX); + m_CurrentY = (int)floor(m_StartY); + m_CurrentZ = (int)floor(m_StartZ); + + m_DiffX = m_EndX - m_StartX; + m_DiffY = m_EndY - m_StartY; + m_DiffZ = m_EndZ - m_StartZ; + + // The actual trace is handled with ChunkMapCS locked by calling our Item() for the specified chunk + int BlockX = (int)floor(m_StartX); + int BlockZ = (int)floor(m_StartZ); + int ChunkX, ChunkZ; + cChunkDef::BlockToChunk(BlockX, BlockZ, ChunkX, ChunkZ); + return m_World->DoWithChunk(ChunkX, ChunkZ, *this); +} + + + + + +void cLineBlockTracer::FixStartAboveWorld(void) +{ + // We must set the start Y to less than cChunkDef::Height so that it is considered inside the world later on + // Therefore we use an EPS-offset from the height, as small as reasonably possible. + const double Height = (double)cChunkDef::Height - 0.00001; + CalcXZIntersection(Height, m_StartX, m_StartZ); + m_StartY = Height; +} + + + + + +void cLineBlockTracer::FixStartBelowWorld(void) +{ + CalcXZIntersection(0, m_StartX, m_StartZ); + m_StartY = 0; +} + + + + + +void cLineBlockTracer::CalcXZIntersection(double a_Y, double & a_IntersectX, double & a_IntersectZ) +{ + double Ratio = (m_StartY - a_Y) / (m_StartY - m_EndY); + a_IntersectX = m_StartX + (m_EndX - m_StartX) * Ratio; + a_IntersectZ = m_StartZ + (m_EndZ - m_StartZ) * Ratio; +} + + + + + +bool cLineBlockTracer::MoveToNextBlock(void) +{ + // Find out which of the current block's walls gets hit by the path: + static const double EPS = 0.00001; + double Coeff = 1; + enum eDirection + { + dirNONE, + dirX, + dirY, + dirZ, + } Direction = dirNONE; + if (abs(m_DiffX) > EPS) + { + double DestX = (m_DirX > 0) ? (m_CurrentX + 1) : m_CurrentX; + Coeff = (m_EndX - DestX) / m_DiffX; + Direction = dirX; + } + if (abs(m_DiffY) > EPS) + { + double DestY = (m_DirY > 0) ? (m_CurrentY + 1) : m_CurrentY; + double CoeffY = (DestY - m_StartY) / m_DiffY; + if (CoeffY < Coeff) + { + Coeff = CoeffY; + Direction = dirY; + } + } + if (abs(m_DiffZ) > EPS) + { + double DestZ = (m_DirZ > 0) ? (m_CurrentZ + 1) : m_CurrentZ; + double CoeffZ = (DestZ - m_StartZ) / m_DiffZ; + if (CoeffZ < Coeff) + { + Coeff = CoeffZ; + Direction = dirZ; + } + } + + // Based on the wall hit, adjust the current coords + switch (Direction) + { + case dirX: m_CurrentX += m_DirX; break; + case dirY: m_CurrentY += m_DirY; break; + case dirZ: m_CurrentZ += m_DirZ; break; + case dirNONE: return false; + } + return true; +} + + + + + +bool cLineBlockTracer::Item(cChunk * a_Chunk) +{ + ASSERT((m_CurrentY >= 0) && (m_CurrentY < cChunkDef::Height)); // This should be provided by FixStartAboveWorld() / FixStartBelowWorld() + + // This is the actual line tracing loop. + bool Finished = false; + while (true) + { + // Report the current block through the callbacks: + if (a_Chunk == NULL) + { + m_Callbacks->OnNoChunk(); + return false; + } + if (a_Chunk->IsValid()) + { + BLOCKTYPE BlockType; + NIBBLETYPE BlockMeta; + int RelX = FAST_FLOOR_DIV(m_CurrentX, cChunkDef::Width); + int RelZ = FAST_FLOOR_DIV(m_CurrentZ, cChunkDef::Width); + a_Chunk->GetBlockTypeMeta(RelX, m_CurrentY, RelZ, BlockType, BlockMeta); + if (m_Callbacks->OnNextBlock(m_CurrentX, m_CurrentY, m_CurrentZ, BlockType, BlockMeta)) + { + // The callback terminated the trace + return false; + } + } + else + { + if (m_Callbacks->OnNextBlockNoData(m_CurrentX, m_CurrentY, m_CurrentZ)) + { + // The callback terminated the trace + return false; + } + } + + // Move to next block + if (!MoveToNextBlock()) + { + // We've reached the end + m_Callbacks->OnNoMoreHits(); + return true; + } + + // Update the current chunk + if (a_Chunk != NULL) + { + a_Chunk = a_Chunk->GetNeighborChunk(m_CurrentX, m_CurrentZ); + } + + if ((m_CurrentY < 0) || (m_CurrentY >= cChunkDef::Height)) + { + // We've gone out of the world, that's the end of this trace + double IntersectX, IntersectZ; + CalcXZIntersection(m_CurrentY, IntersectX, IntersectZ); + if (m_Callbacks->OnOutOfWorld(IntersectX, m_CurrentY, IntersectZ)) + { + // The callback terminated the trace + return false; + } + m_Callbacks->OnNoMoreHits(); + return true; + } + } +} + + + + diff --git a/source/LineBlockTracer.h b/source/LineBlockTracer.h new file mode 100644 index 000000000..4616cb191 --- /dev/null +++ b/source/LineBlockTracer.h @@ -0,0 +1,84 @@ + +// LineBlockTracer.h + +// Declares the cLineBlockTracer class representing a cBlockTracer that traces along a straight line between two points + + + + + +#pragma once + +#include "BlockTracer.h" + + + + + +// fwd: Chunk.h +class cChunk; + +// fwd: cChunkMap.h +typedef cItemCallback cChunkCallback; + + + + + + +class cLineBlockTracer : + public cBlockTracer, + public cChunkCallback +{ + typedef cBlockTracer super; + +public: + cLineBlockTracer(cWorld & a_World, cCallbacks & a_Callbacks); + + /// Traces one line between Start and End; returns true if the entire line was traced (until OnNoMoreHits()) + bool Trace(double a_StartX, double a_StartY, double a_StartZ, double a_EndX, double a_EndY, double a_EndZ); + + // Utility functions for simple one-line usage: + /// Traces one line between Start and End; returns true if the entire line was traced (until OnNoMoreHits()) + static bool Trace(cWorld & a_World, cCallbacks & a_Callbacks, double a_StartX, double a_StartY, double a_StartZ, double a_EndX, double a_EndY, double a_EndZ); + + /// Traces one line between Start and End; returns true if the entire line was traced (until OnNoMoreHits()) + static bool Trace(cWorld & a_World, cCallbacks & a_Callbacks, const Vector3d & a_Start, const Vector3d & a_End); + +protected: + // The start point of the trace + double m_StartX, m_StartY, m_StartZ; + + // The end point of the trace + double m_EndX, m_EndY, m_EndZ; + + // The difference in coords, End - Start + double m_DiffX, m_DiffY, m_DiffZ; + + // The increment at which the block coords are going from Start to End; either +1 or -1 + int m_DirX, m_DirY, m_DirZ; + + // The current block + int m_CurrentX, m_CurrentY, m_CurrentZ; + + + /// Adjusts the start point above the world to just at the world's top + void FixStartAboveWorld(void); + + /// Adjusts the start point below the world to just at the world's bottom + void FixStartBelowWorld(void); + + /// Calculates the XZ coords of an intersection with the specified Yconst plane; assumes that such an intersection exists + void CalcXZIntersection(double a_Y, double & a_IntersectX, double & a_IntersectZ); + + /// Moves m_Current to the next block on the line; returns false if no move is possible (reached the end) + bool MoveToNextBlock(void); + + // cChunkCallback overrides: + virtual bool Item(cChunk * a_Chunk) override; +} ; + + + + + -- cgit v1.2.3 From b522a9b2621e0e585446065412785b8145e21b49 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 4 Aug 2013 16:05:45 +0200 Subject: Ignoring all .ini files in the MCServer folder. Only the .example.ini files are supposed to be in the repository and they must be added specifically by name (git add -f ). All the other .ini files are considered instance-specific and are not to be put into the repo. --- MCServer/.gitignore | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/MCServer/.gitignore b/MCServer/.gitignore index 62225e137..ca10d90e8 100644 --- a/MCServer/.gitignore +++ b/MCServer/.gitignore @@ -1,11 +1,8 @@ *.exe -ChunkWorx.ini -ChunkWorxSave.ini +*.ini MCServer -banned.ini logs players -whitelist.ini world* API.txt *.dat @@ -15,9 +12,6 @@ schematics *.pdb memdump.xml *.grab -ProtectionAreas.ini ProtectionAreas.sqlite helgrind.log -settings.ini -webadmin.ini motd.txt -- cgit v1.2.3 From 6af81c66e9aea6ecc5913266815e7e468872dee4 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 4 Aug 2013 16:06:28 +0200 Subject: cItem: Removed a warning emitted when creating an item from air --- source/Item.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source/Item.h b/source/Item.h index fc54da51d..fee861050 100644 --- a/source/Item.h +++ b/source/Item.h @@ -55,7 +55,10 @@ public: { if (!IsValidItem(m_ItemType)) { - LOGWARNING("%s: creating an invalid item type (%d), resetting to empty.", __FUNCTION__, a_ItemType); + if (m_ItemType != E_BLOCK_AIR) + { + LOGWARNING("%s: creating an invalid item type (%d), resetting to empty.", __FUNCTION__, a_ItemType); + } Empty(); } } -- cgit v1.2.3 From 654714e7bc34b61d01202e3f87adc2fa60baeeab Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 4 Aug 2013 16:07:15 +0200 Subject: LineBlockTracer: Fixed initial errors --- source/BlockTracer.h | 6 +++--- source/LineBlockTracer.cpp | 11 +++++++---- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/source/BlockTracer.h b/source/BlockTracer.h index 4adc61f00..6d67f1052 100644 --- a/source/BlockTracer.h +++ b/source/BlockTracer.h @@ -36,7 +36,7 @@ public: /** Called on each block encountered along the path, including the first block (path start), if chunk data is not loaded When this callback returns true, the tracing is aborted. */ - virtual bool OnNextBlockNoData(int a_BlockX, int a_BlockY, int a_BlockZ) {} + virtual bool OnNextBlockNoData(int a_BlockX, int a_BlockY, int a_BlockZ) { return false; } /** Called when the path goes out of world, either below (a_BlockY < 0) or above (a_BlockY >= cChunkDef::Height) The coords specify the exact point at which the path exited the world. @@ -44,7 +44,7 @@ public: Note that some paths can go out of the world and come back again (parabola), in such a case this callback is followed by OnIntoWorld() and further OnNextBlock() calls */ - virtual bool OnOutOfWorld(double a_BlockX, double a_BlockY, double a_BlockZ) {} + virtual bool OnOutOfWorld(double a_BlockX, double a_BlockY, double a_BlockZ) { return false; } /** Called when the path goes into the world, from either below (a_BlockY < 0) or above (a_BlockY >= cChunkDef::Height) The coords specify the exact point at which the path entered the world. @@ -52,7 +52,7 @@ public: Note that some paths can go out of the world and come back again (parabola), in such a case this callback is followed by further OnNextBlock() calls */ - virtual bool OnIntoWorld(double a_BlockX, double a_BlockY, double a_BlockZ) {} + virtual bool OnIntoWorld(double a_BlockX, double a_BlockY, double a_BlockZ) { return false; } /** Called when the path is sure not to hit any more blocks. Note that for some shapes this might never happen (line with constant Y) diff --git a/source/LineBlockTracer.cpp b/source/LineBlockTracer.cpp index c5939cb78..03464314a 100644 --- a/source/LineBlockTracer.cpp +++ b/source/LineBlockTracer.cpp @@ -148,8 +148,11 @@ bool cLineBlockTracer::MoveToNextBlock(void) if (abs(m_DiffX) > EPS) { double DestX = (m_DirX > 0) ? (m_CurrentX + 1) : m_CurrentX; - Coeff = (m_EndX - DestX) / m_DiffX; - Direction = dirX; + Coeff = (DestX - m_StartX) / m_DiffX; + if (Coeff <= 1) + { + Direction = dirX; + } } if (abs(m_DiffY) > EPS) { @@ -205,8 +208,8 @@ bool cLineBlockTracer::Item(cChunk * a_Chunk) { BLOCKTYPE BlockType; NIBBLETYPE BlockMeta; - int RelX = FAST_FLOOR_DIV(m_CurrentX, cChunkDef::Width); - int RelZ = FAST_FLOOR_DIV(m_CurrentZ, cChunkDef::Width); + int RelX = m_CurrentX - a_Chunk->GetPosX() * cChunkDef::Width; + int RelZ = m_CurrentZ - a_Chunk->GetPosZ() * cChunkDef::Width; a_Chunk->GetBlockTypeMeta(RelX, m_CurrentY, RelZ, BlockType, BlockMeta); if (m_Callbacks->OnNextBlock(m_CurrentX, m_CurrentY, m_CurrentZ, BlockType, BlockMeta)) { -- cgit v1.2.3 From e21ed58d5fbf901e10cf829bba0fb3d1c9952f7b Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 4 Aug 2013 16:08:09 +0200 Subject: cWorld: Added a self-test for LineBlockTracer, disabled by an #ifdef. --- source/World.cpp | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/source/World.cpp b/source/World.cpp index 03e086148..1ff5a5970 100644 --- a/source/World.cpp +++ b/source/World.cpp @@ -59,6 +59,9 @@ #include "tolua++.h" +// DEBUG: Test out the cLineBlockTracer class by tracing a few lines: +#include "LineBlockTracer.h" + #ifndef _WIN32 #include #endif @@ -442,6 +445,60 @@ void cWorld::InitializeSpawn(void) // TODO: Better spawn detection - move spawn out of the water if it isn't set in the INI already m_SpawnY = (double)GetHeight((int)m_SpawnX, (int)m_SpawnZ) + 1.6f; // +1.6f eye height + + + #ifdef TEST_LINEBLOCKTRACER + // DEBUG: Test out the cLineBlockTracer class by tracing a few lines: + class cTracerCallbacks : + public cBlockTracer::cCallbacks + { + virtual bool OnNextBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override + { + LOGD("Block {%d, %d, %d}: %d:%d (%s)", + a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, + ItemToString(cItem(a_BlockType, 1, a_BlockMeta)).c_str() + ); + return false; + } + + virtual bool OnNextBlockNoData(int a_BlockX, int a_BlockY, int a_BlockZ) override + { + LOGD("Block {%d, %d, %d}: no data available", + a_BlockX, a_BlockY, a_BlockZ + ); + return false; + } + + virtual bool OnOutOfWorld(double a_BlockX, double a_BlockY, double a_BlockZ) override + { + LOGD("Out of world at {%f, %f, %f}", a_BlockX, a_BlockY, a_BlockZ); + return false; + } + + virtual bool OnIntoWorld(double a_BlockX, double a_BlockY, double a_BlockZ) override + { + LOGD("Into world at {%f, %f, %f}", a_BlockX, a_BlockY, a_BlockZ); + return false; + } + + virtual void OnNoMoreHits(void) override + { + LOGD("No more hits"); + } + } Callbacks; + LOGD("Spawn is at {%f, %f, %f}", m_SpawnX, m_SpawnY, m_SpawnZ); + LOGD("Tracing a line along +X:"); + cLineBlockTracer::Trace(*this, Callbacks, m_SpawnX - 10, m_SpawnY, m_SpawnZ, m_SpawnX + 10, m_SpawnY, m_SpawnZ); + LOGD("Tracing a line along -Z:"); + cLineBlockTracer::Trace(*this, Callbacks, m_SpawnX, m_SpawnY, m_SpawnZ + 10, m_SpawnX, m_SpawnY, m_SpawnZ - 10); + LOGD("Tracing a line along -Y, out of world:"); + cLineBlockTracer::Trace(*this, Callbacks, m_SpawnX, 260, m_SpawnZ, m_SpawnX, -5, m_SpawnZ); + LOGD("Tracing a line along XY:"); + cLineBlockTracer::Trace(*this, Callbacks, m_SpawnX - 10, m_SpawnY - 10, m_SpawnZ, m_SpawnX + 10, m_SpawnY + 10, m_SpawnZ); + LOGD("Tracing a line in generic direction:"); + cLineBlockTracer::Trace(*this, Callbacks, m_SpawnX - 15, m_SpawnY - 5, m_SpawnZ + 7.5, m_SpawnX + 13, m_SpawnY - 10, m_SpawnZ + 8.5); + LOGD("Tracing tests done"); + #endif // TEST_LINEBLOCKTRACER } -- cgit v1.2.3 From 71bb41ee86e262103909d8007dbc2ef876cd0b24 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 4 Aug 2013 23:11:25 +0200 Subject: LuaState refactoring: initial part. The cLuaState class is a wrapper for the lua_State * and for the common functions on it. The cPlugin_NewLua has been rewritten to use it instead of the raw pointer. Part of #33 --- VC2008/MCServer.vcproj | 8 ++ source/LuaState.cpp | 218 +++++++++++++++++++++++++++++ source/LuaState.h | 90 ++++++++++++ source/ManualBindings.cpp | 19 +-- source/Plugin_NewLua.cpp | 350 ++++++++++++++++------------------------------ source/Plugin_NewLua.h | 11 +- 6 files changed, 447 insertions(+), 249 deletions(-) create mode 100644 source/LuaState.cpp create mode 100644 source/LuaState.h diff --git a/VC2008/MCServer.vcproj b/VC2008/MCServer.vcproj index 54a694f19..8755fb2e8 100644 --- a/VC2008/MCServer.vcproj +++ b/VC2008/MCServer.vcproj @@ -1497,6 +1497,14 @@ RelativePath="..\source\LuaScript.h" > + + + + diff --git a/source/LuaState.cpp b/source/LuaState.cpp new file mode 100644 index 000000000..da86a4b20 --- /dev/null +++ b/source/LuaState.cpp @@ -0,0 +1,218 @@ + +// LuaState.cpp + +// Implements the cLuaState class representing the wrapper over lua_State *, provides associated helper functions + +#include "Globals.h" +#include "LuaState.h" + +extern "C" +{ + #include "lualib.h" +} + +#include "tolua++.h" +#include "Bindings.h" +#include "ManualBindings.h" + +// fwd: SQLite/lsqlite3.c +extern "C" +{ + LUALIB_API int luaopen_lsqlite3(lua_State * L); +} + +// fwd: LuaExpat/lxplib.c: +extern "C" +{ + int luaopen_lxp(lua_State * L); +} + + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cLuaState: + +cLuaState::cLuaState(const AString & a_SubsystemName) : + m_LuaState(NULL), + m_SubsystemName(a_SubsystemName) +{ +} + + + + + +cLuaState::~cLuaState() +{ + if (IsValid()) + { + Close(); + } +} + + + + + +void cLuaState::Create(void) +{ + if (m_LuaState != NULL) + { + LOGWARNING("%s: Trying to create an already-existing LuaState, ignoring.", __FUNCTION__); + return; + } + m_LuaState = lua_open(); + luaL_openlibs(m_LuaState); + tolua_AllToLua_open(m_LuaState); + ManualBindings::Bind(m_LuaState); + luaopen_lsqlite3(m_LuaState); + luaopen_lxp(m_LuaState); +} + + + + + +void cLuaState::Close(void) +{ + if (m_LuaState == NULL) + { + LOGWARNING("%s: Trying to close an invalid LuaState, ignoring.", __FUNCTION__); + return; + } + lua_close(m_LuaState); + m_LuaState = NULL; +} + + + + + +bool cLuaState::LoadFile(const AString & a_FileName) +{ + ASSERT(IsValid()); + + // Load the file: + int s = luaL_loadfile(m_LuaState, a_FileName.c_str()); + if (ReportErrors(s)) + { + LOGWARNING("Can't load %s because of an error in file %s", m_SubsystemName.c_str(), a_FileName.c_str()); + return false; + } + + // Execute the globals: + s = lua_pcall(m_LuaState, 0, LUA_MULTRET, 0); + if (ReportErrors(s)) + { + LOGWARNING("Error in %s in file %s", m_SubsystemName.c_str(), a_FileName.c_str()); + return false; + } + + return true; +} + + + + + +bool cLuaState::PushFunction(const char * a_FunctionName, bool a_ShouldLogFailure /* = true */) +{ + if (!IsValid()) + { + // This happens if cPlugin::Initialize() fails with an error + return false; + } + + lua_getglobal(m_LuaState, a_FunctionName); + if (!lua_isfunction(m_LuaState, -1)) + { + if (a_ShouldLogFailure) + { + LOGWARNING("Error in %s: Could not find function %s()", m_SubsystemName.c_str(), a_FunctionName); + } + lua_pop(m_LuaState, 1); + return false; + } + return true; +} + + + + + +bool cLuaState::PushFunctionFromRegistry(int a_FnRef) +{ + lua_rawgeti(m_LuaState, LUA_REGISTRYINDEX, a_FnRef); // same as lua_getref() + if (!lua_isfunction(m_LuaState, -1)) + { + lua_pop(m_LuaState, 1); + return false; + } + return true; +} + + + + + +void cLuaState::PushStringVector(const AStringVector & a_Vector) +{ + lua_createtable(m_LuaState, a_Vector.size(), 0); + int newTable = lua_gettop(m_LuaState); + int index = 1; + for (AStringVector::const_iterator itr = a_Vector.begin(), end = a_Vector.end(); itr != end; ++itr, ++index) + { + tolua_pushstring(m_LuaState, itr->c_str()); + lua_rawseti(m_LuaState, newTable, index); + } +} + + + + + +bool cLuaState::CallFunction(int a_NumArgs, int a_NumResults, const char * a_FunctionName) +{ + ASSERT(lua_isfunction(m_LuaState, -a_NumArgs - 1)); + + int s = lua_pcall(m_LuaState, a_NumArgs, a_NumResults, 0); + if (ReportErrors(s)) + { + LOGWARNING("Error in %s calling function %s()", m_SubsystemName.c_str(), a_FunctionName); + return false; + } + return true; +} + + + + + +bool cLuaState::ReportErrors(int a_Status) +{ + return ReportErrors(m_LuaState, a_Status); +} + + + + + +bool cLuaState::ReportErrors(lua_State * a_LuaState, int a_Status) +{ + if (a_Status == 0) + { + // No error to report + return false; + } + + LOGWARNING("LUA: %d - %s", a_Status, lua_tostring(a_LuaState, -1)); + lua_pop(a_LuaState, 1); + return true; +} + + + + diff --git a/source/LuaState.h b/source/LuaState.h new file mode 100644 index 000000000..10ff53911 --- /dev/null +++ b/source/LuaState.h @@ -0,0 +1,90 @@ + +// LuaState.h + +// Declares the cLuaState class representing the wrapper over lua_State *, provides associated helper functions + + + + + +#pragma once + + + + + +// fwd: lua.h +struct lua_State; + + + + + +class cLuaState +{ +public: + /** Creates a new instance. The LuaState is not initialized. + a_SubsystemName is used for reporting problems in the console, it is "plugin %s" for plugins, + or "LuaScript" for the cLuaScript template + */ + cLuaState(const AString & a_SubsystemName); + + ~cLuaState(); + + operator lua_State * (void) { return m_LuaState; } + + /// Creates the m_LuaState, if not closed already + void Create(void); + + /// Closes the m_LuaState, if not closed already + void Close(void); + + /// Returns true if the m_LuaState is valid + bool IsValid(void) const { return (m_LuaState != NULL); } + + /** Loads the specified file + Returns false and logs a warning to the console if not successful (but the LuaState is kept open). + m_SubsystemName is displayed in the warning log message. + */ + bool LoadFile(const AString & a_FileName); + + /** Pushes the function of the specified name onto the stack. + Returns true if successful. + If a_ShouldLogFail is true, logs a warning on failure (incl. m_SubsystemName) + */ + bool PushFunction(const char * a_FunctionName, bool a_ShouldLogFailure = true); + + /** Pushes a function that has been saved into the global registry, identified by a_FnRef. + Returns true if successful. Logs a warning on failure + */ + bool PushFunctionFromRegistry(int a_FnRef); + + /// Pushes a string vector, as a table, onto the stack + void PushStringVector(const AStringVector & a_Vector); + + /** + Calls the function that has been pushed onto the stack by PushFunction. + Returns true if successful, logs a warning on failure. + a_FunctionName is used only for the warning log message, the function + to be called must be pushed by PushFunction() beforehand. + */ + bool CallFunction(int a_NumArgs, int a_NumResults, const char * a_FunctionName); + + /// If the status is nonzero, prints the text on the top of Lua stack and returns true + bool ReportErrors(int status); + + /// If the status is nonzero, prints the text on the top of Lua stack and returns true + static bool ReportErrors(lua_State * a_LuaState, int status); + +protected: + lua_State * m_LuaState; + + /** The subsystem name is used for reporting errors to the console, it is either "plugin %s" or "LuaScript" + whatever is given to the constructor + */ + AString m_SubsystemName; +} ; + + + + diff --git a/source/ManualBindings.cpp b/source/ManualBindings.cpp index 7a13d94c0..403ad21d5 100644 --- a/source/ManualBindings.cpp +++ b/source/ManualBindings.cpp @@ -19,13 +19,14 @@ #include "BlockEntities/FurnaceEntity.h" #include "md5/md5.h" #include "LuaWindow.h" +#include "LuaState.h" // fwd: LuaCommandBinder.cpp -bool report_errors(lua_State* lua, int status); +// bool cLuaState::ReportErrors(lua_State* lua, int status); @@ -233,7 +234,7 @@ static int tolua_DoWith(lua_State* tolua_S) } int s = lua_pcall(LuaState, (TableRef == LUA_REFNIL ? 1 : 2), 1, 0); - if (report_errors(LuaState, s)) + if (cLuaState::ReportErrors(LuaState, s)) { return true; // Abort enumeration } @@ -328,7 +329,7 @@ static int tolua_DoWithXYZ(lua_State* tolua_S) } int s = lua_pcall(LuaState, (TableRef == LUA_REFNIL ? 1 : 2), 1, 0); - if (report_errors(LuaState, s)) + if (cLuaState::ReportErrors(LuaState, s)) { return true; // Abort enumeration } @@ -421,7 +422,7 @@ static int tolua_ForEachInChunk(lua_State* tolua_S) } int s = lua_pcall(LuaState, (TableRef == LUA_REFNIL ? 1 : 2), 1, 0); - if (report_errors(LuaState, s)) + if (cLuaState::ReportErrors(LuaState, s)) { return true; /* Abort enumeration */ } @@ -512,7 +513,7 @@ static int tolua_ForEach(lua_State * tolua_S) } int s = lua_pcall(LuaState, (TableRef == LUA_REFNIL ? 1 : 2), 1, 0); - if (report_errors(LuaState, s)) + if (cLuaState::ReportErrors(LuaState, s)) { return true; /* Abort enumeration */ } @@ -677,7 +678,7 @@ static int tolua_cPluginManager_ForEachCommand(lua_State * tolua_S) tolua_pushcppstring(LuaState, a_HelpString); int s = lua_pcall(LuaState, 3, 1, 0); - if (report_errors(LuaState, s)) + if (cLuaState::ReportErrors(LuaState, s)) { return true; /* Abort enumeration */ } @@ -751,7 +752,7 @@ static int tolua_cPluginManager_ForEachConsoleCommand(lua_State * tolua_S) tolua_pushcppstring(LuaState, a_HelpString); int s = lua_pcall(LuaState, 2, 1, 0); - if (report_errors(LuaState, s)) + if (cLuaState::ReportErrors(LuaState, s)) { return true; /* Abort enumeration */ } @@ -1171,8 +1172,8 @@ static int tolua_cPlugin_Call(lua_State* tolua_S) return 0; } - int s = lua_pcall(targetState, top-2, LUA_MULTRET, 0); - if( report_errors( targetState, s ) ) + int s = lua_pcall(targetState, top - 2, LUA_MULTRET, 0); + if (cLuaState::ReportErrors(targetState, s)) { LOGWARN("Error while calling function '%s' in plugin '%s'", funcName.c_str(), self->GetName().c_str() ); return 0; diff --git a/source/Plugin_NewLua.cpp b/source/Plugin_NewLua.cpp index 8b0f047cd..51d16c839 100644 --- a/source/Plugin_NewLua.cpp +++ b/source/Plugin_NewLua.cpp @@ -7,45 +7,10 @@ extern "C" { -#include "lualib.h" + #include "lualib.h" } #include "tolua++.h" -#include "Bindings.h" -#include "ManualBindings.h" - - - - - -// fwd: SQLite/lsqlite3.c -extern "C" -{ - LUALIB_API int luaopen_lsqlite3(lua_State * L); -} - -// fwd: LuaExpat/lxplib.c: -extern "C" -{ - int luaopen_lxp(lua_State * L); -} - - - - - -bool report_errors(lua_State * lua, int status) -{ - if (status == 0) - { - // No error to report - return false; - } - - LOGERROR("LUA: %s", lua_tostring(lua, -1)); - lua_pop(lua, 1); - return true; -} @@ -54,10 +19,9 @@ bool report_errors(lua_State * lua, int status) /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cPlugin_NewLua: -cPlugin_NewLua::cPlugin_NewLua(const AString & a_PluginDirectory) - : m_LuaState( 0 ) - , cWebPlugin() - , cPlugin(a_PluginDirectory) +cPlugin_NewLua::cPlugin_NewLua(const AString & a_PluginDirectory) : + cPlugin(a_PluginDirectory), + m_LuaState(Printf("plugin %s", GetName().c_str())) { } @@ -68,12 +32,7 @@ cPlugin_NewLua::cPlugin_NewLua(const AString & a_PluginDirectory) cPlugin_NewLua::~cPlugin_NewLua() { cCSLock Lock(m_CriticalSection); - - if( m_LuaState ) - { - lua_close( m_LuaState ); - m_LuaState = 0; - } + m_LuaState.Close(); } @@ -83,14 +42,9 @@ cPlugin_NewLua::~cPlugin_NewLua() bool cPlugin_NewLua::Initialize(void) { cCSLock Lock(m_CriticalSection); - if (m_LuaState == NULL) + if (!m_LuaState.IsValid()) { - m_LuaState = lua_open(); - luaL_openlibs(m_LuaState); - tolua_AllToLua_open(m_LuaState); - ManualBindings::Bind(m_LuaState); - luaopen_lsqlite3(m_LuaState); - luaopen_lxp(m_LuaState); + m_LuaState.Create(); // Inject the identification global variables into the state: lua_pushlightuserdata(m_LuaState, this); @@ -110,47 +64,32 @@ bool cPlugin_NewLua::Initialize(void) continue; } AString Path = PluginPath + *itr; - int s = luaL_loadfile(m_LuaState, Path.c_str() ); - if( report_errors( m_LuaState, s ) ) + if (!m_LuaState.LoadFile(Path)) { - LOGERROR("Can't load plugin %s because of an error in file %s", GetLocalDirectory().c_str(), Path.c_str() ); - lua_close( m_LuaState ); - m_LuaState = 0; - return false; - } - - s = lua_pcall(m_LuaState, 0, LUA_MULTRET, 0); - if( report_errors( m_LuaState, s ) ) - { - LOGERROR("Error in plugin %s in file %s", GetLocalDirectory().c_str(), Path.c_str() ); - lua_close( m_LuaState ); - m_LuaState = 0; + m_LuaState.Close(); return false; } } // for itr - Files[] // Call intialize function - if (!PushFunction("Initialize")) + if (!m_LuaState.PushFunction("Initialize")) { - lua_close( m_LuaState ); - m_LuaState = 0; + m_LuaState.Close(); return false; } tolua_pushusertype(m_LuaState, this, "cPlugin_NewLua"); - if (!CallFunction(1, 1, "Initialize")) + if (!m_LuaState.CallFunction(1, 1, "Initialize")) { - lua_close( m_LuaState ); - m_LuaState = 0; + m_LuaState.Close(); return false; } - if( !lua_isboolean( m_LuaState, -1 ) ) + if (!lua_isboolean(m_LuaState, -1)) { - LOGWARN("Error in plugin %s Initialize() must return a boolean value!", GetLocalDirectory().c_str() ); - lua_close( m_LuaState ); - m_LuaState = 0; + LOGWARNING("Error in plugin %s: Initialize() must return a boolean value!", GetName().c_str()); + m_LuaState.Close(); return false; } @@ -165,12 +104,12 @@ bool cPlugin_NewLua::Initialize(void) void cPlugin_NewLua::OnDisable() { cCSLock Lock(m_CriticalSection); - if (!PushFunction("OnDisable", false)) // false = don't log error if not found + if (!m_LuaState.PushFunction("OnDisable", false)) // false = don't log error if not found { return; } - CallFunction(0, 0, "OnDisable"); + m_LuaState.CallFunction(0, 0, "OnDisable"); } @@ -181,14 +120,14 @@ void cPlugin_NewLua::Tick(float a_Dt) { cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_TICK); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return; } tolua_pushnumber( m_LuaState, a_Dt ); - CallFunction(1, 0, FnName); + m_LuaState.CallFunction(1, 0, FnName); } @@ -200,7 +139,7 @@ bool cPlugin_NewLua::OnBlockToPickups(cWorld * a_World, cEntity * a_Digger, int cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_BLOCK_TO_PICKUPS); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -214,7 +153,7 @@ bool cPlugin_NewLua::OnBlockToPickups(cWorld * a_World, cEntity * a_Digger, int tolua_pushnumber (m_LuaState, a_BlockMeta); tolua_pushusertype(m_LuaState, &a_Pickups, "cItems"); - if (!CallFunction(8, 1, FnName)) + if (!m_LuaState.CallFunction(8, 1, FnName)) { return false; } @@ -233,7 +172,7 @@ bool cPlugin_NewLua::OnChat(cPlayer * a_Player, AString & a_Message) cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_CHAT); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -241,7 +180,7 @@ bool cPlugin_NewLua::OnChat(cPlayer * a_Player, AString & a_Message) tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); tolua_pushstring (m_LuaState, a_Message.c_str()); - if (!CallFunction(2, 2, FnName)) + if (!m_LuaState.CallFunction(2, 2, FnName)) { return false; } @@ -264,7 +203,7 @@ bool cPlugin_NewLua::OnChunkAvailable(cWorld * a_World, int a_ChunkX, int a_Chun cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_CHUNK_AVAILABLE); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -273,7 +212,7 @@ bool cPlugin_NewLua::OnChunkAvailable(cWorld * a_World, int a_ChunkX, int a_Chun tolua_pushnumber (m_LuaState, a_ChunkX); tolua_pushnumber (m_LuaState, a_ChunkZ); - if (!CallFunction(3, 1, FnName)) + if (!m_LuaState.CallFunction(3, 1, FnName)) { return false; } @@ -292,7 +231,7 @@ bool cPlugin_NewLua::OnChunkGenerated(cWorld * a_World, int a_ChunkX, int a_Chun cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_CHUNK_GENERATED); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -302,7 +241,7 @@ bool cPlugin_NewLua::OnChunkGenerated(cWorld * a_World, int a_ChunkX, int a_Chun tolua_pushnumber (m_LuaState, a_ChunkZ); tolua_pushusertype(m_LuaState, a_ChunkDesc, "cChunkDesc"); - if (!CallFunction(4, 1, FnName)) + if (!m_LuaState.CallFunction(4, 1, FnName)) { return false; } @@ -321,7 +260,7 @@ bool cPlugin_NewLua::OnChunkGenerating(cWorld * a_World, int a_ChunkX, int a_Chu cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_CHUNK_GENERATING); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -331,7 +270,7 @@ bool cPlugin_NewLua::OnChunkGenerating(cWorld * a_World, int a_ChunkX, int a_Chu tolua_pushnumber (m_LuaState, a_ChunkZ); tolua_pushusertype(m_LuaState, a_pLuaChunk, "cChunkDesc"); - if (!CallFunction(4, 1, FnName)) + if (!m_LuaState.CallFunction(4, 1, FnName)) { return false; } @@ -350,7 +289,7 @@ bool cPlugin_NewLua::OnChunkUnloaded(cWorld * a_World, int a_ChunkX, int a_Chunk cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_CHUNK_UNLOADED); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -359,7 +298,7 @@ bool cPlugin_NewLua::OnChunkUnloaded(cWorld * a_World, int a_ChunkX, int a_Chunk tolua_pushnumber (m_LuaState, a_ChunkX); tolua_pushnumber (m_LuaState, a_ChunkZ); - if (!CallFunction(3, 1, FnName)) + if (!m_LuaState.CallFunction(3, 1, FnName)) { return false; } @@ -378,7 +317,7 @@ bool cPlugin_NewLua::OnChunkUnloading(cWorld * a_World, int a_ChunkX, int a_Chun cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_CHUNK_UNLOADING); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -387,7 +326,7 @@ bool cPlugin_NewLua::OnChunkUnloading(cWorld * a_World, int a_ChunkX, int a_Chun tolua_pushnumber (m_LuaState, a_ChunkX); tolua_pushnumber (m_LuaState, a_ChunkZ); - if (!CallFunction(3, 1, FnName)) + if (!m_LuaState.CallFunction(3, 1, FnName)) { return false; } @@ -406,7 +345,7 @@ bool cPlugin_NewLua::OnCollectingPickup(cPlayer * a_Player, cPickup * a_Pickup) cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_COLLECTING_PICKUP); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -414,7 +353,7 @@ bool cPlugin_NewLua::OnCollectingPickup(cPlayer * a_Player, cPickup * a_Pickup) tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); tolua_pushusertype(m_LuaState, a_Pickup, "cPickup"); - if (!CallFunction(2, 1, FnName)) + if (!m_LuaState.CallFunction(2, 1, FnName)) { return false; } @@ -433,7 +372,7 @@ bool cPlugin_NewLua::OnCraftingNoRecipe(const cPlayer * a_Player, const cCraftin cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_CRAFTING_NO_RECIPE); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -442,7 +381,7 @@ bool cPlugin_NewLua::OnCraftingNoRecipe(const cPlayer * a_Player, const cCraftin tolua_pushusertype(m_LuaState, (void *)a_Grid, "cCraftingGrid"); tolua_pushusertype(m_LuaState, (void *)a_Recipe, "cCraftingRecipe"); - if (!CallFunction(3, 1, FnName)) + if (!m_LuaState.CallFunction(3, 1, FnName)) { return false; } @@ -461,7 +400,7 @@ bool cPlugin_NewLua::OnDisconnect(cPlayer * a_Player, const AString & a_Reason) cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_DISCONNECT); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -469,7 +408,7 @@ bool cPlugin_NewLua::OnDisconnect(cPlayer * a_Player, const AString & a_Reason) tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); tolua_pushstring (m_LuaState, a_Reason.c_str()); - if (!CallFunction(2, 1, FnName)) + if (!m_LuaState.CallFunction(2, 1, FnName)) { return false; } @@ -488,7 +427,7 @@ bool cPlugin_NewLua::OnExecuteCommand(cPlayer * a_Player, const AStringVector & cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_EXECUTE_COMMAND); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -508,7 +447,7 @@ bool cPlugin_NewLua::OnExecuteCommand(cPlayer * a_Player, const AStringVector & ++index; } - if (!CallFunction(2, 1, FnName)) + if (!m_LuaState.CallFunction(2, 1, FnName)) { return false; } @@ -527,7 +466,7 @@ bool cPlugin_NewLua::OnHandshake(cClientHandle * a_Client, const AString & a_Use cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_HANDSHAKE); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -535,7 +474,7 @@ bool cPlugin_NewLua::OnHandshake(cClientHandle * a_Client, const AString & a_Use tolua_pushusertype(m_LuaState, a_Client, "cClientHandle"); tolua_pushstring (m_LuaState, a_Username.c_str()); - if (!CallFunction(2, 1, FnName)) + if (!m_LuaState.CallFunction(2, 1, FnName)) { return false; } @@ -554,7 +493,7 @@ bool cPlugin_NewLua::OnKilling(cEntity & a_Victim, cEntity * a_Killer) cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_KILLING); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -562,7 +501,7 @@ bool cPlugin_NewLua::OnKilling(cEntity & a_Victim, cEntity * a_Killer) tolua_pushusertype(m_LuaState, &a_Victim, "cEntity"); tolua_pushusertype(m_LuaState, a_Killer, "cEntity"); - if (!CallFunction(2, 1, FnName)) + if (!m_LuaState.CallFunction(2, 1, FnName)) { return false; } @@ -581,7 +520,7 @@ bool cPlugin_NewLua::OnLogin(cClientHandle * a_Client, int a_ProtocolVersion, co cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_LOGIN); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -590,7 +529,7 @@ bool cPlugin_NewLua::OnLogin(cClientHandle * a_Client, int a_ProtocolVersion, co tolua_pushnumber (m_LuaState, a_ProtocolVersion); tolua_pushcppstring(m_LuaState, a_Username); - if (!CallFunction(3, 1, FnName)) + if (!m_LuaState.CallFunction(3, 1, FnName)) { return false; } @@ -609,7 +548,7 @@ bool cPlugin_NewLua::OnPlayerBreakingBlock(cPlayer & a_Player, int a_BlockX, int cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_BREAKING_BLOCK); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -622,7 +561,7 @@ bool cPlugin_NewLua::OnPlayerBreakingBlock(cPlayer & a_Player, int a_BlockX, int tolua_pushnumber (m_LuaState, a_BlockType); tolua_pushnumber (m_LuaState, a_BlockMeta); - if (!CallFunction(7, 1, FnName)) + if (!m_LuaState.CallFunction(7, 1, FnName)) { return false; } @@ -641,7 +580,7 @@ bool cPlugin_NewLua::OnPlayerBrokenBlock(cPlayer & a_Player, int a_BlockX, int a cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_BROKEN_BLOCK); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -654,7 +593,7 @@ bool cPlugin_NewLua::OnPlayerBrokenBlock(cPlayer & a_Player, int a_BlockX, int a tolua_pushnumber (m_LuaState, a_BlockType); tolua_pushnumber (m_LuaState, a_BlockMeta); - if (!CallFunction(7, 1, FnName)) + if (!m_LuaState.CallFunction(7, 1, FnName)) { return false; } @@ -673,14 +612,14 @@ bool cPlugin_NewLua::OnPlayerEating(cPlayer & a_Player) cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_EATING); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); - if (!CallFunction(1, 1, FnName)) + if (!m_LuaState.CallFunction(1, 1, FnName)) { return false; } @@ -699,14 +638,14 @@ bool cPlugin_NewLua::OnPlayerJoined(cPlayer & a_Player) cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_JOINED); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); - if (!CallFunction(1, 1, FnName)) + if (!m_LuaState.CallFunction(1, 1, FnName)) { return false; } @@ -725,7 +664,7 @@ bool cPlugin_NewLua::OnPlayerLeftClick(cPlayer & a_Player, int a_BlockX, int a_B cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_LEFT_CLICK); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -737,7 +676,7 @@ bool cPlugin_NewLua::OnPlayerLeftClick(cPlayer & a_Player, int a_BlockX, int a_B tolua_pushnumber (m_LuaState, a_BlockFace); tolua_pushnumber (m_LuaState, a_Status); - if (!CallFunction(6, 1, FnName)) + if (!m_LuaState.CallFunction(6, 1, FnName)) { return false; } @@ -756,14 +695,14 @@ bool cPlugin_NewLua::OnPlayerMoved(cPlayer & a_Player) cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_MOVING); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); - if (!CallFunction(1, 1, FnName)) + if (!m_LuaState.CallFunction(1, 1, FnName)) { return false; } @@ -782,7 +721,7 @@ bool cPlugin_NewLua::OnPlayerPlacedBlock(cPlayer & a_Player, int a_BlockX, int a cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_PLACED_BLOCK); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -798,7 +737,7 @@ bool cPlugin_NewLua::OnPlayerPlacedBlock(cPlayer & a_Player, int a_BlockX, int a tolua_pushnumber (m_LuaState, a_BlockType); tolua_pushnumber (m_LuaState, a_BlockMeta); - if (!CallFunction(10, 1, FnName)) + if (!m_LuaState.CallFunction(10, 1, FnName)) { return false; } @@ -817,7 +756,7 @@ bool cPlugin_NewLua::OnPlayerPlacingBlock(cPlayer & a_Player, int a_BlockX, int cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_PLACING_BLOCK); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -833,7 +772,7 @@ bool cPlugin_NewLua::OnPlayerPlacingBlock(cPlayer & a_Player, int a_BlockX, int tolua_pushnumber (m_LuaState, a_BlockType); tolua_pushnumber (m_LuaState, a_BlockMeta); - if (!CallFunction(10, 1, FnName)) + if (!m_LuaState.CallFunction(10, 1, FnName)) { return false; } @@ -852,7 +791,7 @@ bool cPlugin_NewLua::OnPlayerRightClick(cPlayer & a_Player, int a_BlockX, int a_ cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_RIGHT_CLICK); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -866,7 +805,7 @@ bool cPlugin_NewLua::OnPlayerRightClick(cPlayer & a_Player, int a_BlockX, int a_ tolua_pushnumber (m_LuaState, a_CursorY); tolua_pushnumber (m_LuaState, a_CursorZ); - if (!CallFunction(8, 1, FnName)) + if (!m_LuaState.CallFunction(8, 1, FnName)) { return false; } @@ -885,7 +824,7 @@ bool cPlugin_NewLua::OnPlayerRightClickingEntity(cPlayer & a_Player, cEntity & a cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_RIGHT_CLICKING_ENTITY); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -893,7 +832,7 @@ bool cPlugin_NewLua::OnPlayerRightClickingEntity(cPlayer & a_Player, cEntity & a tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); tolua_pushusertype(m_LuaState, &a_Entity, "cEntity"); - if (!CallFunction(2, 1, FnName)) + if (!m_LuaState.CallFunction(2, 1, FnName)) { return false; } @@ -912,14 +851,14 @@ bool cPlugin_NewLua::OnPlayerShooting(cPlayer & a_Player) cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_SHOOTING); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); - if (!CallFunction(1, 1, FnName)) + if (!m_LuaState.CallFunction(1, 1, FnName)) { return false; } @@ -938,14 +877,14 @@ bool cPlugin_NewLua::OnPlayerSpawned(cPlayer & a_Player) cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_SPAWNED); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); - if (!CallFunction(1, 1, FnName)) + if (!m_LuaState.CallFunction(1, 1, FnName)) { return false; } @@ -964,14 +903,14 @@ bool cPlugin_NewLua::OnPlayerTossingItem(cPlayer & a_Player) cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_TOSSING_ITEM); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); - if (!CallFunction(1, 1, FnName)) + if (!m_LuaState.CallFunction(1, 1, FnName)) { return false; } @@ -990,7 +929,7 @@ bool cPlugin_NewLua::OnPlayerUsedBlock(cPlayer & a_Player, int a_BlockX, int a_B cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_USED_BLOCK); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -1006,7 +945,7 @@ bool cPlugin_NewLua::OnPlayerUsedBlock(cPlayer & a_Player, int a_BlockX, int a_B tolua_pushnumber (m_LuaState, a_BlockType); tolua_pushnumber (m_LuaState, a_BlockMeta); - if (!CallFunction(10, 1, FnName)) + if (!m_LuaState.CallFunction(10, 1, FnName)) { return false; } @@ -1025,7 +964,7 @@ bool cPlugin_NewLua::OnPlayerUsedItem(cPlayer & a_Player, int a_BlockX, int a_Bl cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_USED_ITEM); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -1039,7 +978,7 @@ bool cPlugin_NewLua::OnPlayerUsedItem(cPlayer & a_Player, int a_BlockX, int a_Bl tolua_pushnumber (m_LuaState, a_CursorY); tolua_pushnumber (m_LuaState, a_CursorZ); - if (!CallFunction(8, 1, FnName)) + if (!m_LuaState.CallFunction(8, 1, FnName)) { return false; } @@ -1058,7 +997,7 @@ bool cPlugin_NewLua::OnPlayerUsingBlock(cPlayer & a_Player, int a_BlockX, int a_ cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_USING_BLOCK); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -1074,7 +1013,7 @@ bool cPlugin_NewLua::OnPlayerUsingBlock(cPlayer & a_Player, int a_BlockX, int a_ tolua_pushnumber (m_LuaState, a_BlockType); tolua_pushnumber (m_LuaState, a_BlockMeta); - if (!CallFunction(10, 1, FnName)) + if (!m_LuaState.CallFunction(10, 1, FnName)) { return false; } @@ -1093,7 +1032,7 @@ bool cPlugin_NewLua::OnPlayerUsingItem(cPlayer & a_Player, int a_BlockX, int a_B cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_USING_ITEM); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -1107,7 +1046,7 @@ bool cPlugin_NewLua::OnPlayerUsingItem(cPlayer & a_Player, int a_BlockX, int a_B tolua_pushnumber (m_LuaState, a_CursorY); tolua_pushnumber (m_LuaState, a_CursorZ); - if (!CallFunction(8, 1, FnName)) + if (!m_LuaState.CallFunction(8, 1, FnName)) { return false; } @@ -1126,7 +1065,7 @@ bool cPlugin_NewLua::OnPostCrafting(const cPlayer * a_Player, const cCraftingGri cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_POST_CRAFTING); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -1135,7 +1074,7 @@ bool cPlugin_NewLua::OnPostCrafting(const cPlayer * a_Player, const cCraftingGri tolua_pushusertype(m_LuaState, (void *)a_Grid, "cCraftingGrid"); tolua_pushusertype(m_LuaState, (void *)a_Recipe, "cCraftingRecipe"); - if (!CallFunction(3, 1, FnName)) + if (!m_LuaState.CallFunction(3, 1, FnName)) { return false; } @@ -1154,7 +1093,7 @@ bool cPlugin_NewLua::OnPreCrafting(const cPlayer * a_Player, const cCraftingGrid cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PRE_CRAFTING); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -1163,7 +1102,7 @@ bool cPlugin_NewLua::OnPreCrafting(const cPlayer * a_Player, const cCraftingGrid tolua_pushusertype(m_LuaState, (void *)a_Grid, "cCraftingGrid"); tolua_pushusertype(m_LuaState, (void *)a_Recipe, "cCraftingRecipe"); - if (!CallFunction(3, 1, FnName)) + if (!m_LuaState.CallFunction(3, 1, FnName)) { return false; } @@ -1182,7 +1121,7 @@ bool cPlugin_NewLua::OnTakeDamage(cEntity & a_Receiver, TakeDamageInfo & a_TDI) cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_TAKE_DAMAGE); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -1190,7 +1129,7 @@ bool cPlugin_NewLua::OnTakeDamage(cEntity & a_Receiver, TakeDamageInfo & a_TDI) tolua_pushusertype(m_LuaState, &a_Receiver, "cEntity"); tolua_pushusertype(m_LuaState, &a_TDI, "TakeDamageInfo"); - if (!CallFunction(2, 1, FnName)) + if (!m_LuaState.CallFunction(2, 1, FnName)) { return false; } @@ -1214,7 +1153,7 @@ bool cPlugin_NewLua::OnUpdatedSign( cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_UPDATED_SIGN); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -1229,7 +1168,7 @@ bool cPlugin_NewLua::OnUpdatedSign( tolua_pushstring (m_LuaState, a_Line4.c_str()); tolua_pushusertype(m_LuaState, (void *)a_Player, "cPlayer"); - if (!CallFunction(9, 1, FnName)) + if (!m_LuaState.CallFunction(9, 1, FnName)) { return false; } @@ -1253,7 +1192,7 @@ bool cPlugin_NewLua::OnUpdatingSign( cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_UPDATING_SIGN); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -1268,7 +1207,7 @@ bool cPlugin_NewLua::OnUpdatingSign( tolua_pushstring (m_LuaState, a_Line4.c_str()); tolua_pushusertype(m_LuaState, (void *)a_Player, "cPlayer"); - if (!CallFunction(9, 5, "OnUpdatingSign")) + if (!m_LuaState.CallFunction(9, 5, "OnUpdatingSign")) { return false; } @@ -1303,14 +1242,14 @@ bool cPlugin_NewLua::OnWeatherChanged(cWorld & a_World) cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_WEATHER_CHANGED); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } tolua_pushusertype(m_LuaState, &a_World, "cWorld"); - if (!CallFunction(1, 1, FnName)) + if (!m_LuaState.CallFunction(1, 1, FnName)) { return false; } @@ -1329,7 +1268,7 @@ bool cPlugin_NewLua::OnWeatherChanging(cWorld & a_World, eWeather & a_NewWeather cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_WEATHER_CHANGED); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -1337,7 +1276,7 @@ bool cPlugin_NewLua::OnWeatherChanging(cWorld & a_World, eWeather & a_NewWeather tolua_pushusertype(m_LuaState, &a_World, "cWorld"); tolua_pushnumber (m_LuaState, a_NewWeather); - if (!CallFunction(2, 2, FnName)) + if (!m_LuaState.CallFunction(2, 2, FnName)) { return false; } @@ -1368,29 +1307,22 @@ bool cPlugin_NewLua::HandleCommand(const AStringVector & a_Split, cPlayer * a_Pl cCSLock Lock(m_CriticalSection); // Push the function to be called: - lua_rawgeti(m_LuaState, LUA_REGISTRYINDEX, cmd->second); // same as lua_getref() - - // Push the split: - lua_createtable(m_LuaState, a_Split.size(), 0); - int newTable = lua_gettop(m_LuaState); - int index = 1; - std::vector::const_iterator iter = a_Split.begin(), end = a_Split.end(); - while(iter != end) + if (!m_LuaState.PushFunctionFromRegistry(cmd->second)) { - tolua_pushstring(m_LuaState, (*iter).c_str()); - lua_rawseti(m_LuaState, newTable, index); - ++iter; - ++index; + LOGWARNING("Command handler function for \"%s\" is invalid", cmd->first.c_str()); + return false; } + // Push the split: + m_LuaState.PushStringVector(a_Split); + // Push player: tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); // Call function: - int s = lua_pcall(m_LuaState, 2, 1, 0); - if (report_errors(m_LuaState, s)) + if (!m_LuaState.CallFunction(2, 1, __FUNCTION__)) { - LOGERROR("LUA error in %s. Stack size: %i", __FUNCTION__, lua_gettop(m_LuaState)); + LOGWARNING("LUA error in %s. Stack size: %i", __FUNCTION__, lua_gettop(m_LuaState)); return false; } @@ -1436,10 +1368,9 @@ bool cPlugin_NewLua::HandleConsoleCommand(const AStringVector & a_Split, cComman } // Call function: - int s = lua_pcall(m_LuaState, 1, 2, 0); - if (report_errors(m_LuaState, s)) + if (!m_LuaState.CallFunction(1, 2, __FUNCTION__)) { - LOGERROR("Lua error. Stack size: %i", lua_gettop(m_LuaState)); + LOGWARNING("Lua error in %s. Stack size: %i", __FUNCTION__, lua_gettop(m_LuaState)); return false; } @@ -1604,9 +1535,9 @@ AString cPlugin_NewLua::HandleWebRequest(const HTTPRequest * a_Request ) return ""; sWebPluginTab* Tab = 0; - for( TabList::iterator itr = GetTabs().begin(); itr != GetTabs().end(); ++itr ) + for (TabList::iterator itr = GetTabs().begin(); itr != GetTabs().end(); ++itr) { - if( (*itr)->SafeTitle.compare( SafeTabName ) == 0 ) // This is the one! Rawr + if ((*itr)->SafeTitle.compare(SafeTabName) == 0) // This is the one! Rawr { Tab = *itr; break; @@ -1615,13 +1546,13 @@ AString cPlugin_NewLua::HandleWebRequest(const HTTPRequest * a_Request ) if( Tab ) { - //LOGINFO("1. Stack size: %i", lua_gettop(m_LuaState) ); + // LOGINFO("1. Stack size: %i", lua_gettop(m_LuaState) ); lua_rawgeti( m_LuaState, LUA_REGISTRYINDEX, Tab->UserData); // same as lua_getref() - //LOGINFO("2. Stack size: %i", lua_gettop(m_LuaState) ); + // LOGINFO("2. Stack size: %i", lua_gettop(m_LuaState) ); // Push HTTPRequest tolua_pushusertype( m_LuaState, (void*)a_Request, "const HTTPRequest" ); - //LOGINFO("Calling bound function! :D"); + // LOGINFO("Calling bound function! :D"); int s = lua_pcall( m_LuaState, 1, 1, 0); if ( s != 0 ) @@ -1642,7 +1573,7 @@ AString cPlugin_NewLua::HandleWebRequest(const HTTPRequest * a_Request ) RetVal += tolua_tostring(m_LuaState, -1, 0); lua_pop(m_LuaState, 1); // Pop return value - //LOGINFO("ok. Stack size: %i", lua_gettop(m_LuaState) ); + // LOGINFO("ok. Stack size: %i", lua_gettop(m_LuaState) ); } return RetVal; @@ -1652,7 +1583,7 @@ AString cPlugin_NewLua::HandleWebRequest(const HTTPRequest * a_Request ) -bool cPlugin_NewLua::AddWebTab( const AString & a_Title, lua_State * a_LuaState, int a_FunctionReference ) +bool cPlugin_NewLua::AddWebTab(const AString & a_Title, lua_State * a_LuaState, int a_FunctionReference) { cCSLock Lock(m_CriticalSection); if (a_LuaState != m_LuaState) @@ -1666,7 +1597,7 @@ bool cPlugin_NewLua::AddWebTab( const AString & a_Title, lua_State * a_LuaState, Tab->UserData = a_FunctionReference; - GetTabs().push_back( Tab ); + GetTabs().push_back(Tab); return true; } @@ -1715,10 +1646,9 @@ bool cPlugin_NewLua::CallbackWindowClosing(int a_FnRef, cWindow & a_Window, cPla tolua_pushboolean (m_LuaState, a_CanRefuse ? 1 : 0); // Call function: - int s = lua_pcall(m_LuaState, 3, 1, 0); - if (report_errors(m_LuaState, s)) + if (!m_LuaState.CallFunction(3, 1, __FUNCTION__)) { - LOGERROR("LUA error in %s. Stack size: %i", __FUNCTION__, lua_gettop(m_LuaState)); + LOGWARNING("LUA error in %s. Stack size: %i", __FUNCTION__, lua_gettop(m_LuaState)); return false; } @@ -1741,56 +1671,12 @@ void cPlugin_NewLua::CallbackWindowSlotChanged(int a_FnRef, cWindow & a_Window, tolua_pushnumber (m_LuaState, a_SlotNum); // Call function: - int s = lua_pcall(m_LuaState, 2, 0, 0); - if (report_errors(m_LuaState, s)) + if (!m_LuaState.CallFunction(2, 0, __FUNCTION__)) { - LOGERROR("LUA error in %s. Stack size: %i", __FUNCTION__, lua_gettop(m_LuaState)); + LOGWARNING("LUA error in %s. Stack size: %i", __FUNCTION__, lua_gettop(m_LuaState)); } } - -// Helper functions -bool cPlugin_NewLua::PushFunction(const char * a_FunctionName, bool a_bLogError /* = true */) -{ - if (m_LuaState == NULL) - { - // This happens if Initialize() fails with an error - return false; - } - - lua_getglobal(m_LuaState, a_FunctionName); - if (!lua_isfunction(m_LuaState, -1)) - { - if (a_bLogError) - { - LOGWARN("Error in plugin %s: Could not find function %s()", GetName().c_str(), a_FunctionName); - } - lua_pop(m_LuaState, 1); - return false; - } - return true; -} - - - - - -bool cPlugin_NewLua::CallFunction( int a_NumArgs, int a_NumResults, const char * a_FunctionName) -{ - ASSERT(lua_isfunction(m_LuaState, -a_NumArgs - 1)); - - int s = lua_pcall(m_LuaState, a_NumArgs, a_NumResults, 0); - if (report_errors(m_LuaState, s)) - { - LOGWARN("Error in plugin %s calling function %s()", GetName().c_str(), a_FunctionName); - return false; - } - return true; -} - - - - diff --git a/source/Plugin_NewLua.h b/source/Plugin_NewLua.h index a79affd5d..d31a62601 100644 --- a/source/Plugin_NewLua.h +++ b/source/Plugin_NewLua.h @@ -3,6 +3,7 @@ #include "Plugin.h" #include "WebPlugin.h" +#include "LuaState.h" // Names for the global variables through which the plugin is identified in its LuaState #define LUA_PLUGIN_NAME_VAR_NAME "_MCServerInternal_PluginName" @@ -11,9 +12,6 @@ -// fwd: Lua -typedef struct lua_State lua_State; - // fwd: UI/Window.h class cWindow; @@ -99,7 +97,7 @@ public: /// Binds the console command to call the function specified by a Lua function reference. Simply adds to CommandMap. void BindConsoleCommand(const AString & a_Command, int a_FnRef); - lua_State * GetLuaState(void) { return m_LuaState; } + cLuaState & GetLuaState(void) { return m_LuaState; } cCriticalSection & GetCriticalSection(void) { return m_CriticalSection; } @@ -114,7 +112,7 @@ public: protected: cCriticalSection m_CriticalSection; - lua_State * m_LuaState; + cLuaState m_LuaState; /// Maps command name into Lua function reference typedef std::map CommandMap; @@ -122,9 +120,6 @@ protected: CommandMap m_Commands; CommandMap m_ConsoleCommands; - bool PushFunction(const char * a_FunctionName, bool a_bLogError = true); - bool CallFunction(int a_NumArgs, int a_NumResults, const char * a_FunctionName ); // a_FunctionName is only used for error messages, nothing else - /// Returns the name of Lua function that should handle the specified hook const char * GetHookFnName(cPluginManager::PluginHook a_Hook); } ; // tolua_export -- cgit v1.2.3 From 073bcd0361ff1634bcb3c7c8f075592500997b55 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 5 Aug 2013 10:43:43 +0200 Subject: Added the Carpet block. --- VC2008/MCServer.vcproj | 6 ++- source/BlockID.h | 2 + source/Blocks/BlockCarpet.h | 54 ++++++++++++++++++++++++ source/Blocks/BlockChest.h | 1 + source/Blocks/BlockDropSpenser.h | 2 + source/Blocks/BlockHandler.cpp | 89 ++++++++++++++++++++-------------------- 6 files changed, 109 insertions(+), 45 deletions(-) create mode 100644 source/Blocks/BlockCarpet.h diff --git a/VC2008/MCServer.vcproj b/VC2008/MCServer.vcproj index 6fcd55388..dc0291cd6 100644 --- a/VC2008/MCServer.vcproj +++ b/VC2008/MCServer.vcproj @@ -1,4 +1,4 @@ - + + + diff --git a/source/BlockID.h b/source/BlockID.h index bd2580ca9..ad8dab8bd 100644 --- a/source/BlockID.h +++ b/source/BlockID.h @@ -169,6 +169,8 @@ enum ENUM_BLOCK_ID E_BLOCK_DROPPER = 158, + E_BLOCK_CARPET = 171, + // Keep these two as the last values, without a number - they will get their correct number assigned automagically by C++ // IsValidBlock() depends on this E_BLOCK_NUMBER_OF_TYPES, ///< Number of individual (different) blocktypes diff --git a/source/Blocks/BlockCarpet.h b/source/Blocks/BlockCarpet.h new file mode 100644 index 000000000..f70ff45b6 --- /dev/null +++ b/source/Blocks/BlockCarpet.h @@ -0,0 +1,54 @@ + +// BlockCarpet.h + +// Declares the cBlockCarpetHandler class representing the handler for the carpet block + + + + +#pragma once + + + + + +class cBlockCarpetHandler : + public cBlockHandler +{ +public: + cBlockCarpetHandler(BLOCKTYPE a_BlockType); + + virtual const char * GetStepSound(void) override + { + return "step.cloth"; + } + + + virtual bool GetPlacementBlockTypeMeta( + cWorld * a_World, cPlayer * a_Player, + int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, + int a_CursorX, int a_CursorY, int a_CursorZ, + BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta + ) override + { + a_BlockType = m_BlockType; + a_BlockMeta = a_Player->GetEquippedItem().m_ItemDamage & 0x0f; + return true; + } + + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + a_Pickups.push_back(cItem(E_BLOCK_CARPET, a_BlockMeta)); + } + + + virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override + { + return ((a_RelY > 0) && (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) != E_BLOCK_AIR)); + } +} ; + + + + diff --git a/source/Blocks/BlockChest.h b/source/Blocks/BlockChest.h index 1975e11b2..8164942a3 100644 --- a/source/Blocks/BlockChest.h +++ b/source/Blocks/BlockChest.h @@ -3,6 +3,7 @@ #include "BlockEntity.h" #include "../World.h" +#include "../BlockArea.h" #include "../Player.h" diff --git a/source/Blocks/BlockDropSpenser.h b/source/Blocks/BlockDropSpenser.h index cfb607a7b..e5572da8a 100644 --- a/source/Blocks/BlockDropSpenser.h +++ b/source/Blocks/BlockDropSpenser.h @@ -5,6 +5,8 @@ #pragma once +#include "../Piston.h" + diff --git a/source/Blocks/BlockHandler.cpp b/source/Blocks/BlockHandler.cpp index 550a6795c..8978f4d46 100644 --- a/source/Blocks/BlockHandler.cpp +++ b/source/Blocks/BlockHandler.cpp @@ -5,59 +5,60 @@ #include "../World.h" #include "../Root.h" #include "../PluginManager.h" -#include "BlockSand.h" -#include "BlockGravel.h" -#include "BlockDoor.h" -#include "BlockFire.h" -#include "BlockRedstone.h" -#include "BlockRedstoneTorch.h" -#include "BlockRedstoneRepeater.h" -#include "BlockPiston.h" -#include "BlockWorkbench.h" -#include "BlockEntity.h" -#include "BlockVine.h" -#include "BlockTallGrass.h" -#include "BlockSnow.h" +#include "BlockBed.h" +#include "BlockBrewingStand.h" +#include "BlockCactus.h" +#include "BlockCarpet.h" +#include "BlockCauldron.h" +#include "BlockChest.h" #include "BlockCloth.h" -#include "BlockSlab.h" +#include "BlockCobWeb.h" +#include "BlockCrops.h" +#include "BlockDeadBush.h" #include "BlockDirt.h" -#include "BlockTorch.h" -#include "BlockWood.h" -#include "BlockLeaves.h" -#include "BlockSapling.h" +#include "BlockDoor.h" +#include "BlockDropSpenser.h" +#include "BlockEnderchest.h" +#include "BlockEntity.h" +#include "BlockFarmland.h" +#include "BlockFenceGate.h" +#include "BlockFire.h" +#include "BlockFlower.h" +#include "BlockFlowerPot.h" #include "BlockFluid.h" -#include "BlockChest.h" #include "BlockFurnace.h" -#include "BlockDropSpenser.h" -#include "BlockStairs.h" +#include "BlockGlass.h" +#include "BlockGlowstone.h" +#include "BlockGravel.h" +#include "BlockHopper.h" +#include "BlockIce.h" #include "BlockLadder.h" +#include "BlockLeaves.h" #include "BlockLever.h" -#include "BlockSign.h" -#include "BlockCrops.h" -#include "BlockSugarcane.h" -#include "BlockFlower.h" -#include "BlockMushroom.h" -#include "BlockCactus.h" -#include "BlockStems.h" -#include "BlockGlowstone.h" -#include "BlockStone.h" #include "BlockMelon.h" -#include "BlockIce.h" -#include "BlockOre.h" -#include "BlockNote.h" -#include "BlockBed.h" -#include "BlockFarmland.h" +#include "BlockMushroom.h" #include "BlockMycelium.h" +#include "BlockNote.h" +#include "BlockOre.h" +#include "BlockPiston.h" #include "BlockRail.h" -#include "BlockGlass.h" -#include "BlockEnderchest.h" -#include "BlockFenceGate.h" -#include "BlockFlowerPot.h" -#include "BlockCauldron.h" -#include "BlockBrewingStand.h" -#include "BlockCobWeb.h" -#include "BlockDeadBush.h" -#include "BlockHopper.h" +#include "BlockRedstone.h" +#include "BlockRedstoneRepeater.h" +#include "BlockRedstoneTorch.h" +#include "BlockSand.h" +#include "BlockSapling.h" +#include "BlockSign.h" +#include "BlockSlab.h" +#include "BlockSnow.h" +#include "BlockStairs.h" +#include "BlockStems.h" +#include "BlockStone.h" +#include "BlockSugarcane.h" +#include "BlockTallGrass.h" +#include "BlockTorch.h" +#include "BlockVine.h" +#include "BlockWood.h" +#include "BlockWorkbench.h" -- cgit v1.2.3 From ca5561c395332b266b73b9cb56c50d1cc3c275c5 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 5 Aug 2013 15:24:23 +0200 Subject: cIniFile now reads .example.ini if not requested not to. As specified in #44, when the .ini file cannot be opened, a .example.ini is tried, and if it succeeds, it is written as .ini. This makes it easy to provide ini file templates. --- iniFile/iniFile.cpp | 729 ++++++++++++++++++++++++++++++------------------ iniFile/iniFile.h | 198 +++++++------ source/GroupManager.cpp | 7 +- source/Root.cpp | 17 +- 4 files changed, 569 insertions(+), 382 deletions(-) diff --git a/iniFile/iniFile.cpp b/iniFile/iniFile.cpp index 76f71284f..5ecbc5e06 100644 --- a/iniFile/iniFile.cpp +++ b/iniFile/iniFile.cpp @@ -12,17 +12,13 @@ ////////////////////////////////////////////////////////////////////// /* - !! MODIFIED BY FAKETRUTH !! +!! MODIFIED BY FAKETRUTH and xoft !! */ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules // C++ Includes -#include #include -#include - -using namespace std; // C Includes #include @@ -31,26 +27,32 @@ using namespace std; #include "iniFile.h" #if defined(WIN32) -#define iniEOL endl + #define iniEOL endl #else -#define iniEOL '\r' << endl + #define iniEOL '\r' << endl #endif #ifndef _WIN32 -#define sscanf_s(buffer, stringbuffer, ...) (sscanf(buffer, stringbuffer, __VA_ARGS__)) + #define sscanf_s(buffer, stringbuffer, ...) (sscanf(buffer, stringbuffer, __VA_ARGS__)) #endif +using namespace std; + -cIniFile::cIniFile( const string iniPath) +cIniFile::cIniFile(const string & a_Path) : + m_IsCaseInsensitive(true) { - Path( iniPath); - caseInsensitive = true; + Path(a_Path); } -bool cIniFile::ReadFile() + + + + +bool cIniFile::ReadFile(bool a_AllowExampleRedirect) { // Normally you would use ifstream, but the SGI CC compiler has // a few bugs with ifstream. So ... fstream used. @@ -58,12 +60,31 @@ bool cIniFile::ReadFile() string line; string keyname, valuename, value; string::size_type pLeft, pRight; + bool IsFromExampleRedirect = false; + + f.open((FILE_IO_PREFIX + m_Path).c_str(), ios::in); + if (f.fail()) + { + f.clear(); + if (a_AllowExampleRedirect) + { + // Retry with the .example.ini file instead of .ini: + string ExPath(m_Path.substr(0, m_Path.length() - 4)); + ExPath.append(".example.ini"); + f.open((FILE_IO_PREFIX + ExPath).c_str(), ios::in); + if (f.fail()) + { + return false; + } + IsFromExampleRedirect = true; + } + else + { + return false; + } + } - f.open( (FILE_IO_PREFIX + path).c_str(), ios::in); - if ( f.fail()) - return false; - - while (getline( f, line)) + while (getline(f, line)) { // To be compatible with Win32, check for existence of '\r'. // Win32 files have the '\r' and Unix files don't at the end of a line. @@ -75,49 +96,49 @@ bool cIniFile::ReadFile() { continue; } - if ( line[lineLength - 1] == '\r') + if (line[lineLength - 1] == '\r') { - line = line.substr( 0, lineLength - 1); + line = line.substr(0, lineLength - 1); } if (line.length() == 0) { continue; } - + // Check that the user hasn't opened a binary file by checking the first // character of each line! - if ( !isprint( line[0])) + if (!isprint(line[0])) { - printf( "Failing on char %d\n", line[0]); + printf("%s: Binary-check failed on char %d\n", __FUNCTION__, line[0]); f.close(); return false; } - if (( pLeft = line.find_first_of(";#[=")) == string::npos) + if ((pLeft = line.find_first_of(";#[=")) == string::npos) { continue; } - - switch ( line[pLeft]) + + switch (line[pLeft]) { case '[': { if ( ((pRight = line.find_last_of("]")) != string::npos) && (pRight > pLeft) - ) + ) { - keyname = line.substr( pLeft + 1, pRight - pLeft - 1); - AddKeyName( keyname); + keyname = line.substr(pLeft + 1, pRight - pLeft - 1); + AddKeyName(keyname); } break; } case '=': { - valuename = line.substr( 0, pLeft); - value = line.substr( pLeft + 1); - SetValue( keyname, valuename, value); + valuename = line.substr(0, pLeft); + value = line.substr(pLeft + 1); + SetValue(keyname, valuename, value); break; } @@ -126,11 +147,11 @@ bool cIniFile::ReadFile() { if (names.size() == 0) { - HeaderComment( line.substr( pLeft + 1)); + HeaderComment(line.substr(pLeft + 1)); } else { - KeyComment( keyname, line.substr( pLeft + 1)); + KeyComment(keyname, line.substr(pLeft + 1)); } break; } @@ -138,256 +159,315 @@ bool cIniFile::ReadFile() } // while (getline()) f.close(); - if (names.size() > 0) + if (names.size() == 0) { - return true; + return false; } - return false; + + if (IsFromExampleRedirect) + { + WriteFile(); + } + return true; } -bool cIniFile::WriteFile() +bool cIniFile::WriteFile(void) const { - unsigned commentID, keyID, valueID; - // Normally you would use ofstream, but the SGI CC compiler has - // a few bugs with ofstream. So ... fstream used. - fstream f; + unsigned commentID, keyID, valueID; + // Normally you would use ofstream, but the SGI CC compiler has + // a few bugs with ofstream. So ... fstream used. + fstream f; - f.open( (FILE_IO_PREFIX + path).c_str(), ios::out); - if ( f.fail()) - return false; + f.open((FILE_IO_PREFIX + m_Path).c_str(), ios::out); + if (f.fail()) + { + return false; + } - // Write header comments. - for ( commentID = 0; commentID < comments.size(); ++commentID) - f << ';' << comments[commentID] << iniEOL; - if ( comments.size()) - f << iniEOL; + // Write header comments. + for (commentID = 0; commentID < comments.size(); ++commentID) + { + f << ';' << comments[commentID] << iniEOL; + } + if (comments.size()) + { + f << iniEOL; + } - // Write keys and values. - for ( keyID = 0; keyID < keys.size(); ++keyID) { - f << '[' << names[keyID] << ']' << iniEOL; - // Comments. - for ( commentID = 0; commentID < keys[keyID].comments.size(); ++commentID) - f << ';' << keys[keyID].comments[commentID] << iniEOL; - // Values. - for ( valueID = 0; valueID < keys[keyID].names.size(); ++valueID) - f << keys[keyID].names[valueID] << '=' << keys[keyID].values[valueID] << iniEOL; - f << iniEOL; - } - f.close(); + // Write keys and values. + for (keyID = 0; keyID < keys.size(); ++keyID) + { + f << '[' << names[keyID] << ']' << iniEOL; + + // Comments. + for (commentID = 0; commentID < keys[keyID].comments.size(); ++commentID) + { + f << ';' << keys[keyID].comments[commentID] << iniEOL; + } + + // Values. + for (valueID = 0; valueID < keys[keyID].names.size(); ++valueID) + { + f << keys[keyID].names[valueID] << '=' << keys[keyID].values[valueID] << iniEOL; + } + f << iniEOL; + } + f.close(); - return true; + return true; } -long cIniFile::FindKey( const string & keyname) const +long cIniFile::FindKey(const string & a_KeyName) const { - for ( unsigned keyID = 0; keyID < names.size(); ++keyID) - if ( CheckCase( names[keyID]) == CheckCase( keyname)) - return long(keyID); - return noID; + string CaseKeyName = CheckCase(a_KeyName); + for (unsigned keyID = 0; keyID < names.size(); ++keyID) + { + if (CheckCase(names[keyID]) == CaseKeyName) + { + return long(keyID); + } + } + return noID; } -long cIniFile::FindValue( unsigned const keyID, const string & valuename) const +long cIniFile::FindValue(unsigned const keyID, const string & a_ValueName) const { - if ( !keys.size() || keyID >= keys.size()) - return noID; + if (!keys.size() || (keyID >= keys.size())) + { + return noID; + } - for ( unsigned valueID = 0; valueID < keys[keyID].names.size(); ++valueID) - if ( CheckCase( keys[keyID].names[valueID]) == CheckCase( valuename)) - return long(valueID); - return noID; + string CaseValueName = CheckCase(a_ValueName); + for (unsigned valueID = 0; valueID < keys[keyID].names.size(); ++valueID) + { + if (CheckCase(keys[keyID].names[valueID]) == CaseValueName) + { + return long(valueID); + } + } + return noID; } -unsigned cIniFile::AddKeyName( const string & keyname) +unsigned cIniFile::AddKeyName(const string & keyname) { - names.resize( names.size() + 1, keyname); - keys.resize( keys.size() + 1); - return names.size() - 1; + names.resize(names.size() + 1, keyname); + keys.resize(keys.size() + 1); + return names.size() - 1; } -string cIniFile::KeyName( unsigned const keyID) const +string cIniFile::KeyName(unsigned const keyID) const { - if ( keyID < names.size()) - return names[keyID]; - else - return ""; + if (keyID < names.size()) + { + return names[keyID]; + } + else + { + return ""; + } } -unsigned cIniFile::NumValues( unsigned const keyID) +unsigned cIniFile::NumValues(unsigned const keyID) { - if ( keyID < keys.size()) - return keys[keyID].names.size(); - return 0; + if (keyID < keys.size()) + { + return keys[keyID].names.size(); + } + return 0; } -unsigned cIniFile::NumValues( const string & keyname) +unsigned cIniFile::NumValues(const string & keyname) { - long keyID = FindKey( keyname); - if ( keyID == noID) - return 0; - return keys[keyID].names.size(); + long keyID = FindKey(keyname); + if (keyID == noID) + { + return 0; + } + return keys[keyID].names.size(); } -string cIniFile::ValueName( unsigned const keyID, unsigned const valueID) const +string cIniFile::ValueName(unsigned const keyID, unsigned const valueID) const { - if ( keyID < keys.size() && valueID < keys[keyID].names.size()) - return keys[keyID].names[valueID]; - return ""; + if (keyID < keys.size() && valueID < keys[keyID].names.size()) + { + return keys[keyID].names[valueID]; + } + return ""; } -string cIniFile::ValueName( const string & keyname, unsigned const valueID) const +string cIniFile::ValueName(const string & keyname, unsigned const valueID) const { - long keyID = FindKey( keyname); - if ( keyID == noID) - return ""; - return ValueName( keyID, valueID); + long keyID = FindKey(keyname); + if (keyID == noID) + { + return ""; + } + return ValueName(keyID, valueID); } -bool cIniFile::SetValue( unsigned const keyID, unsigned const valueID, const string & value) +bool cIniFile::SetValue(unsigned const keyID, unsigned const valueID, const string & value) { - if ( keyID < keys.size() && valueID < keys[keyID].names.size()) - keys[keyID].values[valueID] = value; - - return false; + if ((keyID < keys.size()) && (valueID < keys[keyID].names.size())) + { + keys[keyID].values[valueID] = value; + } + return false; } -bool cIniFile::SetValue( const string & keyname, const string & valuename, const string & value, bool const create) +bool cIniFile::SetValue(const string & keyname, const string & valuename, const string & value, bool const create) { - long keyID = FindKey( keyname); - if ( keyID == noID) { - if ( create) - keyID = long( AddKeyName( keyname)); - else - return false; - } + long keyID = FindKey(keyname); + if (keyID == noID) + { + if (create) + { + keyID = long(AddKeyName(keyname)); + } + else + { + return false; + } + } - long valueID = FindValue( unsigned(keyID), valuename); - if ( valueID == noID) { - if ( !create) - return false; - keys[keyID].names.resize( keys[keyID].names.size() + 1, valuename); - keys[keyID].values.resize( keys[keyID].values.size() + 1, value); - } else - { - if(!create) - keys[keyID].values[valueID] = value; - else - { - keys[keyID].names.resize( keys[keyID].names.size() + 1, valuename); - keys[keyID].values.resize( keys[keyID].values.size() + 1, value); - } - } + long valueID = FindValue(unsigned(keyID), valuename); + if (valueID == noID) + { + if (!create) + { + return false; + } + keys[keyID].names.resize(keys[keyID].names.size() + 1, valuename); + keys[keyID].values.resize(keys[keyID].values.size() + 1, value); + } + else + { + if (!create) + { + keys[keyID].values[valueID] = value; + } + else + { + keys[keyID].names.resize(keys[keyID].names.size() + 1, valuename); + keys[keyID].values.resize(keys[keyID].values.size() + 1, value); + } + } - return true; + return true; } -bool cIniFile::SetValueI( const string & keyname, const string & valuename, int const value, bool const create) +bool cIniFile::SetValueI(const string & keyname, const string & valuename, int const value, bool const create) { - AString Data; - Printf(Data, "%d", value); - return SetValue( keyname, valuename, Data, create); + AString Data; + Printf(Data, "%d", value); + return SetValue(keyname, valuename, Data, create); } -bool cIniFile::SetValueF( const string & keyname, const string & valuename, double const value, bool const create) +bool cIniFile::SetValueF(const string & keyname, const string & valuename, double const value, bool const create) { - AString Data; - Printf(Data, "%f", value); - return SetValue( keyname, valuename, Data, create); + AString Data; + Printf(Data, "%f", value); + return SetValue(keyname, valuename, Data, create); } -bool cIniFile::SetValueV( const string & keyname, const string & valuename, char *format, ...) +bool cIniFile::SetValueV(const string & keyname, const string & valuename, char * format, ...) { - va_list args; + va_list args; + va_start(args, format); - va_start( args, format); - - AString Data; - AppendVPrintf(Data, format, args); - va_end( args); - return SetValue( keyname, valuename, Data); + AString Data; + AppendVPrintf(Data, format, args); + va_end(args); + return SetValue(keyname, valuename, Data); } -string cIniFile::GetValue( unsigned const keyID, unsigned const valueID, const string & defValue) const +string cIniFile::GetValue(unsigned const keyID, unsigned const valueID, const string & defValue) const { - if ( keyID < keys.size() && valueID < keys[keyID].names.size()) - return keys[keyID].values[valueID]; - return defValue; + if ((keyID < keys.size()) && (valueID < keys[keyID].names.size())) + { + return keys[keyID].values[valueID]; + } + return defValue; } -string cIniFile::GetValue( const string & keyname, const string & valuename, const string & defValue) const +string cIniFile::GetValue(const string & keyname, const string & valuename, const string & defValue) const { - long keyID = FindKey( keyname); - if ( keyID == noID) - return defValue; + long keyID = FindKey(keyname); + if (keyID == noID) + { + return defValue; + } - long valueID = FindValue( unsigned(keyID), valuename); - if ( valueID == noID) - return defValue; + long valueID = FindValue(unsigned(keyID), valuename); + if (valueID == noID) + { + return defValue; + } - return keys[keyID].values[valueID]; + return keys[keyID].values[valueID]; } @@ -398,7 +478,7 @@ int cIniFile::GetValueI(const string & keyname, const string & valuename, int co { AString Data; Printf(Data, "%d", defValue); - return atoi( GetValue( keyname, valuename, Data).c_str()); + return atoi(GetValue(keyname, valuename, Data).c_str()); } @@ -407,9 +487,9 @@ int cIniFile::GetValueI(const string & keyname, const string & valuename, int co double cIniFile::GetValueF(const string & keyname, const string & valuename, double const defValue) const { - AString Data; - Printf(Data, "%f", defValue); - return atof( GetValue( keyname, valuename, Data).c_str()); + AString Data; + Printf(Data, "%f", defValue); + return atof(GetValue(keyname, valuename, Data).c_str()); } @@ -418,15 +498,15 @@ double cIniFile::GetValueF(const string & keyname, const string & valuename, dou AString cIniFile::GetValueSet(const AString & keyname, const AString & valuename, const AString & defValue) { - long keyID = FindKey( keyname); - if ( keyID == noID) + long keyID = FindKey(keyname); + if (keyID == noID) { SetValue(keyname, valuename, defValue); return defValue; } - long valueID = FindValue( unsigned(keyID), valuename); - if ( valueID == noID) + long valueID = FindValue(unsigned(keyID), valuename); + if (valueID == noID) { SetValue(keyname, valuename, defValue); return defValue; @@ -441,9 +521,9 @@ AString cIniFile::GetValueSet(const AString & keyname, const AString & valuename double cIniFile::GetValueSetF(const AString & keyname, const AString & valuename, const double defValue) { - AString Data; - Printf(Data, "%f", defValue); - return atof(GetValueSet(keyname, valuename, Data).c_str()); + AString Data; + Printf(Data, "%f", defValue); + return atof(GetValueSet(keyname, valuename, Data).c_str()); } @@ -454,182 +534,273 @@ int cIniFile::GetValueSetI(const AString & keyname, const AString & valuename, c { AString Data; Printf(Data, "%d", defValue); - return atoi(GetValueSet(keyname, valuename, Data).c_str()); + return atoi(GetValueSet(keyname, valuename, Data).c_str()); } -bool cIniFile::DeleteValueByID( const unsigned keyID, const unsigned valueID ) +bool cIniFile::DeleteValueByID(const unsigned keyID, const unsigned valueID) { - if ( keyID < keys.size() && valueID < keys[keyID].names.size()) + if (keyID < keys.size() && valueID < keys[keyID].names.size()) { // This looks strange, but is neccessary. vector::iterator npos = keys[keyID].names.begin() + valueID; vector::iterator vpos = keys[keyID].values.begin() + valueID; - keys[keyID].names.erase( npos, npos + 1); - keys[keyID].values.erase( vpos, vpos + 1); + keys[keyID].names.erase(npos, npos + 1); + keys[keyID].values.erase(vpos, vpos + 1); return true; } return false; } -bool cIniFile::DeleteValue( const string & keyname, const string & valuename) + + + + +bool cIniFile::DeleteValue(const string & keyname, const string & valuename) { - long keyID = FindKey( keyname); - if ( keyID == noID) - return false; + long keyID = FindKey(keyname); + if (keyID == noID) + { + return false; + } - long valueID = FindValue( unsigned(keyID), valuename); - if ( valueID == noID) - return false; + long valueID = FindValue(unsigned(keyID), valuename); + if (valueID == noID) + { + return false; + } - return DeleteValueByID( keyID, valueID ); + return DeleteValueByID(keyID, valueID); } -bool cIniFile::DeleteKey( const string & keyname) -{ - long keyID = FindKey( keyname); - if ( keyID == noID) - return false; - // Now hopefully this destroys the vector lists within keys. - // Looking at source, this should be the case using the destructor. - // If not, I may have to do it explicitly. Memory leak check should tell. - // memleak_test.cpp shows that the following not required. - //keys[keyID].names.clear(); - //keys[keyID].values.clear(); - vector::iterator npos = names.begin() + keyID; - vector::iterator kpos = keys.begin() + keyID; - names.erase( npos, npos + 1); - keys.erase( kpos, kpos + 1); - return true; + +bool cIniFile::DeleteKey(const string & keyname) +{ + long keyID = FindKey(keyname); + if (keyID == noID) + { + return false; + } + + vector::iterator npos = names.begin() + keyID; + vector::iterator kpos = keys.begin() + keyID; + names.erase(npos, npos + 1); + keys.erase(kpos, kpos + 1); + + return true; } -void cIniFile::Erase() + + + + +void cIniFile::Clear(void) { - // This loop not needed. The vector<> destructor seems to do - // all the work itself. memleak_test.cpp shows this. - //for ( unsigned i = 0; i < keys.size(); ++i) { - // keys[i].names.clear(); - // keys[i].values.clear(); - //} - names.clear(); - keys.clear(); - comments.clear(); + names.clear(); + keys.clear(); + comments.clear(); } -void cIniFile::HeaderComment( const string & comment) + + + + +void cIniFile::HeaderComment(const string & comment) { - comments.resize( comments.size() + 1, comment); + comments.push_back(comment); + // comments.resize(comments.size() + 1, comment); } -string cIniFile::HeaderComment( unsigned const commentID) const + + + + +string cIniFile::HeaderComment(unsigned const commentID) const { - if ( commentID < comments.size()) - return comments[commentID]; - return ""; + if (commentID < comments.size()) + { + return comments[commentID]; + } + return ""; } -bool cIniFile::DeleteHeaderComment( unsigned commentID) + + + + +bool cIniFile::DeleteHeaderComment(unsigned commentID) { - if ( commentID < comments.size()) { - vector::iterator cpos = comments.begin() + commentID; - comments.erase( cpos, cpos + 1); - return true; - } - return false; + if (commentID < comments.size()) + { + vector::iterator cpos = comments.begin() + commentID; + comments.erase(cpos, cpos + 1); + return true; + } + return false; } -unsigned cIniFile::NumKeyComments( unsigned const keyID) const + + + + +unsigned cIniFile::NumKeyComments(unsigned const keyID) const { - if ( keyID < keys.size()) - return keys[keyID].comments.size(); - return 0; + if (keyID < keys.size()) + { + return keys[keyID].comments.size(); + } + return 0; } -unsigned cIniFile::NumKeyComments( const string & keyname) const + + + + +unsigned cIniFile::NumKeyComments(const string & keyname) const { - long keyID = FindKey( keyname); - if ( keyID == noID) - return 0; - return keys[keyID].comments.size(); + long keyID = FindKey(keyname); + if (keyID == noID) + return 0; + return keys[keyID].comments.size(); } -bool cIniFile::KeyComment( unsigned const keyID, const string & comment) + + + + +bool cIniFile::KeyComment(unsigned const keyID, const string & comment) { - if ( keyID < keys.size()) { - keys[keyID].comments.resize( keys[keyID].comments.size() + 1, comment); - return true; - } - return false; + if (keyID < keys.size()) + { + keys[keyID].comments.resize(keys[keyID].comments.size() + 1, comment); + return true; + } + return false; } -bool cIniFile::KeyComment( const string & keyname, const string & comment) + + + + +bool cIniFile::KeyComment(const string & keyname, const string & comment) { - long keyID = FindKey( keyname); - if ( keyID == noID) - return false; - return KeyComment( unsigned(keyID), comment); + long keyID = FindKey(keyname); + if (keyID == noID) + { + return false; + } + return KeyComment(unsigned(keyID), comment); } -string cIniFile::KeyComment( unsigned const keyID, unsigned const commentID) const + + + + +string cIniFile::KeyComment(unsigned const keyID, unsigned const commentID) const { - if ( keyID < keys.size() && commentID < keys[keyID].comments.size()) - return keys[keyID].comments[commentID]; - return ""; + if ((keyID < keys.size()) && (commentID < keys[keyID].comments.size())) + { + return keys[keyID].comments[commentID]; + } + return ""; } -string cIniFile::KeyComment( const string & keyname, unsigned const commentID) const + + + + +string cIniFile::KeyComment(const string & keyname, unsigned const commentID) const { - long keyID = FindKey( keyname); - if ( keyID == noID) - return ""; - return KeyComment( unsigned(keyID), commentID); + long keyID = FindKey(keyname); + if (keyID == noID) + { + return ""; + } + return KeyComment(unsigned(keyID), commentID); } -bool cIniFile::DeleteKeyComment( unsigned const keyID, unsigned const commentID) + + + + +bool cIniFile::DeleteKeyComment(unsigned const keyID, unsigned const commentID) { - if ( keyID < keys.size() && commentID < keys[keyID].comments.size()) { - vector::iterator cpos = keys[keyID].comments.begin() + commentID; - keys[keyID].comments.erase( cpos, cpos + 1); - return true; - } - return false; + if ((keyID < keys.size()) && (commentID < keys[keyID].comments.size())) + { + vector::iterator cpos = keys[keyID].comments.begin() + commentID; + keys[keyID].comments.erase(cpos, cpos + 1); + return true; + } + return false; } -bool cIniFile::DeleteKeyComment( const string & keyname, unsigned const commentID) + + + + +bool cIniFile::DeleteKeyComment(const string & keyname, unsigned const commentID) { - long keyID = FindKey( keyname); - if ( keyID == noID) - return false; - return DeleteKeyComment( unsigned(keyID), commentID); + long keyID = FindKey(keyname); + if (keyID == noID) + { + return false; + } + return DeleteKeyComment(unsigned(keyID), commentID); } -bool cIniFile::DeleteKeyComments( unsigned const keyID) + + + + +bool cIniFile::DeleteKeyComments(unsigned const keyID) { - if ( keyID < keys.size()) { - keys[keyID].comments.clear(); - return true; - } - return false; + if (keyID < keys.size()) + { + keys[keyID].comments.clear(); + return true; + } + return false; } -bool cIniFile::DeleteKeyComments( const string & keyname) + + + + +bool cIniFile::DeleteKeyComments(const string & keyname) { - long keyID = FindKey( keyname); - if ( keyID == noID) - return false; - return DeleteKeyComments( unsigned(keyID)); + long keyID = FindKey(keyname); + if (keyID == noID) + { + return false; + } + return DeleteKeyComments(unsigned(keyID)); } -string cIniFile::CheckCase( string s) const + + + + +string cIniFile::CheckCase(const string & s) const { - if ( caseInsensitive) - for ( string::size_type i = 0; i < s.length(); ++i) - s[i] = (char)tolower(s[i]); - return s; + if (!m_IsCaseInsensitive) + { + return s; + } + string res(s); + size_t len = res.length(); + for (size_t i = 0; i < len; i++) + { + res[i] = tolower(res[i]); + } + return res; } + + + + diff --git a/iniFile/iniFile.h b/iniFile/iniFile.h index 1afc404e3..ebbcc5081 100644 --- a/iniFile/iniFile.h +++ b/iniFile/iniFile.h @@ -30,135 +30,155 @@ -class cIniFile // tolua_export -{ // tolua_export +// tolua_begin + +class cIniFile +{ private: - bool caseInsensitive; - std::string path; - struct key { + bool m_IsCaseInsensitive; + std::string m_Path; + + struct key + { std::vector names; std::vector values; std::vector comments; - }; - std::vector keys; - std::vector names; + } ; + + std::vector keys; + std::vector names; std::vector comments; - std::string CheckCase( std::string s) const; + + /// If the object is case-insensitive, returns s as lowercase; otherwise returns s as-is + std::string CheckCase(const std::string & s) const; public: - enum errors{ noID = -1}; // tolua_export - cIniFile( const std::string iniPath = ""); // tolua_export - virtual ~cIniFile() {} + enum errors + { + noID = -1, + }; + + /// Creates a new instance; sets m_Path to a_Path, but doesn't read the file + cIniFile(const std::string & a_Path = ""); // Sets whether or not keynames and valuenames should be case sensitive. // The default is case insensitive. - void CaseSensitive() {caseInsensitive = false;} // tolua_export - void CaseInsensitive() {caseInsensitive = true;} // tolua_export + void CaseSensitive (void) { m_IsCaseInsensitive = false; } + void CaseInsensitive(void) { m_IsCaseInsensitive = true; } // Sets path of ini file to read and write from. - void Path(const std::string & newPath) {path = newPath;} // tolua_export - std::string Path() const {return path;} // tolua_export - void SetPath(const std::string & newPath) {Path( newPath);} // tolua_export + void Path(const std::string & newPath) {m_Path = newPath;} + const std::string & Path(void) const {return m_Path;} + void SetPath(const std::string & newPath) {Path(newPath);} - // Reads ini file specified using path. - // Returns true if successful, false otherwise. - bool ReadFile(); // tolua_export + /** Reads the ini file specified in m_Path + If the file doesn't exist and a_AllowExampleRedirect is true, tries to read .example.ini, and + writes its contents as .ini, if successful. + Returns true if successful, false otherwise. + */ + bool ReadFile(bool a_AllowExampleRedirect = true); - // Writes data stored in class to ini file. - bool WriteFile(); // tolua_export + /// Writes data stored in class to ini file specified in m_Path + bool WriteFile(void) const; - // Deletes all stored ini data. - void Erase(); // tolua_export - void Clear() {Erase();} // tolua_export - void Reset() {Erase();} // tolua_export + /// Deletes all stored ini data (but doesn't touch the file) + void Clear(void); + void Reset(void) { Clear(); } + void Erase(void) { Clear(); } // OBSOLETE, this name is misguiding and will be removed from the interface - // Returns index of specified key, or noID if not found. - long FindKey( const std::string & keyname) const; // tolua_export + /// Returns index of specified key, or noID if not found + long FindKey(const std::string & keyname) const; - // Returns index of specified value, in the specified key, or noID if not found. - long FindValue( const unsigned keyID, const std::string & valuename) const; // tolua_export + /// Returns index of specified value, in the specified key, or noID if not found + long FindValue(const unsigned keyID, const std::string & valuename) const; - // Returns number of keys currently in the ini. - unsigned NumKeys() const {return names.size();} // tolua_export - unsigned GetNumKeys() const {return NumKeys();} // tolua_export + /// Returns number of keys currently in the ini + unsigned NumKeys (void) const {return names.size();} + unsigned GetNumKeys(void) const {return NumKeys();} - // Add a key name. - unsigned AddKeyName( const std::string & keyname); // tolua_export + /// Add a key name + unsigned AddKeyName(const std::string & keyname); // Returns key names by index. - std::string KeyName( const unsigned keyID) const; // tolua_export - std::string GetKeyName( const unsigned keyID) const {return KeyName(keyID);} // tolua_export + std::string KeyName(const unsigned keyID) const; + std::string GetKeyName(const unsigned keyID) const {return KeyName(keyID);} // Returns number of values stored for specified key. - unsigned NumValues( const std::string & keyname); // tolua_export - unsigned GetNumValues( const std::string & keyname) {return NumValues( keyname);} // tolua_export - unsigned NumValues( const unsigned keyID); // tolua_export - unsigned GetNumValues( const unsigned keyID) {return NumValues( keyID);} // tolua_export + unsigned NumValues (const std::string & keyname); + unsigned GetNumValues(const std::string & keyname) {return NumValues(keyname);} + unsigned NumValues (const unsigned keyID); + unsigned GetNumValues(const unsigned keyID) {return NumValues(keyID);} // Returns value name by index for a given keyname or keyID. - std::string ValueName( const std::string & keyname, const unsigned valueID) const; // tolua_export - std::string GetValueName( const std::string & keyname, const unsigned valueID) const { // tolua_export - return ValueName( keyname, valueID); - } // tolua_export - std::string ValueName( const unsigned keyID, const unsigned valueID) const; // tolua_export - std::string GetValueName( const unsigned keyID, const unsigned valueID) const { // tolua_export - return ValueName( keyID, valueID); - } // tolua_export + std::string ValueName( const std::string & keyname, const unsigned valueID) const; + std::string GetValueName( const std::string & keyname, const unsigned valueID) const + { + return ValueName(keyname, valueID); + } + std::string ValueName (const unsigned keyID, const unsigned valueID) const; + std::string GetValueName(const unsigned keyID, const unsigned valueID) const + { + return ValueName(keyID, valueID); + } // Gets value of [keyname] valuename =. // Overloaded to return string, int, and double. // Returns defValue if key/value not found. - AString GetValue (const AString & keyname, const AString & valuename, const AString & defValue = "") const; // tolua_export - AString GetValue (const unsigned keyID, const unsigned valueID, const AString & defValue = "") const; // tolua_export - double GetValueF(const AString & keyname, const AString & valuename, const double defValue = 0) const; // tolua_export - int GetValueI(const AString & keyname, const AString & valuename, const int defValue = 0) const; // tolua_export - bool GetValueB(const AString & keyname, const AString & valuename, const bool defValue = false) const { // tolua_export - return ( GetValueI( keyname, valuename, int( defValue)) > 0); - } // tolua_export + AString GetValue (const AString & keyname, const AString & valuename, const AString & defValue = "") const; + AString GetValue (const unsigned keyID, const unsigned valueID, const AString & defValue = "") const; + double GetValueF(const AString & keyname, const AString & valuename, const double defValue = 0) const; + int GetValueI(const AString & keyname, const AString & valuename, const int defValue = 0) const; + bool GetValueB(const AString & keyname, const AString & valuename, const bool defValue = false) const + { + return (GetValueI(keyname, valuename, int(defValue)) > 0); + } // Gets the value; if not found, write the default to the INI file - AString GetValueSet (const AString & keyname, const AString & valuename, const AString & defValue = ""); // tolua_export - double GetValueSetF(const AString & keyname, const AString & valuename, const double defValue = 0.0); // tolua_export - int GetValueSetI(const AString & keyname, const AString & valuename, const int defValue = 0); // tolua_export - bool GetValueSetB(const AString & keyname, const AString & valuename, const bool defValue = false) { // tolua_export + AString GetValueSet (const AString & keyname, const AString & valuename, const AString & defValue = ""); + double GetValueSetF(const AString & keyname, const AString & valuename, const double defValue = 0.0); + int GetValueSetI(const AString & keyname, const AString & valuename, const int defValue = 0); + bool GetValueSetB(const AString & keyname, const AString & valuename, const bool defValue = false) + { return (GetValueSetI(keyname, valuename, defValue ? 1 : 0) > 0); - } // tolua_export + } // Sets value of [keyname] valuename =. // Specify the optional paramter as false (0) if you do not want it to create // the key if it doesn't exist. Returns true if data entered, false otherwise. // Overloaded to accept string, int, and double. - bool SetValue( const unsigned keyID, const unsigned valueID, const std::string & value); // tolua_export - bool SetValue( const std::string & keyname, const std::string & valuename, const std::string & value, const bool create = true); // tolua_export - bool SetValueI( const std::string & keyname, const std::string & valuename, const int value, const bool create = true); // tolua_export - bool SetValueB( const std::string & keyname, const std::string & valuename, const bool value, const bool create = true) { // tolua_export + bool SetValue( const unsigned keyID, const unsigned valueID, const std::string & value); + bool SetValue( const std::string & keyname, const std::string & valuename, const std::string & value, const bool create = true); + bool SetValueI( const std::string & keyname, const std::string & valuename, const int value, const bool create = true); + bool SetValueB( const std::string & keyname, const std::string & valuename, const bool value, const bool create = true) + { return SetValueI( keyname, valuename, int(value), create); - } // tolua_export - bool SetValueF( const std::string & keyname, const std::string & valuename, const double value, const bool create = true); // tolua_export + } + bool SetValueF( const std::string & keyname, const std::string & valuename, const double value, const bool create = true); bool SetValueV( const std::string & keyname, const std::string & valuename, char *format, ...); // Deletes specified value. // Returns true if value existed and deleted, false otherwise. - bool DeleteValueByID( const unsigned keyID, const unsigned valueID ); // tolua_export - bool DeleteValue( const std::string & keyname, const std::string & valuename); // tolua_export + bool DeleteValueByID( const unsigned keyID, const unsigned valueID ); + bool DeleteValue( const std::string & keyname, const std::string & valuename); // Deletes specified key and all values contained within. // Returns true if key existed and deleted, false otherwise. - bool DeleteKey(const std::string & keyname); // tolua_export + bool DeleteKey(const std::string & keyname); // Header comment functions. // Header comments are those comments before the first key. // // Number of header comments. - unsigned NumHeaderComments() {return comments.size();} // tolua_export + unsigned NumHeaderComments(void) {return comments.size();} // Add a header comment. - void HeaderComment( const std::string & comment); // tolua_export + void HeaderComment(const std::string & comment); // Return a header comment. - std::string HeaderComment( const unsigned commentID) const; // tolua_export + std::string HeaderComment(const unsigned commentID) const; // Delete a header comment. - bool DeleteHeaderComment( unsigned commentID); // tolua_export + bool DeleteHeaderComment(unsigned commentID); // Delete all header comments. - void DeleteHeaderComments() {comments.clear();} // tolua_export + void DeleteHeaderComments(void) {comments.clear();} + // Key comment functions. // Key comments are those comments within a key. Any comments @@ -167,20 +187,26 @@ public: // the CIniFile::WriteFile() is called. // // Number of key comments. - unsigned NumKeyComments( const unsigned keyID) const; // tolua_export - unsigned NumKeyComments( const std::string & keyname) const; // tolua_export + unsigned NumKeyComments( const unsigned keyID) const; + unsigned NumKeyComments( const std::string & keyname) const; + // Add a key comment. - bool KeyComment( const unsigned keyID, const std::string & comment); // tolua_export - bool KeyComment( const std::string & keyname, const std::string & comment); // tolua_export + bool KeyComment(const unsigned keyID, const std::string & comment); + bool KeyComment(const std::string & keyname, const std::string & comment); + // Return a key comment. - std::string KeyComment( const unsigned keyID, const unsigned commentID) const; // tolua_export - std::string KeyComment( const std::string & keyname, const unsigned commentID) const; // tolua_export + std::string KeyComment(const unsigned keyID, const unsigned commentID) const; + std::string KeyComment(const std::string & keyname, const unsigned commentID) const; + // Delete a key comment. - bool DeleteKeyComment( const unsigned keyID, const unsigned commentID); // tolua_export - bool DeleteKeyComment( const std::string & keyname, const unsigned commentID); // tolua_export + bool DeleteKeyComment(const unsigned keyID, const unsigned commentID); + bool DeleteKeyComment(const std::string & keyname, const unsigned commentID); + // Delete all comments for a key. - bool DeleteKeyComments( const unsigned keyID); // tolua_export - bool DeleteKeyComments( const std::string & keyname); // tolua_export -}; // tolua_export + bool DeleteKeyComments(const unsigned keyID); + bool DeleteKeyComments(const std::string & keyname); +}; + +// tolua_end #endif diff --git a/source/GroupManager.cpp b/source/GroupManager.cpp index 396ad2e2f..cef32dd58 100644 --- a/source/GroupManager.cpp +++ b/source/GroupManager.cpp @@ -47,11 +47,8 @@ cGroupManager::cGroupManager() cIniFile IniFile("groups.ini"); if (!IniFile.ReadFile()) { - LOGINFO("groups.ini inaccessible, using groups.example.ini for defaults!"); - IniFile.Path("groups.example.ini"); - IniFile.ReadFile(); - IniFile.Path("groups.ini"); - IniFile.WriteFile(); + LOGWARNING("groups.ini inaccessible, no groups are defined"); + return; } unsigned int NumKeys = IniFile.GetNumKeys(); diff --git a/source/Root.cpp b/source/Root.cpp index 59242c60d..f12ccc832 100644 --- a/source/Root.cpp +++ b/source/Root.cpp @@ -112,10 +112,7 @@ void cRoot::Start(void) cIniFile IniFile("settings.ini"); if (!IniFile.ReadFile()) { - LOGINFO("settings.ini inaccessible, using settings.example.ini for defaults!"); - IniFile.Path("settings.example.ini"); - IniFile.ReadFile(); - IniFile.Path("settings.ini"); + LOGWARNING("settings.ini inaccessible, all settings are reset to default values"); } m_PrimaryServerVersion = IniFile.GetValueI("Server", "PrimaryServerVersion", 0); if (m_PrimaryServerVersion == 0) @@ -139,23 +136,19 @@ void cRoot::Start(void) cIniFile WebIniFile("webadmin.ini"); if (!WebIniFile.ReadFile()) { - LOGINFO("webadmin.ini inaccessible, using webadmin.example.ini for defaults!"); - WebIniFile.Path("webadmin.example.ini"); - WebIniFile.ReadFile(); - WebIniFile.Path("webadmin.ini"); - WebIniFile.WriteFile(); + LOGWARNING("webadmin.ini inaccessible, wabadmin is disabled"); } - if (WebIniFile.GetValueB("WebAdmin", "Enabled", false )) + if (WebIniFile.GetValueB("WebAdmin", "Enabled", false)) { LOG("Creating WebAdmin..."); m_WebAdmin = new cWebAdmin(8080); } LOG("Loading settings..."); - m_GroupManager = new cGroupManager(); + m_GroupManager = new cGroupManager(); m_CraftingRecipes = new cCraftingRecipes; - m_FurnaceRecipe = new cFurnaceRecipe(); + m_FurnaceRecipe = new cFurnaceRecipe(); LOG("Loading worlds..."); LoadWorlds(); -- cgit v1.2.3 From 3b418c76956bf44ad13e040ded01cf674336467c Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 5 Aug 2013 15:26:43 +0200 Subject: Alpha-sorted the manual bindings' functions. --- source/ManualBindings.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/source/ManualBindings.cpp b/source/ManualBindings.cpp index 7a13d94c0..f9ff44382 100644 --- a/source/ManualBindings.cpp +++ b/source/ManualBindings.cpp @@ -1372,24 +1372,24 @@ void ManualBindings::Bind(lua_State * tolua_S) tolua_function(tolua_S, "LOGERROR", tolua_LOGERROR); tolua_beginmodule(tolua_S, "cRoot"); - tolua_function(tolua_S, "ForEachWorld", tolua_ForEach); tolua_function(tolua_S, "FindAndDoWithPlayer", tolua_DoWith ); tolua_function(tolua_S, "ForEachPlayer", tolua_ForEach); + tolua_function(tolua_S, "ForEachWorld", tolua_ForEach); tolua_endmodule(tolua_S); tolua_beginmodule(tolua_S, "cWorld"); - tolua_function(tolua_S, "ForEachPlayer", tolua_ForEach); - tolua_function(tolua_S, "ForEachEntity", tolua_ForEach); - tolua_function(tolua_S, "ForEachEntityInChunk", tolua_ForEachInChunk); - tolua_function(tolua_S, "ForEachChestInChunk", tolua_ForEachInChunk); - tolua_function(tolua_S, "ForEachFurnaceInChunk", tolua_ForEachInChunk); - tolua_function(tolua_S, "DoWithPlayer", tolua_DoWith); - tolua_function(tolua_S, "FindAndDoWithPlayer", tolua_DoWith); tolua_function(tolua_S, "DoWithChestAt", tolua_DoWithXYZ); tolua_function(tolua_S, "DoWithDispenserAt", tolua_DoWithXYZ); - tolua_function(tolua_S, "DoWithDropperAt", tolua_DoWithXYZ); tolua_function(tolua_S, "DoWithDropSpenserAt", tolua_DoWithXYZ); + tolua_function(tolua_S, "DoWithDropperAt", tolua_DoWithXYZ); tolua_function(tolua_S, "DoWithFurnaceAt", tolua_DoWithXYZ); + tolua_function(tolua_S, "DoWithPlayer", tolua_DoWith); + tolua_function(tolua_S, "FindAndDoWithPlayer", tolua_DoWith); + tolua_function(tolua_S, "ForEachChestInChunk", tolua_ForEachInChunk); + tolua_function(tolua_S, "ForEachEntity", tolua_ForEach); + tolua_function(tolua_S, "ForEachEntityInChunk", tolua_ForEachInChunk); + tolua_function(tolua_S, "ForEachFurnaceInChunk", tolua_ForEachInChunk); + tolua_function(tolua_S, "ForEachPlayer", tolua_ForEach); tolua_function(tolua_S, "SetSignLines", tolua_cWorld_SetSignLines); tolua_function(tolua_S, "UpdateSign", tolua_cWorld_SetSignLines); tolua_endmodule(tolua_S); @@ -1399,11 +1399,11 @@ void ManualBindings::Bind(lua_State * tolua_S) tolua_endmodule(tolua_S); tolua_beginmodule(tolua_S, "cPluginManager"); - tolua_function(tolua_S, "GetAllPlugins", tolua_cPluginManager_GetAllPlugins); tolua_function(tolua_S, "BindCommand", tolua_cPluginManager_BindCommand); tolua_function(tolua_S, "BindConsoleCommand", tolua_cPluginManager_BindConsoleCommand); tolua_function(tolua_S, "ForEachCommand", tolua_cPluginManager_ForEachCommand); tolua_function(tolua_S, "ForEachConsoleCommand", tolua_cPluginManager_ForEachConsoleCommand); + tolua_function(tolua_S, "GetAllPlugins", tolua_cPluginManager_GetAllPlugins); tolua_endmodule(tolua_S); tolua_beginmodule(tolua_S, "cPlayer"); @@ -1418,17 +1418,17 @@ void ManualBindings::Bind(lua_State * tolua_S) tolua_endmodule(tolua_S); tolua_beginmodule(tolua_S, "cPlugin_NewLua"); - tolua_function(tolua_S, "AddWebTab", tolua_cPlugin_NewLua_AddWebTab); tolua_function(tolua_S, "AddTab", tolua_cPlugin_NewLua_AddTab); + tolua_function(tolua_S, "AddWebTab", tolua_cPlugin_NewLua_AddWebTab); tolua_endmodule(tolua_S); tolua_cclass(tolua_S,"HTTPRequest","HTTPRequest","",NULL); tolua_beginmodule(tolua_S,"HTTPRequest"); // tolua_variable(tolua_S,"Method",tolua_get_HTTPRequest_Method,tolua_set_HTTPRequest_Method); // tolua_variable(tolua_S,"Path",tolua_get_HTTPRequest_Path,tolua_set_HTTPRequest_Path); + tolua_variable(tolua_S,"FormData",tolua_get_HTTPRequest_FormData,0); tolua_variable(tolua_S,"Params",tolua_get_HTTPRequest_Params,0); tolua_variable(tolua_S,"PostParams",tolua_get_HTTPRequest_PostParams,0); - tolua_variable(tolua_S,"FormData",tolua_get_HTTPRequest_FormData,0); tolua_endmodule(tolua_S); tolua_beginmodule(tolua_S, "cWebAdmin"); @@ -1440,8 +1440,8 @@ void ManualBindings::Bind(lua_State * tolua_S) tolua_endmodule(tolua_S); tolua_beginmodule(tolua_S, "cClientHandle"); - tolua_constant(tolua_S, "MIN_VIEW_DISTANCE", cClientHandle::MIN_VIEW_DISTANCE); tolua_constant(tolua_S, "MAX_VIEW_DISTANCE", cClientHandle::MAX_VIEW_DISTANCE); + tolua_constant(tolua_S, "MIN_VIEW_DISTANCE", cClientHandle::MIN_VIEW_DISTANCE); tolua_endmodule(tolua_S); tolua_beginmodule(tolua_S, "cItemGrid"); -- cgit v1.2.3 From d83e4369d3894d4b6f97cb91bed481eb1a05f189 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 5 Aug 2013 15:41:24 +0200 Subject: Exported cWorld:DoWithEntityByID() to Lua API --- source/ManualBindings.cpp | 495 +++++++++++++++++++++++++++------------------- source/World.h | 2 +- 2 files changed, 294 insertions(+), 203 deletions(-) diff --git a/source/ManualBindings.cpp b/source/ManualBindings.cpp index f9ff44382..7e3417ceb 100644 --- a/source/ManualBindings.cpp +++ b/source/ManualBindings.cpp @@ -169,7 +169,7 @@ cPlugin_NewLua * GetLuaPlugin(lua_State * L) - + template< class Ty1, class Ty2, @@ -177,87 +177,177 @@ template< > static int tolua_DoWith(lua_State* tolua_S) { - int NumArgs = lua_gettop(tolua_S) - 1; /* This includes 'self' */ - if ((NumArgs != 2) && (NumArgs != 3)) + int NumArgs = lua_gettop(tolua_S) - 1; /* This includes 'self' */ + if ((NumArgs != 2) && (NumArgs != 3)) { return lua_do_error(tolua_S, "Error in function call '#funcname#': Requires 2 or 3 arguments, got %i", NumArgs); - } + } - Ty1 * self = (Ty1 *) tolua_tousertype(tolua_S, 1, 0); + Ty1 * self = (Ty1 *) tolua_tousertype(tolua_S, 1, 0); - const char * ItemName = tolua_tocppstring(tolua_S, 2, ""); - if ((ItemName == NULL) || (ItemName[0] == 0)) - { + const char * ItemName = tolua_tocppstring(tolua_S, 2, ""); + if ((ItemName == NULL) || (ItemName[0] == 0)) + { return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a non-empty string for parameter #1", NumArgs); - } - if (!lua_isfunction( tolua_S, 3)) - { + } + if (!lua_isfunction( tolua_S, 3)) + { return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a function for parameter #2", NumArgs); - } - - /* luaL_ref gets reference to value on top of the stack, the table is the last argument and therefore on the top */ - int TableRef = LUA_REFNIL; - if (NumArgs == 3) - { - TableRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX); - if (TableRef == LUA_REFNIL) - { + } + + /* luaL_ref gets reference to value on top of the stack, the table is the last argument and therefore on the top */ + int TableRef = LUA_REFNIL; + if (NumArgs == 3) + { + TableRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX); + if (TableRef == LUA_REFNIL) + { return lua_do_error(tolua_S, "Error in function call '#funcname#': Could not get value reference of parameter #3", NumArgs); - } - } + } + } - /* table value is popped, and now function is on top of the stack */ - int FuncRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX); - if (FuncRef == LUA_REFNIL) - { + /* table value is popped, and now function is on top of the stack */ + int FuncRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX); + if (FuncRef == LUA_REFNIL) + { return lua_do_error(tolua_S, "Error in function call '#funcname#': Could not get function reference of parameter #2", NumArgs); - } + } - class cLuaCallback : public cItemCallback + class cLuaCallback : public cItemCallback { - public: - cLuaCallback(lua_State* a_LuaState, int a_FuncRef, int a_TableRef) - : LuaState( a_LuaState ) - , FuncRef( a_FuncRef ) - , TableRef( a_TableRef ) - {} + public: + cLuaCallback(lua_State* a_LuaState, int a_FuncRef, int a_TableRef) + : LuaState( a_LuaState ) + , FuncRef( a_FuncRef ) + , TableRef( a_TableRef ) + {} - private: - virtual bool Item(Ty2 * a_Item) override - { - lua_rawgeti( LuaState, LUA_REGISTRYINDEX, FuncRef); /* Push function reference */ + private: + virtual bool Item(Ty2 * a_Item) override + { + lua_rawgeti( LuaState, LUA_REGISTRYINDEX, FuncRef); /* Push function reference */ tolua_pushusertype(LuaState, a_Item, Ty2::GetClassStatic()); - if (TableRef != LUA_REFNIL) - { - lua_rawgeti( LuaState, LUA_REGISTRYINDEX, TableRef); /* Push table reference */ - } + if (TableRef != LUA_REFNIL) + { + lua_rawgeti( LuaState, LUA_REGISTRYINDEX, TableRef); /* Push table reference */ + } - int s = lua_pcall(LuaState, (TableRef == LUA_REFNIL ? 1 : 2), 1, 0); + int s = lua_pcall(LuaState, (TableRef == LUA_REFNIL ? 1 : 2), 1, 0); if (report_errors(LuaState, s)) { return true; // Abort enumeration } - if (lua_isboolean(LuaState, -1)) - { - return (tolua_toboolean(LuaState, -1, 0) > 0); - } - return false; /* Continue enumeration */ - } - lua_State * LuaState; - int FuncRef; - int TableRef; - } Callback(tolua_S, FuncRef, TableRef); + if (lua_isboolean(LuaState, -1)) + { + return (tolua_toboolean(LuaState, -1, 0) > 0); + } + return false; /* Continue enumeration */ + } + lua_State * LuaState; + int FuncRef; + int TableRef; + } Callback(tolua_S, FuncRef, TableRef); bool bRetVal = (self->*Func1)(ItemName, Callback); - /* Unreference the values again, so the LUA_REGISTRYINDEX can make place for other references */ - luaL_unref(tolua_S, LUA_REGISTRYINDEX, TableRef); - luaL_unref(tolua_S, LUA_REGISTRYINDEX, FuncRef); + /* Unreference the values again, so the LUA_REGISTRYINDEX can make place for other references */ + luaL_unref(tolua_S, LUA_REGISTRYINDEX, TableRef); + luaL_unref(tolua_S, LUA_REGISTRYINDEX, FuncRef); - /* Push return value on stack */ - tolua_pushboolean(tolua_S, bRetVal ); - return 1; + /* Push return value on stack */ + tolua_pushboolean(tolua_S, bRetVal ); + return 1; +} + + + + + +template< + class Ty1, + class Ty2, + bool (Ty1::*Func1)(int, cItemCallback &) +> +static int tolua_DoWithID(lua_State* tolua_S) +{ + int NumArgs = lua_gettop(tolua_S) - 1; /* This includes 'self' */ + if ((NumArgs != 2) && (NumArgs != 3)) + { + return lua_do_error(tolua_S, "Error in function call '#funcname#': Requires 2 or 3 arguments, got %i", NumArgs); + } + + Ty1 * self = (Ty1 *)tolua_tousertype(tolua_S, 1, 0); + + int ItemID = (int)tolua_tonumber(tolua_S, 2, 0); + if (!lua_isfunction(tolua_S, 3)) + { + return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a function for parameter #2", NumArgs); + } + + /* luaL_ref gets reference to value on top of the stack, the table is the last argument and therefore on the top */ + int TableRef = LUA_REFNIL; + if (NumArgs == 3) + { + TableRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX); + if (TableRef == LUA_REFNIL) + { + return lua_do_error(tolua_S, "Error in function call '#funcname#': Could not get value reference of parameter #3", NumArgs); + } + } + + /* table value is popped, and now function is on top of the stack */ + int FuncRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX); + if (FuncRef == LUA_REFNIL) + { + return lua_do_error(tolua_S, "Error in function call '#funcname#': Could not get function reference of parameter #2", NumArgs); + } + + class cLuaCallback : public cItemCallback + { + public: + cLuaCallback(lua_State * a_LuaState, int a_FuncRef, int a_TableRef) : + LuaState(a_LuaState), + FuncRef(a_FuncRef), + TableRef(a_TableRef) + {} + + private: + virtual bool Item(Ty2 * a_Item) override + { + lua_rawgeti(LuaState, LUA_REGISTRYINDEX, FuncRef); // Push function to call + tolua_pushusertype(LuaState, a_Item, Ty2::GetClassStatic()); // Push the item + if (TableRef != LUA_REFNIL) + { + lua_rawgeti(LuaState, LUA_REGISTRYINDEX, TableRef); // Push the optional callbackdata param + } + + int s = lua_pcall(LuaState, (TableRef == LUA_REFNIL ? 1 : 2), 1, 0); + if (report_errors(LuaState, s)) + { + return true; // Abort enumeration + } + if (lua_isboolean(LuaState, -1)) + { + return (tolua_toboolean(LuaState, -1, 0) > 0); + } + return false; /* Continue enumeration */ + } + lua_State * LuaState; + int FuncRef; + int TableRef; + } Callback(tolua_S, FuncRef, TableRef); + + + bool bRetVal = (self->*Func1)(ItemID, Callback); + + /* Unreference the values again, so the LUA_REGISTRYINDEX can make place for other references */ + luaL_unref(tolua_S, LUA_REGISTRYINDEX, TableRef); + luaL_unref(tolua_S, LUA_REGISTRYINDEX, FuncRef); + + /* Push return value on stack */ + tolua_pushboolean(tolua_S, bRetVal ); + return 1; } @@ -269,89 +359,89 @@ template< class Ty1, bool (Ty1::*Func1)(int, int, int, cItemCallback &) > static int tolua_DoWithXYZ(lua_State* tolua_S) { - int NumArgs = lua_gettop(tolua_S) - 1; /* This includes 'self' */ - if ((NumArgs != 4) && (NumArgs != 5)) - { + int NumArgs = lua_gettop(tolua_S) - 1; /* This includes 'self' */ + if ((NumArgs != 4) && (NumArgs != 5)) + { return lua_do_error(tolua_S, "Error in function call '#funcname#': Requires 4 or 5 arguments, got %i", NumArgs); - } + } - Ty1 * self = (Ty1 *) tolua_tousertype(tolua_S, 1, 0); - if (!lua_isnumber(tolua_S, 2) || !lua_isnumber(tolua_S, 3) || !lua_isnumber(tolua_S, 4)) - { + Ty1 * self = (Ty1 *) tolua_tousertype(tolua_S, 1, 0); + if (!lua_isnumber(tolua_S, 2) || !lua_isnumber(tolua_S, 3) || !lua_isnumber(tolua_S, 4)) + { return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a number for parameters #1, #2 and #3"); - } - - int ItemX = ((int)tolua_tonumber(tolua_S, 2, 0)); - int ItemY = ((int)tolua_tonumber(tolua_S, 3, 0)); - int ItemZ = ((int)tolua_tonumber(tolua_S, 4, 0)); - LOG("x %i y %i z %i", ItemX, ItemY, ItemZ ); - if (!lua_isfunction( tolua_S, 5)) - { + } + + int ItemX = ((int)tolua_tonumber(tolua_S, 2, 0)); + int ItemY = ((int)tolua_tonumber(tolua_S, 3, 0)); + int ItemZ = ((int)tolua_tonumber(tolua_S, 4, 0)); + LOG("x %i y %i z %i", ItemX, ItemY, ItemZ ); + if (!lua_isfunction( tolua_S, 5)) + { return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a function for parameter #4"); - } - - /* luaL_ref gets reference to value on top of the stack, the table is the last argument and therefore on the top */ - int TableRef = LUA_REFNIL; - if (NumArgs == 5) - { - TableRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX); - if (TableRef == LUA_REFNIL) - { + } + + /* luaL_ref gets reference to value on top of the stack, the table is the last argument and therefore on the top */ + int TableRef = LUA_REFNIL; + if (NumArgs == 5) + { + TableRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX); + if (TableRef == LUA_REFNIL) + { return lua_do_error(tolua_S, "Error in function call '#funcname#': Could not get value reference of parameter #5"); - } - } + } + } - /* table value is popped, and now function is on top of the stack */ - int FuncRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX); - if (FuncRef == LUA_REFNIL) - { + /* table value is popped, and now function is on top of the stack */ + int FuncRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX); + if (FuncRef == LUA_REFNIL) + { return lua_do_error(tolua_S, "Error in function call '#funcname#': Could not get function reference of parameter #4"); - } - - class cLuaCallback : public cItemCallback - { - public: - cLuaCallback(lua_State* a_LuaState, int a_FuncRef, int a_TableRef) - : LuaState( a_LuaState ) - , FuncRef( a_FuncRef ) - , TableRef( a_TableRef ) - {} - - private: - virtual bool Item(Ty2 * a_Item) override - { - lua_rawgeti( LuaState, LUA_REGISTRYINDEX, FuncRef); /* Push function reference */ - tolua_pushusertype(LuaState, a_Item, Ty2::GetClassStatic()); - if (TableRef != LUA_REFNIL) - { - lua_rawgeti( LuaState, LUA_REGISTRYINDEX, TableRef); /* Push table reference */ - } - - int s = lua_pcall(LuaState, (TableRef == LUA_REFNIL ? 1 : 2), 1, 0); + } + + class cLuaCallback : public cItemCallback + { + public: + cLuaCallback(lua_State* a_LuaState, int a_FuncRef, int a_TableRef) + : LuaState( a_LuaState ) + , FuncRef( a_FuncRef ) + , TableRef( a_TableRef ) + {} + + private: + virtual bool Item(Ty2 * a_Item) override + { + lua_rawgeti( LuaState, LUA_REGISTRYINDEX, FuncRef); /* Push function reference */ + tolua_pushusertype(LuaState, a_Item, Ty2::GetClassStatic()); + if (TableRef != LUA_REFNIL) + { + lua_rawgeti( LuaState, LUA_REGISTRYINDEX, TableRef); /* Push table reference */ + } + + int s = lua_pcall(LuaState, (TableRef == LUA_REFNIL ? 1 : 2), 1, 0); if (report_errors(LuaState, s)) { return true; // Abort enumeration } - if (lua_isboolean(LuaState, -1)) - { - return (tolua_toboolean(LuaState, -1, 0) > 0); - } - return false; /* Continue enumeration */ - } - lua_State * LuaState; - int FuncRef; - int TableRef; - } Callback(tolua_S, FuncRef, TableRef); + if (lua_isboolean(LuaState, -1)) + { + return (tolua_toboolean(LuaState, -1, 0) > 0); + } + return false; /* Continue enumeration */ + } + lua_State * LuaState; + int FuncRef; + int TableRef; + } Callback(tolua_S, FuncRef, TableRef); bool bRetVal = (self->*Func1)(ItemX, ItemY, ItemZ, Callback); - /* Unreference the values again, so the LUA_REGISTRYINDEX can make place for other references */ - luaL_unref(tolua_S, LUA_REGISTRYINDEX, TableRef); - luaL_unref(tolua_S, LUA_REGISTRYINDEX, FuncRef); + /* Unreference the values again, so the LUA_REGISTRYINDEX can make place for other references */ + luaL_unref(tolua_S, LUA_REGISTRYINDEX, TableRef); + luaL_unref(tolua_S, LUA_REGISTRYINDEX, FuncRef); - /* Push return value on stack */ - tolua_pushboolean(tolua_S, bRetVal ); - return 1; + /* Push return value on stack */ + tolua_pushboolean(tolua_S, bRetVal ); + return 1; } @@ -363,89 +453,89 @@ template< class Ty1, bool (Ty1::*Func1)(int, int, cItemCallback &) > static int tolua_ForEachInChunk(lua_State* tolua_S) { - int NumArgs = lua_gettop(tolua_S) - 1; /* This includes 'self' */ - if ((NumArgs != 3) && (NumArgs != 4)) - { + int NumArgs = lua_gettop(tolua_S) - 1; /* This includes 'self' */ + if ((NumArgs != 3) && (NumArgs != 4)) + { return lua_do_error(tolua_S, "Error in function call '#funcname#': Requires 3 or 4 arguments, got %i", NumArgs); - } + } - Ty1 * self = (Ty1 *) tolua_tousertype(tolua_S, 1, 0); - if (!lua_isnumber(tolua_S, 2) || !lua_isnumber(tolua_S, 3)) - { + Ty1 * self = (Ty1 *) tolua_tousertype(tolua_S, 1, 0); + if (!lua_isnumber(tolua_S, 2) || !lua_isnumber(tolua_S, 3)) + { return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a number for parameters #1 and #2"); - } + } - int ChunkX = ((int)tolua_tonumber(tolua_S, 2, 0)); - int ChunkZ = ((int)tolua_tonumber(tolua_S, 3, 0)); + int ChunkX = ((int)tolua_tonumber(tolua_S, 2, 0)); + int ChunkZ = ((int)tolua_tonumber(tolua_S, 3, 0)); - if (!lua_isfunction( tolua_S, 4)) - { + if (!lua_isfunction( tolua_S, 4)) + { return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a function for parameter #3"); - } - - /* luaL_ref gets reference to value on top of the stack, the table is the last argument and therefore on the top */ - int TableRef = LUA_REFNIL; - if (NumArgs == 4) - { - TableRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX); - if (TableRef == LUA_REFNIL) - { + } + + /* luaL_ref gets reference to value on top of the stack, the table is the last argument and therefore on the top */ + int TableRef = LUA_REFNIL; + if (NumArgs == 4) + { + TableRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX); + if (TableRef == LUA_REFNIL) + { return lua_do_error(tolua_S, "Error in function call '#funcname#': Could not get value reference of parameter #4"); - } - } + } + } - /* table value is popped, and now function is on top of the stack */ - int FuncRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX); - if (FuncRef == LUA_REFNIL) - { + /* table value is popped, and now function is on top of the stack */ + int FuncRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX); + if (FuncRef == LUA_REFNIL) + { return lua_do_error(tolua_S, "Error in function call '#funcname#': Could not get function reference of parameter #3"); - } - - class cLuaCallback : public cItemCallback - { - public: - cLuaCallback(lua_State* a_LuaState, int a_FuncRef, int a_TableRef) - : LuaState( a_LuaState ) - , FuncRef( a_FuncRef ) - , TableRef( a_TableRef ) - {} - - private: - virtual bool Item(Ty2 * a_Item) override - { - lua_rawgeti( LuaState, LUA_REGISTRYINDEX, FuncRef); /* Push function reference */ - tolua_pushusertype(LuaState, a_Item, Ty2::GetClassStatic()); - if (TableRef != LUA_REFNIL) - { - lua_rawgeti( LuaState, LUA_REGISTRYINDEX, TableRef); /* Push table reference */ - } - - int s = lua_pcall(LuaState, (TableRef == LUA_REFNIL ? 1 : 2), 1, 0); - if (report_errors(LuaState, s)) - { - return true; /* Abort enumeration */ - } - - if (lua_isboolean(LuaState, -1)) - { - return (tolua_toboolean(LuaState, -1, 0) > 0); - } - return false; /* Continue enumeration */ - } - lua_State * LuaState; - int FuncRef; - int TableRef; - } Callback(tolua_S, FuncRef, TableRef); + } + + class cLuaCallback : public cItemCallback + { + public: + cLuaCallback(lua_State* a_LuaState, int a_FuncRef, int a_TableRef) + : LuaState( a_LuaState ) + , FuncRef( a_FuncRef ) + , TableRef( a_TableRef ) + {} + + private: + virtual bool Item(Ty2 * a_Item) override + { + lua_rawgeti( LuaState, LUA_REGISTRYINDEX, FuncRef); /* Push function reference */ + tolua_pushusertype(LuaState, a_Item, Ty2::GetClassStatic()); + if (TableRef != LUA_REFNIL) + { + lua_rawgeti( LuaState, LUA_REGISTRYINDEX, TableRef); /* Push table reference */ + } + + int s = lua_pcall(LuaState, (TableRef == LUA_REFNIL ? 1 : 2), 1, 0); + if (report_errors(LuaState, s)) + { + return true; /* Abort enumeration */ + } + + if (lua_isboolean(LuaState, -1)) + { + return (tolua_toboolean(LuaState, -1, 0) > 0); + } + return false; /* Continue enumeration */ + } + lua_State * LuaState; + int FuncRef; + int TableRef; + } Callback(tolua_S, FuncRef, TableRef); bool bRetVal = (self->*Func1)(ChunkX, ChunkZ, Callback); - /* Unreference the values again, so the LUA_REGISTRYINDEX can make place for other references */ - luaL_unref(tolua_S, LUA_REGISTRYINDEX, TableRef); - luaL_unref(tolua_S, LUA_REGISTRYINDEX, FuncRef); + /* Unreference the values again, so the LUA_REGISTRYINDEX can make place for other references */ + luaL_unref(tolua_S, LUA_REGISTRYINDEX, TableRef); + luaL_unref(tolua_S, LUA_REGISTRYINDEX, FuncRef); - /* Push return value on stack */ - tolua_pushboolean(tolua_S, bRetVal ); - return 1; + /* Push return value on stack */ + tolua_pushboolean(tolua_S, bRetVal ); + return 1; } @@ -453,7 +543,7 @@ static int tolua_ForEachInChunk(lua_State* tolua_S) template< class Ty1, - class Ty2, + class Ty2, bool (Ty1::*Func1)(cItemCallback &) > static int tolua_ForEach(lua_State * tolua_S) { @@ -1382,14 +1472,15 @@ void ManualBindings::Bind(lua_State * tolua_S) tolua_function(tolua_S, "DoWithDispenserAt", tolua_DoWithXYZ); tolua_function(tolua_S, "DoWithDropSpenserAt", tolua_DoWithXYZ); tolua_function(tolua_S, "DoWithDropperAt", tolua_DoWithXYZ); + tolua_function(tolua_S, "DoWithEntityByID", tolua_DoWithID< cWorld, cEntity, &cWorld::DoWithEntityByID>); tolua_function(tolua_S, "DoWithFurnaceAt", tolua_DoWithXYZ); - tolua_function(tolua_S, "DoWithPlayer", tolua_DoWith); - tolua_function(tolua_S, "FindAndDoWithPlayer", tolua_DoWith); + tolua_function(tolua_S, "DoWithPlayer", tolua_DoWith< cWorld, cPlayer, &cWorld::DoWithPlayer>); + tolua_function(tolua_S, "FindAndDoWithPlayer", tolua_DoWith< cWorld, cPlayer, &cWorld::FindAndDoWithPlayer>); tolua_function(tolua_S, "ForEachChestInChunk", tolua_ForEachInChunk); - tolua_function(tolua_S, "ForEachEntity", tolua_ForEach); + tolua_function(tolua_S, "ForEachEntity", tolua_ForEach< cWorld, cEntity, &cWorld::ForEachEntity>); tolua_function(tolua_S, "ForEachEntityInChunk", tolua_ForEachInChunk); tolua_function(tolua_S, "ForEachFurnaceInChunk", tolua_ForEachInChunk); - tolua_function(tolua_S, "ForEachPlayer", tolua_ForEach); + tolua_function(tolua_S, "ForEachPlayer", tolua_ForEach< cWorld, cPlayer, &cWorld::ForEachPlayer>); tolua_function(tolua_S, "SetSignLines", tolua_cWorld_SetSignLines); tolua_function(tolua_S, "UpdateSign", tolua_cWorld_SetSignLines); tolua_endmodule(tolua_S); diff --git a/source/World.h b/source/World.h index 9de00ceec..695b15f50 100644 --- a/source/World.h +++ b/source/World.h @@ -245,7 +245,7 @@ public: bool ForEachEntityInChunk(int a_ChunkX, int a_ChunkZ, cEntityCallback & a_Callback); // Exported in ManualBindings.cpp /// Calls the callback if the entity with the specified ID is found, with the entity object as the callback param. Returns true if entity found and callback returned false. - bool DoWithEntityByID(int a_UniqueID, cEntityCallback & a_Callback); // TODO: Exported in ManualBindings.cpp + bool DoWithEntityByID(int a_UniqueID, cEntityCallback & a_Callback); // Exported in ManualBindings.cpp /// Compares clients of two chunks, calls the callback accordingly void CompareChunkClients(int a_ChunkX1, int a_ChunkZ1, int a_ChunkX2, int a_ChunkZ2, cClientDiffCallback & a_Callback); -- cgit v1.2.3 From 73fcd7ad1c7108bd3b76d7543cc6f312e083c43c Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 5 Aug 2013 15:54:10 +0200 Subject: Exported the cWorld:TryGetHeight() function --- source/ManualBindings.cpp | 47 +++++++++++++++++++++++++++++++++++++++++++++++ source/World.h | 8 ++++---- 2 files changed, 51 insertions(+), 4 deletions(-) diff --git a/source/ManualBindings.cpp b/source/ManualBindings.cpp index 7e3417ceb..9e9b5f5a8 100644 --- a/source/ManualBindings.cpp +++ b/source/ManualBindings.cpp @@ -686,6 +686,52 @@ tolua_lerror: +static int tolua_cWorld_TryGetHeight(lua_State * tolua_S) +{ + // Exported manually, because tolua would require the out-only param a_Height to be used when calling + // Takes (a_World,) a_BlockX, a_BlockZ + // Returns Height, IsValid + #ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype (tolua_S, 1, "cWorld", 0, &tolua_err) || + !tolua_isnumber (tolua_S, 2, 0, &tolua_err) || + !tolua_isnumber (tolua_S, 3, 0, &tolua_err) || + !tolua_isnoobj (tolua_S, 4, &tolua_err) + ) + goto tolua_lerror; + else + #endif + { + cWorld * self = (cWorld *) tolua_tousertype (tolua_S, 1, 0); + int BlockX = (int) tolua_tonumber (tolua_S, 2, 0); + int BlockZ = (int) tolua_tonumber (tolua_S, 3, 0); + #ifndef TOLUA_RELEASE + if (self == NULL) + { + tolua_error(tolua_S, "Invalid 'self' in function 'TryGetHeight'", NULL); + } + #endif + { + int Height = 0; + bool res = self->TryGetHeight(BlockX, BlockZ, Height); + tolua_pushnumber(tolua_S, Height); + tolua_pushboolean(tolua_S, res ? 1 : 0); + } + } + return 1; + + #ifndef TOLUA_RELEASE +tolua_lerror: + tolua_error(tolua_S, "#ferror in function 'TryGetHeight'.", &tolua_err); + return 0; + #endif +} + + + + + static int tolua_cPluginManager_GetAllPlugins(lua_State * tolua_S) { cPluginManager* self = (cPluginManager*) tolua_tousertype(tolua_S,1,0); @@ -1482,6 +1528,7 @@ void ManualBindings::Bind(lua_State * tolua_S) tolua_function(tolua_S, "ForEachFurnaceInChunk", tolua_ForEachInChunk); tolua_function(tolua_S, "ForEachPlayer", tolua_ForEach< cWorld, cPlayer, &cWorld::ForEachPlayer>); tolua_function(tolua_S, "SetSignLines", tolua_cWorld_SetSignLines); + tolua_function(tolua_S, "TryGetHeight", tolua_cWorld_TryGetHeight); tolua_function(tolua_S, "UpdateSign", tolua_cWorld_SetSignLines); tolua_endmodule(tolua_S); diff --git a/source/World.h b/source/World.h index 695b15f50..5720ae634 100644 --- a/source/World.h +++ b/source/World.h @@ -129,7 +129,7 @@ public: // tolua_end /// Retrieves the world height at the specified coords; returns false if chunk not loaded / generated - bool TryGetHeight(int a_BlockX, int a_BlockZ, int & a_Height); // TODO: Export in ManualBindings.cpp + bool TryGetHeight(int a_BlockX, int a_BlockZ, int & a_Height); // Exported in ManualBindings.cpp // Broadcast respective packets to all clients of the chunk where the event is taking place // (Please keep these alpha-sorted) @@ -174,7 +174,7 @@ public: If a_MarkDirty is set, the chunk is set as dirty (used after generating) */ void SetChunkData( - int a_ChunkX, int a_ChunkZ, + int a_ChunkX, int a_ChunkZ, const BLOCKTYPE * a_BlockTypes, const NIBBLETYPE * a_BlockMeta, const NIBBLETYPE * a_BlockLight, @@ -319,8 +319,8 @@ public: void SetBlockMeta(const Vector3i & a_Pos, NIBBLETYPE a_MetaData ) { SetBlockMeta( a_Pos.x, a_Pos.y, a_Pos.z, a_MetaData ); } // tolua_end - /** Writes the block area into the specified coords. - Returns true if all chunks have been processed. + /** Writes the block area into the specified coords. + Returns true if all chunks have been processed. Prefer cBlockArea::Write() instead, this is the internal implementation; cBlockArea does error checking, too. a_DataTypes is a bitmask of cBlockArea::baXXX constants ORed together. */ -- cgit v1.2.3 From 2151bb8f5bad91975010ab1022177fdb94cc2a3e Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 6 Aug 2013 08:01:00 +0200 Subject: cLuaState can now contain a detached LuaState, too. This will be useful for cases when we get a lua_State * from the outside and are asked to perform operations on it. --- source/LuaState.cpp | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++ source/LuaState.h | 23 +++++++++++++++++- 2 files changed, 89 insertions(+), 1 deletion(-) diff --git a/source/LuaState.cpp b/source/LuaState.cpp index da86a4b20..117023755 100644 --- a/source/LuaState.cpp +++ b/source/LuaState.cpp @@ -37,6 +37,7 @@ extern "C" cLuaState::cLuaState(const AString & a_SubsystemName) : m_LuaState(NULL), + m_IsOwned(false), m_SubsystemName(a_SubsystemName) { } @@ -45,6 +46,17 @@ cLuaState::cLuaState(const AString & a_SubsystemName) : +cLuaState::cLuaState(lua_State * a_AttachState) : + m_LuaState(a_AttachState), + m_IsOwned(false), + m_SubsystemName("") +{ +} + + + + + cLuaState::~cLuaState() { if (IsValid()) @@ -70,6 +82,7 @@ void cLuaState::Create(void) ManualBindings::Bind(m_LuaState); luaopen_lsqlite3(m_LuaState); luaopen_lxp(m_LuaState); + m_IsOwned = true; } @@ -83,8 +96,62 @@ void cLuaState::Close(void) LOGWARNING("%s: Trying to close an invalid LuaState, ignoring.", __FUNCTION__); return; } + if (!m_IsOwned) + { + LOGWARNING( + "%s: Detected mis-use, calling Close() on an attached state (0x%p). Detaching instead.", + __FUNCTION__, m_LuaState + ); + Detach(); + return; + } lua_close(m_LuaState); m_LuaState = NULL; + m_IsOwned = false; +} + + + + + +void cLuaState::Attach(lua_State * a_State) +{ + if (m_LuaState != NULL) + { + LOGINFO("%s: Already contains a LuaState (0x%p), will be closed / detached.", __FUNCTION__, m_LuaState); + if (m_IsOwned) + { + Close(); + } + else + { + Detach(); + } + } + m_LuaState = a_State; + m_IsOwned = false; +} + + + + + +void cLuaState::Detach(void) +{ + if (m_LuaState == NULL) + { + return; + } + if (m_IsOwned) + { + LOGWARNING( + "%s: Detected a mis-use, calling Detach() when the state is owned. Closing the owned state (0x%p).", + __FUNCTION__, m_LuaState + ); + Close(); + return; + } + m_LuaState = NULL; } diff --git a/source/LuaState.h b/source/LuaState.h index 10ff53911..fca532d89 100644 --- a/source/LuaState.h +++ b/source/LuaState.h @@ -3,6 +3,12 @@ // Declares the cLuaState class representing the wrapper over lua_State *, provides associated helper functions +/* +The contained lua_State can be either owned or attached. +Owned lua_State is created by calling Create() and the cLuaState automatically closes the state +Or, lua_State can be attached by calling Attach(), the cLuaState doesn't close such a state +Attaching a state will automatically close an owned state. +*/ @@ -29,16 +35,28 @@ public: */ cLuaState(const AString & a_SubsystemName); + /** Creates a new instance. The a_AttachState is attached. + Subsystem name is set to "". + */ + explicit cLuaState(lua_State * a_AttachState); + ~cLuaState(); + /// Allows this object to be used in the same way as a lua_State *, for example in the LuaLib functions operator lua_State * (void) { return m_LuaState; } - /// Creates the m_LuaState, if not closed already + /// Creates the m_LuaState, if not closed already. This state will be automatically closed in the destructor void Create(void); /// Closes the m_LuaState, if not closed already void Close(void); + /// Attaches the specified state. Operations will be carried out on this state, but it will not be closed in the destructor + void Attach(lua_State * a_State); + + /// Detaches a previously attached state. + void Detach(void); + /// Returns true if the m_LuaState is valid bool IsValid(void) const { return (m_LuaState != NULL); } @@ -79,6 +97,9 @@ public: protected: lua_State * m_LuaState; + /// If true, the state is owned by this object and will be auto-Closed. False => attached state + bool m_IsOwned; + /** The subsystem name is used for reporting errors to the console, it is either "plugin %s" or "LuaScript" whatever is given to the constructor */ -- cgit v1.2.3 From 2030bd47c823b47606e9567a1974761f80cf0d55 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 6 Aug 2013 08:59:54 +0200 Subject: cLuaState now tracks the function name and number of args --- source/LuaState.cpp | 188 +++++++++++++++++- source/LuaState.h | 50 ++++- source/Plugin_NewLua.cpp | 498 ++++++++++++++++++++++------------------------- 3 files changed, 459 insertions(+), 277 deletions(-) diff --git a/source/LuaState.cpp b/source/LuaState.cpp index 117023755..e60a0f80c 100644 --- a/source/LuaState.cpp +++ b/source/LuaState.cpp @@ -38,7 +38,8 @@ extern "C" cLuaState::cLuaState(const AString & a_SubsystemName) : m_LuaState(NULL), m_IsOwned(false), - m_SubsystemName(a_SubsystemName) + m_SubsystemName(a_SubsystemName), + m_NumCurrentFunctionArgs(-1) { } @@ -49,7 +50,8 @@ cLuaState::cLuaState(const AString & a_SubsystemName) : cLuaState::cLuaState(lua_State * a_AttachState) : m_LuaState(a_AttachState), m_IsOwned(false), - m_SubsystemName("") + m_SubsystemName(""), + m_NumCurrentFunctionArgs(-1) { } @@ -187,6 +189,8 @@ bool cLuaState::LoadFile(const AString & a_FileName) bool cLuaState::PushFunction(const char * a_FunctionName, bool a_ShouldLogFailure /* = true */) { + ASSERT(m_NumCurrentFunctionArgs == -1); // If not, there's already something pushed onto the stack + if (!IsValid()) { // This happens if cPlugin::Initialize() fails with an error @@ -203,6 +207,8 @@ bool cLuaState::PushFunction(const char * a_FunctionName, bool a_ShouldLogFailur lua_pop(m_LuaState, 1); return false; } + m_CurrentFunctionName.assign(a_FunctionName); + m_NumCurrentFunctionArgs = 0; return true; } @@ -212,12 +218,17 @@ bool cLuaState::PushFunction(const char * a_FunctionName, bool a_ShouldLogFailur bool cLuaState::PushFunctionFromRegistry(int a_FnRef) { + ASSERT(IsValid()); + ASSERT(m_NumCurrentFunctionArgs == -1); // If not, there's already something pushed onto the stack + lua_rawgeti(m_LuaState, LUA_REGISTRYINDEX, a_FnRef); // same as lua_getref() if (!lua_isfunction(m_LuaState, -1)) { lua_pop(m_LuaState, 1); return false; } + m_CurrentFunctionName = ""; + m_NumCurrentFunctionArgs = 0; return true; } @@ -227,6 +238,9 @@ bool cLuaState::PushFunctionFromRegistry(int a_FnRef) void cLuaState::PushStringVector(const AStringVector & a_Vector) { + ASSERT(IsValid()); + ASSERT(m_NumCurrentFunctionArgs >= 0); // A function must be pushed to stack first + lua_createtable(m_LuaState, a_Vector.size(), 0); int newTable = lua_gettop(m_LuaState); int index = 1; @@ -235,22 +249,184 @@ void cLuaState::PushStringVector(const AStringVector & a_Vector) tolua_pushstring(m_LuaState, itr->c_str()); lua_rawseti(m_LuaState, newTable, index); } + m_NumCurrentFunctionArgs += 1; +} + + + + + +void cLuaState::PushUserType(void * a_Object, const char * a_Type) +{ + ASSERT(IsValid()); + ASSERT(m_NumCurrentFunctionArgs >= 0); // A function must be pushed to stack first + + tolua_pushusertype(m_LuaState, a_Object, a_Type); + m_NumCurrentFunctionArgs += 1; +} + + + + + +void cLuaState::PushNumber(int a_Value) +{ + ASSERT(IsValid()); + ASSERT(m_NumCurrentFunctionArgs >= 0); // A function must be pushed to stack first + + tolua_pushnumber(m_LuaState, a_Value); + m_NumCurrentFunctionArgs += 1; +} + + + + + +void cLuaState::PushNumber(double a_Value) +{ + ASSERT(IsValid()); + ASSERT(m_NumCurrentFunctionArgs >= 0); // A function must be pushed to stack first + + tolua_pushnumber(m_LuaState, a_Value); + m_NumCurrentFunctionArgs += 1; +} + + + + + +void cLuaState::PushString(const char * a_Value) +{ + ASSERT(IsValid()); + ASSERT(m_NumCurrentFunctionArgs >= 0); // A function must be pushed to stack first + + tolua_pushstring(m_LuaState, a_Value); + m_NumCurrentFunctionArgs += 1; +} + + + + + +void cLuaState::PushBool(bool a_Value) +{ + ASSERT(IsValid()); + ASSERT(m_NumCurrentFunctionArgs >= 0); // A function must be pushed to stack first + + tolua_pushboolean(m_LuaState, a_Value ? 1 : 0); + m_NumCurrentFunctionArgs += 1; +} + + + + + +void cLuaState::PushObject(cWorld * a_World) +{ + ASSERT(IsValid()); + ASSERT(m_NumCurrentFunctionArgs >= 0); // A function must be pushed to stack first + + tolua_pushusertype(m_LuaState, a_World, "cWorld"); + m_NumCurrentFunctionArgs += 1; +} + + + + + +void cLuaState::PushObject(cPlayer * a_Player) +{ + ASSERT(IsValid()); + ASSERT(m_NumCurrentFunctionArgs >= 0); // A function must be pushed to stack first + + tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); + m_NumCurrentFunctionArgs += 1; +} + + + + + +void cLuaState::PushObject(cEntity * a_Entity) +{ + ASSERT(IsValid()); + ASSERT(m_NumCurrentFunctionArgs >= 0); // A function must be pushed to stack first + + tolua_pushusertype(m_LuaState, a_Entity, "cEntity"); + m_NumCurrentFunctionArgs += 1; +} + + + + + +void cLuaState::PushObject(cItem * a_Item) +{ + ASSERT(IsValid()); + ASSERT(m_NumCurrentFunctionArgs >= 0); // A function must be pushed to stack first + + tolua_pushusertype(m_LuaState, a_Item, "cItem"); + m_NumCurrentFunctionArgs += 1; +} + + + + + +void cLuaState::PushObject(cItems * a_Items) +{ + ASSERT(IsValid()); + ASSERT(m_NumCurrentFunctionArgs >= 0); // A function must be pushed to stack first + + tolua_pushusertype(m_LuaState, a_Items, "cItems"); + m_NumCurrentFunctionArgs += 1; +} + + + + + +void cLuaState::PushObject(cClientHandle * a_Client) +{ + ASSERT(IsValid()); + ASSERT(m_NumCurrentFunctionArgs >= 0); // A function must be pushed to stack first + + tolua_pushusertype(m_LuaState, a_Client, "cClientHandle"); + m_NumCurrentFunctionArgs += 1; +} + + + + + +void cLuaState::PushObject(cPickup * a_Pickup) +{ + ASSERT(IsValid()); + ASSERT(m_NumCurrentFunctionArgs >= 0); // A function must be pushed to stack first + + tolua_pushusertype(m_LuaState, a_Pickup, "cPickup"); + m_NumCurrentFunctionArgs += 1; } -bool cLuaState::CallFunction(int a_NumArgs, int a_NumResults, const char * a_FunctionName) +bool cLuaState::CallFunction(int a_NumResults) { - ASSERT(lua_isfunction(m_LuaState, -a_NumArgs - 1)); + ASSERT (m_NumCurrentFunctionArgs >= 0); // A function must be pushed to stack first + ASSERT(lua_isfunction(m_LuaState, -m_NumCurrentFunctionArgs - 1)); - int s = lua_pcall(m_LuaState, a_NumArgs, a_NumResults, 0); + int s = lua_pcall(m_LuaState, m_NumCurrentFunctionArgs, a_NumResults, 0); if (ReportErrors(s)) { - LOGWARNING("Error in %s calling function %s()", m_SubsystemName.c_str(), a_FunctionName); + LOGWARNING("Error in %s calling function %s()", m_SubsystemName.c_str(), m_CurrentFunctionName); + m_NumCurrentFunctionArgs = -1; + m_CurrentFunctionName.clear(); return false; } + m_NumCurrentFunctionArgs = -1; + m_CurrentFunctionName.clear(); return true; } diff --git a/source/LuaState.h b/source/LuaState.h index fca532d89..18c7c1354 100644 --- a/source/LuaState.h +++ b/source/LuaState.h @@ -8,6 +8,11 @@ The contained lua_State can be either owned or attached. Owned lua_State is created by calling Create() and the cLuaState automatically closes the state Or, lua_State can be attached by calling Attach(), the cLuaState doesn't close such a state Attaching a state will automatically close an owned state. + +Calling a Lua function is done by pushing the function, either by PushFunction() or PushFunctionFromRegistry(), +then pushing the arguments (PushString(), PushNumber(), PushUserData() etc.) and finally +executing CallFunction(). cLuaState automatically keeps track of the number of arguments and the name of the +function (for logging purposes), which makes the call less error-prone. */ @@ -22,6 +27,14 @@ Attaching a state will automatically close an owned state. // fwd: lua.h struct lua_State; +class cWorld; +class cPlayer; +class cEntity; +class cItem; +class cItems; +class cClientHandle; +class cPickup; + @@ -80,13 +93,36 @@ public: /// Pushes a string vector, as a table, onto the stack void PushStringVector(const AStringVector & a_Vector); + /// Pushes a usertype of the specified class type onto the stack + void PushUserType(void * a_Object, const char * a_Type); + + /// Pushes an integer onto the stack + void PushNumber(int a_Value); + + /// Pushes a double onto the stack + void PushNumber(double a_Value); + + /// Pushes a string onto the stack + void PushString(const char * a_Value); + + /// Pushes a bool onto the stack + void PushBool(bool a_Value); + + // Special family of functions that do PushUserType internally, but require one less parameter + void PushObject(cWorld * a_World); + void PushObject(cPlayer * a_Player); + void PushObject(cEntity * a_Entity); + void PushObject(cItem * a_Item); + void PushObject(cItems * a_Items); + void PushObject(cClientHandle * a_ClientHandle); + void PushObject(cPickup * a_Pickup); + /** - Calls the function that has been pushed onto the stack by PushFunction. + Calls the function that has been pushed onto the stack by PushFunction(), + with arguments pushed by PushXXX(). Returns true if successful, logs a warning on failure. - a_FunctionName is used only for the warning log message, the function - to be called must be pushed by PushFunction() beforehand. */ - bool CallFunction(int a_NumArgs, int a_NumResults, const char * a_FunctionName); + bool CallFunction(int a_NumReturnValues); /// If the status is nonzero, prints the text on the top of Lua stack and returns true bool ReportErrors(int status); @@ -104,6 +140,12 @@ protected: whatever is given to the constructor */ AString m_SubsystemName; + + /// Name of the currently pushed function (for the Push / Call chain) + AString m_CurrentFunctionName; + + /// Number of arguments currently pushed (for the Push / Call chain) + int m_NumCurrentFunctionArgs; } ; diff --git a/source/Plugin_NewLua.cpp b/source/Plugin_NewLua.cpp index 51d16c839..b3dac7912 100644 --- a/source/Plugin_NewLua.cpp +++ b/source/Plugin_NewLua.cpp @@ -78,9 +78,9 @@ bool cPlugin_NewLua::Initialize(void) return false; } - tolua_pushusertype(m_LuaState, this, "cPlugin_NewLua"); + m_LuaState.PushUserType(this, "cPlugin_NewLua"); - if (!m_LuaState.CallFunction(1, 1, "Initialize")) + if (!m_LuaState.CallFunction(1)) { m_LuaState.Close(); return false; @@ -109,7 +109,7 @@ void cPlugin_NewLua::OnDisable() return; } - m_LuaState.CallFunction(0, 0, "OnDisable"); + m_LuaState.CallFunction(0); } @@ -124,10 +124,8 @@ void cPlugin_NewLua::Tick(float a_Dt) { return; } - - tolua_pushnumber( m_LuaState, a_Dt ); - - m_LuaState.CallFunction(1, 0, FnName); + m_LuaState.PushNumber(a_Dt); + m_LuaState.CallFunction(0); } @@ -144,16 +142,16 @@ bool cPlugin_NewLua::OnBlockToPickups(cWorld * a_World, cEntity * a_Digger, int return false; } - tolua_pushusertype(m_LuaState, a_World, "cWorld"); - tolua_pushusertype(m_LuaState, a_Digger, "cEntity"); - tolua_pushnumber (m_LuaState, a_BlockX); - tolua_pushnumber (m_LuaState, a_BlockY); - tolua_pushnumber (m_LuaState, a_BlockZ); - tolua_pushnumber (m_LuaState, a_BlockType); - tolua_pushnumber (m_LuaState, a_BlockMeta); - tolua_pushusertype(m_LuaState, &a_Pickups, "cItems"); + m_LuaState.PushObject(a_World); + m_LuaState.PushObject(a_Digger); + m_LuaState.PushNumber(a_BlockX); + m_LuaState.PushNumber(a_BlockY); + m_LuaState.PushNumber(a_BlockZ); + m_LuaState.PushNumber(a_BlockType); + m_LuaState.PushNumber(a_BlockMeta); + m_LuaState.PushObject(&a_Pickups); - if (!m_LuaState.CallFunction(8, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -177,10 +175,10 @@ bool cPlugin_NewLua::OnChat(cPlayer * a_Player, AString & a_Message) return false; } - tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); - tolua_pushstring (m_LuaState, a_Message.c_str()); + m_LuaState.PushObject(a_Player); + m_LuaState.PushString(a_Message.c_str()); - if (!m_LuaState.CallFunction(2, 2, FnName)) + if (!m_LuaState.CallFunction(2)) { return false; } @@ -208,11 +206,11 @@ bool cPlugin_NewLua::OnChunkAvailable(cWorld * a_World, int a_ChunkX, int a_Chun return false; } - tolua_pushusertype(m_LuaState, a_World, "cWorld"); - tolua_pushnumber (m_LuaState, a_ChunkX); - tolua_pushnumber (m_LuaState, a_ChunkZ); + m_LuaState.PushObject(a_World); + m_LuaState.PushNumber(a_ChunkX); + m_LuaState.PushNumber(a_ChunkZ); - if (!m_LuaState.CallFunction(3, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -236,12 +234,12 @@ bool cPlugin_NewLua::OnChunkGenerated(cWorld * a_World, int a_ChunkX, int a_Chun return false; } - tolua_pushusertype(m_LuaState, a_World, "cWorld"); - tolua_pushnumber (m_LuaState, a_ChunkX); - tolua_pushnumber (m_LuaState, a_ChunkZ); - tolua_pushusertype(m_LuaState, a_ChunkDesc, "cChunkDesc"); + m_LuaState.PushObject(a_World); + m_LuaState.PushNumber(a_ChunkX); + m_LuaState.PushNumber(a_ChunkZ); + m_LuaState.PushUserType(a_ChunkDesc, "cChunkDesc"); - if (!m_LuaState.CallFunction(4, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -255,7 +253,7 @@ bool cPlugin_NewLua::OnChunkGenerated(cWorld * a_World, int a_ChunkX, int a_Chun -bool cPlugin_NewLua::OnChunkGenerating(cWorld * a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_pLuaChunk) +bool cPlugin_NewLua::OnChunkGenerating(cWorld * a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc) { cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_CHUNK_GENERATING); @@ -265,12 +263,12 @@ bool cPlugin_NewLua::OnChunkGenerating(cWorld * a_World, int a_ChunkX, int a_Chu return false; } - tolua_pushusertype(m_LuaState, a_World, "cWorld"); - tolua_pushnumber (m_LuaState, a_ChunkX); - tolua_pushnumber (m_LuaState, a_ChunkZ); - tolua_pushusertype(m_LuaState, a_pLuaChunk, "cChunkDesc"); + m_LuaState.PushObject(a_World); + m_LuaState.PushNumber(a_ChunkX); + m_LuaState.PushNumber(a_ChunkZ); + m_LuaState.PushUserType(a_ChunkDesc, "cChunkDesc"); - if (!m_LuaState.CallFunction(4, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -294,11 +292,11 @@ bool cPlugin_NewLua::OnChunkUnloaded(cWorld * a_World, int a_ChunkX, int a_Chunk return false; } - tolua_pushusertype(m_LuaState, a_World, "cWorld"); - tolua_pushnumber (m_LuaState, a_ChunkX); - tolua_pushnumber (m_LuaState, a_ChunkZ); + m_LuaState.PushObject(a_World); + m_LuaState.PushNumber(a_ChunkX); + m_LuaState.PushNumber(a_ChunkZ); - if (!m_LuaState.CallFunction(3, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -322,11 +320,11 @@ bool cPlugin_NewLua::OnChunkUnloading(cWorld * a_World, int a_ChunkX, int a_Chun return false; } - tolua_pushusertype(m_LuaState, a_World, "cWorld"); - tolua_pushnumber (m_LuaState, a_ChunkX); - tolua_pushnumber (m_LuaState, a_ChunkZ); + m_LuaState.PushObject(a_World); + m_LuaState.PushNumber(a_ChunkX); + m_LuaState.PushNumber(a_ChunkZ); - if (!m_LuaState.CallFunction(3, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -350,10 +348,10 @@ bool cPlugin_NewLua::OnCollectingPickup(cPlayer * a_Player, cPickup * a_Pickup) return false; } - tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); - tolua_pushusertype(m_LuaState, a_Pickup, "cPickup"); + m_LuaState.PushObject(a_Player); + m_LuaState.PushObject(a_Pickup); - if (!m_LuaState.CallFunction(2, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -377,11 +375,11 @@ bool cPlugin_NewLua::OnCraftingNoRecipe(const cPlayer * a_Player, const cCraftin return false; } - tolua_pushusertype(m_LuaState, (void *)a_Player, "cPlayer"); - tolua_pushusertype(m_LuaState, (void *)a_Grid, "cCraftingGrid"); - tolua_pushusertype(m_LuaState, (void *)a_Recipe, "cCraftingRecipe"); + m_LuaState.PushUserType((void *)a_Player, "cPlayer"); + m_LuaState.PushUserType((void *)a_Grid, "cCraftingGrid"); + m_LuaState.PushUserType((void *)a_Recipe, "cCraftingRecipe"); - if (!m_LuaState.CallFunction(3, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -405,10 +403,10 @@ bool cPlugin_NewLua::OnDisconnect(cPlayer * a_Player, const AString & a_Reason) return false; } - tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); - tolua_pushstring (m_LuaState, a_Reason.c_str()); + m_LuaState.PushObject(a_Player); + m_LuaState.PushString(a_Reason.c_str()); - if (!m_LuaState.CallFunction(2, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -432,22 +430,10 @@ bool cPlugin_NewLua::OnExecuteCommand(cPlayer * a_Player, const AStringVector & return false; } - tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); - - // Push the split: - lua_createtable(m_LuaState, a_Split.size(), 0); - int newTable = lua_gettop(m_LuaState); - int index = 1; - std::vector::const_iterator iter = a_Split.begin(), end = a_Split.end(); - while(iter != end) - { - tolua_pushstring(m_LuaState, (*iter).c_str()); - lua_rawseti(m_LuaState, newTable, index); - ++iter; - ++index; - } + m_LuaState.PushObject(a_Player); + m_LuaState.PushStringVector(a_Split); - if (!m_LuaState.CallFunction(2, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -471,10 +457,10 @@ bool cPlugin_NewLua::OnHandshake(cClientHandle * a_Client, const AString & a_Use return false; } - tolua_pushusertype(m_LuaState, a_Client, "cClientHandle"); - tolua_pushstring (m_LuaState, a_Username.c_str()); + m_LuaState.PushUserType(a_Client, "cClientHandle"); + m_LuaState.PushString (a_Username.c_str()); - if (!m_LuaState.CallFunction(2, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -498,10 +484,10 @@ bool cPlugin_NewLua::OnKilling(cEntity & a_Victim, cEntity * a_Killer) return false; } - tolua_pushusertype(m_LuaState, &a_Victim, "cEntity"); - tolua_pushusertype(m_LuaState, a_Killer, "cEntity"); + m_LuaState.PushObject(&a_Victim); + m_LuaState.PushObject(a_Killer); - if (!m_LuaState.CallFunction(2, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -525,11 +511,11 @@ bool cPlugin_NewLua::OnLogin(cClientHandle * a_Client, int a_ProtocolVersion, co return false; } - tolua_pushusertype (m_LuaState, a_Client, "cClientHandle"); - tolua_pushnumber (m_LuaState, a_ProtocolVersion); - tolua_pushcppstring(m_LuaState, a_Username); + m_LuaState.PushObject(a_Client); + m_LuaState.PushNumber(a_ProtocolVersion); + m_LuaState.PushString(a_Username.c_str()); - if (!m_LuaState.CallFunction(3, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -553,15 +539,15 @@ bool cPlugin_NewLua::OnPlayerBreakingBlock(cPlayer & a_Player, int a_BlockX, int return false; } - tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); - tolua_pushnumber (m_LuaState, a_BlockX); - tolua_pushnumber (m_LuaState, a_BlockY); - tolua_pushnumber (m_LuaState, a_BlockZ); - tolua_pushnumber (m_LuaState, a_BlockFace); - tolua_pushnumber (m_LuaState, a_BlockType); - tolua_pushnumber (m_LuaState, a_BlockMeta); + m_LuaState.PushObject(&a_Player); + m_LuaState.PushNumber(a_BlockX); + m_LuaState.PushNumber(a_BlockY); + m_LuaState.PushNumber(a_BlockZ); + m_LuaState.PushNumber(a_BlockFace); + m_LuaState.PushNumber(a_BlockType); + m_LuaState.PushNumber(a_BlockMeta); - if (!m_LuaState.CallFunction(7, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -585,15 +571,15 @@ bool cPlugin_NewLua::OnPlayerBrokenBlock(cPlayer & a_Player, int a_BlockX, int a return false; } - tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); - tolua_pushnumber (m_LuaState, a_BlockX); - tolua_pushnumber (m_LuaState, a_BlockY); - tolua_pushnumber (m_LuaState, a_BlockZ); - tolua_pushnumber (m_LuaState, a_BlockFace); - tolua_pushnumber (m_LuaState, a_BlockType); - tolua_pushnumber (m_LuaState, a_BlockMeta); + m_LuaState.PushObject(&a_Player); + m_LuaState.PushNumber(a_BlockX); + m_LuaState.PushNumber(a_BlockY); + m_LuaState.PushNumber(a_BlockZ); + m_LuaState.PushNumber(a_BlockFace); + m_LuaState.PushNumber(a_BlockType); + m_LuaState.PushNumber(a_BlockMeta); - if (!m_LuaState.CallFunction(7, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -617,9 +603,9 @@ bool cPlugin_NewLua::OnPlayerEating(cPlayer & a_Player) return false; } - tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); + m_LuaState.PushObject(&a_Player); - if (!m_LuaState.CallFunction(1, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -643,9 +629,9 @@ bool cPlugin_NewLua::OnPlayerJoined(cPlayer & a_Player) return false; } - tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); + m_LuaState.PushObject(&a_Player); - if (!m_LuaState.CallFunction(1, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -669,14 +655,14 @@ bool cPlugin_NewLua::OnPlayerLeftClick(cPlayer & a_Player, int a_BlockX, int a_B return false; } - tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); - tolua_pushnumber (m_LuaState, a_BlockX); - tolua_pushnumber (m_LuaState, a_BlockY); - tolua_pushnumber (m_LuaState, a_BlockZ); - tolua_pushnumber (m_LuaState, a_BlockFace); - tolua_pushnumber (m_LuaState, a_Status); + m_LuaState.PushObject(&a_Player); + m_LuaState.PushNumber(a_BlockX); + m_LuaState.PushNumber(a_BlockY); + m_LuaState.PushNumber(a_BlockZ); + m_LuaState.PushNumber(a_BlockFace); + m_LuaState.PushNumber(a_Status); - if (!m_LuaState.CallFunction(6, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -700,9 +686,9 @@ bool cPlugin_NewLua::OnPlayerMoved(cPlayer & a_Player) return false; } - tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); + m_LuaState.PushObject(&a_Player); - if (!m_LuaState.CallFunction(1, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -726,18 +712,18 @@ bool cPlugin_NewLua::OnPlayerPlacedBlock(cPlayer & a_Player, int a_BlockX, int a return false; } - tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); - tolua_pushnumber (m_LuaState, a_BlockX); - tolua_pushnumber (m_LuaState, a_BlockY); - tolua_pushnumber (m_LuaState, a_BlockZ); - tolua_pushnumber (m_LuaState, a_BlockFace); - tolua_pushnumber (m_LuaState, a_CursorX); - tolua_pushnumber (m_LuaState, a_CursorY); - tolua_pushnumber (m_LuaState, a_CursorZ); - tolua_pushnumber (m_LuaState, a_BlockType); - tolua_pushnumber (m_LuaState, a_BlockMeta); + m_LuaState.PushObject(&a_Player); + m_LuaState.PushNumber(a_BlockX); + m_LuaState.PushNumber(a_BlockY); + m_LuaState.PushNumber(a_BlockZ); + m_LuaState.PushNumber(a_BlockFace); + m_LuaState.PushNumber(a_CursorX); + m_LuaState.PushNumber(a_CursorY); + m_LuaState.PushNumber(a_CursorZ); + m_LuaState.PushNumber(a_BlockType); + m_LuaState.PushNumber(a_BlockMeta); - if (!m_LuaState.CallFunction(10, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -761,18 +747,18 @@ bool cPlugin_NewLua::OnPlayerPlacingBlock(cPlayer & a_Player, int a_BlockX, int return false; } - tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); - tolua_pushnumber (m_LuaState, a_BlockX); - tolua_pushnumber (m_LuaState, a_BlockY); - tolua_pushnumber (m_LuaState, a_BlockZ); - tolua_pushnumber (m_LuaState, a_BlockFace); - tolua_pushnumber (m_LuaState, a_CursorX); - tolua_pushnumber (m_LuaState, a_CursorY); - tolua_pushnumber (m_LuaState, a_CursorZ); - tolua_pushnumber (m_LuaState, a_BlockType); - tolua_pushnumber (m_LuaState, a_BlockMeta); + m_LuaState.PushObject(&a_Player); + m_LuaState.PushNumber(a_BlockX); + m_LuaState.PushNumber(a_BlockY); + m_LuaState.PushNumber(a_BlockZ); + m_LuaState.PushNumber(a_BlockFace); + m_LuaState.PushNumber(a_CursorX); + m_LuaState.PushNumber(a_CursorY); + m_LuaState.PushNumber(a_CursorZ); + m_LuaState.PushNumber(a_BlockType); + m_LuaState.PushNumber(a_BlockMeta); - if (!m_LuaState.CallFunction(10, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -796,16 +782,16 @@ bool cPlugin_NewLua::OnPlayerRightClick(cPlayer & a_Player, int a_BlockX, int a_ return false; } - tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); - tolua_pushnumber (m_LuaState, a_BlockX); - tolua_pushnumber (m_LuaState, a_BlockY); - tolua_pushnumber (m_LuaState, a_BlockZ); - tolua_pushnumber (m_LuaState, a_BlockFace); - tolua_pushnumber (m_LuaState, a_CursorX); - tolua_pushnumber (m_LuaState, a_CursorY); - tolua_pushnumber (m_LuaState, a_CursorZ); + m_LuaState.PushObject(&a_Player); + m_LuaState.PushNumber(a_BlockX); + m_LuaState.PushNumber(a_BlockY); + m_LuaState.PushNumber(a_BlockZ); + m_LuaState.PushNumber(a_BlockFace); + m_LuaState.PushNumber(a_CursorX); + m_LuaState.PushNumber(a_CursorY); + m_LuaState.PushNumber(a_CursorZ); - if (!m_LuaState.CallFunction(8, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -829,10 +815,10 @@ bool cPlugin_NewLua::OnPlayerRightClickingEntity(cPlayer & a_Player, cEntity & a return false; } - tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); - tolua_pushusertype(m_LuaState, &a_Entity, "cEntity"); + m_LuaState.PushObject(&a_Player); + m_LuaState.PushObject(&a_Entity); - if (!m_LuaState.CallFunction(2, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -856,9 +842,9 @@ bool cPlugin_NewLua::OnPlayerShooting(cPlayer & a_Player) return false; } - tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); + m_LuaState.PushObject(&a_Player); - if (!m_LuaState.CallFunction(1, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -882,9 +868,9 @@ bool cPlugin_NewLua::OnPlayerSpawned(cPlayer & a_Player) return false; } - tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); + m_LuaState.PushObject(&a_Player); - if (!m_LuaState.CallFunction(1, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -908,9 +894,9 @@ bool cPlugin_NewLua::OnPlayerTossingItem(cPlayer & a_Player) return false; } - tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); + m_LuaState.PushObject(&a_Player); - if (!m_LuaState.CallFunction(1, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -934,18 +920,18 @@ bool cPlugin_NewLua::OnPlayerUsedBlock(cPlayer & a_Player, int a_BlockX, int a_B return false; } - tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); - tolua_pushnumber (m_LuaState, a_BlockX); - tolua_pushnumber (m_LuaState, a_BlockY); - tolua_pushnumber (m_LuaState, a_BlockZ); - tolua_pushnumber (m_LuaState, a_BlockFace); - tolua_pushnumber (m_LuaState, a_CursorX); - tolua_pushnumber (m_LuaState, a_CursorY); - tolua_pushnumber (m_LuaState, a_CursorZ); - tolua_pushnumber (m_LuaState, a_BlockType); - tolua_pushnumber (m_LuaState, a_BlockMeta); + m_LuaState.PushObject(&a_Player); + m_LuaState.PushNumber(a_BlockX); + m_LuaState.PushNumber(a_BlockY); + m_LuaState.PushNumber(a_BlockZ); + m_LuaState.PushNumber(a_BlockFace); + m_LuaState.PushNumber(a_CursorX); + m_LuaState.PushNumber(a_CursorY); + m_LuaState.PushNumber(a_CursorZ); + m_LuaState.PushNumber(a_BlockType); + m_LuaState.PushNumber(a_BlockMeta); - if (!m_LuaState.CallFunction(10, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -969,16 +955,16 @@ bool cPlugin_NewLua::OnPlayerUsedItem(cPlayer & a_Player, int a_BlockX, int a_Bl return false; } - tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); - tolua_pushnumber (m_LuaState, a_BlockX); - tolua_pushnumber (m_LuaState, a_BlockY); - tolua_pushnumber (m_LuaState, a_BlockZ); - tolua_pushnumber (m_LuaState, a_BlockFace); - tolua_pushnumber (m_LuaState, a_CursorX); - tolua_pushnumber (m_LuaState, a_CursorY); - tolua_pushnumber (m_LuaState, a_CursorZ); + m_LuaState.PushObject(&a_Player); + m_LuaState.PushNumber(a_BlockX); + m_LuaState.PushNumber(a_BlockY); + m_LuaState.PushNumber(a_BlockZ); + m_LuaState.PushNumber(a_BlockFace); + m_LuaState.PushNumber(a_CursorX); + m_LuaState.PushNumber(a_CursorY); + m_LuaState.PushNumber(a_CursorZ); - if (!m_LuaState.CallFunction(8, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -1002,18 +988,18 @@ bool cPlugin_NewLua::OnPlayerUsingBlock(cPlayer & a_Player, int a_BlockX, int a_ return false; } - tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); - tolua_pushnumber (m_LuaState, a_BlockX); - tolua_pushnumber (m_LuaState, a_BlockY); - tolua_pushnumber (m_LuaState, a_BlockZ); - tolua_pushnumber (m_LuaState, a_BlockFace); - tolua_pushnumber (m_LuaState, a_CursorX); - tolua_pushnumber (m_LuaState, a_CursorY); - tolua_pushnumber (m_LuaState, a_CursorZ); - tolua_pushnumber (m_LuaState, a_BlockType); - tolua_pushnumber (m_LuaState, a_BlockMeta); + m_LuaState.PushObject(&a_Player); + m_LuaState.PushNumber(a_BlockX); + m_LuaState.PushNumber(a_BlockY); + m_LuaState.PushNumber(a_BlockZ); + m_LuaState.PushNumber(a_BlockFace); + m_LuaState.PushNumber(a_CursorX); + m_LuaState.PushNumber(a_CursorY); + m_LuaState.PushNumber(a_CursorZ); + m_LuaState.PushNumber(a_BlockType); + m_LuaState.PushNumber(a_BlockMeta); - if (!m_LuaState.CallFunction(10, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -1037,16 +1023,16 @@ bool cPlugin_NewLua::OnPlayerUsingItem(cPlayer & a_Player, int a_BlockX, int a_B return false; } - tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); - tolua_pushnumber (m_LuaState, a_BlockX); - tolua_pushnumber (m_LuaState, a_BlockY); - tolua_pushnumber (m_LuaState, a_BlockZ); - tolua_pushnumber (m_LuaState, a_BlockFace); - tolua_pushnumber (m_LuaState, a_CursorX); - tolua_pushnumber (m_LuaState, a_CursorY); - tolua_pushnumber (m_LuaState, a_CursorZ); + m_LuaState.PushObject(&a_Player); + m_LuaState.PushNumber(a_BlockX); + m_LuaState.PushNumber(a_BlockY); + m_LuaState.PushNumber(a_BlockZ); + m_LuaState.PushNumber(a_BlockFace); + m_LuaState.PushNumber(a_CursorX); + m_LuaState.PushNumber(a_CursorY); + m_LuaState.PushNumber(a_CursorZ); - if (!m_LuaState.CallFunction(8, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -1070,11 +1056,11 @@ bool cPlugin_NewLua::OnPostCrafting(const cPlayer * a_Player, const cCraftingGri return false; } - tolua_pushusertype(m_LuaState, (void *)a_Player, "cPlayer"); - tolua_pushusertype(m_LuaState, (void *)a_Grid, "cCraftingGrid"); - tolua_pushusertype(m_LuaState, (void *)a_Recipe, "cCraftingRecipe"); + m_LuaState.PushUserType((void *)a_Player, "cPlayer"); + m_LuaState.PushUserType((void *)a_Grid, "cCraftingGrid"); + m_LuaState.PushUserType((void *)a_Recipe, "cCraftingRecipe"); - if (!m_LuaState.CallFunction(3, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -1098,11 +1084,11 @@ bool cPlugin_NewLua::OnPreCrafting(const cPlayer * a_Player, const cCraftingGrid return false; } - tolua_pushusertype(m_LuaState, (void *)a_Player, "cPlayer"); - tolua_pushusertype(m_LuaState, (void *)a_Grid, "cCraftingGrid"); - tolua_pushusertype(m_LuaState, (void *)a_Recipe, "cCraftingRecipe"); + m_LuaState.PushUserType((void *)a_Player, "cPlayer"); + m_LuaState.PushUserType((void *)a_Grid, "cCraftingGrid"); + m_LuaState.PushUserType((void *)a_Recipe, "cCraftingRecipe"); - if (!m_LuaState.CallFunction(3, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -1126,10 +1112,10 @@ bool cPlugin_NewLua::OnTakeDamage(cEntity & a_Receiver, TakeDamageInfo & a_TDI) return false; } - tolua_pushusertype(m_LuaState, &a_Receiver, "cEntity"); - tolua_pushusertype(m_LuaState, &a_TDI, "TakeDamageInfo"); + m_LuaState.PushObject(&a_Receiver); + m_LuaState.PushUserType(&a_TDI, "TakeDamageInfo"); - if (!m_LuaState.CallFunction(2, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -1158,17 +1144,17 @@ bool cPlugin_NewLua::OnUpdatedSign( return false; } - tolua_pushusertype(m_LuaState, (void *)a_World, "cWorld"); - tolua_pushnumber (m_LuaState, a_BlockX); - tolua_pushnumber (m_LuaState, a_BlockY); - tolua_pushnumber (m_LuaState, a_BlockZ); - tolua_pushstring (m_LuaState, a_Line1.c_str()); - tolua_pushstring (m_LuaState, a_Line2.c_str()); - tolua_pushstring (m_LuaState, a_Line3.c_str()); - tolua_pushstring (m_LuaState, a_Line4.c_str()); - tolua_pushusertype(m_LuaState, (void *)a_Player, "cPlayer"); + m_LuaState.PushObject(a_World); + m_LuaState.PushNumber(a_BlockX); + m_LuaState.PushNumber(a_BlockY); + m_LuaState.PushNumber(a_BlockZ); + m_LuaState.PushString(a_Line1.c_str()); + m_LuaState.PushString(a_Line2.c_str()); + m_LuaState.PushString(a_Line3.c_str()); + m_LuaState.PushString(a_Line4.c_str()); + m_LuaState.PushObject(a_Player); - if (!m_LuaState.CallFunction(9, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -1197,17 +1183,17 @@ bool cPlugin_NewLua::OnUpdatingSign( return false; } - tolua_pushusertype(m_LuaState, (void *)a_World, "cWorld"); - tolua_pushnumber (m_LuaState, a_BlockX); - tolua_pushnumber (m_LuaState, a_BlockY); - tolua_pushnumber (m_LuaState, a_BlockZ); - tolua_pushstring (m_LuaState, a_Line1.c_str()); - tolua_pushstring (m_LuaState, a_Line2.c_str()); - tolua_pushstring (m_LuaState, a_Line3.c_str()); - tolua_pushstring (m_LuaState, a_Line4.c_str()); - tolua_pushusertype(m_LuaState, (void *)a_Player, "cPlayer"); + m_LuaState.PushObject(a_World); + m_LuaState.PushNumber(a_BlockX); + m_LuaState.PushNumber(a_BlockY); + m_LuaState.PushNumber(a_BlockZ); + m_LuaState.PushString(a_Line1.c_str()); + m_LuaState.PushString(a_Line2.c_str()); + m_LuaState.PushString(a_Line3.c_str()); + m_LuaState.PushString(a_Line4.c_str()); + m_LuaState.PushObject(a_Player); - if (!m_LuaState.CallFunction(9, 5, "OnUpdatingSign")) + if (!m_LuaState.CallFunction(5)) { return false; } @@ -1247,9 +1233,9 @@ bool cPlugin_NewLua::OnWeatherChanged(cWorld & a_World) return false; } - tolua_pushusertype(m_LuaState, &a_World, "cWorld"); + m_LuaState.PushObject(&a_World); - if (!m_LuaState.CallFunction(1, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -1273,10 +1259,10 @@ bool cPlugin_NewLua::OnWeatherChanging(cWorld & a_World, eWeather & a_NewWeather return false; } - tolua_pushusertype(m_LuaState, &a_World, "cWorld"); - tolua_pushnumber (m_LuaState, a_NewWeather); + m_LuaState.PushObject(&a_World); + m_LuaState.PushNumber(a_NewWeather); - if (!m_LuaState.CallFunction(2, 2, FnName)) + if (!m_LuaState.CallFunction(2)) { return false; } @@ -1313,14 +1299,11 @@ bool cPlugin_NewLua::HandleCommand(const AStringVector & a_Split, cPlayer * a_Pl return false; } - // Push the split: m_LuaState.PushStringVector(a_Split); - - // Push player: - tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); + m_LuaState.PushObject(a_Player); // Call function: - if (!m_LuaState.CallFunction(2, 1, __FUNCTION__)) + if (!m_LuaState.CallFunction(1)) { LOGWARNING("LUA error in %s. Stack size: %i", __FUNCTION__, lua_gettop(m_LuaState)); return false; @@ -1352,23 +1335,12 @@ bool cPlugin_NewLua::HandleConsoleCommand(const AStringVector & a_Split, cComman cCSLock Lock(m_CriticalSection); // Push the function to be called: - lua_rawgeti(m_LuaState, LUA_REGISTRYINDEX, cmd->second); // same as lua_getref() + m_LuaState.PushFunctionFromRegistry(cmd->second); - // Push the split: - lua_createtable(m_LuaState, a_Split.size(), 0); - int newTable = lua_gettop(m_LuaState); - int index = 1; - std::vector::const_iterator iter = a_Split.begin(), end = a_Split.end(); - while(iter != end) - { - tolua_pushstring(m_LuaState, (*iter).c_str()); - lua_rawseti(m_LuaState, newTable, index); - ++iter; - ++index; - } + m_LuaState.PushStringVector(a_Split); // Call function: - if (!m_LuaState.CallFunction(1, 2, __FUNCTION__)) + if (!m_LuaState.CallFunction(2)) { LOGWARNING("Lua error in %s. Stack size: %i", __FUNCTION__, lua_gettop(m_LuaState)); return false; @@ -1546,29 +1518,21 @@ AString cPlugin_NewLua::HandleWebRequest(const HTTPRequest * a_Request ) if( Tab ) { - // LOGINFO("1. Stack size: %i", lua_gettop(m_LuaState) ); - lua_rawgeti( m_LuaState, LUA_REGISTRYINDEX, Tab->UserData); // same as lua_getref() + m_LuaState.PushFunctionFromRegistry(Tab->UserData); - // LOGINFO("2. Stack size: %i", lua_gettop(m_LuaState) ); // Push HTTPRequest - tolua_pushusertype( m_LuaState, (void*)a_Request, "const HTTPRequest" ); - // LOGINFO("Calling bound function! :D"); - int s = lua_pcall( m_LuaState, 1, 1, 0); - - if ( s != 0 ) + m_LuaState.PushUserType((void*)a_Request, "const HTTPRequest"); + + if (!m_LuaState.CallFunction(1)) { - std::string err = lua_tostring(m_LuaState, -1); - LOGERROR("-- %s", err.c_str() ); - lua_pop(m_LuaState, 1); - LOGINFO("error. Stack size: %i", lua_gettop(m_LuaState) ); - return err; // Show the error message in the web page, looks cool + return "Lua encountered error while processing the page request"; } - if( !lua_isstring( m_LuaState, -1 ) ) + if (!lua_isstring(m_LuaState, -1)) { - LOGWARN("WARNING: WebPlugin tab '%s' did not return a string!", Tab->Title.c_str() ); - lua_pop(m_LuaState, 1); // Pop return value - return std::string("WARNING: WebPlugin tab '") + Tab->Title + std::string("' did not return a string!"); + LOGWARNING("WebPlugin tab '%s' did not return a string!", Tab->Title.c_str()); + lua_pop(m_LuaState, 1); // Pop return value + return Printf("WARNING: WebPlugin tab '%s' did not return a string!", Tab->Title.c_str()); } RetVal += tolua_tostring(m_LuaState, -1, 0); @@ -1640,13 +1604,13 @@ bool cPlugin_NewLua::CallbackWindowClosing(int a_FnRef, cWindow & a_Window, cPla ASSERT(a_FnRef != LUA_REFNIL); cCSLock Lock(m_CriticalSection); - lua_rawgeti(m_LuaState, LUA_REGISTRYINDEX, a_FnRef); // Push the function to be called - tolua_pushusertype(m_LuaState, &a_Window, "cWindow"); - tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); - tolua_pushboolean (m_LuaState, a_CanRefuse ? 1 : 0); + m_LuaState.PushFunctionFromRegistry(a_FnRef); + m_LuaState.PushUserType(&a_Window, "cWindow"); + m_LuaState.PushObject(&a_Player); + m_LuaState.PushBool(a_CanRefuse); // Call function: - if (!m_LuaState.CallFunction(3, 1, __FUNCTION__)) + if (!m_LuaState.CallFunction(1)) { LOGWARNING("LUA error in %s. Stack size: %i", __FUNCTION__, lua_gettop(m_LuaState)); return false; @@ -1666,12 +1630,12 @@ void cPlugin_NewLua::CallbackWindowSlotChanged(int a_FnRef, cWindow & a_Window, ASSERT(a_FnRef != LUA_REFNIL); cCSLock Lock(m_CriticalSection); - lua_rawgeti(m_LuaState, LUA_REGISTRYINDEX, a_FnRef); // Push the function to be called - tolua_pushusertype(m_LuaState, &a_Window, "cWindow"); - tolua_pushnumber (m_LuaState, a_SlotNum); + m_LuaState.PushFunctionFromRegistry(a_FnRef); + m_LuaState.PushUserType(&a_Window, "cWindow"); + m_LuaState.PushNumber(a_SlotNum); // Call function: - if (!m_LuaState.CallFunction(2, 0, __FUNCTION__)) + if (!m_LuaState.CallFunction(0)) { LOGWARNING("LUA error in %s. Stack size: %i", __FUNCTION__, lua_gettop(m_LuaState)); } -- cgit v1.2.3 From 4034136922a5b47450fa25c6be4bc35411a8d1ba Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 6 Aug 2013 17:17:26 +0200 Subject: cLuaState is used for pushing splits in ManualBindings --- source/ManualBindings.cpp | 31 ++++++++----------------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/source/ManualBindings.cpp b/source/ManualBindings.cpp index 141335602..292b33726 100644 --- a/source/ManualBindings.cpp +++ b/source/ManualBindings.cpp @@ -25,13 +25,6 @@ -// fwd: LuaCommandBinder.cpp -// bool cLuaState::ReportErrors(lua_State* lua, int status); - - - - - /**************************** * Better error reporting for Lua **/ @@ -84,23 +77,14 @@ int lua_do_error(lua_State* L, const char * a_pFormat, ...) * Lua bound functions with special return types **/ -static int tolua_StringSplit(lua_State* tolua_S) +static int tolua_StringSplit(lua_State * tolua_S) { - std::string str = ((std::string) tolua_tocppstring(tolua_S,1,0)); - std::string delim = ((std::string) tolua_tocppstring(tolua_S,2,0)); - - AStringVector Split = StringSplit( str, delim ); + cLuaState LuaState(tolua_S); + std::string str = (std::string)tolua_tocppstring(LuaState, 1, 0); + std::string delim = (std::string)tolua_tocppstring(LuaState, 2, 0); - lua_createtable(tolua_S, Split.size(), 0); - int newTable = lua_gettop(tolua_S); - int index = 1; - std::vector::const_iterator iter = Split.begin(); - while(iter != Split.end()) { - tolua_pushstring( tolua_S, (*iter).c_str() ); - lua_rawseti(tolua_S, newTable, index); - ++iter; - ++index; - } + AStringVector Split = StringSplit(str, delim); + LuaState.PushStringVector(Split); return 1; } @@ -158,7 +142,8 @@ cPlugin_NewLua * GetLuaPlugin(lua_State * L) lua_getglobal(L, LUA_PLUGIN_INSTANCE_VAR_NAME); if (!lua_islightuserdata(L, -1)) { - LOGERROR("%s: cannot get plugin instance, what have you done to my Lua state?", __FUNCTION__); + LOGWARNING("%s: cannot get plugin instance, what have you done to my Lua state?", __FUNCTION__); + lua_pop(L); return NULL; } cPlugin_NewLua * Plugin = (cPlugin_NewLua *)lua_topointer(L, -1); -- cgit v1.2.3 From 0281b1db6e862af628bd9ea6712ce7e2f66cc4d8 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 6 Aug 2013 19:27:48 +0200 Subject: Fixed compilation in ManualBindings --- source/ManualBindings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ManualBindings.cpp b/source/ManualBindings.cpp index 292b33726..f428b0905 100644 --- a/source/ManualBindings.cpp +++ b/source/ManualBindings.cpp @@ -143,7 +143,7 @@ cPlugin_NewLua * GetLuaPlugin(lua_State * L) if (!lua_islightuserdata(L, -1)) { LOGWARNING("%s: cannot get plugin instance, what have you done to my Lua state?", __FUNCTION__); - lua_pop(L); + lua_pop(L, 1); return NULL; } cPlugin_NewLua * Plugin = (cPlugin_NewLua *)lua_topointer(L, -1); -- cgit v1.2.3 From c55fabb5ad34ec57760b90ea11960f7f426990db Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 6 Aug 2013 19:28:09 +0200 Subject: cLuaScript now uses cLuaState --- MCServer/webadmin/template.lua | 16 ++- source/LuaScript.cpp | 232 +++-------------------------------------- source/LuaScript.h | 36 +++---- source/LuaState.cpp | 2 +- source/WebAdmin.cpp | 8 +- 5 files changed, 51 insertions(+), 243 deletions(-) diff --git a/MCServer/webadmin/template.lua b/MCServer/webadmin/template.lua index f508ad5aa..1ab1aab88 100644 --- a/MCServer/webadmin/template.lua +++ b/MCServer/webadmin/template.lua @@ -4,6 +4,10 @@ function Output(String) table.insert(SiteContent, String) end + + + + function GetTableSize(Table) local Size = 0 for key,value in pairs(Table) do @@ -12,6 +16,10 @@ function GetTableSize(Table) return Size end + + + + function GetDefaultPage() local PM = cRoot:Get():GetPluginManager() @@ -42,11 +50,15 @@ function GetDefaultPage() return Content, SubTitle end + + + + function ShowPage(WebAdmin, TemplateRequest) SiteContent = {} local BaseURL = WebAdmin:GetBaseURL(TemplateRequest.Request.Path) local Title = "MCServer" - local MemoryUsage = WebAdmin:GetMemoryUsage() + local MemoryUsage = cWebAdmin:GetMemoryUsage() local NumChunks = cRoot:Get():GetTotalChunkCount() local PluginPage = WebAdmin:GetPage(TemplateRequest.Request) local PageContent = PluginPage.Content @@ -408,6 +420,7 @@ function ShowPage(WebAdmin, TemplateRequest)