diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Bindings/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/Bindings/ManualBindings.cpp | 184 | ||||
-rw-r--r-- | src/Bindings/PluginManager.h | 2 | ||||
-rw-r--r-- | src/BookContent.cpp | 12 | ||||
-rw-r--r-- | src/BookContent.h | 30 | ||||
-rw-r--r-- | src/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/Item.cpp | 4 | ||||
-rw-r--r-- | src/Protocol/Protocol_1_9.cpp | 32 | ||||
-rw-r--r-- | src/WorldStorage/NBTChunkSerializer.cpp | 4 |
9 files changed, 237 insertions, 35 deletions
diff --git a/src/Bindings/CMakeLists.txt b/src/Bindings/CMakeLists.txt index 7b1635a4a..15d629117 100644 --- a/src/Bindings/CMakeLists.txt +++ b/src/Bindings/CMakeLists.txt @@ -85,6 +85,7 @@ set(BINDING_DEPENDENCIES ../BlockEntities/FlowerPotEntity.h ../BlockID.h ../BlockInfo.h + ../BookContent.h ../BoundingBox.h ../ChatColor.h ../ChunkDef.h @@ -143,7 +144,6 @@ set(BINDING_DEPENDENCIES ../Vector3.h ../WebAdmin.h ../World.h - ../BookContent.h ) if (NOT MSVC) diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 2a08e3e56..32711223d 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -3967,6 +3967,93 @@ static int tolua_cEntity_GetSpeed(lua_State * tolua_S) +static int tolua_cBookContent_AddPage(lua_State * tolua_S) +{ + // cBookContent:AddPage(string) + // cBookContent:AddPage(cCompositeChat) + + cLuaState L(tolua_S); + if ( + !L.CheckParamSelf("cBookContent") || + lua_isnil(L, 2) || + !L.CheckParamEnd(3) + ) + { + return 0; + } + + cBookContent * BookContent = nullptr; + L.GetStackValue(1, BookContent); + + // Check type of second param + if (L.GetTypeText(2) == "string") + { + AString Page; + L.GetStackValue(2, Page); + BookContent->AddPage(Page); + } + else if (L.CheckParamUserType(2, "cCompositeChat")) + { + cCompositeChat * CompositeChat = nullptr; + L.GetStackValue(2, CompositeChat); + if (BookContent->IsSigned()) + { + BookContent->AddPage(CompositeChat->CreateJsonString()); + } + else + { + BookContent->AddPage(CompositeChat->ExtractText()); + } + } + else + { + return L.ApiParamError("Expected a string or a cCompositeChat."); + } + return 0; +} + + + + + +static int tolua_cBookContent_GetPage(lua_State * tolua_S) +{ + // cBookContent::GetPage(Index) -> string + + cLuaState L(tolua_S); + if ( + !L.CheckParamSelf("cBookContent") || + !L.CheckParamNumber(2) || + !L.CheckParamEnd(3) + ) + { + return 0; + } + + cBookContent * BookContent = nullptr; + size_t Index; + L.GetStackValues(1, BookContent, Index); + + if (BookContent->GetPages().empty()) + { + return L.ApiParamError("Getting the page at the index is not possbile. The book has no pages."); + } + + // Check if the index is valid + if ((Index <= 0) || (Index > BookContent->GetPages().size())) + { + return L.ApiParamError("Index %d out of range. The valid range is %d - %d.", Index, 1, BookContent->GetPages().size()); + } + + L.Push(BookContent->GetPage(Index - 1)); + return 1; + +} + + + + + static int tolua_cBookContent_GetPages(lua_State * tolua_S) { // cBookContent::GetPages() -> table of strings @@ -3990,6 +4077,68 @@ static int tolua_cBookContent_GetPages(lua_State * tolua_S) +static int tolua_cBookContent_SetPage(lua_State * tolua_S) +{ + // cBookContent::SetPage(index, string) + // cBookContent::SetPage(index, cCompositeChat) + + cLuaState L(tolua_S); + if ( + !L.CheckParamSelf("cBookContent") || + !L.CheckParamNumber(2) || + lua_isnil(L, 3) || + !L.CheckParamEnd(4) + ) + { + return 0; + } + + cBookContent * BookContent = nullptr; + size_t Index; + L.GetStackValues(1, BookContent, Index); + + if (BookContent->GetPages().empty()) + { + return L.ApiParamError("Changing the page at the index is not possbile. The book has no pages."); + } + + // Check if the index is valid + if ((Index <= 0) || (Index > BookContent->GetPages().size())) + { + return L.ApiParamError("The index %d is out of range. The valid range is %d to %d.", Index, 1, BookContent->GetPages().size()); + } + + // Check type of third param + if (L.GetTypeText(3) == "string") + { + AString Page; + L.GetStackValue(3, Page); + BookContent->SetPage(Index - 1, Page); + } + else if (L.CheckParamUserType(3, "cCompositeChat")) + { + cCompositeChat * CompositeChat = nullptr; + L.GetStackValue(3, CompositeChat); + if (BookContent->IsSigned()) + { + BookContent->SetPage(Index - 1, CompositeChat->CreateJsonString()); + } + else + { + BookContent->SetPage(Index - 1, CompositeChat->ExtractText()); + } + } + else + { + return L.ApiParamError("Expected a string or a cCompositeChat."); + } + return 0; +} + + + + + static int tolua_cBookContent_SetPages(lua_State * tolua_S) { // cBookContent::SetPages(table) @@ -4010,9 +4159,25 @@ static int tolua_cBookContent_SetPages(lua_State * tolua_S) BookContent->ClearPages(); Pages->ForEachArrayElement([=](cLuaState & a_LuaState, int a_Index) -> bool { - AString Page; - a_LuaState.GetStackValue(-1, Page); - BookContent->AddPage(Page); + if (a_LuaState.GetTypeText(-1) == "string") + { + AString Page; + a_LuaState.GetStackValue(-1, Page); + BookContent->AddPage(Page); + } + else if (a_LuaState.CheckParamUserType(-1, "cCompositeChat")) + { + cCompositeChat * CompositeChat = nullptr; + a_LuaState.GetStackValue(-1, CompositeChat); + if (BookContent->IsSigned()) + { + BookContent->AddPage(CompositeChat->CreateJsonString()); + } + else + { + BookContent->AddPage(CompositeChat->ExtractText()); + } + } return false; } ); @@ -4051,6 +4216,14 @@ void cManualBindings::Bind(lua_State * tolua_S) tolua_function(tolua_S, "Base64Decode", tolua_Base64Decode); tolua_function(tolua_S, "md5", tolua_md5_obsolete); // OBSOLETE, use cCryptoHash.md5() instead + tolua_beginmodule(tolua_S, "cBookContent"); + tolua_function(tolua_S, "AddPage", tolua_cBookContent_AddPage); + tolua_function(tolua_S, "GetPage", tolua_cBookContent_GetPage); + tolua_function(tolua_S, "GetPages", tolua_cBookContent_GetPages); + tolua_function(tolua_S, "SetPage", tolua_cBookContent_SetPage); + tolua_function(tolua_S, "SetPages", tolua_cBookContent_SetPages); + tolua_endmodule(tolua_S); + tolua_beginmodule(tolua_S, "cBoundingBox"); tolua_function(tolua_S, "CalcLineIntersection", tolua_cBoundingBox_CalcLineIntersection); tolua_function(tolua_S, "Intersect", tolua_cBoundingBox_Intersect); @@ -4250,11 +4423,6 @@ void cManualBindings::Bind(lua_State * tolua_S) tolua_variable(tolua_S, "PostParams", tolua_get_HTTPRequest_PostParams, nullptr); tolua_endmodule(tolua_S); - tolua_beginmodule(tolua_S, "cBookContent"); - tolua_function(tolua_S, "GetPages", tolua_cBookContent_GetPages); - tolua_function(tolua_S, "SetPages", tolua_cBookContent_SetPages); - tolua_endmodule(tolua_S); - BindNetwork(tolua_S); BindRankManager(tolua_S); BindWorld(tolua_S); diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index d7bbf62c2..0c02404d2 100644 --- a/src/Bindings/PluginManager.h +++ b/src/Bindings/PluginManager.h @@ -248,7 +248,7 @@ public: bool CallHookHandshake (cClientHandle & a_ClientHandle, const AString & a_Username); bool CallHookHopperPullingItem (cWorld & a_World, cHopperEntity & a_Hopper, int a_DstSlotNum, cBlockEntityWithItems & a_SrcEntity, int a_SrcSlotNum); bool CallHookHopperPushingItem (cWorld & a_World, cHopperEntity & a_Hopper, int a_SrcSlotNum, cBlockEntityWithItems & a_DstEntity, int a_DstSlotNum); - bool CallHookKilled (cEntity & a_Victim, TakeDamageInfo & a_TDI, AString & a_DeathMessage); + bool CallHookKilled (cEntity & a_Victim, TakeDamageInfo & a_TDI, AString & a_DeathMessage); bool CallHookKilling (cEntity & a_Victim, cEntity * a_Killer, TakeDamageInfo & a_TDI); bool CallHookLogin (cClientHandle & a_Client, UInt32 a_ProtocolVersion, const AString & a_Username); bool CallHookPlayerAnimation (cPlayer & a_Player, int a_Animation); diff --git a/src/BookContent.cpp b/src/BookContent.cpp index 4163d77d1..40819316b 100644 --- a/src/BookContent.cpp +++ b/src/BookContent.cpp @@ -80,8 +80,16 @@ void cBookContent::WriteToNBTCompound(const cBookContent & a_BookContent, cFastN return; } - a_Writer.AddString("author", a_BookContent.GetAuthor()); - a_Writer.AddString("title", a_BookContent.GetTitle()); + if (!a_BookContent.GetAuthor().empty()) + { + a_Writer.AddString("author", a_BookContent.GetAuthor()); + + } + if (!a_BookContent.GetTitle().empty()) + { + a_Writer.AddString("title", a_BookContent.GetTitle()); + + } a_Writer.BeginList("pages", TAG_String); for (const auto & Page : a_BookContent.GetPages()) { diff --git a/src/BookContent.h b/src/BookContent.h index 43fd93742..f8a6b6a38 100644 --- a/src/BookContent.h +++ b/src/BookContent.h @@ -14,7 +14,9 @@ class cBookContent { public: /** Creates a empty book */ - cBookContent() {} + cBookContent(): + m_IsSigned(false) + {} /** Set the author of the book */ void SetAuthor(const AString & a_Author) { m_Author = a_Author; } @@ -28,9 +30,6 @@ public: /** Returns the title of the book */ const AString & GetTitle(void) const { return m_Title; } - /** Add a page to the end of the book */ - void AddPage(const AString & a_Page) { m_Pages.emplace_back(a_Page); } - /** Clears the whole book */ void Clear(); @@ -39,13 +38,29 @@ public: // tolua_end + /** Required in ManualBindings to save the page as simple string or json string */ + void SetIsSigned(bool a_IsSigned) { m_IsSigned = a_IsSigned; } + + /** Returns true if the book is signed */ + bool IsSigned(void) const { return m_IsSigned; } + + /** Add a page to the end of the book */ + void AddPage(const AString & a_Page) { m_Pages.emplace_back(a_Page); } + + /** Returns the page at the index */ + const AString & GetPage(size_t a_Index) { return m_Pages[a_Index]; } + + /** Changes the page at the index */ + void SetPage(size_t a_Index, const AString & a_Page) { m_Pages[a_Index] = a_Page; } + + /** Removes all pages */ void ClearPages(void) { m_Pages.clear(); } - /** Returns a AStringVector ref to the pages. Used in ManualBindings and for saving the book */ - const AStringVector & GetPages(void) const { return m_Pages; } + /** Returns a ref to the vector. Used in ManualBindings and for saving the book */ + const std::vector<AString> & GetPages(void) const { return m_Pages; } /** Read the book content from nbt. The boolean a_SaveAsJson is optional. If the book is signed, the text should be in a json string */ static void ParseFromNBT(int TagTag, cBookContent & a_BookContent, const cParsedNBT & a_NBT, bool a_SaveAsJson = false); @@ -63,4 +78,7 @@ private: /** Contains the pages */ AStringVector m_Pages; + /** If true the book is written */ + bool m_IsSigned; + }; // tolua_export diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a71da1363..548fa746c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -85,6 +85,7 @@ SET (HDRS BlockInServerPluginInterface.h BlockInfo.h BlockTracer.h + BookContent.h BrewingRecipes.h Broadcaster.h BoundingBox.h @@ -154,7 +155,6 @@ SET (HDRS VoronoiMap.h WebAdmin.h World.h - BookContent.h XMLParser.h ) diff --git a/src/Item.cpp b/src/Item.cpp index 412c66ec3..09f8f39d7 100644 --- a/src/Item.cpp +++ b/src/Item.cpp @@ -258,6 +258,10 @@ void cItem::FromJson(const Json::Value & a_Value) { m_BookContent.SetAuthor(a_Value.get("author", "").asString()); m_BookContent.SetTitle(a_Value.get("title", "").asString()); + if (m_ItemType == E_ITEM_WRITTEN_BOOK) + { + m_BookContent.SetIsSigned(true); + } if (a_Value.isMember("pages")) { for (Json::Value::ArrayIndex i = 0; i != a_Value["pages"].size(); i++) diff --git a/src/Protocol/Protocol_1_9.cpp b/src/Protocol/Protocol_1_9.cpp index 712658329..8e43fd2cc 100644 --- a/src/Protocol/Protocol_1_9.cpp +++ b/src/Protocol/Protocol_1_9.cpp @@ -2966,20 +2966,24 @@ void cProtocol_1_9_0::HandleVanillaPluginMessage(cByteBuffer & a_ByteBuffer, con BookItem = cItem(E_ITEM_BOOK_AND_QUILL); cBookContent::ParseFromNBT(0, BookItem.m_BookContent, NBT); } + BookItem.m_BookContent.SetIsSigned(IsSigned); // The equipped item contains the old book content if (cRoot::Get()->GetPluginManager()->CallHookPlayerEditingBook(Player, Player.GetEquippedItem().m_BookContent, BookItem.m_BookContent, IsSigned)) { - // Plugin denied the editing of the book + // Plugin denied the player to edit the book + cInventory & inv = Player.GetInventory(); + inv.SetHotbarSlot(inv.GetEquippedSlotNum(), BookItem); + Player.GetInventory().SendEquippedSlot(); return; } - // Book has been edited, inform plugins - cRoot::Get()->GetPluginManager()->CallHookPlayerEditedBook(Player, BookItem.m_BookContent, IsSigned); - cInventory & inv = Player.GetInventory(); inv.SetHotbarSlot(inv.GetEquippedSlotNum(), BookItem); Player.GetInventory().SendEquippedSlot(); + + // Book has been edited by player, inform plugins + cRoot::Get()->GetPluginManager()->CallHookPlayerEditedBook(Player, BookItem.m_BookContent, IsSigned); return; } LOG("Unhandled vanilla plugin channel: \"%s\".", a_Channel.c_str()); @@ -3418,9 +3422,9 @@ void cProtocol_1_9_0::WriteItem(cPacketizer & a_Pkt, const cItem & a_Item) return; } - if ((ItemType == E_ITEM_BOOK_AND_QUILL) && (a_Item.m_BookContent.GetPages().size() == 0)) + if ((ItemType == E_ITEM_BOOK_AND_QUILL) && a_Item.m_BookContent.GetPages().empty()) { - // Don't send any nbt tag if the book is writeable and has no pages + // Don't send any nbt tag if the book is not signed and has no pages // If a tag with a empty pages list is send, the player can't enter anything a_Pkt.WriteBEInt8(0); return; @@ -3539,24 +3543,24 @@ void cProtocol_1_9_0::WriteItem(cPacketizer & a_Pkt, const cItem & a_Item) { if (a_Item.m_ItemType == E_ITEM_WRITTEN_BOOK) { - // Only send author and title for a signed book + // Only send author and title if the book is signed Writer.AddString("author", a_Item.m_BookContent.GetAuthor()); Writer.AddString("title", a_Item.m_BookContent.GetTitle()); } - if (a_Item.m_BookContent.GetPages().size() > 0) + if (a_Item.m_BookContent.GetPages().empty()) { + // A signed book, has a empty page Writer.BeginList("pages", TAG_String); - for (auto & Page : a_Item.m_BookContent.GetPages()) - { - Writer.AddString("", Page); - } + Writer.AddString("", ""); Writer.EndList(); } else { - // A signed book, has a empty page Writer.BeginList("pages", TAG_String); - Writer.AddString("", ""); + for (const auto & Page : a_Item.m_BookContent.GetPages()) + { + Writer.AddString("", Page); + } Writer.EndList(); } } diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index 702439133..df627006c 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -106,8 +106,8 @@ void cNBTChunkSerializer::AddItem(const cItem & a_Item, int a_Slot, const AStrin // Write the tag compound (for enchantment, firework, custom name and repair cost): if ( (!a_Item.m_Enchantments.IsEmpty()) || - ((a_Item.m_ItemType == E_ITEM_FIREWORK_ROCKET) || (a_Item.m_ItemType == E_ITEM_FIREWORK_STAR) || - (a_Item.m_ItemType == E_ITEM_WRITTEN_BOOK)) || (a_Item.m_ItemType == E_ITEM_BOOK_AND_QUILL) || + (a_Item.m_ItemType == E_ITEM_FIREWORK_ROCKET) || (a_Item.m_ItemType == E_ITEM_FIREWORK_STAR) || + (a_Item.m_ItemType == E_ITEM_WRITTEN_BOOK) || (a_Item.m_ItemType == E_ITEM_BOOK_AND_QUILL) || (a_Item.m_RepairCost > 0) || (a_Item.m_CustomName != "") || (!a_Item.m_LoreTable.empty()) |