diff --git a/MCServer/Plugins/Debuggers/Debuggers.lua b/MCServer/Plugins/Debuggers/Debuggers.lua index 12929541..e2124c07 100644 --- a/MCServer/Plugins/Debuggers/Debuggers.lua +++ b/MCServer/Plugins/Debuggers/Debuggers.lua @@ -27,6 +27,8 @@ function Initialize(Plugin) PluginManager:BindCommand("/wool", "debuggers", HandleWoolCmd, "Sets all your armor to blue wool"); PluginManager:BindCommand("/testwnd", "debuggers", HandleTestWndCmd, "Opens up a window using plugin API"); PluginManager:BindCommand("/gc", "debuggers", HandleGCCmd, "Activates the Lua garbage collector"); + PluginManager:BindCommand("/fast", "debuggers", HandleFastCmd, "Switches between fast and normal movement speed"); + PluginManager:BindCommand("/dash", "debuggers", HandleDashCmd, "Switches between fast and normal sprinting speed"); -- Enable the following line for BlockArea / Generator interface testing: -- PluginManager:AddHook(Plugin, cPluginManager.HOOK_CHUNK_GENERATED); @@ -633,6 +635,40 @@ end +function HandleFastCmd(a_Split, a_Player) + if (a_Player:GetNormalMaxSpeed() <= 0.11) then + -- The player has normal speed, set double speed: + a_Player:SetNormalMaxSpeed(0.2); + a_Player:SendMessage("You are now fast"); + else + -- The player has fast speed, set normal speed: + a_Player:SetNormalMaxSpeed(0.1); + a_Player:SendMessage("Back to normal speed"); + end + return true; +end + + + + + +function HandleDashCmd(a_Split, a_Player) + if (a_Player:GetSprintingMaxSpeed() <= 0.14) then + -- The player has normal sprinting speed, set double Sprintingspeed: + a_Player:SetSprintingMaxSpeed(0.4); + a_Player:SendMessage("You can now sprint very fast"); + else + -- The player has fast sprinting speed, set normal sprinting speed: + a_Player:SetSprintingMaxSpeed(0.13); + a_Player:SendMessage("Back to normal sprinting"); + end + return true; +end; + + + + + function OnChat(a_Player, a_Message) return false, "blabla " .. a_Message; end diff --git a/source/Bindings.cpp b/source/Bindings.cpp index ed48a856..9f201b19 100644 --- a/source/Bindings.cpp +++ b/source/Bindings.cpp @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 07/01/13 20:42:05. +** Generated automatically by tolua++-1.0.92 on 07/07/13 15:41:32. */ #ifndef __cplusplus @@ -9308,6 +9308,234 @@ static int tolua_AllToLua_cPlayer_LoadPermissionsFromDisk00(lua_State* tolua_S) return 0; #endif } +#endif //#ifndef TOLUA_DISABLE + +/* method: GetMaxSpeed of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetMaxSpeed00 +static int tolua_AllToLua_cPlayer_GetMaxSpeed00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cPlayer* self = (const cPlayer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetMaxSpeed'", NULL); +#endif + { + double tolua_ret = (double) self->GetMaxSpeed(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetMaxSpeed'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetNormalMaxSpeed of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetNormalMaxSpeed00 +static int tolua_AllToLua_cPlayer_GetNormalMaxSpeed00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cPlayer* self = (const cPlayer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetNormalMaxSpeed'", NULL); +#endif + { + double tolua_ret = (double) self->GetNormalMaxSpeed(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetNormalMaxSpeed'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetSprintingMaxSpeed of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetSprintingMaxSpeed00 +static int tolua_AllToLua_cPlayer_GetSprintingMaxSpeed00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cPlayer* self = (const cPlayer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetSprintingMaxSpeed'", NULL); +#endif + { + double tolua_ret = (double) self->GetSprintingMaxSpeed(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetSprintingMaxSpeed'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetNormalMaxSpeed of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_SetNormalMaxSpeed00 +static int tolua_AllToLua_cPlayer_SetNormalMaxSpeed00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + double a_Speed = ((double) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetNormalMaxSpeed'", NULL); +#endif + { + self->SetNormalMaxSpeed(a_Speed); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetNormalMaxSpeed'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetSprintingMaxSpeed of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_SetSprintingMaxSpeed00 +static int tolua_AllToLua_cPlayer_SetSprintingMaxSpeed00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + double a_Speed = ((double) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetSprintingMaxSpeed'", NULL); +#endif + { + self->SetSprintingMaxSpeed(a_Speed); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetSprintingMaxSpeed'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetCrouch of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_SetCrouch00 +static int tolua_AllToLua_cPlayer_SetCrouch00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isboolean(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + bool a_IsCrouched = ((bool) tolua_toboolean(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetCrouch'", NULL); +#endif + { + self->SetCrouch(a_IsCrouched); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetCrouch'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetSprint of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_SetSprint00 +static int tolua_AllToLua_cPlayer_SetSprint00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isboolean(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + bool a_IsSprinting = ((bool) tolua_toboolean(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetSprint'", NULL); +#endif + { + self->SetSprint(a_IsSprinting); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetSprint'.",&tolua_err); + return 0; +#endif +} #endif //#ifndef TOLUA_DISABLE class Lua__cPlayer : public cPlayer, public ToluaBase { @@ -12929,7 +13157,8 @@ static int tolua_AllToLua_cInventory_AddItem00(lua_State* tolua_S) !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) || (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const cItem",0,&tolua_err)) || !tolua_isboolean(tolua_S,3,1,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) + !tolua_isboolean(tolua_S,4,1,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) ) goto tolua_lerror; else @@ -12938,11 +13167,12 @@ static int tolua_AllToLua_cInventory_AddItem00(lua_State* tolua_S) cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0); const cItem* a_ItemStack = ((const cItem*) tolua_tousertype(tolua_S,2,0)); bool a_AllowNewStacks = ((bool) tolua_toboolean(tolua_S,3,true)); + bool a_tryToFillEquippedFirst = ((bool) tolua_toboolean(tolua_S,4,false)); #ifndef TOLUA_RELEASE if (!self) tolua_error(tolua_S,"invalid 'self' in function 'AddItem'", NULL); #endif { - int tolua_ret = (int) self->AddItem(*a_ItemStack,a_AllowNewStacks); + int tolua_ret = (int) self->AddItem(*a_ItemStack,a_AllowNewStacks,a_tryToFillEquippedFirst); tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); } } @@ -12965,7 +13195,8 @@ static int tolua_AllToLua_cInventory_AddItems00(lua_State* tolua_S) !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) || (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"cItems",0,&tolua_err)) || !tolua_isboolean(tolua_S,3,0,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) + !tolua_isboolean(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) ) goto tolua_lerror; else @@ -12974,11 +13205,12 @@ static int tolua_AllToLua_cInventory_AddItems00(lua_State* tolua_S) cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0); cItems* a_ItemStackList = ((cItems*) tolua_tousertype(tolua_S,2,0)); bool a_AllowNewStacks = ((bool) tolua_toboolean(tolua_S,3,0)); + bool a_tryToFillEquippedFirst = ((bool) tolua_toboolean(tolua_S,4,0)); #ifndef TOLUA_RELEASE if (!self) tolua_error(tolua_S,"invalid 'self' in function 'AddItems'", NULL); #endif { - int tolua_ret = (int) self->AddItems(*a_ItemStackList,a_AllowNewStacks,false); + int tolua_ret = (int) self->AddItems(*a_ItemStackList,a_AllowNewStacks,a_tryToFillEquippedFirst); tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); } } @@ -15808,7 +16040,8 @@ static int tolua_AllToLua_cItemGrid_AddItem00(lua_State* tolua_S) !tolua_isusertype(tolua_S,1,"cItemGrid",0,&tolua_err) || (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"cItem",0,&tolua_err)) || !tolua_isboolean(tolua_S,3,1,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) + !tolua_isnumber(tolua_S,4,1,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) ) goto tolua_lerror; else @@ -15817,11 +16050,12 @@ static int tolua_AllToLua_cItemGrid_AddItem00(lua_State* tolua_S) cItemGrid* self = (cItemGrid*) tolua_tousertype(tolua_S,1,0); cItem* a_ItemStack = ((cItem*) tolua_tousertype(tolua_S,2,0)); bool a_AllowNewStacks = ((bool) tolua_toboolean(tolua_S,3,true)); + int a_PrioritarySlot = ((int) tolua_tonumber(tolua_S,4,-1)); #ifndef TOLUA_RELEASE if (!self) tolua_error(tolua_S,"invalid 'self' in function 'AddItem'", NULL); #endif { - int tolua_ret = (int) self->AddItem(*a_ItemStack,a_AllowNewStacks, false); + int tolua_ret = (int) self->AddItem(*a_ItemStack,a_AllowNewStacks,a_PrioritarySlot); tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); } } @@ -15844,7 +16078,8 @@ static int tolua_AllToLua_cItemGrid_AddItems00(lua_State* tolua_S) !tolua_isusertype(tolua_S,1,"cItemGrid",0,&tolua_err) || (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"cItems",0,&tolua_err)) || !tolua_isboolean(tolua_S,3,1,&tolua_err) || - !tolua_isnoobj(tolua_S,4,&tolua_err) + !tolua_isnumber(tolua_S,4,1,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) ) goto tolua_lerror; else @@ -15853,11 +16088,12 @@ static int tolua_AllToLua_cItemGrid_AddItems00(lua_State* tolua_S) cItemGrid* self = (cItemGrid*) tolua_tousertype(tolua_S,1,0); cItems* a_ItemStackList = ((cItems*) tolua_tousertype(tolua_S,2,0)); bool a_AllowNewStacks = ((bool) tolua_toboolean(tolua_S,3,true)); + int a_PrioritarySlot = ((int) tolua_tonumber(tolua_S,4,-1)); #ifndef TOLUA_RELEASE if (!self) tolua_error(tolua_S,"invalid 'self' in function 'AddItems'", NULL); #endif { - int tolua_ret = (int) self->AddItems(*a_ItemStackList,a_AllowNewStacks); + int tolua_ret = (int) self->AddItems(*a_ItemStackList,a_AllowNewStacks,a_PrioritarySlot); tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); } } @@ -28201,6 +28437,13 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"IsVisible",tolua_AllToLua_cPlayer_IsVisible00); tolua_function(tolua_S,"MoveToWorld",tolua_AllToLua_cPlayer_MoveToWorld00); tolua_function(tolua_S,"LoadPermissionsFromDisk",tolua_AllToLua_cPlayer_LoadPermissionsFromDisk00); + tolua_function(tolua_S,"GetMaxSpeed",tolua_AllToLua_cPlayer_GetMaxSpeed00); + tolua_function(tolua_S,"GetNormalMaxSpeed",tolua_AllToLua_cPlayer_GetNormalMaxSpeed00); + tolua_function(tolua_S,"GetSprintingMaxSpeed",tolua_AllToLua_cPlayer_GetSprintingMaxSpeed00); + tolua_function(tolua_S,"SetNormalMaxSpeed",tolua_AllToLua_cPlayer_SetNormalMaxSpeed00); + tolua_function(tolua_S,"SetSprintingMaxSpeed",tolua_AllToLua_cPlayer_SetSprintingMaxSpeed00); + tolua_function(tolua_S,"SetCrouch",tolua_AllToLua_cPlayer_SetCrouch00); + tolua_function(tolua_S,"SetSprint",tolua_AllToLua_cPlayer_SetSprint00); tolua_endmodule(tolua_S); tolua_cclass(tolua_S,"Lua__cPlayer","Lua__cPlayer","cPlayer",NULL); tolua_beginmodule(tolua_S,"Lua__cPlayer"); diff --git a/source/Bindings.h b/source/Bindings.h index 1b2c12da..4b278f61 100644 --- a/source/Bindings.h +++ b/source/Bindings.h @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 07/01/13 20:42:05. +** Generated automatically by tolua++-1.0.92 on 07/07/13 15:41:32. */ /* Exported function */ diff --git a/source/ClientHandle.cpp b/source/ClientHandle.cpp index f8bfa5b1..4afa2fdb 100644 --- a/source/ClientHandle.cpp +++ b/source/ClientHandle.cpp @@ -1193,6 +1193,17 @@ void cClientHandle::HandleEntityAction(int a_EntityID, char a_ActionID) m_Player->GetWorld()->BroadcastPlayerAnimation(*m_Player, 3); break; } + case 4: // Start sprinting + { + m_Player->SetSprint(true); + break; + } + case 5: // Stop sprinting + { + m_Player->SetSprint(false); + SendPlayerMaxSpeed(); + break; + } } } diff --git a/source/Player.cpp b/source/Player.cpp index 4dea1c3d..35c0dcb8 100644 --- a/source/Player.cpp +++ b/source/Player.cpp @@ -50,7 +50,10 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName) , m_ClientHandle( a_Client ) , m_FoodExhaustionLevel(0.f) , m_FoodTickTimer(0) + , m_NormalMaxSpeed(0.1) + , m_SprintingMaxSpeed(0.13) , m_IsCrouched(false) + , m_IsSprinting(false) { LOGD("Created a player object for \"%s\" @ \"%s\" at %p, ID %d", a_PlayerName.c_str(), a_Client->GetIPString().c_str(), @@ -356,6 +359,41 @@ const cSlotNums & cPlayer::GetInventoryPaintSlots(void) const +double cPlayer::GetMaxSpeed(void) const +{ + return m_IsSprinting ? m_SprintingMaxSpeed : m_NormalMaxSpeed; +} + + + + + +void cPlayer::SetNormalMaxSpeed(double a_Speed) +{ + m_NormalMaxSpeed = a_Speed; + if (!m_IsSprinting) + { + m_ClientHandle->SendPlayerMaxSpeed(); + } +} + + + + + +void cPlayer::SetSprintingMaxSpeed(double a_Speed) +{ + m_SprintingMaxSpeed = a_Speed; + if (m_IsSprinting) + { + m_ClientHandle->SendPlayerMaxSpeed(); + } +} + + + + + void cPlayer::SetCrouch(bool a_IsCrouched) { // Set the crouch status, broadcast to all visible players @@ -373,6 +411,22 @@ void cPlayer::SetCrouch(bool a_IsCrouched) +void cPlayer::SetSprint(bool a_IsSprinting) +{ + if (a_IsSprinting == m_IsSprinting) + { + // No change + return; + } + + m_IsSprinting = a_IsSprinting; + m_ClientHandle->SendPlayerMaxSpeed(); +} + + + + + void cPlayer::DoTakeDamage(TakeDamageInfo & a_TDI) { if (m_GameMode == eGameMode_Creative) diff --git a/source/Player.h b/source/Player.h index 639b2595..ea293297 100644 --- a/source/Player.h +++ b/source/Player.h @@ -171,11 +171,34 @@ public: /// Returns the list of slots currently stored for inventory painting. To be used by cWindow only const cSlotNums & GetInventoryPaintSlots(void) const; + // tolua_begin + + /// Returns the current maximum speed, as reported in the 1.6.1+ protocol (takes current sprinting state into account) + double GetMaxSpeed(void) const; + + /// Gets the normal maximum speed, as reported in the 1.6.1+ protocol, in the protocol units + double GetNormalMaxSpeed(void) const { return m_NormalMaxSpeed; } + + /// Gets the sprinting maximum speed, as reported in the 1.6.1+ protocol, in the protocol units + double GetSprintingMaxSpeed(void) const { return m_SprintingMaxSpeed; } + + /// Sets the normal maximum speed, as reported in the 1.6.1+ protocol. Sends the update to player, if needed. + void SetNormalMaxSpeed(double a_Speed); + + /// Sets the sprinting maximum speed, as reported in the 1.6.1+ protocol. Sends the update to player, if needed. + void SetSprintingMaxSpeed(double a_Speed); + /// Sets the crouch status, broadcasts to all visible players void SetCrouch(bool a_IsCrouched); + /// Starts or stops sprinting, sends the max speed update to the client, if needed + void SetSprint(bool a_IsSprinting); + + // tolua_end + // cEntity overrides: - virtual bool IsCrouched(void) const { return m_IsCrouched; } + virtual bool IsCrouched (void) const { return m_IsCrouched; } + virtual bool IsSprinting(void) const { return m_IsSprinting; } protected: typedef std::map< std::string, bool > PermissionMap; @@ -226,7 +249,14 @@ protected: cSlotNums m_InventoryPaintSlots; + /// Max speed, in ENTITY_PROPERTIES packet's units, when the player is walking. 0.1 by default + double m_NormalMaxSpeed; + + /// Max speed, in ENTITY_PROPERTIES packet's units, when the player is sprinting. 0.13 by default + double m_SprintingMaxSpeed; + bool m_IsCrouched; + bool m_IsSprinting; virtual void Destroyed(void); diff --git a/source/Protocol/Protocol16x.cpp b/source/Protocol/Protocol16x.cpp index d7237b47..a4572977 100644 --- a/source/Protocol/Protocol16x.cpp +++ b/source/Protocol/Protocol16x.cpp @@ -74,7 +74,7 @@ void cProtocol161::SendAttachEntity(const cEntity & a_Entity, const cEntity * a_ void cProtocol161::SendChat(const AString & a_Message) { - super::SendChat(Printf("{\"text\":\"%s\"}", a_Message.c_str())); + super::SendChat(Printf("{\"text\":\"%s\"}", EscapeString(a_Message).c_str())); } @@ -83,15 +83,7 @@ void cProtocol161::SendChat(const AString & a_Message) void cProtocol161::SendGameMode(eGameMode a_GameMode) { super::SendGameMode(a_GameMode); - - // Also send the EntityProperties packet specifying the movementSpeed: - cCSLock Lock(m_CSPacket); - WriteByte(PACKET_ENTITY_PROPERTIES); - WriteInt(m_Client->GetPlayer()->GetUniqueID()); - WriteInt(1); - WriteString("generic.movementSpeed"); - WriteDouble(0.1); - Flush(); + SendPlayerMaxSpeed(); } @@ -112,6 +104,21 @@ void cProtocol161::SendHealth(void) +void cProtocol161::SendPlayerMaxSpeed(void) +{ + cCSLock Lock(m_CSPacket); + WriteByte(PACKET_ENTITY_PROPERTIES); + WriteInt(m_Client->GetPlayer()->GetUniqueID()); + WriteInt(1); + WriteString("generic.movementSpeed"); + WriteDouble(m_Client->GetPlayer()->GetMaxSpeed()); + Flush(); +} + + + + + void cProtocol161::SendWindowOpen(char a_WindowID, char a_WindowType, const AString & a_WindowTitle, char a_NumSlots) { if (a_WindowType < 0) diff --git a/source/Protocol/Protocol16x.h b/source/Protocol/Protocol16x.h index b3d051a1..a357fc05 100644 --- a/source/Protocol/Protocol16x.h +++ b/source/Protocol/Protocol16x.h @@ -29,11 +29,12 @@ public: cProtocol161(cClientHandle * a_Client); // cProtocol150 overrides: - virtual void SendAttachEntity(const cEntity & a_Entity, const cEntity * a_Vehicle) override; - virtual void SendChat (const AString & a_Message) override; - virtual void SendGameMode (eGameMode a_GameMode) override; - virtual void SendHealth (void) override; - virtual void SendWindowOpen (char a_WindowID, char a_WindowType, const AString & a_WindowTitle, char a_NumSlots) override; + virtual void SendAttachEntity (const cEntity & a_Entity, const cEntity * a_Vehicle) override; + virtual void SendChat (const AString & a_Message) override; + virtual void SendGameMode (eGameMode a_GameMode) override; + virtual void SendHealth (void) override; + virtual void SendPlayerMaxSpeed(void) override; + virtual void SendWindowOpen (char a_WindowID, char a_WindowType, const AString & a_WindowTitle, char a_NumSlots) override; virtual int ParseEntityAction (void) override; virtual int ParsePlayerAbilities(void) override; diff --git a/source/StringUtils.cpp b/source/StringUtils.cpp index b55ce51e..2bb6ae76 100644 --- a/source/StringUtils.cpp +++ b/source/StringUtils.cpp @@ -569,3 +569,40 @@ AString & CreateHexDump(AString & a_Out, const void * a_Data, int a_Size, int a_ + +AString EscapeString(const AString & a_Message) +{ + AString EscapedMsg; + size_t len = a_Message.size(); + size_t last = 0; + EscapedMsg.reserve(len); + for (size_t i = 0; i < len; i++) + { + char ch = a_Message[i]; + switch (ch) + { + case '\'': + case '\"': + case '\\': + { + if (i > last) + { + EscapedMsg.append(a_Message, last, i - last); + } + EscapedMsg.push_back('\\'); + EscapedMsg.push_back(ch); + last = i + 1; + break; + } + } + } + if (len > last) + { + EscapedMsg.append(a_Message, last, len - last); + } + return EscapedMsg; +} + + + + diff --git a/source/StringUtils.h b/source/StringUtils.h index 995ecab1..be2fe235 100644 --- a/source/StringUtils.h +++ b/source/StringUtils.h @@ -66,6 +66,9 @@ extern AString & UTF8ToRawBEUTF16(const char * a_UTF8, size_t a_UTF8Length, AStr /// Creates a nicely formatted HEX dump of the given memory block. Max a_BytesPerLine is 120 extern AString & CreateHexDump(AString & a_Out, const void * a_Data, int a_Size, int a_BytesPerLine); +/// Returns a copy of a_Message with all quotes and backslashes escaped by a backslash +extern AString EscapeString(const AString & a_Message); + // If you have any other string helper functions, declare them here