From 41b05416c75b9cbe31406f04b58b5da9892872f8 Mon Sep 17 00:00:00 2001 From: Mike Hunsinger Date: Thu, 23 Jan 2014 00:27:39 -0700 Subject: [PATCH 01/23] Split TossItem into three Toss functions (Held, Equipped and Pickup) --- .../APIDump/Hooks/OnPlayerTossingItem.lua | 7 +- src/ClientHandle.cpp | 5 +- src/Entities/Player.cpp | 107 ++++++++++-------- src/Entities/Player.h | 9 +- src/UI/Window.cpp | 37 +++++- 5 files changed, 105 insertions(+), 60 deletions(-) diff --git a/MCServer/Plugins/APIDump/Hooks/OnPlayerTossingItem.lua b/MCServer/Plugins/APIDump/Hooks/OnPlayerTossingItem.lua index 85c943721..2b65294ef 100644 --- a/MCServer/Plugins/APIDump/Hooks/OnPlayerTossingItem.lua +++ b/MCServer/Plugins/APIDump/Hooks/OnPlayerTossingItem.lua @@ -5,7 +5,7 @@ return CalledWhen = "A player is tossing an item. Plugin may override / refuse.", DefaultFnName = "OnPlayerTossingItem", -- also used as pagename Desc = [[ - This hook is called when a {{cPlayer|player}} has tossed an item (Q keypress). The + This hook is called when a {{cPlayer|player}} has tossed an item. The {{cPickup|pickup}} has not been spawned yet. Plugins may disallow the tossing, but in that case they need to clean up - the player's client already thinks the item has been tossed so the {{cInventory|inventory}} needs to be re-sent to the player.

@@ -18,8 +18,9 @@ return }, Returns = [[ If the function returns false or no value, other plugins' callbacks are called and finally MCServer - creates the pickup for the item and tosses it, using {{cPlayer}}:TossItem. If the function returns - true, no other callbacks are called for this event and MCServer doesn't toss the item. + creates the pickup for the item and tosses it, using {{cPlayer}}:TossHeldItem, {{cPlayer}}:TossEquippedItem, + or {{cPlayer}}:TossPickup. If the function returns true, no other callbacks are called for this event + and MCServer doesn't toss the item. ]], }, -- HOOK_PLAYER_TOSSING_ITEM } diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 74d192129..ab3c85ba9 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -658,7 +658,8 @@ void cClientHandle::HandleLeftClick(int a_BlockX, int a_BlockY, int a_BlockZ, ch // A plugin doesn't agree with the tossing. The plugin itself is responsible for handling the consequences (possible inventory mismatch) return; } - m_Player->TossItem(false); + + m_Player->TossEquippedItem(); return; } @@ -713,7 +714,7 @@ void cClientHandle::HandleLeftClick(int a_BlockX, int a_BlockY, int a_BlockZ, ch // A plugin doesn't agree with the tossing. The plugin itself is responsible for handling the consequences (possible inventory mismatch) return; } - m_Player->TossItem(false, 64); // Toss entire slot - if there aren't enough items, the maximum will be ejected + m_Player->TossEquippedItem(64); // Toss entire slot - if there aren't enough items, the maximum will be ejected return; } diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index c1f2456eb..ca39d4d9d 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1342,59 +1342,68 @@ AString cPlayer::GetColor(void) const -void cPlayer::TossItem( - bool a_bDraggingItem, - char a_Amount /* = 1 */, - short a_CreateType /* = 0 */, - short a_CreateHealth /* = 0 */ -) +void cPlayer::TossEquippedItem(char a_Amount) { cItems Drops; - if (a_CreateType != 0) - { - // Just create item without touching the inventory (used in creative mode) - Drops.push_back(cItem(a_CreateType, a_Amount, a_CreateHealth)); - } - else - { - // Drop an item from the inventory: - if (a_bDraggingItem) - { - cItem & Item = GetDraggingItem(); - if (!Item.IsEmpty()) - { - char OriginalItemAmount = Item.m_ItemCount; - Item.m_ItemCount = std::min(OriginalItemAmount, a_Amount); - Drops.push_back(Item); - if (OriginalItemAmount > a_Amount) - { - Item.m_ItemCount = OriginalItemAmount - (char)a_Amount; - } - else - { - Item.Empty(); - } - } - } - else - { - // Else drop equipped item - cItem DroppedItem(GetInventory().GetEquippedItem()); - if (!DroppedItem.IsEmpty()) - { - char NewAmount = a_Amount; - if (NewAmount > GetInventory().GetEquippedItem().m_ItemCount) - { - NewAmount = GetInventory().GetEquippedItem().m_ItemCount; // Drop only what's there - } + cItem DroppedItem(GetInventory().GetEquippedItem()); + if (!DroppedItem.IsEmpty()) + { + char NewAmount = a_Amount; + if (NewAmount > GetInventory().GetEquippedItem().m_ItemCount) + { + NewAmount = GetInventory().GetEquippedItem().m_ItemCount; // Drop only what's there + } - GetInventory().GetHotbarGrid().ChangeSlotCount(GetInventory().GetEquippedSlotNum() /* Returns hotbar subslot, which HotbarGrid takes */, -a_Amount); + GetInventory().GetHotbarGrid().ChangeSlotCount(GetInventory().GetEquippedSlotNum() /* Returns hotbar subslot, which HotbarGrid takes */, -a_Amount); + + DroppedItem.m_ItemCount = NewAmount; + Drops.push_back(DroppedItem); + } + + double vX = 0, vY = 0, vZ = 0; + EulerToVector(-GetYaw(), GetPitch(), vZ, vX, vY); + vY = -vY * 2 + 1.f; + m_World->SpawnItemPickups(Drops, GetPosX(), GetEyeHeight(), GetPosZ(), vX * 3, vY * 3, vZ * 3, true); // 'true' because created by player +} + + + + + +void cPlayer::TossHeldItem(char a_Amount) +{ + cItems Drops; + cItem & Item = GetDraggingItem(); + if (!Item.IsEmpty()) + { + char OriginalItemAmount = Item.m_ItemCount; + Item.m_ItemCount = std::min(OriginalItemAmount, a_Amount); + Drops.push_back(Item); + if (OriginalItemAmount > a_Amount) + { + Item.m_ItemCount = OriginalItemAmount - a_Amount; + } + else + { + Item.Empty(); + } + } + + double vX = 0, vY = 0, vZ = 0; + EulerToVector(-GetYaw(), GetPitch(), vZ, vX, vY); + vY = -vY * 2 + 1.f; + m_World->SpawnItemPickups(Drops, GetPosX(), GetEyeHeight(), GetPosZ(), vX * 3, vY * 3, vZ * 3, true); // 'true' because created by player +} + + + + + +void cPlayer::TossPickup(const cItem & a_Item) +{ + cItems Drops; + Drops.push_back(a_Item); - DroppedItem.m_ItemCount = NewAmount; - Drops.push_back(DroppedItem); - } - } - } double vX = 0, vY = 0, vZ = 0; EulerToVector(-GetYaw(), GetPitch(), vZ, vX, vY); vY = -vY * 2 + 1.f; diff --git a/src/Entities/Player.h b/src/Entities/Player.h index bf3ca08e8..71033ab77 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -214,7 +214,14 @@ public: /// Returns the full color code to use for this player, based on their primary group or set in m_Color AString GetColor(void) const; - void TossItem(bool a_bDraggingItem, char a_Amount = 1, short a_CreateType = 0, short a_CreateHealth = 0); + // tosses the item in the selected hotbar slot + void TossEquippedItem(char a_Amount = 1); + + // tosses the item held in hand (when in UI windows) + void TossHeldItem(char a_Amount = 1); + + // tosses a pickup newly created from a_Item + void TossPickup(const cItem & a_Item); /// Heals the player by the specified amount of HPs (positive only); sends health update void Heal(int a_Health); diff --git a/src/UI/Window.cpp b/src/UI/Window.cpp index 3ffeff7a0..3dd6d2264 100644 --- a/src/UI/Window.cpp +++ b/src/UI/Window.cpp @@ -13,7 +13,8 @@ #include "../BlockEntities/DropSpenserEntity.h" #include "../BlockEntities/EnderChestEntity.h" #include "../BlockEntities/HopperEntity.h" - +#include "../Root.h" +#include "../Bindings/PluginManager.h" @@ -169,6 +170,8 @@ void cWindow::Clicked( const cItem & a_ClickedItem ) { + cPluginManager * PlgMgr = cRoot::Get()->GetPluginManager(); + if (a_WindowID != m_WindowID) { LOGWARNING("%s: Wrong window ID (exp %d, got %d) received from \"%s\"; ignoring click.", __FUNCTION__, m_WindowID, a_WindowID, a_Player.GetName().c_str()); @@ -179,14 +182,36 @@ void cWindow::Clicked( { case caRightClickOutside: { + if (PlgMgr->CallHookPlayerTossingItem(a_Player)) + { + // A plugin doesn't agree with the tossing. The plugin itself is responsible for handling the consequences (possible inventory mismatch) + return; + } + + if (a_Player.IsGameModeCreative()) + { + a_Player.TossPickup(a_ClickedItem); + } + // Toss one of the dragged items: - a_Player.TossItem(true); + a_Player.TossHeldItem(); return; } case caLeftClickOutside: { + if (PlgMgr->CallHookPlayerTossingItem(a_Player)) + { + // A plugin doesn't agree with the tossing. The plugin itself is responsible for handling the consequences (possible inventory mismatch) + return; + } + + if (a_Player.IsGameModeCreative()) + { + a_Player.TossPickup(a_ClickedItem); + } + // Toss all dragged items: - a_Player.TossItem(true, a_Player.GetDraggingItem().m_ItemCount); + a_Player.TossHeldItem(a_Player.GetDraggingItem().m_ItemCount); return; } case caLeftClickOutsideHoldNothing: @@ -259,11 +284,13 @@ void cWindow::OpenedByPlayer(cPlayer & a_Player) bool cWindow::ClosedByPlayer(cPlayer & a_Player, bool a_CanRefuse) { + cPluginManager * PlgMgr = cRoot::Get()->GetPluginManager(); + // Checks whether the player is still holding an item if (a_Player.IsDraggingItem()) { - LOGD("Player holds item! Dropping it..."); - a_Player.TossItem(true, a_Player.GetDraggingItem().m_ItemCount); + LOGD("Player holds item! Dropping it..."); + a_Player.TossHeldItem(a_Player.GetDraggingItem().m_ItemCount); } cClientHandle * ClientHandle = a_Player.GetClientHandle(); From 00d73177463936c149b31171b8d4b00daacc608d Mon Sep 17 00:00:00 2001 From: Mike Hunsinger Date: Thu, 23 Jan 2014 00:53:00 -0700 Subject: [PATCH 02/23] Removed extra line --- src/UI/Window.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/UI/Window.cpp b/src/UI/Window.cpp index 3dd6d2264..3d23dfd07 100644 --- a/src/UI/Window.cpp +++ b/src/UI/Window.cpp @@ -284,8 +284,6 @@ void cWindow::OpenedByPlayer(cPlayer & a_Player) bool cWindow::ClosedByPlayer(cPlayer & a_Player, bool a_CanRefuse) { - cPluginManager * PlgMgr = cRoot::Get()->GetPluginManager(); - // Checks whether the player is still holding an item if (a_Player.IsDraggingItem()) { From 11948b1d4b98e0147217eef2928a2391c2d8e958 Mon Sep 17 00:00:00 2001 From: Mike Hunsinger Date: Thu, 23 Jan 2014 19:54:00 -0700 Subject: [PATCH 03/23] Fixed spacing and doxycomments. --- .../APIDump/Hooks/OnPlayerTossingItem.lua | 4 ++-- src/Entities/Player.cpp | 6 ++--- src/Entities/Player.h | 6 ++--- src/UI/Window.cpp | 22 +++++++++---------- 4 files changed, 18 insertions(+), 20 deletions(-) diff --git a/MCServer/Plugins/APIDump/Hooks/OnPlayerTossingItem.lua b/MCServer/Plugins/APIDump/Hooks/OnPlayerTossingItem.lua index 2b65294ef..48aac2aa0 100644 --- a/MCServer/Plugins/APIDump/Hooks/OnPlayerTossingItem.lua +++ b/MCServer/Plugins/APIDump/Hooks/OnPlayerTossingItem.lua @@ -19,8 +19,8 @@ return Returns = [[ If the function returns false or no value, other plugins' callbacks are called and finally MCServer creates the pickup for the item and tosses it, using {{cPlayer}}:TossHeldItem, {{cPlayer}}:TossEquippedItem, - or {{cPlayer}}:TossPickup. If the function returns true, no other callbacks are called for this event - and MCServer doesn't toss the item. + or {{cPlayer}}:TossPickup. If the function returns true, no other callbacks are called for this event + and MCServer doesn't toss the item. ]], }, -- HOOK_PLAYER_TOSSING_ITEM } diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index ca39d4d9d..64cd334d1 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1389,8 +1389,8 @@ void cPlayer::TossHeldItem(char a_Amount) } } - double vX = 0, vY = 0, vZ = 0; - EulerToVector(-GetYaw(), GetPitch(), vZ, vX, vY); + double vX = 0, vY = 0, vZ = 0; + EulerToVector(-GetYaw(), GetPitch(), vZ, vX, vY); vY = -vY * 2 + 1.f; m_World->SpawnItemPickups(Drops, GetPosX(), GetEyeHeight(), GetPosZ(), vX * 3, vY * 3, vZ * 3, true); // 'true' because created by player } @@ -1402,7 +1402,7 @@ void cPlayer::TossHeldItem(char a_Amount) void cPlayer::TossPickup(const cItem & a_Item) { cItems Drops; - Drops.push_back(a_Item); + Drops.push_back(a_Item); double vX = 0, vY = 0, vZ = 0; EulerToVector(-GetYaw(), GetPitch(), vZ, vX, vY); diff --git a/src/Entities/Player.h b/src/Entities/Player.h index 71033ab77..7925e70a1 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -214,13 +214,13 @@ public: /// Returns the full color code to use for this player, based on their primary group or set in m_Color AString GetColor(void) const; - // tosses the item in the selected hotbar slot + /** tosses the item in the selected hotbar slot */ void TossEquippedItem(char a_Amount = 1); - // tosses the item held in hand (when in UI windows) + /** tosses the item held in hand (when in UI windows) */ void TossHeldItem(char a_Amount = 1); - // tosses a pickup newly created from a_Item + /** tosses a pickup newly created from a_Item */ void TossPickup(const cItem & a_Item); /// Heals the player by the specified amount of HPs (positive only); sends health update diff --git a/src/UI/Window.cpp b/src/UI/Window.cpp index 3d23dfd07..4261a58d9 100644 --- a/src/UI/Window.cpp +++ b/src/UI/Window.cpp @@ -171,7 +171,6 @@ void cWindow::Clicked( ) { cPluginManager * PlgMgr = cRoot::Get()->GetPluginManager(); - if (a_WindowID != m_WindowID) { LOGWARNING("%s: Wrong window ID (exp %d, got %d) received from \"%s\"; ignoring click.", __FUNCTION__, m_WindowID, a_WindowID, a_Player.GetName().c_str()); @@ -182,16 +181,15 @@ void cWindow::Clicked( { case caRightClickOutside: { - if (PlgMgr->CallHookPlayerTossingItem(a_Player)) + if (PlgMgr->CallHookPlayerTossingItem(a_Player)) { // A plugin doesn't agree with the tossing. The plugin itself is responsible for handling the consequences (possible inventory mismatch) return; } - - if (a_Player.IsGameModeCreative()) - { - a_Player.TossPickup(a_ClickedItem); - } + if (a_Player.IsGameModeCreative()) + { + a_Player.TossPickup(a_ClickedItem); + } // Toss one of the dragged items: a_Player.TossHeldItem(); @@ -205,10 +203,10 @@ void cWindow::Clicked( return; } - if (a_Player.IsGameModeCreative()) - { - a_Player.TossPickup(a_ClickedItem); - } + if (a_Player.IsGameModeCreative()) + { + a_Player.TossPickup(a_ClickedItem); + } // Toss all dragged items: a_Player.TossHeldItem(a_Player.GetDraggingItem().m_ItemCount); @@ -288,7 +286,7 @@ bool cWindow::ClosedByPlayer(cPlayer & a_Player, bool a_CanRefuse) if (a_Player.IsDraggingItem()) { LOGD("Player holds item! Dropping it..."); - a_Player.TossHeldItem(a_Player.GetDraggingItem().m_ItemCount); + a_Player.TossHeldItem(a_Player.GetDraggingItem().m_ItemCount); } cClientHandle * ClientHandle = a_Player.GetClientHandle(); From 9926ea58e841af94ded4ea55e409020c732f6cb7 Mon Sep 17 00:00:00 2001 From: Mike Hunsinger Date: Thu, 23 Jan 2014 20:01:08 -0700 Subject: [PATCH 04/23] Fixed indentation and doxygen comments... For real this time. --- .../APIDump/Hooks/OnPlayerTossingItem.lua | 4 ++-- src/Entities/Player.cpp | 6 ++--- src/UI/Window.cpp | 24 +++++++++---------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/MCServer/Plugins/APIDump/Hooks/OnPlayerTossingItem.lua b/MCServer/Plugins/APIDump/Hooks/OnPlayerTossingItem.lua index 48aac2aa0..ad2a87ed6 100644 --- a/MCServer/Plugins/APIDump/Hooks/OnPlayerTossingItem.lua +++ b/MCServer/Plugins/APIDump/Hooks/OnPlayerTossingItem.lua @@ -19,8 +19,8 @@ return Returns = [[ If the function returns false or no value, other plugins' callbacks are called and finally MCServer creates the pickup for the item and tosses it, using {{cPlayer}}:TossHeldItem, {{cPlayer}}:TossEquippedItem, - or {{cPlayer}}:TossPickup. If the function returns true, no other callbacks are called for this event - and MCServer doesn't toss the item. + or {{cPlayer}}:TossPickup. If the function returns true, no other callbacks are called for this event + and MCServer doesn't toss the item. ]], }, -- HOOK_PLAYER_TOSSING_ITEM } diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 64cd334d1..54de4dee9 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1389,8 +1389,8 @@ void cPlayer::TossHeldItem(char a_Amount) } } - double vX = 0, vY = 0, vZ = 0; - EulerToVector(-GetYaw(), GetPitch(), vZ, vX, vY); + double vX = 0, vY = 0, vZ = 0; + EulerToVector(-GetYaw(), GetPitch(), vZ, vX, vY); vY = -vY * 2 + 1.f; m_World->SpawnItemPickups(Drops, GetPosX(), GetEyeHeight(), GetPosZ(), vX * 3, vY * 3, vZ * 3, true); // 'true' because created by player } @@ -1402,7 +1402,7 @@ void cPlayer::TossHeldItem(char a_Amount) void cPlayer::TossPickup(const cItem & a_Item) { cItems Drops; - Drops.push_back(a_Item); + Drops.push_back(a_Item); double vX = 0, vY = 0, vZ = 0; EulerToVector(-GetYaw(), GetPitch(), vZ, vX, vY); diff --git a/src/UI/Window.cpp b/src/UI/Window.cpp index 4261a58d9..dd058b304 100644 --- a/src/UI/Window.cpp +++ b/src/UI/Window.cpp @@ -170,7 +170,7 @@ void cWindow::Clicked( const cItem & a_ClickedItem ) { - cPluginManager * PlgMgr = cRoot::Get()->GetPluginManager(); + cPluginManager * PlgMgr = cRoot::Get()->GetPluginManager(); if (a_WindowID != m_WindowID) { LOGWARNING("%s: Wrong window ID (exp %d, got %d) received from \"%s\"; ignoring click.", __FUNCTION__, m_WindowID, a_WindowID, a_Player.GetName().c_str()); @@ -181,15 +181,15 @@ void cWindow::Clicked( { case caRightClickOutside: { - if (PlgMgr->CallHookPlayerTossingItem(a_Player)) + if (PlgMgr->CallHookPlayerTossingItem(a_Player)) { // A plugin doesn't agree with the tossing. The plugin itself is responsible for handling the consequences (possible inventory mismatch) return; } - if (a_Player.IsGameModeCreative()) - { - a_Player.TossPickup(a_ClickedItem); - } + if (a_Player.IsGameModeCreative()) + { + a_Player.TossPickup(a_ClickedItem); + } // Toss one of the dragged items: a_Player.TossHeldItem(); @@ -203,10 +203,10 @@ void cWindow::Clicked( return; } - if (a_Player.IsGameModeCreative()) - { - a_Player.TossPickup(a_ClickedItem); - } + if (a_Player.IsGameModeCreative()) + { + a_Player.TossPickup(a_ClickedItem); + } // Toss all dragged items: a_Player.TossHeldItem(a_Player.GetDraggingItem().m_ItemCount); @@ -285,8 +285,8 @@ bool cWindow::ClosedByPlayer(cPlayer & a_Player, bool a_CanRefuse) // Checks whether the player is still holding an item if (a_Player.IsDraggingItem()) { - LOGD("Player holds item! Dropping it..."); - a_Player.TossHeldItem(a_Player.GetDraggingItem().m_ItemCount); + LOGD("Player holds item! Dropping it..."); + a_Player.TossHeldItem(a_Player.GetDraggingItem().m_ItemCount); } cClientHandle * ClientHandle = a_Player.GetClientHandle(); From 7c12247263502030fbf50fc6fda12bb8f67a269b Mon Sep 17 00:00:00 2001 From: Mike Hunsinger Date: Thu, 23 Jan 2014 20:11:10 -0700 Subject: [PATCH 05/23] Fixed indentation once and for all. --- src/Entities/Player.cpp | 60 ++++++++++++++++++++--------------------- src/UI/Window.cpp | 30 ++++++++++----------- 2 files changed, 45 insertions(+), 45 deletions(-) diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 54de4dee9..b2574c433 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1345,20 +1345,20 @@ AString cPlayer::GetColor(void) const void cPlayer::TossEquippedItem(char a_Amount) { cItems Drops; - cItem DroppedItem(GetInventory().GetEquippedItem()); - if (!DroppedItem.IsEmpty()) - { - char NewAmount = a_Amount; - if (NewAmount > GetInventory().GetEquippedItem().m_ItemCount) - { - NewAmount = GetInventory().GetEquippedItem().m_ItemCount; // Drop only what's there - } + cItem DroppedItem(GetInventory().GetEquippedItem()); + if (!DroppedItem.IsEmpty()) + { + char NewAmount = a_Amount; + if (NewAmount > GetInventory().GetEquippedItem().m_ItemCount) + { + NewAmount = GetInventory().GetEquippedItem().m_ItemCount; // Drop only what's there + } - GetInventory().GetHotbarGrid().ChangeSlotCount(GetInventory().GetEquippedSlotNum() /* Returns hotbar subslot, which HotbarGrid takes */, -a_Amount); + GetInventory().GetHotbarGrid().ChangeSlotCount(GetInventory().GetEquippedSlotNum() /* Returns hotbar subslot, which HotbarGrid takes */, -a_Amount); - DroppedItem.m_ItemCount = NewAmount; - Drops.push_back(DroppedItem); - } + DroppedItem.m_ItemCount = NewAmount; + Drops.push_back(DroppedItem); + } double vX = 0, vY = 0, vZ = 0; EulerToVector(-GetYaw(), GetPitch(), vZ, vX, vY); @@ -1373,24 +1373,24 @@ void cPlayer::TossEquippedItem(char a_Amount) void cPlayer::TossHeldItem(char a_Amount) { cItems Drops; - cItem & Item = GetDraggingItem(); - if (!Item.IsEmpty()) - { - char OriginalItemAmount = Item.m_ItemCount; - Item.m_ItemCount = std::min(OriginalItemAmount, a_Amount); - Drops.push_back(Item); - if (OriginalItemAmount > a_Amount) - { - Item.m_ItemCount = OriginalItemAmount - a_Amount; - } - else - { - Item.Empty(); - } - } + cItem & Item = GetDraggingItem(); + if (!Item.IsEmpty()) + { + char OriginalItemAmount = Item.m_ItemCount; + Item.m_ItemCount = std::min(OriginalItemAmount, a_Amount); + Drops.push_back(Item); + if (OriginalItemAmount > a_Amount) + { + Item.m_ItemCount = OriginalItemAmount - a_Amount; + } + else + { + Item.Empty(); + } + } - double vX = 0, vY = 0, vZ = 0; - EulerToVector(-GetYaw(), GetPitch(), vZ, vX, vY); + double vX = 0, vY = 0, vZ = 0; + EulerToVector(-GetYaw(), GetPitch(), vZ, vX, vY); vY = -vY * 2 + 1.f; m_World->SpawnItemPickups(Drops, GetPosX(), GetEyeHeight(), GetPosZ(), vX * 3, vY * 3, vZ * 3, true); // 'true' because created by player } @@ -1402,7 +1402,7 @@ void cPlayer::TossHeldItem(char a_Amount) void cPlayer::TossPickup(const cItem & a_Item) { cItems Drops; - Drops.push_back(a_Item); + Drops.push_back(a_Item); double vX = 0, vY = 0, vZ = 0; EulerToVector(-GetYaw(), GetPitch(), vZ, vX, vY); diff --git a/src/UI/Window.cpp b/src/UI/Window.cpp index dd058b304..1a8456f70 100644 --- a/src/UI/Window.cpp +++ b/src/UI/Window.cpp @@ -181,15 +181,15 @@ void cWindow::Clicked( { case caRightClickOutside: { - if (PlgMgr->CallHookPlayerTossingItem(a_Player)) + if (PlgMgr->CallHookPlayerTossingItem(a_Player)) { - // A plugin doesn't agree with the tossing. The plugin itself is responsible for handling the consequences (possible inventory mismatch) - return; + // A plugin doesn't agree with the tossing. The plugin itself is responsible for handling the consequences (possible inventory mismatch) + return; + } + if (a_Player.IsGameModeCreative()) + { + a_Player.TossPickup(a_ClickedItem); } - if (a_Player.IsGameModeCreative()) - { - a_Player.TossPickup(a_ClickedItem); - } // Toss one of the dragged items: a_Player.TossHeldItem(); @@ -199,14 +199,14 @@ void cWindow::Clicked( { if (PlgMgr->CallHookPlayerTossingItem(a_Player)) { - // A plugin doesn't agree with the tossing. The plugin itself is responsible for handling the consequences (possible inventory mismatch) - return; + // A plugin doesn't agree with the tossing. The plugin itself is responsible for handling the consequences (possible inventory mismatch) + return; } - if (a_Player.IsGameModeCreative()) - { - a_Player.TossPickup(a_ClickedItem); - } + if (a_Player.IsGameModeCreative()) + { + a_Player.TossPickup(a_ClickedItem); + } // Toss all dragged items: a_Player.TossHeldItem(a_Player.GetDraggingItem().m_ItemCount); @@ -285,8 +285,8 @@ bool cWindow::ClosedByPlayer(cPlayer & a_Player, bool a_CanRefuse) // Checks whether the player is still holding an item if (a_Player.IsDraggingItem()) { - LOGD("Player holds item! Dropping it..."); - a_Player.TossHeldItem(a_Player.GetDraggingItem().m_ItemCount); + LOGD("Player holds item! Dropping it..."); + a_Player.TossHeldItem(a_Player.GetDraggingItem().m_ItemCount); } cClientHandle * ClientHandle = a_Player.GetClientHandle(); From 22d101034ffe810297455fb4caa27baf138a6342 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 23 Jan 2014 22:24:20 +0100 Subject: [PATCH 06/23] Fixed flint&steel failure on the Y world edges. --- src/Items/ItemLighter.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Items/ItemLighter.h b/src/Items/ItemLighter.h index 4281a2d0c..8f3389d95 100644 --- a/src/Items/ItemLighter.h +++ b/src/Items/ItemLighter.h @@ -42,6 +42,10 @@ public: { // Light a fire next to/on top of the block if air: AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); + if ((a_BlockY < 0) || (a_BlockY >= cChunkDef::Height)) + { + break; + } if (a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ) == E_BLOCK_AIR) { a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_FIRE, 0); From ebc3f6aa28cae2510efa4d5de9562d24e6d8e96a Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 24 Jan 2014 08:59:21 +0100 Subject: [PATCH 07/23] APIDump: Fixed indent after merge. --- MCServer/Plugins/APIDump/Hooks/OnPlayerTossingItem.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MCServer/Plugins/APIDump/Hooks/OnPlayerTossingItem.lua b/MCServer/Plugins/APIDump/Hooks/OnPlayerTossingItem.lua index ad2a87ed6..82d5bb390 100644 --- a/MCServer/Plugins/APIDump/Hooks/OnPlayerTossingItem.lua +++ b/MCServer/Plugins/APIDump/Hooks/OnPlayerTossingItem.lua @@ -19,8 +19,8 @@ return Returns = [[ If the function returns false or no value, other plugins' callbacks are called and finally MCServer creates the pickup for the item and tosses it, using {{cPlayer}}:TossHeldItem, {{cPlayer}}:TossEquippedItem, - or {{cPlayer}}:TossPickup. If the function returns true, no other callbacks are called for this event - and MCServer doesn't toss the item. + or {{cPlayer}}:TossPickup. If the function returns true, no other callbacks are called for this event + and MCServer doesn't toss the item. ]], }, -- HOOK_PLAYER_TOSSING_ITEM } From b02940209d64e4239ac6c0e7c8cb4f1d8280b7aa Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 24 Jan 2014 09:57:12 +0100 Subject: [PATCH 08/23] Fixed crash with failed entity-loading. This should fix issues reported in: http://forum.mc-server.org/showthread.php?tid=1328 http://forum.mc-server.org/showthread.php?tid=1308 --- src/Entities/Entity.cpp | 3 ++- src/WorldStorage/WSSAnvil.cpp | 9 +++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 565c78dfd..09fb7052d 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -73,7 +73,8 @@ cEntity::cEntity(eEntityType a_EntityType, double a_X, double a_Y, double a_Z, d cEntity::~cEntity() { - ASSERT(!m_World->HasEntity(m_UniqueID)); // Before deleting, the entity needs to have been removed from the world + // Before deleting, the entity needs to have been removed from the world, if ever added + ASSERT((m_World == NULL) || !m_World->HasEntity(m_UniqueID)); /* // DEBUG: diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index 8be6372e2..e2a882f65 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -1926,14 +1926,19 @@ bool cWSSAnvil::LoadEntityBaseFromNBT(cEntity & a_Entity, const cParsedNBT & a_N double Speed[3]; if (!LoadDoublesListFromNBT(Speed, 3, a_NBT, a_NBT.FindChildByName(a_TagIdx, "Motion"))) { - return false; + // Provide default speed: + Speed[0] = 0; + Speed[1] = 0; + Speed[2] = 0; } a_Entity.SetSpeed(Speed[0], Speed[1], Speed[2]); double Rotation[3]; if (!LoadDoublesListFromNBT(Rotation, 2, a_NBT, a_NBT.FindChildByName(a_TagIdx, "Rotation"))) { - return false; + // Provide default rotation: + Rotation[0] = 0; + Rotation[1] = 0; } a_Entity.SetYaw(Rotation[0]); a_Entity.SetRoll(Rotation[1]); From 0369c585fb16777acd4639122f8cee2d7c60833d Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 24 Jan 2014 09:58:40 +0100 Subject: [PATCH 09/23] Fixed a few compile-time and runtime warnings in ScoreboardSerializer. --- src/WorldStorage/ScoreboardSerializer.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/WorldStorage/ScoreboardSerializer.cpp b/src/WorldStorage/ScoreboardSerializer.cpp index a53971dc2..c65e13f98 100644 --- a/src/WorldStorage/ScoreboardSerializer.cpp +++ b/src/WorldStorage/ScoreboardSerializer.cpp @@ -31,16 +31,12 @@ cScoreboardSerializer::cScoreboardSerializer(const AString & a_WorldName, cScore bool cScoreboardSerializer::Load(void) { - cFile File; - if (!File.Open(FILE_IO_PREFIX + m_Path, cFile::fmRead)) + AString Data = cFile::ReadWholeFile(FILE_IO_PREFIX + m_Path); + if (Data.empty()) { return false; } - AString Data; - File.ReadRestOfFile(Data); - File.Close(); - AString Uncompressed; int res = UncompressStringGZIP(Data.data(), Data.size(), Uncompressed); @@ -313,13 +309,13 @@ bool cScoreboardSerializer::LoadScoreboardFromNBT(const cParsedNBT & a_NBT) CurrLine = a_NBT.FindChildByName(Child, "AllowFriendlyFire"); if (CurrLine >= 0) { - AllowsFriendlyFire = a_NBT.GetInt(CurrLine); + AllowsFriendlyFire = (a_NBT.GetInt(CurrLine) != 0); } CurrLine = a_NBT.FindChildByName(Child, "SeeFriendlyInvisibles"); if (CurrLine >= 0) { - CanSeeFriendlyInvisible = a_NBT.GetInt(CurrLine); + CanSeeFriendlyInvisible = (a_NBT.GetInt(CurrLine) != 0); } cTeam * Team = m_ScoreBoard->RegisterTeam(Name, DisplayName, Prefix, Suffix); From e75f979e01b34fbd1a2993be9fd4aa7211da26cf Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 24 Jan 2014 10:24:24 +0100 Subject: [PATCH 10/23] Fixed Win nightbuilds not producing PDBs. --- Install/Zip2008_PDBs.list | 8 +------- src/CMakeLists.txt | 7 +++++++ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Install/Zip2008_PDBs.list b/Install/Zip2008_PDBs.list index b9c822c38..608b0185b 100644 --- a/Install/Zip2008_PDBs.list +++ b/Install/Zip2008_PDBs.list @@ -1,8 +1,2 @@ MCServer\*.pdb -VC2008\Release\*.pdb -VC2008\Release\JsonCpp\*.pdb -VC2008\Release\Lua\*.pdb -VC2008\Release\ToLua\*.pdb -VC2008\Release\webserver\*.pdb -VC2008\Release\zlib\*.pdb -src\Bindings.* \ No newline at end of file +src\Bindings\Bindings.* \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 51182d3bc..a8cc0530d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -134,6 +134,13 @@ else () "StackWalker.cpp LeakFinder.h" PROPERTIES COMPILE_FLAGS "/Yc\"Globals.h\"" ) list(APPEND SOURCE "Resources/MCServer.rc") + + # Make MSVC generate the PDB files even for the release build: + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Zi") + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /Zi") + set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /DEBUG") + set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /DEBUG") + set(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${CMAKE_MODULE_LINKER_FLAGS_RELEASE} /DEBUG") endif() set(EXECUTABLE MCServer) From d8014d1ed8dd2374f77d670a1368958c8a10541a Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 24 Jan 2014 18:51:15 +0100 Subject: [PATCH 11/23] ProtoProxy: Fixed connection on *nix. --- Tools/ProtoProxy/Connection.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Tools/ProtoProxy/Connection.cpp b/Tools/ProtoProxy/Connection.cpp index cd66e2dfd..b63935f38 100644 --- a/Tools/ProtoProxy/Connection.cpp +++ b/Tools/ProtoProxy/Connection.cpp @@ -243,7 +243,8 @@ void cConnection::Run(void) FD_ZERO(&ReadFDs); FD_SET(m_ServerSocket, &ReadFDs); FD_SET(m_ClientSocket, &ReadFDs); - int res = select(2, &ReadFDs, NULL, NULL, NULL); + SOCKET MaxSocket = std::max(m_ServerSocket, m_ClientSocket); + int res = select(MaxSocket + 1, &ReadFDs, NULL, NULL, NULL); if (res <= 0) { printf("select() failed: %d; aborting client", SocketError); From 4eb52b25db3dfa8a2d4574243e829480dcad6e38 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 24 Jan 2014 19:58:37 +0000 Subject: [PATCH 12/23] Updated Core --- MCServer/Plugins/Core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MCServer/Plugins/Core b/MCServer/Plugins/Core index 759cf48ba..5fe3662a8 160000 --- a/MCServer/Plugins/Core +++ b/MCServer/Plugins/Core @@ -1 +1 @@ -Subproject commit 759cf48ba3f1409e6d7b60cb821ee17e589bdef8 +Subproject commit 5fe3662a8719f79cb2ca0a16150c716a3c5eb19c From f0a75f7f73effcaccc6dcb73c42fd8c9f4492dcd Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 24 Jan 2014 19:22:10 +0100 Subject: [PATCH 13/23] Fixed a failure in cSquid. Probably due to rounding errors the squid was querying out-of-chunk coords. --- src/Mobs/Squid.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Mobs/Squid.cpp b/src/Mobs/Squid.cpp index a311108ae..5a27762ff 100644 --- a/src/Mobs/Squid.cpp +++ b/src/Mobs/Squid.cpp @@ -43,7 +43,8 @@ void cSquid::Tick(float a_Dt, cChunk & a_Chunk) } int RelX = (int)floor(Pos.x) - a_Chunk.GetPosX() * cChunkDef::Width; int RelZ = (int)floor(Pos.z) - a_Chunk.GetPosZ() * cChunkDef::Width; - if (!IsBlockWater(a_Chunk.GetBlock(RelX, RelY, RelZ)) && !IsOnFire()) + BLOCKTYPE BlockType; + if (a_Chunk.UnboundedRelGetBlockType(RelX, RelY, RelZ, BlockType) && !IsBlockWater(BlockType) && !IsOnFire()) { // Burn for 10 ticks, then decide again StartBurning(10); From 6c1d992eeba5c300da1a2b7a50fbda52b3774ff4 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 24 Jan 2014 22:23:33 +0100 Subject: [PATCH 14/23] Fixed a possible deadlock on client disconnect. --- src/ClientHandle.cpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 18e3d560e..56ad4e4ba 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -148,15 +148,6 @@ cClientHandle::~cClientHandle() SendDisconnect("Server shut down? Kthnxbai"); } - // Queue all remaining outgoing packets to cSocketThreads: - { - cCSLock Lock(m_CSOutgoingData); - AString Data; - m_OutgoingData.ReadAll(Data); - m_OutgoingData.CommitRead(); - cRoot::Get()->GetServer()->WriteToClient(this, Data); - } - // Close the socket as soon as it sends all outgoing data: cRoot::Get()->GetServer()->RemoveClient(this); From d0da5d392f64c63fefde352a2a0b569317ca59cc Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 24 Jan 2014 23:03:48 +0100 Subject: [PATCH 15/23] Added per-connection comm logging in debug mode. It is meant for debugging only, so it is compiled only into debug mode. It is activated by starting the server with "/logcomm" parameter. --- src/Protocol/Protocol17x.cpp | 64 ++++++++++++++++++++++++++++++++++++ src/Protocol/Protocol17x.h | 5 +++ src/main.cpp | 25 +++++++++++++- 3 files changed, 93 insertions(+), 1 deletion(-) diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 9506332dc..d2d0df7f7 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -53,6 +53,18 @@ Implements the 1.7.x protocol classes: +#ifdef _DEBUG +// fwd: main.cpp: +extern bool g_ShouldLogComm; +#endif + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cProtocol172: + cProtocol172::cProtocol172(cClientHandle * a_Client, const AString & a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State) : super(a_Client), m_ServerAddress(a_ServerAddress), @@ -63,6 +75,15 @@ cProtocol172::cProtocol172(cClientHandle * a_Client, const AString & a_ServerAdd m_OutPacketLenBuffer(20), // 20 bytes is more than enough for one VarInt m_IsEncrypted(false) { + // Create the comm log file, if so requested: + #ifdef _DEBUG + if (g_ShouldLogComm) + { + cFile::CreateFolder("CommLogs"); + AString FileName = Printf("CommLogs/%x__%s.log", (unsigned)time(NULL), a_Client->GetIPString().c_str()); + m_CommLogFile.Open(FileName, cFile::fmWrite); + } + #endif // _DEBUG } @@ -1065,6 +1086,18 @@ void cProtocol172::SendWindowProperty(const cWindow & a_Window, short a_Property void cProtocol172::AddReceivedData(const char * a_Data, int a_Size) { + // Write the incoming data into the comm log file: + #ifdef _DEBUG + if (g_ShouldLogComm) + { + AString Hex; + CreateHexDump(Hex, a_Data, a_Size, 16); + m_CommLogFile.Printf("Incoming data: %d bytes. %d bytes unparsed already present in buffer.\n%s\n", + a_Size, m_ReceivedData.GetReadableSpace(), Hex.c_str() + ); + } + #endif + if (!m_ReceivedData.Write(a_Data, a_Size)) { // Too much data in the incoming queue, report to caller: @@ -1100,6 +1133,24 @@ void cProtocol172::AddReceivedData(const char * a_Data, int a_Size) return; } + // Log the packet info into the comm log file: + #ifdef _DEBUG + if (g_ShouldLogComm) + { + AString PacketData; + bb.ReadAll(PacketData); + bb.ResetRead(); + bb.ReadVarInt(PacketType); + ASSERT(PacketData.size() > 0); + PacketData.resize(PacketData.size() - 1); + AString PacketDataHex; + CreateHexDump(PacketDataHex, PacketData.data(), PacketData.size(), 16); + m_CommLogFile.Printf("Next incoming packet is type %u (0x%x), length %u (0x%x) at state %d. Payload:\n%s\n", + PacketType, PacketType, PacketLen, PacketLen, m_State, PacketDataHex.c_str() + ); + } + #endif // _DEBUG + if (!HandlePacket(bb, PacketType)) { // Unknown packet, already been reported, but without the length. Log the length here: @@ -1807,6 +1858,19 @@ cProtocol172::cPacketizer::~cPacketizer() m_Out.ReadAll(DataToSend); m_Protocol.SendData(DataToSend.data(), DataToSend.size()); m_Out.CommitRead(); + + // Log the comm into logfile: + #ifdef _DEBUG + if (g_ShouldLogComm) + { + AString Hex; + ASSERT(DataToSend.size() > 0); + CreateHexDump(Hex, DataToSend.data() + 1, DataToSend.size() - 1, 16); + m_Protocol.m_CommLogFile.Printf("Outgoing packet: type %d (0x%x), length %u (0x%x), state %d. Payload:\n%s\n", + DataToSend[0], DataToSend[0], PacketLen, PacketLen, m_Protocol.m_State, Hex.c_str() + ); + } + #endif // _DEBUG } diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h index 3f440f313..b04a1f019 100644 --- a/src/Protocol/Protocol17x.h +++ b/src/Protocol/Protocol17x.h @@ -223,6 +223,11 @@ protected: CryptoPP::CFB_Mode::Decryption m_Decryptor; CryptoPP::CFB_Mode::Encryption m_Encryptor; + #ifdef _DEBUG + /** The logfile where the comm is logged, when g_ShouldLogComm is true */ + cFile m_CommLogFile; + #endif + /// Adds the received (unencrypted) data to m_ReceivedData, parses complete packets void AddReceivedData(const char * a_Data, int a_Size); diff --git a/src/main.cpp b/src/main.cpp index 340149e0b..68bf6683f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -19,6 +19,15 @@ bool g_SERVER_TERMINATED = false; // Set to true when the server terminates, so +#ifdef _DEBUG +/** If set to true, the protocols will log each player's communication to a separate logfile */ +bool g_ShouldLogComm; +#endif + + + + + /// If defined, a thorough leak finder will be used (debug MSVC only); leaks will be output to the Output window #define ENABLE_LEAK_FINDER @@ -216,12 +225,26 @@ int main( int argc, char **argv ) #ifndef _DEBUG std::signal(SIGSEGV, NonCtrlHandler); std::signal(SIGTERM, NonCtrlHandler); - std::signal(SIGINT, NonCtrlHandler); + std::signal(SIGINT, NonCtrlHandler); #endif // DEBUG: test the dumpfile creation: // *((int *)0) = 0; + // Check if comm logging is to be enabled: + #ifdef _DEBUG + for (int i = 0; i < argc; i++) + { + if ( + (_stricmp(argv[i], "/commlog") == 0) || + (_stricmp(argv[i], "/logcomm") == 0) + ) + { + g_ShouldLogComm = true; + } + } + #endif // _DEBUG + #if !defined(ANDROID_NDK) try #endif From ebcaaad63aaf854e01f63104a820dfcbd76cc80e Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 24 Jan 2014 23:05:26 +0100 Subject: [PATCH 16/23] Fixed *nix compilation for previous commit. --- src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 68bf6683f..902e9e43b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -236,8 +236,8 @@ int main( int argc, char **argv ) for (int i = 0; i < argc; i++) { if ( - (_stricmp(argv[i], "/commlog") == 0) || - (_stricmp(argv[i], "/logcomm") == 0) + (NoCaseCompare(argv[i], "/commlog") == 0) || + (NoCaseCompare(argv[i], "/logcomm") == 0) ) { g_ShouldLogComm = true; From b2fd91ee6b391b36a8b2d88d818fe370798238e8 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 25 Jan 2014 05:25:43 -0800 Subject: [PATCH 17/23] Reformatted Bindings Dependecies --- src/CMakeLists.txt | 86 +++++++++++++++++++++++++++++++--------------- 1 file changed, 58 insertions(+), 28 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 51182d3bc..4058c1873 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -16,34 +16,64 @@ if (NOT MSVC) #lib dependecies are not included - set(BINDING_DEPENDECIES ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/virtual_method_hooks.lua) - set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/AllToLua.pkg) - set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} ChunkDef.h BiomeDef.h) - set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} OSSupport/File.h Bindings/LuaFunctions.h) - set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} Bindings/PluginManager.h Bindings/Plugin.h) - set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} Bindings/PluginLua.h Bindings/WebPlugin.h) - set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} Bindings/LuaWindow.h BlockID.h StringUtils.h) - set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} Defines.h ChatColor.h ClientHandle.h) - set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} Entities/Entity.h Entities/Floater.h ) - set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} Entities/Pawn.h Entities/Player.h) - set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} Entities/Pickup.h Entities/ProjectileEntity.h) - set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} Entities/TNTEntity.h Entities/Effects.h) - set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} Server.h World.h Inventory.h Enchantments.h) - set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} Item.h ItemGrid.h BlockEntities/BlockEntity.h) - set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} BlockEntities/BlockEntityWithItems.h) - set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} BlockEntities/ChestEntity.h) - set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} BlockEntities/DropSpenserEntity.h) - set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} BlockEntities/DispenserEntity.h) - set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} BlockEntities/DropperEntity.h) - set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} BlockEntities/FurnaceEntity.h) - set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} BlockEntities/HopperEntity.h) - set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} BlockEntities/JukeboxEntity.h) - set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} BlockEntities/NoteEntity.h) - set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} BlockEntities/SignEntity.h WebAdmin.h Root.h) - set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} Vector3f.h Vector3d.h Vector3i.h Matrix4f.h) - set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} Cuboid.h BoundingBox.h Tracer.h Group.h) - set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} BlockArea.h Generating/ChunkDesc.h) - set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} CraftingRecipes.h UI/Window.h Mobs/Monster.h) + set(BINDING_DEPENDECIES + ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/virtual_method_hooks.lua + ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/AllToLua.pkg + ChunkDef.h + BiomeDef.h + OSSupport/File.h + Bindings/LuaFunctions.h + Bindings/PluginManager.h + Bindings/Plugin.h + Bindings/PluginLua.h + Bindings/WebPlugin.h + Bindings/LuaWindow.h + BlockID.h + StringUtils.h + Defines.h + ChatColor.h + ClientHandle.h + Entities/Entity.h + Entities/Floater.h + Entities/Pawn.h + Entities/Player.h + Entities/Pickup.h + Entities/ProjectileEntity.h + Entities/TNTEntity.h + Entities/Effects.h + Server.h + World.h + Inventory.h + Enchantments.h + Item.h + ItemGrid.h + BlockEntities/BlockEntity.h + BlockEntities/BlockEntityWithItems.h + BlockEntities/ChestEntity.h + BlockEntities/DropSpenserEntity.h + BlockEntities/DispenserEntity.h + BlockEntities/DropperEntity.h + BlockEntities/FurnaceEntity.h + BlockEntities/HopperEntity.h + BlockEntities/JukeboxEntity.h + BlockEntities/NoteEntity.h + BlockEntities/SignEntity.h + WebAdmin.h + Root.h + Vector3f.h + Vector3d.h + Vector3i.h + Matrix4f.h + Cuboid.h + BoundingBox.h + Tracer.h + Group.h + BlockArea.h + Generating/ChunkDesc.h + CraftingRecipes.h + UI/Window.h + Mobs/Monster.h + ) include_directories(Bindings) include_directories(.) From 45bc1ff033271bc0c6a9e5931a00c554e065c375 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 25 Jan 2014 05:35:04 -0800 Subject: [PATCH 18/23] Added dependecy output to Bindings/BindingsDependencies.txt --- .gitignore | 1 + src/CMakeLists.txt | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/.gitignore b/.gitignore index a108a9ece..923735d25 100644 --- a/.gitignore +++ b/.gitignore @@ -57,6 +57,7 @@ install_mainfest.txt src/MCServer lib/tolua++/tolua src/Bindings/Bindings.* +src/Bindings/BindingsDependecies.txt MCServer.dir/ #win32 cmake stuff diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4058c1873..9d03a4ffa 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -94,6 +94,13 @@ if (NOT MSVC) target_link_libraries(Bindings lua sqlite tolualib) + #clear file + file(WRITE ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/BindingDependecies.txt) + foreach(dependecy ${BINDING_DEPENDECIES}) + #write each dependecy on a seperate line + file(APPEND ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/BindingDependecies.txt "${dependecy}\n") + endforeach() + set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "Bindings.cpp Bindings.h") foreach(folder ${FOLDERS}) From cb7c5a6181cd17485c518dd18b82d72af933e7bd Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 25 Jan 2014 05:37:19 -0800 Subject: [PATCH 19/23] Simplified .gitignore --- .gitignore | 60 +++++------------------------------------------------- 1 file changed, 5 insertions(+), 55 deletions(-) diff --git a/.gitignore b/.gitignore index 923735d25..007b21519 100644 --- a/.gitignore +++ b/.gitignore @@ -71,58 +71,8 @@ MCServer.dir/ #cmake output folders ZERO_CHECK.dir/ -lib/cryptopp/Debug/ -lib/cryptopp/DebugProfile/ -lib/cryptopp/Release/ -lib/cryptopp/ReleaseProfile/ -lib/cryptopp/cryptopp.dir/ -lib/expat/Debug/ -lib/expat/DebugProfile/ -lib/expat/Release/ -lib/expat/ReleaseProfile/ -lib/expat/expat.dir/ -lib/inifile/Debug/ -lib/inifile/DebugProfile/ -lib/inifile/Release/ -lib/inifile/ReleaseProfile/ -lib/inifile/inifile.dir/ -lib/jsoncpp/Debug/ -lib/jsoncpp/DebugProfile/ -lib/jsoncpp/Release/ -lib/jsoncpp/ReleaseProfile/ -lib/jsoncpp/jsoncpp.dir/ -lib/lua/Debug/ -lib/lua/DebugProfile/ -lib/lua/Release/ -lib/lua/ReleaseProfile/ -lib/lua/lua.dir/ -lib/luaexpat/Debug/ -lib/luaexpat/DebugProfile/ -lib/luaexpat/Release/ -lib/luaexpat/ReleaseProfile/ -lib/luaexpat/luaexpat.dir/ -lib/md5/Debug/ -lib/md5/DebugProfile/ -lib/md5/Release/ -lib/md5/ReleaseProfile/ -lib/md5/md5.dir/ -lib/sqlite/Debug/ -lib/sqlite/DebugProfile/ -lib/sqlite/Release/ -lib/sqlite/ReleaseProfile/ -lib/sqlite/sqlite.dir/ -lib/tolua++/Debug/ -lib/tolua++/DebugProfile/ -lib/tolua++/Release/ -lib/tolua++/ReleaseProfile/ -lib/tolua++/tolua.dir/ -lib/tolua++/tolualib.dir/ -lib/zlib/Debug/ -lib/zlib/DebugProfile/ -lib/zlib/Release/ -lib/zlib/ReleaseProfile/ -lib/zlib/zlib.dir/ -src/Debug/ -src/DebugProfile/ -src/Release/ -src/ReleaseProfile/ +Debug/ +DebugProfile/ +Release/ +ReleaseProfile/ +*.dir/ From 9d1ebaaf0d7260b6b5d3e7d78bc0980c90192543 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 24 Jan 2014 23:06:06 +0100 Subject: [PATCH 20/23] Ignoring the Comm Logs. --- MCServer/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/MCServer/.gitignore b/MCServer/.gitignore index c18dd7a67..e3aebbf92 100644 --- a/MCServer/.gitignore +++ b/MCServer/.gitignore @@ -4,6 +4,7 @@ *.lib *.ini MCServer +CommLogs/ logs players world* From 96b4af15963ac70b25ab243d84d48221a3d41369 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 25 Jan 2014 15:06:21 +0100 Subject: [PATCH 21/23] Protocol17: Comm logging shows the data left over from previous parse. --- src/Protocol/Protocol17x.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index d2d0df7f7..8abe4f259 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -1090,10 +1090,23 @@ void cProtocol172::AddReceivedData(const char * a_Data, int a_Size) #ifdef _DEBUG if (g_ShouldLogComm) { + if (m_ReceivedData.GetReadableSpace() > 0) + { + AString AllData; + int OldReadableSpace = m_ReceivedData.GetReadableSpace(); + m_ReceivedData.ReadAll(AllData); + m_ReceivedData.ResetRead(); + m_ReceivedData.SkipRead(m_ReceivedData.GetReadableSpace() - OldReadableSpace); + AString Hex; + CreateHexDump(Hex, AllData.data(), AllData.size(), 16); + m_CommLogFile.Printf("Incoming data, %d (0x%x) bytes unparsed already present in buffer:\n%s\n", + AllData.size(), AllData.size(), Hex.c_str() + ); + } AString Hex; CreateHexDump(Hex, a_Data, a_Size, 16); - m_CommLogFile.Printf("Incoming data: %d bytes. %d bytes unparsed already present in buffer.\n%s\n", - a_Size, m_ReceivedData.GetReadableSpace(), Hex.c_str() + m_CommLogFile.Printf("Incoming data: %d (0x%x) bytes: \n%s\n", + a_Size, a_Size, Hex.c_str() ); } #endif From 5aa3fc4c564252359613eb0d91225247f65e0d45 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 25 Jan 2014 15:27:34 +0100 Subject: [PATCH 22/23] Added cFile::Flush(). This is useful when using cFile as a log file and we know the server may crash after a specific write, so we flush the file before continuing. --- src/OSSupport/File.cpp | 9 +++++++++ src/OSSupport/File.h | 45 +++++++++++++++++++++++------------------- 2 files changed, 34 insertions(+), 20 deletions(-) diff --git a/src/OSSupport/File.cpp b/src/OSSupport/File.cpp index 9f7c0d439..0ebd04915 100644 --- a/src/OSSupport/File.cpp +++ b/src/OSSupport/File.cpp @@ -450,3 +450,12 @@ int cFile::Printf(const char * a_Fmt, ...) + +void cFile::Flush(void) +{ + fflush(m_File); +} + + + + diff --git a/src/OSSupport/File.h b/src/OSSupport/File.h index 01663a229..07fce6661 100644 --- a/src/OSSupport/File.h +++ b/src/OSSupport/File.h @@ -18,6 +18,8 @@ Usage: 2, Check if the file was opened using IsOpen() 3, Read / write 4, Destroy the instance + +For reading entire files into memory, just use the static cFile::ReadWholeFile() */ @@ -55,7 +57,7 @@ public: static const char PathSeparator = '/'; #endif - /// The mode in which to open the file + /** The mode in which to open the file */ enum eMode { fmRead, // Read-only. If the file doesn't exist, object will not be valid @@ -63,13 +65,13 @@ public: fmReadWrite // Read/write. If the file already exists, it will be left intact; writing will overwrite the data from the beginning } ; - /// Simple constructor - creates an unopened file object, use Open() to open / create a real file + /** Simple constructor - creates an unopened file object, use Open() to open / create a real file */ cFile(void); - /// Constructs and opens / creates the file specified, use IsOpen() to check for success + /** Constructs and opens / creates the file specified, use IsOpen() to check for success */ cFile(const AString & iFileName, eMode iMode); - /// Auto-closes the file, if open + /** Auto-closes the file, if open */ ~cFile(); bool Open(const AString & iFileName, eMode iMode); @@ -77,60 +79,63 @@ public: bool IsOpen(void) const; bool IsEOF(void) const; - /// Reads up to iNumBytes bytes into iBuffer, returns the number of bytes actually read, or -1 on failure; asserts if not open + /** Reads up to iNumBytes bytes into iBuffer, returns the number of bytes actually read, or -1 on failure; asserts if not open */ int Read (void * iBuffer, int iNumBytes); - /// Writes up to iNumBytes bytes from iBuffer, returns the number of bytes actually written, or -1 on failure; asserts if not open + /** Writes up to iNumBytes bytes from iBuffer, returns the number of bytes actually written, or -1 on failure; asserts if not open */ int Write(const void * iBuffer, int iNumBytes); - /// Seeks to iPosition bytes from file start, returns old position or -1 for failure; asserts if not open + /** Seeks to iPosition bytes from file start, returns old position or -1 for failure; asserts if not open */ int Seek (int iPosition); - /// Returns the current position (bytes from file start) or -1 for failure; asserts if not open + /** Returns the current position (bytes from file start) or -1 for failure; asserts if not open */ int Tell (void) const; - /// Returns the size of file, in bytes, or -1 for failure; asserts if not open + /** Returns the size of file, in bytes, or -1 for failure; asserts if not open */ int GetSize(void) const; - /// Reads the file from current position till EOF into an AString; returns the number of bytes read or -1 for error + /** Reads the file from current position till EOF into an AString; returns the number of bytes read or -1 for error */ int ReadRestOfFile(AString & a_Contents); // tolua_begin - /// Returns true if the file specified exists + /** Returns true if the file specified exists */ static bool Exists(const AString & a_FileName); - /// Deletes a file, returns true if successful + /** Deletes a file, returns true if successful */ static bool Delete(const AString & a_FileName); - /// Renames a file or folder, returns true if successful. May fail if dest already exists (libc-dependant)! + /** Renames a file or folder, returns true if successful. May fail if dest already exists (libc-dependant)! */ static bool Rename(const AString & a_OrigPath, const AString & a_NewPath); - /// Copies a file, returns true if successful. + /** Copies a file, returns true if successful. */ static bool Copy(const AString & a_SrcFileName, const AString & a_DstFileName); - /// Returns true if the specified path is a folder + /** Returns true if the specified path is a folder */ static bool IsFolder(const AString & a_Path); - /// Returns true if the specified path is a regular file + /** Returns true if the specified path is a regular file */ static bool IsFile(const AString & a_Path); - /// Returns the size of the file, or a negative number on error + /** Returns the size of the file, or a negative number on error */ static int GetSize(const AString & a_FileName); - /// Creates a new folder with the specified name. Returns true if successful. Path may be relative or absolute + /** Creates a new folder with the specified name. Returns true if successful. Path may be relative or absolute */ static bool CreateFolder(const AString & a_FolderPath); - /// Returns the entire contents of the specified file as a string. Returns empty string on error. + /** Returns the entire contents of the specified file as a string. Returns empty string on error. */ static AString ReadWholeFile(const AString & a_FileName); // tolua_end - /// Returns the list of all items in the specified folder (files, folders, nix pipes, whatever's there). + /** Returns the list of all items in the specified folder (files, folders, nix pipes, whatever's there). */ static AStringVector GetFolderContents(const AString & a_Folder); // Exported in ManualBindings.cpp int Printf(const char * a_Fmt, ...); + /** Flushes all the bufferef output into the file (only when writing) */ + void Flush(void); + private: #ifdef USE_STDIO_FILE FILE * m_File; From ff066453b805748d6e665b3ad219a62c777e4453 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 25 Jan 2014 15:28:16 +0100 Subject: [PATCH 23/23] Comm logging is available in both Debug and Release modes. --- src/Protocol/Protocol17x.cpp | 26 ++++++++++++++++---------- src/Protocol/Protocol17x.h | 2 -- src/main.cpp | 4 ---- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 8abe4f259..504dd99c3 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -53,10 +53,8 @@ Implements the 1.7.x protocol classes: -#ifdef _DEBUG // fwd: main.cpp: extern bool g_ShouldLogComm; -#endif @@ -76,14 +74,12 @@ cProtocol172::cProtocol172(cClientHandle * a_Client, const AString & a_ServerAdd m_IsEncrypted(false) { // Create the comm log file, if so requested: - #ifdef _DEBUG if (g_ShouldLogComm) { cFile::CreateFolder("CommLogs"); AString FileName = Printf("CommLogs/%x__%s.log", (unsigned)time(NULL), a_Client->GetIPString().c_str()); m_CommLogFile.Open(FileName, cFile::fmWrite); } - #endif // _DEBUG } @@ -1087,7 +1083,6 @@ void cProtocol172::SendWindowProperty(const cWindow & a_Window, short a_Property void cProtocol172::AddReceivedData(const char * a_Data, int a_Size) { // Write the incoming data into the comm log file: - #ifdef _DEBUG if (g_ShouldLogComm) { if (m_ReceivedData.GetReadableSpace() > 0) @@ -1109,7 +1104,6 @@ void cProtocol172::AddReceivedData(const char * a_Data, int a_Size) a_Size, a_Size, Hex.c_str() ); } - #endif if (!m_ReceivedData.Write(a_Data, a_Size)) { @@ -1147,7 +1141,6 @@ void cProtocol172::AddReceivedData(const char * a_Data, int a_Size) } // Log the packet info into the comm log file: - #ifdef _DEBUG if (g_ShouldLogComm) { AString PacketData; @@ -1162,7 +1155,6 @@ void cProtocol172::AddReceivedData(const char * a_Data, int a_Size) PacketType, PacketType, PacketLen, PacketLen, m_State, PacketDataHex.c_str() ); } - #endif // _DEBUG if (!HandlePacket(bb, PacketType)) { @@ -1180,6 +1172,12 @@ void cProtocol172::AddReceivedData(const char * a_Data, int a_Size) LOGD("Packet contents:\n%s", Out.c_str()); #endif // _DEBUG + // Put a message in the comm log: + if (g_ShouldLogComm) + { + m_CommLogFile.Printf("^^^^^^ Unhandled packet ^^^^^^\n\n\n"); + } + return; } @@ -1189,6 +1187,16 @@ void cProtocol172::AddReceivedData(const char * a_Data, int a_Size) LOGWARNING("Protocol 1.7: Wrong number of bytes read for packet 0x%x, state %d. Read %u bytes, packet contained %u bytes", PacketType, m_State, bb.GetUsedSpace() - bb.GetReadableSpace(), PacketLen ); + + // Put a message in the comm log: + if (g_ShouldLogComm) + { + m_CommLogFile.Printf("^^^^^^ Wrong number of bytes read for this packet (exp %d left, got %d left) ^^^^^^\n\n\n", + 1, bb.GetReadableSpace() + ); + m_CommLogFile.Flush(); + } + ASSERT(!"Read wrong number of bytes!"); m_Client->PacketError(PacketType); } @@ -1873,7 +1881,6 @@ cProtocol172::cPacketizer::~cPacketizer() m_Out.CommitRead(); // Log the comm into logfile: - #ifdef _DEBUG if (g_ShouldLogComm) { AString Hex; @@ -1883,7 +1890,6 @@ cProtocol172::cPacketizer::~cPacketizer() DataToSend[0], DataToSend[0], PacketLen, PacketLen, m_Protocol.m_State, Hex.c_str() ); } - #endif // _DEBUG } diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h index b04a1f019..cac7f0d29 100644 --- a/src/Protocol/Protocol17x.h +++ b/src/Protocol/Protocol17x.h @@ -223,10 +223,8 @@ protected: CryptoPP::CFB_Mode::Decryption m_Decryptor; CryptoPP::CFB_Mode::Encryption m_Encryptor; - #ifdef _DEBUG /** The logfile where the comm is logged, when g_ShouldLogComm is true */ cFile m_CommLogFile; - #endif /// Adds the received (unencrypted) data to m_ReceivedData, parses complete packets diff --git a/src/main.cpp b/src/main.cpp index 902e9e43b..06b344c25 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -19,10 +19,8 @@ bool g_SERVER_TERMINATED = false; // Set to true when the server terminates, so -#ifdef _DEBUG /** If set to true, the protocols will log each player's communication to a separate logfile */ bool g_ShouldLogComm; -#endif @@ -232,7 +230,6 @@ int main( int argc, char **argv ) // *((int *)0) = 0; // Check if comm logging is to be enabled: - #ifdef _DEBUG for (int i = 0; i < argc; i++) { if ( @@ -243,7 +240,6 @@ int main( int argc, char **argv ) g_ShouldLogComm = true; } } - #endif // _DEBUG #if !defined(ANDROID_NDK) try