Fixes problems with windows:
- Changed cPlayer:OpenWindow to accept a ref, tolua adds a nil check - Close open lua window in destructor, to avoid dangling pointers
This commit is contained in:
parent
2b699dc749
commit
7922e6addb
@ -4,8 +4,10 @@
|
||||
|
||||
#include "Globals.h"
|
||||
#include "LuaWindow.h"
|
||||
#include "../Entities/Player.h"
|
||||
#include "../UI/SlotArea.h"
|
||||
#include "PluginLua.h"
|
||||
#include "Root.h"
|
||||
#include "lua/src/lauxlib.h" // Needed for LUA_REFNIL
|
||||
|
||||
|
||||
@ -51,6 +53,24 @@ cLuaWindow::~cLuaWindow()
|
||||
{
|
||||
m_Contents.RemoveListener(*this);
|
||||
|
||||
// Close open lua window from players, to avoid dangling pointers
|
||||
class cPlayerCallback : public cPlayerListCallback
|
||||
{
|
||||
virtual bool Item(cPlayer * a_Player)
|
||||
{
|
||||
if (a_Player->GetWindow() == m_LuaWindow)
|
||||
{
|
||||
a_Player->CloseWindow(false);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
cLuaWindow * m_LuaWindow;
|
||||
public:
|
||||
cPlayerCallback(cLuaWindow & a_LuaWindow) { m_LuaWindow = &a_LuaWindow; }
|
||||
} PlayerCallback(*this);
|
||||
|
||||
cRoot::Get()->ForEachPlayer(PlayerCallback);
|
||||
|
||||
// Must delete slot areas now, because they are referencing this->m_Contents and would try to access it in cWindow's
|
||||
// destructor, when the member is already gone.
|
||||
for (cSlotAreas::iterator itr = m_SlotAreas.begin(), end = m_SlotAreas.end(); itr != end; ++itr)
|
||||
|
@ -15,7 +15,8 @@
|
||||
#include "../ItemGrid.h"
|
||||
|
||||
|
||||
|
||||
class cPlayer;
|
||||
typedef cItemCallback<cPlayer> cPlayerListCallback;
|
||||
|
||||
|
||||
/** A window that has been created by a Lua plugin and is handled entirely by that plugin
|
||||
|
@ -297,7 +297,7 @@ bool cBeaconEntity::UsedBy(cPlayer * a_Player)
|
||||
// if (a_Player->GetWindow() != Window)
|
||||
// -> Because mojang doesn't send a 'close window' packet when you click the cancel button in the beacon inventory ...
|
||||
{
|
||||
a_Player->OpenWindow(Window);
|
||||
a_Player->OpenWindow(*Window);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -65,7 +65,7 @@ bool cBrewingstandEntity::UsedBy(cPlayer * a_Player)
|
||||
{
|
||||
if (a_Player->GetWindow() != Window)
|
||||
{
|
||||
a_Player->OpenWindow(Window);
|
||||
a_Player->OpenWindow(*Window);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,7 +101,7 @@ bool cChestEntity::UsedBy(cPlayer * a_Player)
|
||||
{
|
||||
if (a_Player->GetWindow() != Window)
|
||||
{
|
||||
a_Player->OpenWindow(Window);
|
||||
a_Player->OpenWindow(*Window);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -153,7 +153,7 @@ bool cDropSpenserEntity::UsedBy(cPlayer * a_Player)
|
||||
{
|
||||
if (a_Player->GetWindow() != Window)
|
||||
{
|
||||
a_Player->OpenWindow(Window);
|
||||
a_Player->OpenWindow(*Window);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -66,7 +66,7 @@ bool cEnderChestEntity::UsedBy(cPlayer * a_Player)
|
||||
{
|
||||
if (a_Player->GetWindow() != Window)
|
||||
{
|
||||
a_Player->OpenWindow(Window);
|
||||
a_Player->OpenWindow(*Window);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -69,7 +69,7 @@ bool cFurnaceEntity::UsedBy(cPlayer * a_Player)
|
||||
{
|
||||
if (a_Player->GetWindow() != Window)
|
||||
{
|
||||
a_Player->OpenWindow(Window);
|
||||
a_Player->OpenWindow(*Window);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,7 +95,7 @@ bool cHopperEntity::UsedBy(cPlayer * a_Player)
|
||||
{
|
||||
if (a_Player->GetWindow() != Window)
|
||||
{
|
||||
a_Player->OpenWindow(Window);
|
||||
a_Player->OpenWindow(*Window);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,7 @@ public:
|
||||
virtual bool OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override
|
||||
{
|
||||
cWindow * Window = new cAnvilWindow(a_BlockX, a_BlockY, a_BlockZ);
|
||||
a_Player->OpenWindow(Window);
|
||||
a_Player->OpenWindow(*Window);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ public:
|
||||
virtual bool OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override
|
||||
{
|
||||
cWindow * Window = new cEnchantingWindow(a_BlockX, a_BlockY, a_BlockZ);
|
||||
a_Player->OpenWindow(Window);
|
||||
a_Player->OpenWindow(*Window);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ public:
|
||||
virtual bool OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override
|
||||
{
|
||||
cWindow * Window = new cCraftingWindow(a_BlockX, a_BlockY, a_BlockZ);
|
||||
a_Player->OpenWindow(Window);
|
||||
a_Player->OpenWindow(*Window);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1222,7 +1222,7 @@ void cMinecartWithChest::OnRightClicked(cPlayer & a_Player)
|
||||
{
|
||||
if (a_Player.GetWindow() != Window)
|
||||
{
|
||||
a_Player.OpenWindow(Window);
|
||||
a_Player.OpenWindow(*Window);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1310,15 +1310,15 @@ cTeam * cPlayer::UpdateTeam(void)
|
||||
|
||||
|
||||
|
||||
void cPlayer::OpenWindow(cWindow * a_Window)
|
||||
void cPlayer::OpenWindow(cWindow & a_Window)
|
||||
{
|
||||
if (a_Window != m_CurrentWindow)
|
||||
if (&a_Window != m_CurrentWindow)
|
||||
{
|
||||
CloseWindow(false);
|
||||
}
|
||||
a_Window->OpenedByPlayer(*this);
|
||||
m_CurrentWindow = a_Window;
|
||||
a_Window->SendWholeWindow(*GetClientHandle());
|
||||
a_Window.OpenedByPlayer(*this);
|
||||
m_CurrentWindow = &a_Window;
|
||||
a_Window.SendWholeWindow(*GetClientHandle());
|
||||
}
|
||||
|
||||
|
||||
|
@ -229,7 +229,7 @@ public:
|
||||
// tolua_begin
|
||||
|
||||
/** Opens the specified window; closes the current one first using CloseWindow() */
|
||||
void OpenWindow(cWindow * a_Window);
|
||||
void OpenWindow(cWindow & a_Window);
|
||||
|
||||
/** Closes the current window, resets current window to m_InventoryWindow. A plugin may refuse the closing if a_CanRefuse is true */
|
||||
void CloseWindow(bool a_CanRefuse = true);
|
||||
|
Loading…
Reference in New Issue
Block a user