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 "Globals.h"
|
||||||
#include "LuaWindow.h"
|
#include "LuaWindow.h"
|
||||||
|
#include "../Entities/Player.h"
|
||||||
#include "../UI/SlotArea.h"
|
#include "../UI/SlotArea.h"
|
||||||
#include "PluginLua.h"
|
#include "PluginLua.h"
|
||||||
|
#include "Root.h"
|
||||||
#include "lua/src/lauxlib.h" // Needed for LUA_REFNIL
|
#include "lua/src/lauxlib.h" // Needed for LUA_REFNIL
|
||||||
|
|
||||||
|
|
||||||
@ -51,6 +53,24 @@ cLuaWindow::~cLuaWindow()
|
|||||||
{
|
{
|
||||||
m_Contents.RemoveListener(*this);
|
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
|
// 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.
|
// destructor, when the member is already gone.
|
||||||
for (cSlotAreas::iterator itr = m_SlotAreas.begin(), end = m_SlotAreas.end(); itr != end; ++itr)
|
for (cSlotAreas::iterator itr = m_SlotAreas.begin(), end = m_SlotAreas.end(); itr != end; ++itr)
|
||||||
|
@ -15,7 +15,8 @@
|
|||||||
#include "../ItemGrid.h"
|
#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
|
/** 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)
|
// if (a_Player->GetWindow() != Window)
|
||||||
// -> Because mojang doesn't send a 'close window' packet when you click the cancel button in the beacon inventory ...
|
// -> 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;
|
return true;
|
||||||
|
@ -65,7 +65,7 @@ bool cBrewingstandEntity::UsedBy(cPlayer * a_Player)
|
|||||||
{
|
{
|
||||||
if (a_Player->GetWindow() != Window)
|
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)
|
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)
|
if (a_Player->GetWindow() != Window)
|
||||||
{
|
{
|
||||||
a_Player->OpenWindow(Window);
|
a_Player->OpenWindow(*Window);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -66,7 +66,7 @@ bool cEnderChestEntity::UsedBy(cPlayer * a_Player)
|
|||||||
{
|
{
|
||||||
if (a_Player->GetWindow() != Window)
|
if (a_Player->GetWindow() != Window)
|
||||||
{
|
{
|
||||||
a_Player->OpenWindow(Window);
|
a_Player->OpenWindow(*Window);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -69,7 +69,7 @@ bool cFurnaceEntity::UsedBy(cPlayer * a_Player)
|
|||||||
{
|
{
|
||||||
if (a_Player->GetWindow() != Window)
|
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)
|
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
|
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);
|
cWindow * Window = new cAnvilWindow(a_BlockX, a_BlockY, a_BlockZ);
|
||||||
a_Player->OpenWindow(Window);
|
a_Player->OpenWindow(*Window);
|
||||||
return true;
|
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
|
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);
|
cWindow * Window = new cEnchantingWindow(a_BlockX, a_BlockY, a_BlockZ);
|
||||||
a_Player->OpenWindow(Window);
|
a_Player->OpenWindow(*Window);
|
||||||
return true;
|
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
|
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);
|
cWindow * Window = new cCraftingWindow(a_BlockX, a_BlockY, a_BlockZ);
|
||||||
a_Player->OpenWindow(Window);
|
a_Player->OpenWindow(*Window);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1222,7 +1222,7 @@ void cMinecartWithChest::OnRightClicked(cPlayer & a_Player)
|
|||||||
{
|
{
|
||||||
if (a_Player.GetWindow() != Window)
|
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);
|
CloseWindow(false);
|
||||||
}
|
}
|
||||||
a_Window->OpenedByPlayer(*this);
|
a_Window.OpenedByPlayer(*this);
|
||||||
m_CurrentWindow = a_Window;
|
m_CurrentWindow = &a_Window;
|
||||||
a_Window->SendWholeWindow(*GetClientHandle());
|
a_Window.SendWholeWindow(*GetClientHandle());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -229,7 +229,7 @@ public:
|
|||||||
// tolua_begin
|
// tolua_begin
|
||||||
|
|
||||||
/** Opens the specified window; closes the current one first using CloseWindow() */
|
/** 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 */
|
/** 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);
|
void CloseWindow(bool a_CanRefuse = true);
|
||||||
|
Loading…
Reference in New Issue
Block a user