1
0

Merge pull request #1598 from mc-server/SignEditor

Fixed a security problem with signs.
This commit is contained in:
Mattes D 2014-11-18 08:52:48 +01:00
commit 9ece37e8f1
7 changed files with 85 additions and 21 deletions

View File

@ -2500,7 +2500,7 @@ end
SetCommandBlocksEnabled = { Params = "IsEnabled (bool)", Return = "", Notes = "Sets whether command blocks should be enabled on the (entire) server." },
SetShouldUseChatPrefixes = { Params = "", Return = "ShouldUse (bool)", Notes = "Sets whether coloured chat prefixes such as [INFO] is used with the SendMessageXXX() or BroadcastChatXXX(), or simply the entire message is coloured in the respective colour." },
ShouldUseChatPrefixes = { Params = "", Return = "bool", Notes = "Returns whether coloured chat prefixes are prepended to chat messages or the entire message is simply coloured." },
SetSignLines = { Params = "X, Y, Z, Line1, Line2, Line3, Line4, [{{cPlayer|Player}}]", Return = "", Notes = "Sets the sign text at the specified coords. The sign-updating hooks are called for the change. The Player parameter is used to indicate the player from whom the change has come, it may be nil. Same as UpdateSign()." },
SetSignLines = { Params = "X, Y, Z, Line1, Line2, Line3, Line4, [{{cPlayer|Player}}]", Return = "", Notes = "Sets the sign text at the specified coords. The sign-updating hooks are called for the change. The Player parameter is used to indicate the player from whom the change has come, it may be nil." },
SetTicksUntilWeatherChange = { Params = "NumTicks", Return = "", Notes = "Sets the number of ticks after which the weather will be changed." },
SetTimeOfDay = { Params = "TimeOfDayTicks", Return = "", Notes = "Sets the time of day, expressed as number of ticks past sunrise, in the range 0 .. 24000." },
SetWeather = { Params = "Weather", Return = "", Notes = "Sets the current weather (wSunny, wRain, wStorm) and resets the TicksUntilWeatherChange to the default value for the new weather. The normal weather-changing hooks are called for the change." },
@ -2515,7 +2515,7 @@ end
SpawnExperienceOrb = { Params = "X, Y, Z, Reward", Return = "EntityID", Notes = "Spawns an {{cExpOrb|experience orb}} at the specified coords, with the given reward" },
SpawnPrimedTNT = { Params = "X, Y, Z, FuseTicks, InitialVelocityCoeff", Return = "", Notes = "Spawns a {{cTNTEntity|primed TNT entity}} at the specified coords, with the given fuse ticks. The entity gets a random speed multiplied by the InitialVelocityCoeff, 1 being the default value." },
TryGetHeight = { Params = "BlockX, BlockZ", Return = "IsValid, Height", Notes = "Returns true and height of the highest non-air block if the chunk is loaded, or false otherwise." },
UpdateSign = { Params = "X, Y, Z, Line1, Line2, Line3, Line4, [{{cPlayer|Player}}]", Return = "", Notes = "Sets the sign text at the specified coords. The sign-updating hooks are called for the change. The Player parameter is used to indicate the player from whom the change has come, it may be nil. Same as SetSignLiens()" },
UpdateSign = { Params = "X, Y, Z, Line1, Line2, Line3, Line4, [{{cPlayer|Player}}]", Return = "", Notes = "(<b>DEPRECATED</b>) Please use SetSignLines()." },
UseBlockEntity = { Params = "{{cPlayer|Player}}, BlockX, BlockY, BlockZ", Return = "", Notes = "Makes the specified Player use the block entity at the specified coords (open chest UI, etc.) If the cords are in an unloaded chunk or there's no block entity, ignores the call." },
WakeUpSimulators = { Params = "BlockX, BlockY, BlockZ", Return = "", Notes = "Wakes up the simulators for the specified block." },
WakeUpSimulatorsInArea = { Params = "MinBlockX, MaxBlockX, MinBlockY, MaxBlockY, MinBlockZ, MaxBlockZ", Return = "", Notes = "Wakes up the simulators for all the blocks in the specified area (edges inclusive)." },

View File

@ -7,6 +7,9 @@
#include "../BlockInfo.h"
#include "../World.h"
#include "../Entities/Player.h"
#include "LuaState.h"
@ -222,6 +225,64 @@ static int tolua_get_AllToLua_g_BlockFullyOccupiesVoxel(lua_State* tolua_S)
/** function: cWorld:SetSignLines */
static int tolua_cWorld_SetSignLines(lua_State * tolua_S)
{
cLuaState LuaState(tolua_S);
#ifndef TOLUA_RELEASE
tolua_Error tolua_err;
if (
!tolua_isusertype (LuaState, 1, "cWorld", 0, &tolua_err) ||
!tolua_isnumber (LuaState, 2, 0, &tolua_err) ||
!tolua_isnumber (LuaState, 3, 0, &tolua_err) ||
!tolua_isnumber (LuaState, 4, 0, &tolua_err) ||
!tolua_iscppstring(LuaState, 5, 0, &tolua_err) ||
!tolua_iscppstring(LuaState, 6, 0, &tolua_err) ||
!tolua_iscppstring(LuaState, 7, 0, &tolua_err) ||
!tolua_iscppstring(LuaState, 8, 0, &tolua_err) ||
!tolua_isusertype (LuaState, 9, "cPlayer", 1, &tolua_err) ||
!tolua_isnoobj (LuaState, 10, &tolua_err)
)
goto tolua_lerror;
else
#endif
{
cWorld * self = (cWorld *) tolua_tousertype (LuaState, 1, nullptr);
int BlockX = (int) tolua_tonumber (LuaState, 2, 0);
int BlockY = (int) tolua_tonumber (LuaState, 3, 0);
int BlockZ = (int) tolua_tonumber (LuaState, 4, 0);
const AString Line1 = tolua_tocppstring(LuaState, 5, 0);
const AString Line2 = tolua_tocppstring(LuaState, 6, 0);
const AString Line3 = tolua_tocppstring(LuaState, 7, 0);
const AString Line4 = tolua_tocppstring(LuaState, 8, 0);
cPlayer * Player = (cPlayer *)tolua_tousertype (LuaState, 9, nullptr);
#ifndef TOLUA_RELEASE
if (self == nullptr)
{
tolua_error(LuaState, "invalid 'self' in function 'UpdateSign'", nullptr);
}
#endif
{
bool res = self->SetSignLines(BlockX, BlockY, BlockZ, Line1, Line2, Line3, Line4, Player);
tolua_pushboolean(LuaState, res ? 1 : 0);
}
}
LOGWARNING("Warning in function call 'UpdateSign': UpdateSign() is deprecated. Please use SetSignLines()");
LuaState.LogStackTrace(0);
return 1;
#ifndef TOLUA_RELEASE
tolua_lerror:
tolua_error(LuaState, "#ferror in function 'UpdateSign'.", &tolua_err);
return 0;
#endif
}
void DeprecatedBindings::Bind(lua_State * tolua_S)
{
tolua_beginmodule(tolua_S, nullptr);
@ -235,6 +296,10 @@ void DeprecatedBindings::Bind(lua_State * tolua_S)
tolua_array(tolua_S, "g_BlockIsSolid", tolua_get_AllToLua_g_BlockIsSolid, nullptr);
tolua_array(tolua_S, "g_BlockFullyOccupiesVoxel", tolua_get_AllToLua_g_BlockFullyOccupiesVoxel, nullptr);
tolua_beginmodule(tolua_S, "cWorld");
tolua_function(tolua_S, "UpdateSign", tolua_cWorld_SetSignLines);
tolua_endmodule(tolua_S);
tolua_endmodule(tolua_S);
}

View File

@ -1034,11 +1034,11 @@ static int tolua_cWorld_SetSignLines(lua_State * tolua_S)
#ifndef TOLUA_RELEASE
if (self == nullptr)
{
tolua_error(tolua_S, "invalid 'self' in function 'SetSignLines' / 'UpdateSign'", nullptr);
tolua_error(tolua_S, "invalid 'self' in function 'SetSignLines'", nullptr);
}
#endif
{
bool res = self->UpdateSign(BlockX, BlockY, BlockZ, Line1, Line2, Line3, Line4, Player);
bool res = self->SetSignLines(BlockX, BlockY, BlockZ, Line1, Line2, Line3, Line4, Player);
tolua_pushboolean(tolua_S, res ? 1 : 0);
}
}
@ -1046,7 +1046,7 @@ static int tolua_cWorld_SetSignLines(lua_State * tolua_S)
#ifndef TOLUA_RELEASE
tolua_lerror:
tolua_error(tolua_S, "#ferror in function 'SetSignLines' / 'UpdateSign'.", &tolua_err);
tolua_error(tolua_S, "#ferror in function 'SetSignLines'.", &tolua_err);
return 0;
#endif
}
@ -3405,7 +3405,6 @@ void ManualBindings::Bind(lua_State * tolua_S)
tolua_function(tolua_S, "ScheduleTask", tolua_cWorld_ScheduleTask);
tolua_function(tolua_S, "SetSignLines", tolua_cWorld_SetSignLines);
tolua_function(tolua_S, "TryGetHeight", tolua_cWorld_TryGetHeight);
tolua_function(tolua_S, "UpdateSign", tolua_cWorld_SetSignLines);
tolua_endmodule(tolua_S);
tolua_beginmodule(tolua_S, "cMapManager");

View File

@ -94,6 +94,7 @@ cClientHandle::cClientHandle(const cSocket * a_Socket, int a_ViewDistance) :
m_UniqueID(0),
m_HasSentPlayerChunk(false),
m_Locale("en_GB"),
m_LastPlacedSign(0, -1, 0),
m_ProtocolVersion(0)
{
m_Protocol = new cProtocolRecognizer(this);
@ -1501,6 +1502,7 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, e
{
m_Player->GetInventory().RemoveOneEquippedItem();
}
cChunkInterface ChunkInterface(World->GetChunkMap());
NewBlock->OnPlacedByPlayer(ChunkInterface, *World, m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, BlockType, BlockMeta);
@ -1678,8 +1680,11 @@ void cClientHandle::HandleUpdateSign(
const AString & a_Line3, const AString & a_Line4
)
{
cWorld * World = m_Player->GetWorld();
World->UpdateSign(a_BlockX, a_BlockY, a_BlockZ, a_Line1, a_Line2, a_Line3, a_Line4, m_Player);
if (m_LastPlacedSign.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
{
m_LastPlacedSign.Set(0, -1, 0);
m_Player->GetWorld()->SetSignLines(a_BlockX, a_BlockY, a_BlockZ, a_Line1, a_Line2, a_Line3, a_Line4, m_Player);
}
}
@ -2258,6 +2263,7 @@ void cClientHandle::SendDisconnect(const AString & a_Reason)
void cClientHandle::SendEditSign(int a_BlockX, int a_BlockY, int a_BlockZ)
{
m_LastPlacedSign.Set(a_BlockX, a_BlockY, a_BlockZ);
m_Protocol->SendEditSign(a_BlockX, a_BlockY, a_BlockZ);
}

View File

@ -438,6 +438,9 @@ private:
/** Client Settings */
AString m_Locale;
/** The positions from the last sign that the player placed. It's needed to verify the sign text change. */
Vector3i m_LastPlacedSign;
/** The plugin channels that the client has registered. */
cChannels m_PluginChannels;

View File

@ -2929,15 +2929,18 @@ bool cWorld::SetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, const AStrin
AString Line2(a_Line2);
AString Line3(a_Line3);
AString Line4(a_Line4);
if (cRoot::Get()->GetPluginManager()->CallHookUpdatingSign(*this, a_BlockX, a_BlockY, a_BlockZ, Line1, Line2, Line3, Line4, a_Player))
{
return false;
}
if (m_ChunkMap->SetSignLines(a_BlockX, a_BlockY, a_BlockZ, Line1, Line2, Line3, Line4))
{
cRoot::Get()->GetPluginManager()->CallHookUpdatedSign(*this, a_BlockX, a_BlockY, a_BlockZ, Line1, Line2, Line3, Line4, a_Player);
return true;
}
return false;
}
@ -2945,15 +2948,6 @@ bool cWorld::SetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, const AStrin
bool cWorld::UpdateSign(int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player)
{
return SetSignLines(a_BlockX, a_BlockY, a_BlockZ, a_Line1, a_Line2, a_Line3, a_Line4, a_Player);
}
bool cWorld::SetCommandBlockCommand(int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Command)
{
class cUpdateCommandBlock : public cCommandBlockCallback

View File

@ -378,11 +378,8 @@ public:
/** Marks the chunk as failed-to-load: */
void ChunkLoadFailed(int a_ChunkX, int a_ChunkZ);
/** Sets the sign text, asking plugins for permission first. a_Player is the player who this change belongs to, may be nullptr. Returns true if sign text changed. Same as UpdateSign() */
/** Sets the sign text, asking plugins for permission first. a_Player is the player who this change belongs to, may be nullptr. Returns true if sign text changed. */
bool SetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player = nullptr); // Exported in ManualBindings.cpp
/** Sets the sign text, asking plugins for permission first. a_Player is the player who this change belongs to, may be nullptr. Returns true if sign text changed. Same as SetSignLines() */
bool UpdateSign(int a_X, int a_Y, int a_Z, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player = nullptr); // Exported in ManualBindings.cpp
/** Sets the command block command. Returns true if command changed. */
bool SetCommandBlockCommand(int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Command); // tolua_export