diff options
author | Lukas Pioch <lukas@zgow.de> | 2017-08-23 18:09:47 +0200 |
---|---|---|
committer | Lukas Pioch <lukas@zgow.de> | 2017-08-27 17:49:08 +0200 |
commit | a5bae9f2f37921bfcf6203282155a8779c818120 (patch) | |
tree | b51bcc42cdc65fd7d0d76fd312216ec0720c706a | |
parent | Added a new param to OnPlayerEditingBook and changed the names (diff) | |
download | cuberite-a5bae9f2f37921bfcf6203282155a8779c818120.tar cuberite-a5bae9f2f37921bfcf6203282155a8779c818120.tar.gz cuberite-a5bae9f2f37921bfcf6203282155a8779c818120.tar.bz2 cuberite-a5bae9f2f37921bfcf6203282155a8779c818120.tar.lz cuberite-a5bae9f2f37921bfcf6203282155a8779c818120.tar.xz cuberite-a5bae9f2f37921bfcf6203282155a8779c818120.tar.zst cuberite-a5bae9f2f37921bfcf6203282155a8779c818120.zip |
-rw-r--r-- | Server/Plugins/APIDump/APIDesc.lua | 125 | ||||
-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 |
10 files changed, 330 insertions, 67 deletions
diff --git a/Server/Plugins/APIDump/APIDesc.lua b/Server/Plugins/APIDump/APIDesc.lua index 73443aa41..5768e89f6 100644 --- a/Server/Plugins/APIDump/APIDesc.lua +++ b/Server/Plugins/APIDump/APIDesc.lua @@ -7022,10 +7022,37 @@ local Item5 = cItem(E_ITEM_DIAMOND_CHESTPLATE, 1, 0, "thorns=1;unbreaking=3"); cBookContent = { Desc = [[ -This class contains the information for a signed or writeable book: The author, title and the pages. A page of the writeable book is a simple string. For a signed book it can be a json string. For the json string use {{cCompositeChat}} to create a page and then the function {{cCompositeChat#CreateJsonString_1|CreateJsonString}} to get the json string. +This class contains the information for a signed or writeable book: The author, title and the pages. A page of the writeable book is a simple string. For a signed book it can be a json string. Use {{cCompositeChat}} to create a more complex page with formatting. ]], Functions = { + AddPage = + { + { + Params = + { + { + Name = "Page", + Type = "string", + }, + }, + Notes = "Add a page to the end of the book", + }, + { + Params = + { + { + Name = "Page", + Type = "cCompositeChat", + }, + }, + Notes = "Add a page to the end of the book. For signed book saves it as json string, otherwise as simple string", + } + }, + Clear = + { + Notes = "Clears the whole book", + }, constructor = { Returns = @@ -7036,18 +7063,17 @@ This class contains the information for a signed or writeable book: The author, }, Notes = "Creates a empty book", }, - SetAuthor = + GetAuthor = { - Params = + Returns = { { - Name = "Author", Type = "string", }, }, - Notes = "Set the author of the book", + Notes = "Returns the author of the book", }, - GetAuthor = + GetTitle = { Returns = { @@ -7055,74 +7081,109 @@ This class contains the information for a signed or writeable book: The author, Type = "string", }, }, - Notes = "Get the author of the book", + Notes = "Returns the title of the book", }, - SetTitle = + GetPage = { Params = { { - Name = "Title", + Type = "number", + }, + }, + Returns = + { + { Type = "string", }, }, - Notes = "Set the title of the book", + Notes = "Returns the page at the given index, can be a json string or a simple string. Note: one-based", }, - GetTitle = + GetPages = { Returns = { { - Type = "string", + Type = "table", }, }, - Notes = "Returns the title of the book", + Notes = "Returns the pages of the book as a table", }, - AddPage = + IsEmpty = + { + Returns = + { + { + Type = "boolean", + }, + }, + Notes = "Returns true if the book has no author, title and no pages", + }, + SetAuthor = { Params = { { - Name = "Page", + Name = "Author", Type = "string", }, }, - Notes = "Add a page to the end of the book. Note: If it's a written book, the page can be a json string", + Notes = "Set the author of the book", }, - GetPages = + SetPage = { - Returns = { + Params = { - Type = "table", + { + Name = "Index", + Type = "number", + }, + { + Name = "Page", + Type = "string", + }, }, + Notes = "Set's the page at the given index. Note: one-based", + }, + { + Params = + { + { + Name = "Index", + Type = "number", + }, + { + Name = "Page", + Type = "cCompositeChat", + }, + }, + Notes = "Set's the page at the given index. For signed book saves it as json string, otherwise as simple string. Note: one-based", }, - Notes = "Returns the pages of the book as a table", }, SetPages = { - Params = { + Params = { - Name = "Pages", - Type = "table", + { + Name = "Pages", + Type = "table", + }, }, + Notes = "Sets all pages of the book. A entry can be a string or a {{cCompositeChat}}", }, - Notes = "Set the pages of the book", }, - Clear = - { - Notes = "Clears the whole book", - }, - IsEmpty = + SetTitle = { - Returns = + Params = { { - Type = "boolean", + Name = "Title", + Type = "string", }, }, - Notes = "Returns true if the book has no author, title and no pages", + Notes = "Set the title of the book", }, }, }, 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()) |