diff --git a/Plugins/Core/onblockplace.lua b/Plugins/Core/onblockplace.lua index ba75bf5c2..45d9a082e 100644 --- a/Plugins/Core/onblockplace.lua +++ b/Plugins/Core/onblockplace.lua @@ -1,3 +1,5 @@ +local BlockData = {} + function OnBlockPlace( Block, Player ) -- dont check if the direction is in the air @@ -11,43 +13,8 @@ function OnBlockPlace( Block, Player ) return true end - local collision = false - local World = Player:GetWorld() - local PlayerList = World:GetAllPlayers() - - -- check if a player occupies the placement location - for i, Player in ipairs( PlayerList ) do - - -- drop the decimals, we only care about the full block X,Y,Z - local PlayerX = math.floor(Player:GetPosX(), 0) - local PlayerY = math.floor(Player:GetPosY(), 0) - local PlayerZ = math.floor(Player:GetPosZ(), 0) - - local BlockX = Block.m_PosX - local BlockY = Block.m_PosY - local BlockZ = Block.m_PosZ - - -- player height is 2 blocks, so we check the position and then offset it up one - -- so they can't place a block on there face - - if Block.m_Direction == 0 then if PlayerY == BlockY-2 and PlayerX == BlockX and PlayerZ == BlockZ then collision = true end end - if Block.m_Direction == 1 then if PlayerY == BlockY+1 and PlayerX == BlockX and PlayerZ == BlockZ then collision = true end end - - if Block.m_Direction == 2 then if PlayerY == BlockY and PlayerX == BlockX and PlayerZ == BlockZ-1 then collision = true end end - if Block.m_Direction == 2 then if PlayerY+1 == BlockY and PlayerX == BlockX and PlayerZ == BlockZ-1 then collision = true end end - - if Block.m_Direction == 3 then if PlayerY == BlockY and PlayerX == BlockX and PlayerZ == BlockZ+1 then collision = true end end - if Block.m_Direction == 3 then if PlayerY+1 == BlockY and PlayerX == BlockX and PlayerZ == BlockZ+1 then collision = true end end - - if Block.m_Direction == 4 then if PlayerY == BlockY and PlayerX == BlockX-1 and PlayerZ == BlockZ then collision = true end end - if Block.m_Direction == 4 then if PlayerY+1 == BlockY and PlayerX == BlockX-1 and PlayerZ == BlockZ then collision = true end end - - if Block.m_Direction == 5 then if PlayerY == BlockY and PlayerX == BlockX+1 and PlayerZ == BlockZ then collision = true end end - if Block.m_Direction == 5 then if PlayerY+1 == BlockY and PlayerX == BlockX+1 and PlayerZ == BlockZ then collision = true end end - - end - - if collision then + BlockData = Block + if( Player:GetWorld():ForEachPlayer( CheckCollision ) == false ) then return true else return false @@ -57,4 +24,36 @@ function OnBlockPlace( Block, Player ) return false +end + +function CheckCollision( Player ) + -- drop the decimals, we only care about the full block X,Y,Z + local PlayerX = math.floor(Player:GetPosX(), 0) + local PlayerY = math.floor(Player:GetPosY(), 0) + local PlayerZ = math.floor(Player:GetPosZ(), 0) + + local BlockX = BlockData.m_PosX + local BlockY = BlockData.m_PosY + local BlockZ = BlockData.m_PosZ + + -- player height is 2 blocks, so we check the position and then offset it up one + -- so they can't place a block on there face + + local collision = false + if BlockData.m_Direction == 0 then if PlayerY == BlockY-2 and PlayerX == BlockX and PlayerZ == BlockZ then collision = true end end + if BlockData.m_Direction == 1 then if PlayerY == BlockY+1 and PlayerX == BlockX and PlayerZ == BlockZ then collision = true end end + + if BlockData.m_Direction == 2 then if PlayerY == BlockY and PlayerX == BlockX and PlayerZ == BlockZ-1 then collision = true end end + if BlockData.m_Direction == 2 then if PlayerY+1 == BlockY and PlayerX == BlockX and PlayerZ == BlockZ-1 then collision = true end end + + if BlockData.m_Direction == 3 then if PlayerY == BlockY and PlayerX == BlockX and PlayerZ == BlockZ+1 then collision = true end end + if BlockData.m_Direction == 3 then if PlayerY+1 == BlockY and PlayerX == BlockX and PlayerZ == BlockZ+1 then collision = true end end + + if BlockData.m_Direction == 4 then if PlayerY == BlockY and PlayerX == BlockX-1 and PlayerZ == BlockZ then collision = true end end + if BlockData.m_Direction == 4 then if PlayerY+1 == BlockY and PlayerX == BlockX-1 and PlayerZ == BlockZ then collision = true end end + + if BlockData.m_Direction == 5 then if PlayerY == BlockY and PlayerX == BlockX+1 and PlayerZ == BlockZ then collision = true end end + if BlockData.m_Direction == 5 then if PlayerY+1 == BlockY and PlayerX == BlockX+1 and PlayerZ == BlockZ then collision = true end end + + return collision end \ No newline at end of file diff --git a/Plugins/Core/playerlist.lua b/Plugins/Core/playerlist.lua index c120f068f..63990e825 100644 --- a/Plugins/Core/playerlist.lua +++ b/Plugins/Core/playerlist.lua @@ -1,16 +1,16 @@ +local PlayerTable = {} + function HandlePlayerListCommand( Split, Player ) - local World = Player:GetWorld() - local PlayerList = World:GetAllPlayers() + PlayerTable = {} + Player:GetWorld():ForEachPlayer( AppendToTable ) - local Message = cChatColor.Green .. "Connected players: (".. cChatColor.White.. #PlayerList .. cChatColor.Green .. ")" + local Message = cChatColor.Green .. "Connected players: (".. cChatColor.White.. #PlayerTable .. cChatColor.Green .. ")" Player:SendMessage( Message ) - - local PlayerTable = {} - for i, TempPlayer in ipairs( PlayerList ) do - local PlayerName = TempPlayer:GetName() - table.insert(PlayerTable, PlayerName ) - end - + Player:SendMessage( table.concat(PlayerTable, " ") ) return true +end + +function AppendToTable( Player ) + table.insert(PlayerTable, Player:GetName() ) end \ No newline at end of file diff --git a/Plugins/Core/web_playerlist.lua b/Plugins/Core/web_playerlist.lua index 6c736ce3c..62ccb1d44 100644 --- a/Plugins/Core/web_playerlist.lua +++ b/Plugins/Core/web_playerlist.lua @@ -1,3 +1,6 @@ +local PlayerHTML = "" +local PlayerNum = 0 + function HandleRequest_PlayerList( Request ) local World = cRoot:Get():GetWorld() local Content = "" @@ -16,20 +19,25 @@ function HandleRequest_PlayerList( Request ) Content = Content .. "

Connected Players: " .. World:GetNumPlayers() .. "

" Content = Content .. "" + PlayerNum = 0 + PlayerHTML = "" + World:ForEachPlayer( CreatePlayerList ) - local PlayerList = World:GetAllPlayers() - if( #PlayerList > 0 ) then - for i, Player in ipairs( PlayerList ) do - Content = Content .. "" - Content = Content .. "" - Content = Content .. "" - Content = Content .. "" - Content = Content .. "" - end + if( PlayerHTML ~= "" ) then + Content = Content .. PlayerHTML else Content = Content .. "" end Content = Content .. "
" .. i .. "." .. Player:GetName() .. "Kick
None
" Content = Content .. "
" return Content +end + +function CreatePlayerList( Player, Data ) + PlayerNum = PlayerNum + 1 + PlayerHTML = PlayerHTML .. "" + PlayerHTML = PlayerHTML .. "" .. PlayerNum .. "." + PlayerHTML = PlayerHTML .. "" .. Player:GetName() .. "" + PlayerHTML = PlayerHTML .. "Kick" + PlayerHTML = PlayerHTML .. "" end \ No newline at end of file diff --git a/source/ManualBindings.cpp b/source/ManualBindings.cpp index ba844b702..840109a8f 100644 --- a/source/ManualBindings.cpp +++ b/source/ManualBindings.cpp @@ -16,7 +16,17 @@ #include "md5/md5.h" - +static bool report_errors(lua_State* lua, int status) +{ + if ( status!=0 ) + { + std::string s = lua_tostring(lua, -1); + LOGERROR("-- %s", s.c_str() ); + lua_pop(lua, 1); + return true; + } + return false; +} /**************************** @@ -91,13 +101,59 @@ static int tolua_LOGERROR(lua_State* tolua_S) -static int tolua_cWorld_GetAllPlayers(lua_State* tolua_S) +static int tolua_cWorld_ForEachPlayer(lua_State* tolua_S) { cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); - lua_State* L = tolua_S; - self->GetAllPlayers(L); + if( !lua_isfunction( tolua_S, 2 ) ) + { + LOGWARN("Error in function call 'ForEachPlayer': Expected a function for parameter #1"); + return 0; + } + + int Reference = luaL_ref(tolua_S, LUA_REGISTRYINDEX); + if( Reference == LUA_REFNIL ) + { + LOGWARN("Error in function call 'ForEachPlayer': Could not get function reference"); + return 0; + } + + class cLuaPlayerCallback : public cPlayerListCallback + { + virtual bool Item(cPlayer * a_Player) override + { + lua_rawgeti( LuaState, LUA_REGISTRYINDEX, Reference); + tolua_pushusertype( LuaState, a_Player, "cPlayer" ); + + int s = lua_pcall( LuaState, 1, 1, 0); + if( report_errors( LuaState, s ) ) + { + return false; + } + + if( lua_isboolean( LuaState, -1 ) ) + { + return (tolua_toboolean( LuaState, -1, 0) > 0); + } + + LOGINFO("Stack size: %i", lua_gettop(LuaState) ); + + return false; + } + public: + lua_State* LuaState; + int Reference; + } Callback; + + Callback.LuaState = tolua_S; + Callback.Reference = Reference; + + bool bRetVal = self->ForEachPlayer( &Callback ); + + luaL_unref( tolua_S, LUA_REGISTRYINDEX, Reference ); + + tolua_pushboolean( tolua_S, bRetVal ); return 1; } @@ -397,7 +453,7 @@ void ManualBindings::Bind( lua_State* tolua_S ) tolua_function(tolua_S,"Log",tolua_LOG); // Deprecated tolua_beginmodule(tolua_S,"cWorld"); - tolua_function(tolua_S,"GetAllPlayers",tolua_cWorld_GetAllPlayers); + tolua_function(tolua_S,"ForEachPlayer",tolua_cWorld_ForEachPlayer); tolua_endmodule(tolua_S); tolua_beginmodule(tolua_S,"cPlugin"); tolua_function(tolua_S,"GetCommands",tolua_cPlugin_GetCommands); diff --git a/source/cWorld.cpp b/source/cWorld.cpp index c007070c6..737751901 100644 --- a/source/cWorld.cpp +++ b/source/cWorld.cpp @@ -989,26 +989,6 @@ bool cWorld::ForEachPlayer(cPlayerListCallback * a_Callback) - -void cWorld::GetAllPlayers( lua_State* L ) -{ - lua_createtable(L, m_Players.size(), 0); - int newTable = lua_gettop(L); - int index = 1; - cPlayerList::const_iterator iter = m_Players.begin(); - while(iter != m_Players.end()) - { - tolua_pushusertype( L, (*iter), "cPlayer" ); - lua_rawseti(L, newTable, index); - ++iter; - ++index; - } -} - - - - - // TODO: This interface is dangerous! cPlayer* cWorld::GetPlayer( const char* a_PlayerName ) { diff --git a/source/cWorld.h b/source/cWorld.h index b895a8a9b..146724262 100644 --- a/source/cWorld.h +++ b/source/cWorld.h @@ -76,13 +76,10 @@ public: void AddPlayer( cPlayer* a_Player ); void RemovePlayer( cPlayer* a_Player ); - bool ForEachPlayer(cPlayerListCallback * a_Callback); // Calls the callback for each player in the list - - // TODO: This interface is dangerous! - cPlayerList & GetAllPlayers() {return m_Players; } - + typedef struct lua_State lua_State; - void GetAllPlayers( lua_State* L ); // >> EXPORTED IN MANUALBINDINGS << + bool ForEachPlayer(cPlayerListCallback * a_Callback); // Calls the callback for each player in the list + // >> EXPORTED IN MANUALBINDINGS << unsigned int GetNumPlayers(); //tolua_export // TODO: This interface is dangerous