book and quill implementation

This commit is contained in:
DrPerkyLegit
2026-05-23 10:56:05 -04:00
parent 6f68cf0a20
commit f1d4882fe0
10 changed files with 181 additions and 152 deletions

View File

@@ -1440,113 +1440,111 @@ void PlayerConnection::handlePlayerAbilities(shared_ptr<PlayerAbilitiesPacket> p
void PlayerConnection::handleCustomPayload(shared_ptr<CustomPayloadPacket> customPayloadPacket)
{
#if 0
if (CustomPayloadPacket.CUSTOM_BOOK_PACKET.equals(customPayloadPacket.identifier))
if (CustomPayloadPacket::CUSTOM_BOOK_PACKET.compare(customPayloadPacket->identifier) == 0)
{
ByteArrayInputStream bais(customPayloadPacket->data);
DataInputStream input(&bais);
shared_ptr<ItemInstance> sentItem = Packet::readItem(input);
shared_ptr<ItemInstance> sentItem = Packet::readItem(&input);
if (!WritingBookItem.makeSureTagIsValid(sentItem.getTag()))
if (sentItem->tag == nullptr)
{
throw new IOException("Invalid book tag!");
throw new IOException(L"Invalid book tag!");
}
// make sure the sent item is the currently carried item
ItemInstance carried = player.inventory.getSelected();
if (sentItem != null && sentItem.id == Item.writingBook.id && sentItem.id == carried.id)
shared_ptr<ItemInstance> carried = player->inventory->getSelected();
if (sentItem != nullptr && sentItem->id == Item::writingBook_Id && sentItem->id == carried->id)
{
carried.addTagElement(WrittenBookItem.TAG_PAGES, sentItem.getTag().getList(WrittenBookItem.TAG_PAGES));
player->inventory->setItem(player->inventory->selected, sentItem);
}
}
else if (CustomPayloadPacket.CUSTOM_BOOK_SIGN_PACKET.equals(customPayloadPacket.identifier))
else if (CustomPayloadPacket::CUSTOM_BOOK_SIGN_PACKET.compare(customPayloadPacket->identifier) == 0)
{
DataInputStream input = new DataInputStream(new ByteArrayInputStream(customPayloadPacket.data));
ItemInstance sentItem = Packet.readItem(input);
ByteArrayInputStream bais(customPayloadPacket->data);
DataInputStream input(&bais);
shared_ptr<ItemInstance> sentItem = Packet::readItem(&input);
if (!WrittenBookItem.makeSureTagIsValid(sentItem.getTag()))
if (sentItem->tag == nullptr)
{
throw new IOException("Invalid book tag!");
throw new IOException(L"Invalid book tag!");
}
// make sure the sent item is the currently carried item
ItemInstance carried = player.inventory.getSelected();
if (sentItem != null && sentItem.id == Item.writtenBook.id && carried.id == Item.writingBook.id)
shared_ptr<ItemInstance> carried = player->inventory->getSelected();
if (sentItem != nullptr && sentItem->id == Item::writingBook_Id && sentItem->id == carried->id)
{
carried.addTagElement(WrittenBookItem.TAG_AUTHOR, new StringTag(WrittenBookItem.TAG_AUTHOR, player.getName()));
carried.addTagElement(WrittenBookItem.TAG_TITLE, new StringTag(WrittenBookItem.TAG_TITLE, sentItem.getTag().getString(WrittenBookItem.TAG_TITLE)));
carried.addTagElement(WrittenBookItem.TAG_PAGES, sentItem.getTag().getList(WrittenBookItem.TAG_PAGES));
carried.id = Item.writtenBook.id;
sentItem->setHoverName(sentItem->tag->getString(L"title"));
sentItem->id = 387;
player->inventory->setItem(player->inventory->selected, sentItem);
}
}
else
#endif
if (CustomPayloadPacket::TRADER_SELECTION_PACKET.compare(customPayloadPacket->identifier) == 0)
else if (CustomPayloadPacket::TRADER_SELECTION_PACKET.compare(customPayloadPacket->identifier) == 0)
{
ByteArrayInputStream bais(customPayloadPacket->data);
DataInputStream input(&bais);
int selection = input.readInt();
AbstractContainerMenu *menu = player->containerMenu;
if (dynamic_cast<MerchantMenu *>(menu))
{
static_cast<MerchantMenu *>(menu)->setSelectionHint(selection);
}
}
else if (CustomPayloadPacket::SET_ADVENTURE_COMMAND_PACKET.compare(customPayloadPacket->identifier) == 0)
{
if (!server->isCommandBlockEnabled())
{
app.DebugPrintf("Command blocks not enabled");
//player->sendMessage(ChatMessageComponent.forTranslation("advMode.notEnabled"));
}
else
{
//player.sendMessage(ChatMessageComponent.forTranslation("advMode.notAllowed"));
}
}
else if (CustomPayloadPacket::SET_BEACON_PACKET.compare(customPayloadPacket->identifier) == 0)
{
if ( dynamic_cast<BeaconMenu *>( player->containerMenu) != nullptr)
{
ByteArrayInputStream bais(customPayloadPacket->data);
DataInputStream input(&bais);
int selection = input.readInt();
int primary = input.readInt();
int secondary = input.readInt();
AbstractContainerMenu *menu = player->containerMenu;
if (dynamic_cast<MerchantMenu *>(menu))
BeaconMenu *beaconMenu = static_cast<BeaconMenu *>(player->containerMenu);
Slot *slot = beaconMenu->getSlot(0);
if (slot->hasItem())
{
static_cast<MerchantMenu *>(menu)->setSelectionHint(selection);
slot->remove(1);
shared_ptr<BeaconTileEntity> beacon = beaconMenu->getBeacon();
beacon->setPrimaryPower(primary);
beacon->setSecondaryPower(secondary);
beacon->setChanged();
}
}
else if (CustomPayloadPacket::SET_ADVENTURE_COMMAND_PACKET.compare(customPayloadPacket->identifier) == 0)
}
else if (CustomPayloadPacket::SET_ITEM_NAME_PACKET.compare(customPayloadPacket->identifier) == 0)
{
AnvilMenu *menu = dynamic_cast<AnvilMenu *>( player->containerMenu);
if (menu)
{
if (!server->isCommandBlockEnabled())
if (customPayloadPacket->data.data == nullptr || customPayloadPacket->data.length < 1)
{
app.DebugPrintf("Command blocks not enabled");
//player->sendMessage(ChatMessageComponent.forTranslation("advMode.notEnabled"));
menu->setItemName(L"");
}
else
{
//player.sendMessage(ChatMessageComponent.forTranslation("advMode.notAllowed"));
}
}
else if (CustomPayloadPacket::SET_BEACON_PACKET.compare(customPayloadPacket->identifier) == 0)
{
if ( dynamic_cast<BeaconMenu *>( player->containerMenu) != nullptr)
{
ByteArrayInputStream bais(customPayloadPacket->data);
DataInputStream input(&bais);
int primary = input.readInt();
int secondary = input.readInt();
BeaconMenu *beaconMenu = static_cast<BeaconMenu *>(player->containerMenu);
Slot *slot = beaconMenu->getSlot(0);
if (slot->hasItem())
DataInputStream dis(&bais);
wstring name = dis.readUTF();
if (name.length() <= 30)
{
slot->remove(1);
shared_ptr<BeaconTileEntity> beacon = beaconMenu->getBeacon();
beacon->setPrimaryPower(primary);
beacon->setSecondaryPower(secondary);
beacon->setChanged();
}
}
}
else if (CustomPayloadPacket::SET_ITEM_NAME_PACKET.compare(customPayloadPacket->identifier) == 0)
{
AnvilMenu *menu = dynamic_cast<AnvilMenu *>( player->containerMenu);
if (menu)
{
if (customPayloadPacket->data.data == nullptr || customPayloadPacket->data.length < 1)
{
menu->setItemName(L"");
}
else
{
ByteArrayInputStream bais(customPayloadPacket->data);
DataInputStream dis(&bais);
wstring name = dis.readUTF();
if (name.length() <= 30)
{
menu->setItemName(name);
}
menu->setItemName(name);
}
}
}
}
}
bool PlayerConnection::isDisconnected()

View File

@@ -215,8 +215,8 @@ Item *Item::skull = nullptr;
// TU14
//Item *Item::writingBook = nullptr;
//Item *Item::writtenBook = nullptr;
Item *Item::writingBook = nullptr;
Item *Item::writtenBook = nullptr;
Item *Item::emerald = nullptr;
@@ -461,8 +461,8 @@ void Item::staticCtor()
Item::skull = (new SkullItem(141)) ->setIconName(L"skull")->setDescriptionId(IDS_ITEM_SKULL)->setUseDescriptionId(IDS_DESC_SKULL);
// TU14
//Item::writingBook = (new WritingBookItem(130))->setIcon(11, 11)->setDescriptionId("writingBook");
//Item::writtenBook = (new WrittenBookItem(131))->setIcon(12, 11)->setDescriptionId("writtenBook");
Item::writingBook = (new WritingBookItem(130))->setIconName(L"writingBook")->setDescriptionId(-1)->setUseDescriptionId(-1)->setMaxStackSize(1);
Item::writtenBook = (new WrittenBookItem(131))->setIconName(L"writtenBook")->setDescriptionId(-1)->setUseDescriptionId(-1)->setMaxStackSize(1);
Item::emerald = (new Item(132)) ->setBaseItemTypeAndMaterial(eBaseItemType_treasure, eMaterial_emerald)->setIconName(L"emerald")->setDescriptionId(IDS_ITEM_EMERALD)->setUseDescriptionId(IDS_DESC_EMERALD);

View File

@@ -382,8 +382,8 @@ public:
static Item *frame;
// TU14
//static Item writingBook;
//static Item writtenBook;
static Item* writingBook;
static Item* writtenBook;
static Item *emerald;

View File

@@ -12,6 +12,11 @@ public:
ListTag() : Tag(L"") {}
ListTag(const wstring &name) : Tag(name) {}
//Needed type for some things
byte getType() const { return type; }
void setType(byte newType) { type = newType; }
vector<Tag*>& getList() { return list; }
void write(DataOutput *dos)
{
if (list.size() > 0) type = (list[0])->getId();

View File

@@ -0,0 +1,26 @@
#include "stdafx.h"
#include "Item.h"
#include "Player.h"
#include "ItemInstance.h"
#include "WritingBookItem.h"
#include "../Minecraft.Client/Minecraft.h"
#include "../Minecraft.Client/MultiplayerLocalPlayer.h"
WritingBookItem::WritingBookItem(int id) : Item(id)
{
setMaxStackSize(1);
}
shared_ptr<ItemInstance> WritingBookItem::use(shared_ptr<ItemInstance> instance, Level *level, shared_ptr<Player> player)
{
//shared_ptr<MultiplayerLocalPlayer> player1 = Minecraft::GetInstance()->player;
//player1->openItemInstanceGui(instance, player1);
player->openItemInstanceGui(instance);
return instance;
}
bool WritingBookItem::TestUse(shared_ptr<ItemInstance> itemInstance, Level* level, shared_ptr<Player> player)
{
return true;
}

View File

@@ -0,0 +1,12 @@
#pragma once
#include "Item.h"
class WritingBookItem : public Item
{
public:
WritingBookItem(int id);
virtual shared_ptr<ItemInstance> use(shared_ptr<ItemInstance> instance, Level* level, shared_ptr<Player> player);
virtual bool TestUse(shared_ptr<ItemInstance> itemInstance, Level* level, shared_ptr<Player> player);
};

View File

@@ -0,0 +1,48 @@
#include "stdafx.h"
#include "HtmlString.h"
#include "WrittenBookItem.h"
#include "../Minecraft.Client/Minecraft.h"
#include "../Minecraft.Client/MultiplayerLocalPlayer.h"
WrittenBookItem::WrittenBookItem(int id) : Item(id)
{
}
bool WrittenBookItem::isFoil(shared_ptr<ItemInstance> itemInstance)
{
return true;
}
const Rarity* WrittenBookItem::getRarity(shared_ptr<ItemInstance> itemInstance)
{
return Rarity::common;
}
shared_ptr<ItemInstance> WrittenBookItem::use(shared_ptr<ItemInstance> instance, Level* level, shared_ptr<Player> player)
{
//shared_ptr<MultiplayerLocalPlayer> player1 = Minecraft::GetInstance()->player;
//player1->openItemInstanceGui(instance, player1);
player->openItemInstanceGui(instance);
return instance;
}
bool WrittenBookItem::TestUse(shared_ptr<ItemInstance> itemInstance, Level* level, shared_ptr<Player> player)
{
return true;
}
void WrittenBookItem::appendHoverText(shared_ptr<ItemInstance> itemInstance, shared_ptr<Player> player, vector<HtmlString>* lines, bool advanced)
{
if (!itemInstance->hasTag())
{
return;
}
HtmlString stringd = HtmlString(L"By " + (itemInstance->tag->getString(L"author")), eHTMLColor_7, false, false);
HtmlString stringf = HtmlString(L"Original", eHTMLColor_7, false, false);
lines->push_back(stringd);
lines->push_back(stringf);
//lines->push_back(wstring(L"tone"));
}

View File

@@ -1,82 +1,18 @@
#pragma once
/*
class WrittenBookItem extends Item {
#include "Item.h"
public static final int TITLE_LENGTH = 16;
public static final int PAGE_LENGTH = 256;
public static final int MAX_PAGES = 50;
public static final String TAG_TITLE = "title";
public static final String TAG_AUTHOR = "author";
public static final String TAG_PAGES = "pages";
class WrittenBookItem : public Item
{
public:
public WrittenBookItem(int id) {
super(id);
setMaxStackSize(1);
}
wstring authorName = L"Unknown";
public static boolean makeSureTagIsValid(CompoundTag bookTag) {
WrittenBookItem(int id);
bool isFoil(shared_ptr<ItemInstance> itemInstance);
const Rarity* getRarity(shared_ptr<ItemInstance> itemInstance) override;
void appendHoverText(shared_ptr<ItemInstance> itemInstance, shared_ptr<Player> player, vector<HtmlString>* lines, bool advanced);
if (!WritingBookItem.makeSureTagIsValid(bookTag)) {
return false;
}
if (!bookTag.contains(TAG_TITLE)) {
return false;
}
String title = bookTag.getString(TAG_TITLE);
if (title == null || title.length() > TITLE_LENGTH) {
return false;
}
if (!bookTag.contains(TAG_AUTHOR)) {
return false;
}
return true;
}
@Override
public String getHoverName(ItemInstance itemInstance) {
if (itemInstance.hasTag()) {
CompoundTag itemTag = itemInstance.getTag();
StringTag titleTag = (StringTag) itemTag.get(TAG_TITLE);
if (titleTag != null) {
return titleTag.toString();
}
}
return super.getHoverName(itemInstance);
}
@Override
public void appendHoverText(ItemInstance itemInstance, Player player, List<String> lines, boolean advanced) {
if (itemInstance.hasTag()) {
CompoundTag itemTag = itemInstance.getTag();
StringTag authorTag = (StringTag) itemTag.get(TAG_AUTHOR);
if (authorTag != null) {
lines.add(ChatFormatting.GRAY + String.format(I18n.get("book.byAuthor", authorTag.data)));
}
}
}
@Override
public ItemInstance use(ItemInstance itemInstance, Level level, Player player) {
player.openItemInstanceGui(itemInstance);
return itemInstance;
}
@Override
public boolean shouldOverrideMultiplayerNBT() {
return true;
}
@Override
public boolean isFoil(ItemInstance itemInstance) {
return true;
}
};
*/
virtual shared_ptr<ItemInstance> use(shared_ptr<ItemInstance> instance, Level* level, shared_ptr<Player> player);
virtual bool TestUse(shared_ptr<ItemInstance> itemInstance, Level* level, shared_ptr<Player> player);
};

View File

@@ -23,6 +23,8 @@
#include "LeafTileItem.h"
#include "MapItem.h"
#include "MinecartItem.h"
#include "WritingBookItem.h"
#include "WrittenBookItem.h"
//#include "PaintingItem.h"
#include "PickaxeItem.h"
#include "PistonTileItem.h"

View File

@@ -783,6 +783,8 @@ set(MINECRAFT_WORLD_SOURCES
"WoolCarpetTile.cpp"
"WoolTileItem.cpp"
"WorkbenchTile.cpp"
"WrittenBookItem.cpp"
"WritingBookItem.cpp"
"XZPacket.cpp"
"Zombie.cpp"
"ZoomLayer.cpp"