summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MCServer/Plugins/Debuggers/Debuggers.lua36
-rw-r--r--source/Bindings.cpp261
-rw-r--r--source/Bindings.h2
-rw-r--r--source/ClientHandle.cpp11
-rw-r--r--source/Player.cpp54
-rw-r--r--source/Player.h32
-rw-r--r--source/Protocol/Protocol16x.cpp27
-rw-r--r--source/Protocol/Protocol16x.h11
-rw-r--r--source/StringUtils.cpp37
-rw-r--r--source/StringUtils.h3
10 files changed, 448 insertions, 26 deletions
diff --git a/MCServer/Plugins/Debuggers/Debuggers.lua b/MCServer/Plugins/Debuggers/Debuggers.lua
index 12929541e..e2124c079 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 ed48a8563..9f201b19d 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
@@ -9310,6 +9310,234 @@ static int tolua_AllToLua_cPlayer_LoadPermissionsFromDisk00(lua_State* tolua_S)
}
#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 {
public:
void Initialize( cWorld* a_World) {
@@ -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 1b2c12dad..4b278f618 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 f8bfa5b15..4afa2fdbc 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 4dea1c3d7..35c0dcb83 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 639b2595b..ea293297a 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 d7237b47a..a4572977d 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 b3d051a14..a357fc05f 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 b55ce51e6..2bb6ae76e 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 995ecab1f..be2fe2359 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