mirror of
https://github.com/neoStudiosLCE/neoLegacy.git
synced 2026-06-09 00:33:00 +00:00
feat: multiplayer feat/less hardcoded lists (#89)
Some checks are pending
Sync branches with main / sync (push) Waiting to run
Some checks are pending
Sync branches with main / sync (push) Waiting to run
* CustomPayloadPacket Changes commented all code for old equip packets cleaned up custom payload key creation added 2 new payload packet definitions for upcoming changes * server sided recipe list * code cleanup for recipes * add dtor for recipe classes to fix memory leak * forgot this part to the dtor commit * dtor changes tested and fixed * server side creative menu list
This commit is contained in:
parent
9f37450178
commit
b67cbb85f3
|
|
@ -61,6 +61,8 @@
|
|||
#include "Windows64/Network/WinsockNetLayer.h"
|
||||
#endif
|
||||
|
||||
#include "../Minecraft.World/Recipes.h"
|
||||
|
||||
|
||||
#ifdef _DURANGO
|
||||
#include "../Minecraft.World/DurangoStats.h"
|
||||
|
|
@ -137,6 +139,9 @@ ClientConnection::ClientConnection(Minecraft *minecraft, Socket *socket, int iUs
|
|||
maxPlayers = 20;
|
||||
m_isForkServer = false;
|
||||
|
||||
m_recivedRecipeRegistyUpdate = false;
|
||||
m_recivedCreativeRegistyUpdate = false;
|
||||
|
||||
this->minecraft = minecraft;
|
||||
|
||||
if( iUserIndex < 0 )
|
||||
|
|
@ -246,6 +251,14 @@ void ClientConnection::handleLogin(shared_ptr<LoginPacket> packet)
|
|||
{
|
||||
if (done) return;
|
||||
|
||||
if (!m_recivedRecipeRegistyUpdate) {
|
||||
Recipes::getInstance()->loadFromLocal();
|
||||
}
|
||||
|
||||
if (!m_recivedCreativeRegistyUpdate) {
|
||||
IUIScene_CreativeMenu::loadFromLocal();
|
||||
}
|
||||
|
||||
PlayerUID OnlineXuid;
|
||||
ProfileManager.GetXUID(m_userIndex,&OnlineXuid,true); // online xuid
|
||||
MOJANG_DATA *pMojangData = nullptr;
|
||||
|
|
@ -4025,6 +4038,16 @@ void ClientConnection::handleCustomPayload(shared_ptr<CustomPayloadPacket> custo
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (CustomPayloadPacket::UPDATE_RECIPE_REGISTRY.compare(customPayloadPacket->identifier) == 0) {
|
||||
this->m_recivedRecipeRegistyUpdate = true;
|
||||
|
||||
Recipes::getInstance()->loadFromPacket(customPayloadPacket->data);
|
||||
}
|
||||
else if (CustomPayloadPacket::UPDATE_CREATIVE_REGISTRY.compare(customPayloadPacket->identifier) == 0) {
|
||||
this->m_recivedCreativeRegistyUpdate = true;
|
||||
|
||||
IUIScene_CreativeMenu::loadFromPacket(customPayloadPacket->data);
|
||||
}
|
||||
}
|
||||
|
||||
Connection *ClientConnection::getConnection()
|
||||
|
|
|
|||
|
|
@ -49,6 +49,8 @@ private:
|
|||
std::unordered_set<int> m_trackedEntityIds;
|
||||
std::unordered_set<int64_t> m_visibleChunks;
|
||||
bool m_isForkServer; // true when connected to a fork server (received MC|ForkHello)
|
||||
bool m_recivedRecipeRegistyUpdate;
|
||||
bool m_recivedCreativeRegistyUpdate;
|
||||
|
||||
static int64_t chunkKey(int x, int z) { return ((int64_t)x << 32) | ((int64_t)z & 0xFFFFFFFF); }
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#include "IUIScene_CreativeMenu.h"
|
||||
#include "stdafx.h"
|
||||
#include "IUIScene_CreativeMenu.h"
|
||||
|
||||
|
|
@ -22,6 +23,56 @@ vector< shared_ptr<ItemInstance> > IUIScene_CreativeMenu::categoryGroups[eCreati
|
|||
#define ITEM_AUX(id, aux) list->push_back( shared_ptr<ItemInstance>(new ItemInstance(id, 1, aux)) );
|
||||
#define DEF(index) list = &categoryGroups[index];
|
||||
|
||||
void IUIScene_CreativeMenu::_wipeCreativeItems() {
|
||||
for (int i = 0; i < eCreativeInventoryGroupsCount; i++) {
|
||||
IUIScene_CreativeMenu::categoryGroups[i].clear();
|
||||
}
|
||||
}
|
||||
|
||||
void IUIScene_CreativeMenu::loadFromLocal() {
|
||||
IUIScene_CreativeMenu::_wipeCreativeItems();
|
||||
IUIScene_CreativeMenu::staticCtor();
|
||||
}
|
||||
|
||||
void IUIScene_CreativeMenu::loadFromPacket(byteArray packetData) {
|
||||
ByteArrayInputStream bais(packetData);
|
||||
DataInputStream input(&bais);
|
||||
|
||||
IUIScene_CreativeMenu::_wipeCreativeItems();
|
||||
|
||||
for (int i = 0; i < eCreativeInventoryGroupsCount; i++) {
|
||||
int itemCount = input.readShort();
|
||||
|
||||
for (int j = 0; j < itemCount; j++) {
|
||||
int itemId = input.readShort();
|
||||
int itemAux = input.readShort();
|
||||
|
||||
shared_ptr<ItemInstance> item = std::make_shared<ItemInstance>(itemId, 1, 0);
|
||||
item->setRawAuxValue(itemAux);
|
||||
item->tag = Packet::readNbt(&input);
|
||||
|
||||
IUIScene_CreativeMenu::categoryGroups[i].emplace_back(item);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::shared_ptr<CustomPayloadPacket> IUIScene_CreativeMenu::createUpdatePacket() {
|
||||
ByteArrayOutputStream baos;
|
||||
DataOutputStream dos(&baos);
|
||||
|
||||
for (int i = 0; i < eCreativeInventoryGroupsCount; i++) {
|
||||
dos.writeShort(IUIScene_CreativeMenu::categoryGroups[i].size());
|
||||
for (shared_ptr<ItemInstance>& item : IUIScene_CreativeMenu::categoryGroups[i]) {
|
||||
dos.writeShort(item->id);
|
||||
dos.writeShort(item->getAuxValue());
|
||||
Packet::writeNbt(item->tag, &dos);
|
||||
}
|
||||
}
|
||||
|
||||
return std::make_shared<CustomPayloadPacket>(CustomPayloadPacket::UPDATE_CREATIVE_REGISTRY, baos.toByteArray());
|
||||
}
|
||||
|
||||
void IUIScene_CreativeMenu::staticCtor()
|
||||
{
|
||||
vector< shared_ptr<ItemInstance> > *list;
|
||||
|
|
@ -801,55 +852,56 @@ void IUIScene_CreativeMenu::staticCtor()
|
|||
ITEM_AUX(Item::potion_Id,MACRO_MAKEPOTION_AUXVAL(MASK_SPLASH, MASK_LEVEL2EXTENDED, MASK_JUMPBOOST))
|
||||
// end of tu31 potions
|
||||
|
||||
if (specs == nullptr) {
|
||||
specs = new TabSpec * [eCreativeInventoryTab_COUNT];
|
||||
|
||||
specs = new TabSpec*[eCreativeInventoryTab_COUNT];
|
||||
|
||||
// Top Row
|
||||
ECreative_Inventory_Groups blocksGroup[] = {eCreativeInventory_BuildingBlocks};
|
||||
specs[eCreativeInventoryTab_BuildingBlocks] = new TabSpec(L"Structures", IDS_GROUPNAME_BUILDING_BLOCKS, 1, blocksGroup);
|
||||
// Top Row
|
||||
ECreative_Inventory_Groups blocksGroup[] = { eCreativeInventory_BuildingBlocks };
|
||||
specs[eCreativeInventoryTab_BuildingBlocks] = new TabSpec(L"Structures", IDS_GROUPNAME_BUILDING_BLOCKS, 1, blocksGroup);
|
||||
|
||||
#ifndef _CONTENT_PACKAGE
|
||||
ECreative_Inventory_Groups decorationsGroup[] = {eCreativeInventory_Decoration};
|
||||
ECreative_Inventory_Groups debugDecorationsGroup[] = {eCreativeInventory_ArtToolsDecorations};
|
||||
specs[eCreativeInventoryTab_Decorations] = new TabSpec(L"Decoration", IDS_GROUPNAME_DECORATIONS, 1, decorationsGroup, 0, nullptr, 1, debugDecorationsGroup);
|
||||
ECreative_Inventory_Groups decorationsGroup[] = { eCreativeInventory_Decoration };
|
||||
ECreative_Inventory_Groups debugDecorationsGroup[] = { eCreativeInventory_ArtToolsDecorations };
|
||||
specs[eCreativeInventoryTab_Decorations] = new TabSpec(L"Decoration", IDS_GROUPNAME_DECORATIONS, 1, decorationsGroup, 0, nullptr, 1, debugDecorationsGroup);
|
||||
#else
|
||||
ECreative_Inventory_Groups decorationsGroup[] = {eCreativeInventory_Decoration};
|
||||
specs[eCreativeInventoryTab_Decorations] = new TabSpec(L"Decoration", IDS_GROUPNAME_DECORATIONS, 1, decorationsGroup);
|
||||
ECreative_Inventory_Groups decorationsGroup[] = { eCreativeInventory_Decoration };
|
||||
specs[eCreativeInventoryTab_Decorations] = new TabSpec(L"Decoration", IDS_GROUPNAME_DECORATIONS, 1, decorationsGroup);
|
||||
#endif
|
||||
|
||||
ECreative_Inventory_Groups redAndTranGroup[] = {eCreativeInventory_Transport, eCreativeInventory_Redstone};
|
||||
specs[eCreativeInventoryTab_RedstoneAndTransport] = new TabSpec(L"RedstoneAndTransport", IDS_GROUPNAME_REDSTONE_AND_TRANSPORT, 2, redAndTranGroup);
|
||||
ECreative_Inventory_Groups redAndTranGroup[] = { eCreativeInventory_Transport, eCreativeInventory_Redstone };
|
||||
specs[eCreativeInventoryTab_RedstoneAndTransport] = new TabSpec(L"RedstoneAndTransport", IDS_GROUPNAME_REDSTONE_AND_TRANSPORT, 2, redAndTranGroup);
|
||||
|
||||
ECreative_Inventory_Groups materialsGroup[] = {eCreativeInventory_Materials};
|
||||
specs[eCreativeInventoryTab_Materials] = new TabSpec(L"Materials", IDS_GROUPNAME_MATERIALS, 1, materialsGroup);
|
||||
ECreative_Inventory_Groups materialsGroup[] = { eCreativeInventory_Materials };
|
||||
specs[eCreativeInventoryTab_Materials] = new TabSpec(L"Materials", IDS_GROUPNAME_MATERIALS, 1, materialsGroup);
|
||||
|
||||
ECreative_Inventory_Groups foodGroup[] = {eCreativeInventory_Food};
|
||||
specs[eCreativeInventoryTab_Food] = new TabSpec(L"Food", IDS_GROUPNAME_FOOD, 1, foodGroup);
|
||||
ECreative_Inventory_Groups foodGroup[] = { eCreativeInventory_Food };
|
||||
specs[eCreativeInventoryTab_Food] = new TabSpec(L"Food", IDS_GROUPNAME_FOOD, 1, foodGroup);
|
||||
|
||||
ECreative_Inventory_Groups toolsGroup[] = {eCreativeInventory_ToolsArmourWeapons};
|
||||
specs[eCreativeInventoryTab_ToolsWeaponsArmor] = new TabSpec(L"Tools", IDS_GROUPNAME_TOOLS_WEAPONS_ARMOR, 1, toolsGroup);
|
||||
ECreative_Inventory_Groups toolsGroup[] = { eCreativeInventory_ToolsArmourWeapons };
|
||||
specs[eCreativeInventoryTab_ToolsWeaponsArmor] = new TabSpec(L"Tools", IDS_GROUPNAME_TOOLS_WEAPONS_ARMOR, 1, toolsGroup);
|
||||
|
||||
ECreative_Inventory_Groups brewingGroup[] = {eCreativeInventory_Brewing, eCreativeInventory_Potions_Level2_Extended, eCreativeInventory_Potions_Extended, eCreativeInventory_Potions_Level2, eCreativeInventory_Potions_Basic};
|
||||
ECreative_Inventory_Groups brewingGroup[] = { eCreativeInventory_Brewing, eCreativeInventory_Potions_Level2_Extended, eCreativeInventory_Potions_Extended, eCreativeInventory_Potions_Level2, eCreativeInventory_Potions_Basic };
|
||||
|
||||
// Just use the text LT - the graphic doesn't fit in splitscreen either
|
||||
// In 480p there's not enough room for the LT button, so use text instead
|
||||
//if(!RenderManager.IsHiDef() && !RenderManager.IsWidescreen())
|
||||
{
|
||||
specs[eCreativeInventoryTab_Brewing] = new TabSpec(L"Brewing", IDS_GROUPNAME_POTIONS_480, 5, brewingGroup);
|
||||
// Just use the text LT - the graphic doesn't fit in splitscreen either
|
||||
// In 480p there's not enough room for the LT button, so use text instead
|
||||
//if(!RenderManager.IsHiDef() && !RenderManager.IsWidescreen())
|
||||
{
|
||||
specs[eCreativeInventoryTab_Brewing] = new TabSpec(L"Brewing", IDS_GROUPNAME_POTIONS_480, 5, brewingGroup);
|
||||
}
|
||||
// else
|
||||
// {
|
||||
// specs[eCreativeInventoryTab_Brewing] = new TabSpec(L"icon_brewing.png", IDS_GROUPNAME_POTIONS, 1, brewingGroup, 4, potionsGroup);
|
||||
// }
|
||||
|
||||
#ifndef _CONTENT_PACKAGE
|
||||
ECreative_Inventory_Groups miscGroup[] = { eCreativeInventory_Misc };
|
||||
ECreative_Inventory_Groups debugMiscGroup[] = { eCreativeInventory_ArtToolsMisc };
|
||||
specs[eCreativeInventoryTab_Misc] = new TabSpec(L"Misc", IDS_GROUPNAME_MISCELLANEOUS, 1, miscGroup, 0, nullptr, 1, debugMiscGroup);
|
||||
#else
|
||||
ECreative_Inventory_Groups miscGroup[] = { eCreativeInventory_Misc };
|
||||
specs[eCreativeInventoryTab_Misc] = new TabSpec(L"Misc", IDS_GROUPNAME_MISCELLANEOUS, 1, miscGroup);
|
||||
#endif
|
||||
}
|
||||
// else
|
||||
// {
|
||||
// specs[eCreativeInventoryTab_Brewing] = new TabSpec(L"icon_brewing.png", IDS_GROUPNAME_POTIONS, 1, brewingGroup, 4, potionsGroup);
|
||||
// }
|
||||
|
||||
#ifndef _CONTENT_PACKAGE
|
||||
ECreative_Inventory_Groups miscGroup[] = {eCreativeInventory_Misc};
|
||||
ECreative_Inventory_Groups debugMiscGroup[] = {eCreativeInventory_ArtToolsMisc};
|
||||
specs[eCreativeInventoryTab_Misc] = new TabSpec(L"Misc", IDS_GROUPNAME_MISCELLANEOUS, 1, miscGroup, 0, nullptr, 1, debugMiscGroup);
|
||||
#else
|
||||
ECreative_Inventory_Groups miscGroup[] = {eCreativeInventory_Misc};
|
||||
specs[eCreativeInventoryTab_Misc] = new TabSpec(L"Misc", IDS_GROUPNAME_MISCELLANEOUS, 1, miscGroup);
|
||||
#endif
|
||||
}
|
||||
|
||||
IUIScene_CreativeMenu::IUIScene_CreativeMenu()
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
#include "IUIScene_AbstractContainerMenu.h"
|
||||
#include "../../../Minecraft.World/AbstractContainerMenu.h"
|
||||
#include "../../../Minecraft.World/CustomPayloadPacket.h"
|
||||
// 4J Stu - This class is for code that is common between XUI and Iggy
|
||||
|
||||
class SimpleContainer;
|
||||
|
|
@ -100,10 +101,16 @@ protected:
|
|||
bool m_bCarryingCreativeItem;
|
||||
int m_creativeSlotX, m_creativeSlotY, m_inventorySlotX, m_inventorySlotY;
|
||||
|
||||
static void _wipeCreativeItems();
|
||||
|
||||
public:
|
||||
static void staticCtor();
|
||||
IUIScene_CreativeMenu();
|
||||
|
||||
static void loadFromLocal();
|
||||
static void loadFromPacket(byteArray packetData);
|
||||
|
||||
static std::shared_ptr<CustomPayloadPacket> createUpdatePacket();
|
||||
protected:
|
||||
ECreativeInventoryTabs m_curTab;
|
||||
int m_tabDynamicPos[eCreativeInventoryTab_COUNT];
|
||||
|
|
|
|||
|
|
@ -2417,7 +2417,7 @@ void PlayerConnection::handleCustomPayload(shared_ptr<CustomPayloadPacket> custo
|
|||
player->inventory->setItem(player->inventory->selected, sentItem);
|
||||
}
|
||||
}
|
||||
else if (CustomPayloadPacket::QUICK_EQUIP_PACKET.compare(customPayloadPacket->identifier) == 0) {
|
||||
/*else if (CustomPayloadPacket::QUICK_EQUIP_PACKET.compare(customPayloadPacket->identifier) == 0) {
|
||||
//ByteArrayInputStream bais(customPayloadPacket->data);
|
||||
//DataInputStream input(&bais);
|
||||
//shared_ptr<ItemInstance> sentItem = Packet::readItem(&input);
|
||||
|
|
@ -2448,7 +2448,7 @@ void PlayerConnection::handleCustomPayload(shared_ptr<CustomPayloadPacket> custo
|
|||
//PlayerList* playerList = MinecraftServer::getInstance()->getPlayers();
|
||||
//playerList->broadcastAll(std::make_shared<SetEquippedItemPacket>(player->entityId, slot, sentItem));
|
||||
|
||||
}
|
||||
}*/
|
||||
else if (CustomPayloadPacket::TRADER_SELECTION_PACKET.compare(customPayloadPacket->identifier) == 0)
|
||||
{
|
||||
ByteArrayInputStream bais(customPayloadPacket->data);
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@
|
|||
#include "Common/Network/Sony/NetworkPlayerSony.h"
|
||||
#endif
|
||||
|
||||
#include "../Minecraft.World/Recipes.h"
|
||||
|
||||
#if defined(_WINDOWS64) && defined(MINECRAFT_SERVER_BUILD)
|
||||
#include "../Minecraft.Server/Access/Access.h"
|
||||
#include "../Minecraft.Server/Common/StringUtils.h"
|
||||
|
|
@ -51,6 +53,7 @@ extern bool g_Win64DedicatedServer;
|
|||
static unsigned int s_playerListTickCount = 0;
|
||||
static const int kIdentityResponseGraceTicks = 200; // 10 seconds at 20 TPS
|
||||
#endif
|
||||
#include "../Minecraft.Client/Common/UI/IUIScene_CreativeMenu.h"
|
||||
|
||||
// 4J - this class is fairly substantially altered as there didn't seem any point in porting code for banning, whitelisting, ops etc.
|
||||
|
||||
|
|
@ -300,6 +303,9 @@ bool PlayerList::placeNewPlayer(Connection *connection, shared_ptr<ServerPlayer>
|
|||
app.DebugPrintf("RECONNECT: placeNewPlayer smallId=%d entityId=%d dim=%d\n",
|
||||
newSmallId, player->entityId, level->dimension->id);
|
||||
|
||||
playerConnection->send(Recipes::getInstance()->createUpdatePacket());
|
||||
playerConnection->send(IUIScene_CreativeMenu::createUpdatePacket());
|
||||
|
||||
playerConnection->send(std::make_shared<LoginPacket>(L"", player->entityId, level->getLevelData()->getGenerator(),
|
||||
level->getSeed(),
|
||||
player->gameMode->getGameModeForPlayer()->getId(),
|
||||
|
|
|
|||
|
|
@ -5,30 +5,39 @@
|
|||
#include "CustomPayloadPacket.h"
|
||||
|
||||
// Mojang-defined custom packets
|
||||
const wstring CustomPayloadPacket::CUSTOM_BOOK_PACKET = L"MC|BEdit";
|
||||
const wstring CustomPayloadPacket::CUSTOM_BOOK_SIGN_PACKET = L"MC|BSign";
|
||||
const wstring CustomPayloadPacket::TEXTURE_PACK_PACKET = L"MC|TPack";
|
||||
const wstring CustomPayloadPacket::TRADER_LIST_PACKET = L"MC|TrList";
|
||||
const wstring CustomPayloadPacket::TRADER_SELECTION_PACKET = L"MC|TrSel";
|
||||
const wstring CustomPayloadPacket::SET_ADVENTURE_COMMAND_PACKET = L"MC|AdvCdm";
|
||||
const wstring CustomPayloadPacket::SET_BEACON_PACKET = L"MC|Beacon";
|
||||
const wstring CustomPayloadPacket::SET_ITEM_NAME_PACKET = L"MC|ItemName";
|
||||
const wstring CustomPayloadPacket::CUSTOM_BOOK_PACKET = CreateVanillaPayloadKey(L"BEdit");
|
||||
const wstring CustomPayloadPacket::CUSTOM_BOOK_SIGN_PACKET = CreateVanillaPayloadKey(L"BSign");
|
||||
const wstring CustomPayloadPacket::TEXTURE_PACK_PACKET = CreateVanillaPayloadKey(L"TPack");
|
||||
const wstring CustomPayloadPacket::TRADER_LIST_PACKET = CreateVanillaPayloadKey(L"TrList");
|
||||
const wstring CustomPayloadPacket::TRADER_SELECTION_PACKET = CreateVanillaPayloadKey(L"TrSel");
|
||||
|
||||
const wstring CustomPayloadPacket::CIPHER_KEY_CHANNEL = L"MC|CKey";
|
||||
const wstring CustomPayloadPacket::CIPHER_ACK_CHANNEL = L"MC|CAck";
|
||||
const wstring CustomPayloadPacket::CIPHER_ON_CHANNEL = L"MC|COn";
|
||||
// neoLegacy-defined custom packets
|
||||
const wstring CustomPayloadPacket::UPDATE_RECIPE_REGISTRY = CreatePayloadKey(L"neo", L"UpdRReg");
|
||||
const wstring CustomPayloadPacket::UPDATE_CREATIVE_REGISTRY = CreatePayloadKey(L"neo", L"UpdCReg");
|
||||
|
||||
const wstring CustomPayloadPacket::IDENTITY_TOKEN_ISSUE = L"MC|CTIssue";
|
||||
const wstring CustomPayloadPacket::IDENTITY_TOKEN_CHALLENGE = L"MC|CTChallenge";
|
||||
const wstring CustomPayloadPacket::IDENTITY_TOKEN_RESPONSE = L"MC|CTResponse";
|
||||
//todo: figure out if we should replace the packets in the comment section with a custom payload identifier
|
||||
//comment section start
|
||||
const wstring CustomPayloadPacket::SET_ADVENTURE_COMMAND_PACKET = CreateVanillaPayloadKey(L"AdvCdm");
|
||||
const wstring CustomPayloadPacket::SET_BEACON_PACKET = CreateVanillaPayloadKey(L"Beacon");
|
||||
const wstring CustomPayloadPacket::SET_ITEM_NAME_PACKET = CreateVanillaPayloadKey(L"ItemName");
|
||||
|
||||
const wstring CustomPayloadPacket::FORK_HELLO_CHANNEL = L"MC|ForkHello";
|
||||
const wstring CustomPayloadPacket::FORK_PLAYER_LEAVE_CHANNEL = L"MC|ForkPLeave";
|
||||
const wstring CustomPayloadPacket::CIPHER_KEY_CHANNEL = CreateVanillaPayloadKey(L"CKey");
|
||||
const wstring CustomPayloadPacket::CIPHER_ACK_CHANNEL = CreateVanillaPayloadKey(L"CAck");
|
||||
const wstring CustomPayloadPacket::CIPHER_ON_CHANNEL = CreateVanillaPayloadKey(L"COn");
|
||||
|
||||
const wstring CustomPayloadPacket::QUICK_EQUIP_PACKET = L"MC|QEquip";
|
||||
const wstring CustomPayloadPacket::QUICK_EQUIP_SERVER_PACKET = L"MC|QEquipServer";
|
||||
const wstring CustomPayloadPacket::IDENTITY_TOKEN_ISSUE = CreateVanillaPayloadKey(L"CTIssue");
|
||||
const wstring CustomPayloadPacket::IDENTITY_TOKEN_CHALLENGE = CreateVanillaPayloadKey(L"CTChallenge");
|
||||
const wstring CustomPayloadPacket::IDENTITY_TOKEN_RESPONSE = CreateVanillaPayloadKey(L"CTResponse");
|
||||
|
||||
const wstring CustomPayloadPacket::ENCHANTMENT_LIST_PACKET = L"MC|EnchList";
|
||||
const wstring CustomPayloadPacket::FORK_HELLO_CHANNEL = CreateVanillaPayloadKey(L"ForkHello");
|
||||
const wstring CustomPayloadPacket::FORK_PLAYER_LEAVE_CHANNEL = CreateVanillaPayloadKey(L"ForkPLeave");
|
||||
|
||||
const wstring CustomPayloadPacket::ENCHANTMENT_LIST_PACKET = CreateVanillaPayloadKey(L"EnchList");
|
||||
//comment section end
|
||||
|
||||
//removed cause its now handled on the server side
|
||||
// const wstring CustomPayloadPacket::QUICK_EQUIP_PACKET = CreateVanillaPayloadKey(L"QEquip");
|
||||
// const wstring CustomPayloadPacket::QUICK_EQUIP_SERVER_PACKET = CreateVanillaPayloadKey(L"QEquipServer");
|
||||
|
||||
CustomPayloadPacket::CustomPayloadPacket()
|
||||
: length(0)
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@ using namespace std;
|
|||
|
||||
#include "Packet.h"
|
||||
|
||||
#define CreatePayloadKey(identifier, action) identifier L"|" action
|
||||
#define CreateVanillaPayloadKey(action) CreatePayloadKey(L"MC", action)
|
||||
|
||||
class CustomPayloadPacket : public Packet, public enable_shared_from_this<CustomPayloadPacket>
|
||||
{
|
||||
public:
|
||||
|
|
@ -17,6 +20,10 @@ public:
|
|||
static const wstring SET_BEACON_PACKET;
|
||||
static const wstring SET_ITEM_NAME_PACKET;
|
||||
|
||||
// neoLegacy-defined custom packets
|
||||
static const wstring UPDATE_RECIPE_REGISTRY;
|
||||
static const wstring UPDATE_CREATIVE_REGISTRY;
|
||||
|
||||
// Security: stream cipher handshake channels
|
||||
static const wstring CIPHER_KEY_CHANNEL; // server->client: carries 32-byte key (16 AES key + 16 IV)
|
||||
static const wstring CIPHER_ACK_CHANNEL; // client->server: ack (empty payload)
|
||||
|
|
@ -32,8 +39,8 @@ public:
|
|||
static const wstring FORK_PLAYER_LEAVE_CHANNEL; // server->client: player disconnected (payload: UTF gamertag)
|
||||
|
||||
// Fixes for MP related crashes
|
||||
static const wstring QUICK_EQUIP_PACKET;
|
||||
static const wstring QUICK_EQUIP_SERVER_PACKET;
|
||||
//static const wstring QUICK_EQUIP_PACKET;
|
||||
//static const wstring QUICK_EQUIP_SERVER_PACKET;
|
||||
|
||||
static const wstring ENCHANTMENT_LIST_PACKET;
|
||||
|
||||
|
|
|
|||
|
|
@ -43,4 +43,8 @@ public:
|
|||
// 4J Added
|
||||
static void updatePossibleRecipes(shared_ptr<CraftingContainer> craftSlots, bool *firework, bool *charge, bool *fade);
|
||||
static bool isValidIngredient(shared_ptr<ItemInstance> item, bool firework, bool charge, bool fade);
|
||||
|
||||
virtual void writeToStream(DataOutputStream* dos) {
|
||||
dos->writeByte(99);
|
||||
}
|
||||
};
|
||||
|
|
@ -220,6 +220,11 @@ void ItemInstance::setAuxValue(int value)
|
|||
}
|
||||
}
|
||||
|
||||
void ItemInstance::setRawAuxValue(int value)
|
||||
{
|
||||
auxValue = value;
|
||||
}
|
||||
|
||||
int ItemInstance::getMaxDamage()
|
||||
{
|
||||
return Item::items[id]->getMaxDamage();
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@ public:
|
|||
int getDamageValue();
|
||||
int getAuxValue() const;
|
||||
void setAuxValue(int value);
|
||||
void setRawAuxValue(int value);
|
||||
int getMaxDamage();
|
||||
bool hurt(int dmg, Random *random);
|
||||
void hurtAndBreak(int dmg, shared_ptr<LivingEntity> owner);
|
||||
|
|
|
|||
|
|
@ -103,7 +103,5 @@ public:
|
|||
static shared_ptr<ItemInstance> readItem(DataInputStream *dis);
|
||||
static void writeItem(shared_ptr<ItemInstance> item, DataOutputStream *dos);
|
||||
static CompoundTag *readNbt(DataInputStream *dis);
|
||||
|
||||
protected:
|
||||
static void writeNbt(CompoundTag *tag, DataOutputStream *dos);
|
||||
};
|
||||
|
|
@ -29,20 +29,14 @@ void Recipes::_init()
|
|||
{
|
||||
// 4J Jev: instance = new Recipes();
|
||||
recipies = new RecipyList();
|
||||
}
|
||||
|
||||
Recipes::Recipes()
|
||||
{
|
||||
int iCount=0;
|
||||
_init();
|
||||
|
||||
pArmorRecipes = new ArmorRecipes;
|
||||
pClothDyeRecipes = new ClothDyeRecipes;
|
||||
pFoodRecipies = new FoodRecipies;
|
||||
pOreRecipies = new OreRecipies;
|
||||
pStructureRecipies = new StructureRecipies;
|
||||
pToolRecipies = new ToolRecipies;
|
||||
pWeaponRecipies = new WeaponRecipies;
|
||||
pArmorRecipes = new ArmorRecipes;
|
||||
pClothDyeRecipes = new ClothDyeRecipes;
|
||||
pFoodRecipies = new FoodRecipies;
|
||||
pOreRecipies = new OreRecipies;
|
||||
pStructureRecipies = new StructureRecipies;
|
||||
pToolRecipies = new ToolRecipies;
|
||||
pWeaponRecipies = new WeaponRecipies;
|
||||
|
||||
// 4J Stu - These just don't work with our crafting menu
|
||||
//recipies->push_back(new ArmorDyeRecipe());
|
||||
|
|
@ -50,8 +44,10 @@ Recipes::Recipes()
|
|||
//recipies->add(new MapExtendingRecipe());
|
||||
//recipies->add(new FireworksRecipe());
|
||||
pFireworksRecipes = new FireworksRecipe();
|
||||
}
|
||||
|
||||
|
||||
void Recipes::_compileRecipes()
|
||||
{
|
||||
addShapedRecipy(new ItemInstance(Tile::wood, 4, 0), //
|
||||
L"sczg",
|
||||
L"#", //
|
||||
|
|
@ -186,7 +182,7 @@ Recipes::Recipes()
|
|||
L"W#W", //
|
||||
L"W#W", //
|
||||
|
||||
L'#', Item::stick,
|
||||
L'#', Item::stick,
|
||||
L'W', new ItemInstance(Tile::wood, 1, TreeTile::ACACIA_TRUNK),
|
||||
L'S');
|
||||
|
||||
|
|
@ -195,7 +191,7 @@ Recipes::Recipes()
|
|||
L"W#W", //
|
||||
L"W#W", //
|
||||
|
||||
L'#', Item::stick,
|
||||
L'#', Item::stick,
|
||||
L'W', new ItemInstance(Tile::wood, 1, TreeTile::DARK_TRUNK),
|
||||
L'S');
|
||||
|
||||
|
|
@ -475,12 +471,10 @@ Recipes::Recipes()
|
|||
L'S');
|
||||
|
||||
pArmorRecipes->addRecipes(this);
|
||||
//iCount=getRecipies()->size();
|
||||
|
||||
|
||||
pClothDyeRecipes->addRecipes(this);
|
||||
|
||||
|
||||
|
||||
addShapedRecipy(new ItemInstance(Tile::snow, 1), //
|
||||
L"sscig",
|
||||
L"##", //
|
||||
|
|
@ -497,7 +491,7 @@ Recipes::Recipes()
|
|||
L'#', Item::prismarine_shard,
|
||||
L'S');
|
||||
|
||||
addShapedRecipy(new ItemInstance(Tile::prismarine, 1,PrismarineTile::TYPE_BRICKS), //
|
||||
addShapedRecipy(new ItemInstance(Tile::prismarine, 1, PrismarineTile::TYPE_BRICKS), //
|
||||
L"ssscig",
|
||||
L"###", //
|
||||
L"###", //
|
||||
|
|
@ -507,7 +501,7 @@ Recipes::Recipes()
|
|||
L'S');
|
||||
|
||||
|
||||
addShapedRecipy(new ItemInstance(Tile::prismarine, 1,PrismarineTile::TYPE_DARK), //
|
||||
addShapedRecipy(new ItemInstance(Tile::prismarine, 1, PrismarineTile::TYPE_DARK), //
|
||||
L"ssscicig",
|
||||
L"###", //
|
||||
L"#X#", //
|
||||
|
|
@ -657,10 +651,6 @@ Recipes::Recipes()
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
//iCount=getRecipies()->size();
|
||||
|
||||
addShapedRecipy(new ItemInstance(Item::cake, 1), //
|
||||
L"ssscicicicig",
|
||||
L"AAA", //
|
||||
|
|
@ -770,7 +760,7 @@ Recipes::Recipes()
|
|||
L'#', Tile::wood,
|
||||
L'V');
|
||||
|
||||
addShapedRecipy(new ItemInstance((Item *)Item::fishingRod, 1), //
|
||||
addShapedRecipy(new ItemInstance((Item*)Item::fishingRod, 1), //
|
||||
L"ssscicig",
|
||||
L" #", //
|
||||
L" #X", //
|
||||
|
|
@ -803,7 +793,7 @@ Recipes::Recipes()
|
|||
L'F');
|
||||
|
||||
// Moved bow and arrow in from weapons to avoid stacking on the group name display
|
||||
addShapedRecipy(new ItemInstance((Item *)Item::bow, 1), //
|
||||
addShapedRecipy(new ItemInstance((Item*)Item::bow, 1), //
|
||||
L"ssscicig",
|
||||
L" #X", //
|
||||
L"# X", //
|
||||
|
|
@ -850,7 +840,7 @@ Recipes::Recipes()
|
|||
L'#', Tile::glass,
|
||||
L'T');
|
||||
|
||||
|
||||
|
||||
|
||||
// torch made of charcoal - moved to be the default due to the tutorial using it
|
||||
addShapedRecipy(new ItemInstance(Tile::torch, 4), //
|
||||
|
|
@ -961,12 +951,12 @@ Recipes::Recipes()
|
|||
|
||||
addShapelessRecipy(new ItemInstance(Item::fireball, 3), //
|
||||
L"iiig",
|
||||
Item::gunpowder, Item::blazePowder,Item::coal,
|
||||
Item::gunpowder, Item::blazePowder, Item::coal,
|
||||
L'T');
|
||||
|
||||
addShapelessRecipy(new ItemInstance(Item::fireball, 3), //
|
||||
L"iizg",
|
||||
Item::gunpowder, Item::blazePowder,new ItemInstance(Item::coal, 1, CoalItem::CHAR_COAL),
|
||||
Item::gunpowder, Item::blazePowder, new ItemInstance(Item::coal, 1, CoalItem::CHAR_COAL),
|
||||
L'T');
|
||||
|
||||
addShapedRecipy(new ItemInstance(Item::lead, 2), //
|
||||
|
|
@ -1096,24 +1086,24 @@ Recipes::Recipes()
|
|||
|
||||
L'#', Tile::wood, L'X', Item::diamond,
|
||||
'D');
|
||||
|
||||
addShapedRecipy(new ItemInstance(Item::leather, 1),
|
||||
L"sscig",
|
||||
L"##",
|
||||
L"##",
|
||||
|
||||
L'#', Item::rabbit_hide,
|
||||
L'D');
|
||||
addShapedRecipy(new ItemInstance(Item::leather, 1),
|
||||
L"sscig",
|
||||
L"##",
|
||||
L"##",
|
||||
|
||||
L'#', Item::rabbit_hide,
|
||||
L'D');
|
||||
|
||||
addShapedRecipy(new ItemInstance(Item::armor_stand, 1),
|
||||
L"ssscictg",
|
||||
L"SSS",
|
||||
L" S ",
|
||||
L"SXS",
|
||||
L'S', Item::stick,
|
||||
L'X', Tile::stoneSlabHalf,
|
||||
L"ssscictg",
|
||||
L"SSS",
|
||||
L" S ",
|
||||
L"SXS",
|
||||
L'S', Item::stick,
|
||||
L'X', Tile::stoneSlabHalf,
|
||||
L'D');
|
||||
|
||||
|
||||
|
||||
|
||||
addShapedRecipy(new ItemInstance(Item::paper, 3), //
|
||||
|
|
@ -1206,21 +1196,21 @@ Recipes::Recipes()
|
|||
L'D');
|
||||
|
||||
// 4J - TODO - put these new 1.7.3 items in required place within recipes
|
||||
addShapedRecipy(new ItemInstance(static_cast<Tile *>(Tile::pistonBase), 1), //
|
||||
addShapedRecipy(new ItemInstance(static_cast<Tile*>(Tile::pistonBase), 1), //
|
||||
L"sssctcicictg",
|
||||
L"TTT", //
|
||||
L"#X#", //
|
||||
L"#R#", //
|
||||
L"TTT", //
|
||||
L"#X#", //
|
||||
L"#R#", //
|
||||
|
||||
L'#', Tile::cobblestone, L'X', Item::ironIngot, L'R', Item::redStone, L'T', Tile::wood,
|
||||
L'#', Tile::cobblestone, L'X', Item::ironIngot, L'R', Item::redStone, L'T', Tile::wood,
|
||||
L'M');
|
||||
|
||||
addShapedRecipy(new ItemInstance(static_cast<Tile *>(Tile::pistonStickyBase), 1), //
|
||||
addShapedRecipy(new ItemInstance(static_cast<Tile*>(Tile::pistonStickyBase), 1), //
|
||||
L"sscictg",
|
||||
L"S", //
|
||||
L"P", //
|
||||
L"S", //
|
||||
L"P", //
|
||||
|
||||
L'S', Item::slimeBall, L'P', Tile::pistonBase,
|
||||
L'S', Item::slimeBall, L'P', Tile::pistonBase,
|
||||
L'M');
|
||||
|
||||
|
||||
|
|
@ -1233,7 +1223,7 @@ Recipes::Recipes()
|
|||
L'P', Item::paper, L'G', Item::gunpowder,
|
||||
L'D');
|
||||
|
||||
addShapedRecipy(new ItemInstance(Item::fireworksCharge,1), //
|
||||
addShapedRecipy(new ItemInstance(Item::fireworksCharge, 1), //
|
||||
L"sscicig",
|
||||
L" D ", //
|
||||
L" G ", //
|
||||
|
|
@ -1241,7 +1231,7 @@ Recipes::Recipes()
|
|||
L'D', Item::dye_powder, L'G', Item::gunpowder,
|
||||
L'D');
|
||||
|
||||
addShapedRecipy(new ItemInstance(Item::fireworksCharge,1), //
|
||||
addShapedRecipy(new ItemInstance(Item::fireworksCharge, 1), //
|
||||
L"sscicig",
|
||||
L" D ", //
|
||||
L" C ", //
|
||||
|
|
@ -1249,37 +1239,38 @@ Recipes::Recipes()
|
|||
L'D', Item::dye_powder, L'C', Item::fireworksCharge,
|
||||
L'D');
|
||||
|
||||
|
||||
// Sort so the largest recipes get checked first!
|
||||
/* 4J-PB - TODO
|
||||
Collections.sort(recipies, new Comparator<Recipy>()
|
||||
{
|
||||
public: int compare(Recipy r0, Recipy r1)
|
||||
{
|
||||
|
||||
// shapeless recipes are put in the back of the list
|
||||
if (r0 instanceof ShapelessRecipy && r1 instanceof ShapedRecipy)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (r1 instanceof ShapelessRecipy && r0 instanceof ShapedRecipy)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (r1.size() < r0.size()) return -1;
|
||||
if (r1.size() > r0.size()) return 1;
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
*/
|
||||
|
||||
// 4J-PB removed System.out.println(recipies->size() + L" recipes");
|
||||
|
||||
// 4J-PB - build the array of ingredients required per recipe
|
||||
buildRecipeIngredientsArray();
|
||||
}
|
||||
|
||||
void Recipes::_wipeRecipes()
|
||||
{
|
||||
int iCount = recipies->size();
|
||||
|
||||
for (int i = 0; i < iCount; i++) {
|
||||
Recipy::INGREDIENTS_REQUIRED& req = m_pRecipeIngredientsRequired[i];
|
||||
|
||||
delete[] req.iIngIDA;
|
||||
delete[] req.iIngValA;
|
||||
delete[] req.iIngAuxValA;
|
||||
delete[] req.uiGridA;
|
||||
}
|
||||
|
||||
for (int i = 0; i < iCount; i++) {
|
||||
delete (*recipies)[i];
|
||||
}
|
||||
|
||||
recipies->clear();
|
||||
|
||||
delete[] m_pRecipeIngredientsRequired;
|
||||
m_pRecipeIngredientsRequired = nullptr;
|
||||
}
|
||||
|
||||
Recipes::Recipes()
|
||||
{
|
||||
_init();
|
||||
_compileRecipes();
|
||||
}
|
||||
|
||||
// 4J-PB - this function has been substantially changed due to the differences with a va_list of classes in C++ and Java
|
||||
ShapedRecipy *Recipes::addShapedRecipy(ItemInstance *result, ...)
|
||||
{
|
||||
|
|
@ -1563,7 +1554,7 @@ void Recipes::buildRecipeIngredientsArray(void)
|
|||
|
||||
int iRecipeC=static_cast<int>(recipies->size());
|
||||
|
||||
m_pRecipeIngredientsRequired= new Recipy::INGREDIENTS_REQUIRED [iRecipeC];
|
||||
m_pRecipeIngredientsRequired = new Recipy::INGREDIENTS_REQUIRED [iRecipeC];
|
||||
|
||||
int iCount=0;
|
||||
for (auto& recipe : *recipies)
|
||||
|
|
@ -1577,4 +1568,46 @@ void Recipes::buildRecipeIngredientsArray(void)
|
|||
Recipy::INGREDIENTS_REQUIRED *Recipes::getRecipeIngredientsArray(void)
|
||||
{
|
||||
return m_pRecipeIngredientsRequired;
|
||||
}
|
||||
}
|
||||
|
||||
void Recipes::loadFromLocal()
|
||||
{
|
||||
this->_wipeRecipes();
|
||||
this->_compileRecipes();
|
||||
}
|
||||
|
||||
void Recipes::loadFromPacket(byteArray packetData)
|
||||
{
|
||||
ByteArrayInputStream bais(packetData);
|
||||
DataInputStream input(&bais);
|
||||
|
||||
this->_wipeRecipes();
|
||||
{
|
||||
int iCount = input.readInt();
|
||||
for (int i = 0; i < iCount; i++) {
|
||||
int recipeType = input.readByte();
|
||||
|
||||
if (recipeType == 1) {
|
||||
recipies->push_back(ShapelessRecipy::readFromStream(&input));
|
||||
} else if (recipeType == 2) {
|
||||
recipies->push_back(ShapedRecipy::readFromStream(&input));
|
||||
}
|
||||
}
|
||||
}
|
||||
this->buildRecipeIngredientsArray();
|
||||
}
|
||||
|
||||
std::shared_ptr<CustomPayloadPacket> Recipes::createUpdatePacket()
|
||||
{
|
||||
ByteArrayOutputStream baos;
|
||||
DataOutputStream dos(&baos);
|
||||
|
||||
int iCount = recipies->size();
|
||||
dos.writeInt(iCount);
|
||||
|
||||
for (int i = 0; i < iCount; i++) {
|
||||
(*recipies)[i]->writeToStream(&dos);
|
||||
}
|
||||
|
||||
return std::make_shared<CustomPayloadPacket>(CustomPayloadPacket::UPDATE_RECIPE_REGISTRY, baos.toByteArray());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import net.minecraft.world.level.tile.Tile;
|
|||
*/
|
||||
|
||||
#include "Recipy.h"
|
||||
#include "../Minecraft.World/CustomPayloadPacket.h"
|
||||
|
||||
#pragma once
|
||||
using namespace std;
|
||||
|
|
@ -84,6 +85,8 @@ public:
|
|||
|
||||
private:
|
||||
void _init(); // 4J add
|
||||
void _compileRecipes();
|
||||
void _wipeRecipes();
|
||||
Recipes();
|
||||
|
||||
public:
|
||||
|
|
@ -97,6 +100,11 @@ public:
|
|||
shared_ptr<ItemInstance> getItemForRecipe(Recipy *r);
|
||||
Recipy::INGREDIENTS_REQUIRED *getRecipeIngredientsArray();
|
||||
|
||||
void loadFromLocal();
|
||||
void loadFromPacket(byteArray packetData);
|
||||
|
||||
std::shared_ptr<CustomPayloadPacket> createUpdatePacket();
|
||||
|
||||
private:
|
||||
void buildRecipeIngredientsArray();
|
||||
Recipy::INGREDIENTS_REQUIRED *m_pRecipeIngredientsRequired;
|
||||
|
|
|
|||
|
|
@ -10,13 +10,13 @@
|
|||
#define RECIPE_TYPE_2x2 0
|
||||
#define RECIPE_TYPE_3x3 1
|
||||
|
||||
class Recipy
|
||||
class Recipy
|
||||
{
|
||||
public:
|
||||
enum _eGroupType
|
||||
{
|
||||
eGroupType_First=0,
|
||||
eGroupType_Structure=0,
|
||||
eGroupType_First = 0,
|
||||
eGroupType_Structure = 0,
|
||||
eGroupType_Tool,
|
||||
eGroupType_Food,
|
||||
eGroupType_Armour,
|
||||
|
|
@ -28,28 +28,30 @@ public:
|
|||
eGroupType; // to class the item produced by the recipe
|
||||
|
||||
// 4J-PB - we'll classing an ingredient ID with a different aux value as a different IngID AuxVal pair
|
||||
typedef struct
|
||||
typedef struct
|
||||
{
|
||||
int iIngC;
|
||||
int iType; // Can be a 2x2 or a 3x3. Inventory crafting can only make a 2x2.
|
||||
int *iIngIDA;
|
||||
int *iIngValA;
|
||||
int *iIngAuxValA;
|
||||
Recipy *pRecipy;
|
||||
int* iIngIDA;
|
||||
int* iIngValA;
|
||||
int* iIngAuxValA;
|
||||
Recipy* pRecipy;
|
||||
bool bCanMake[XUSER_MAX_COUNT];
|
||||
unsigned int *uiGridA; // hold the layout of the recipe (id | auxval<<24)
|
||||
unsigned int* uiGridA; // hold the layout of the recipe (id | auxval<<24)
|
||||
unsigned short usBitmaskMissingGridIngredients[XUSER_MAX_COUNT]; // each bit set means we don't have that grid ingredient
|
||||
}
|
||||
INGREDIENTS_REQUIRED;
|
||||
~Recipy() {}
|
||||
virtual bool matches(shared_ptr<CraftingContainer> craftSlots, Level *level) = 0;
|
||||
virtual ~Recipy() = default;
|
||||
virtual bool matches(shared_ptr<CraftingContainer> craftSlots, Level* level) = 0;
|
||||
virtual shared_ptr<ItemInstance> assemble(shared_ptr<CraftingContainer> craftSlots) = 0;
|
||||
virtual int size() = 0;
|
||||
virtual const ItemInstance *getResultItem() = 0;
|
||||
virtual const int getGroup() = 0;
|
||||
virtual const ItemInstance* getResultItem() = 0;
|
||||
virtual const int getGroup() = 0;
|
||||
|
||||
// 4J-PB
|
||||
virtual bool reqs(int iRecipe) = 0;
|
||||
virtual void reqs(INGREDIENTS_REQUIRED *pIngReq) = 0;
|
||||
virtual void reqs(INGREDIENTS_REQUIRED* pIngReq) = 0;
|
||||
|
||||
virtual void writeToStream(DataOutputStream* dos) = 0;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,24 @@ ShapedRecipy::ShapedRecipy(int width, int height, ItemInstance **recipeItems, It
|
|||
_keepTag = false;
|
||||
}
|
||||
|
||||
ShapedRecipy::~ShapedRecipy() {
|
||||
// todo: why does this cause a error when clearing out these specifically?
|
||||
// might be leaking memory here but im not sure cause it crashes when you clear them, so we dont clear them
|
||||
/*for (int x = 0; x < 3; x++) {
|
||||
for (int y = 0; y < 3; y++) {
|
||||
if (x < width && y < height) {
|
||||
delete recipeItems[x + y * width];
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
delete[] recipeItems;
|
||||
delete result;
|
||||
|
||||
recipeItems = nullptr;
|
||||
result = nullptr;
|
||||
}
|
||||
|
||||
const int ShapedRecipy::getGroup()
|
||||
{
|
||||
return group;
|
||||
|
|
@ -227,4 +245,65 @@ ShapedRecipy *ShapedRecipy::keepTag()
|
|||
{
|
||||
_keepTag = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
void ShapedRecipy::writeToStream(DataOutputStream* dos) {
|
||||
dos->writeByte(2);
|
||||
dos->writeByte(this->group);
|
||||
|
||||
//write result item, it should always be valid
|
||||
{
|
||||
dos->writeShort(this->result->id);
|
||||
dos->writeByte(this->result->count);
|
||||
dos->writeShort(this->result->getAuxValue());
|
||||
|
||||
Packet::writeNbt(this->result->tag, dos);
|
||||
}
|
||||
|
||||
dos->writeByte((this->width << 2) | this->height);
|
||||
|
||||
for (int i = 0; i < (this->width * this->height); i++) {
|
||||
ItemInstance* ingredients_item = this->recipeItems[i];
|
||||
dos->writeBoolean(ingredients_item == nullptr);
|
||||
if (ingredients_item == nullptr) continue;
|
||||
|
||||
dos->writeShort(ingredients_item->id);
|
||||
dos->writeShort(ingredients_item->getAuxValue());
|
||||
Packet::writeNbt(ingredients_item->tag, dos);
|
||||
}
|
||||
}
|
||||
|
||||
ShapedRecipy* ShapedRecipy::readFromStream(DataInputStream* dis) {
|
||||
int groupType = dis->readByte();
|
||||
|
||||
int resultItemID = dis->readShort();
|
||||
int resultItemCount = dis->readByte();
|
||||
int resultItemAux = dis->readShort();
|
||||
|
||||
ItemInstance* resultItem = new ItemInstance(resultItemID, resultItemCount, 0);
|
||||
resultItem->setRawAuxValue(resultItemAux);
|
||||
resultItem->tag = Packet::readNbt(dis);
|
||||
|
||||
unsigned char packedSize = dis->readByte();
|
||||
|
||||
int width = (packedSize >> 2) & 0x3;
|
||||
int height = packedSize & 0x3;
|
||||
ItemInstance** ids = new ItemInstance*[width * height];
|
||||
|
||||
for (int i = 0; i < width * height; i++) {
|
||||
ItemInstance* ingredients_item = nullptr;
|
||||
bool isNull = dis->readBoolean();
|
||||
if (!isNull) {
|
||||
int itemId = dis->readShort();
|
||||
int itemAux = dis->readShort();
|
||||
|
||||
ingredients_item = new ItemInstance(itemId, 1, 0);
|
||||
ingredients_item->setRawAuxValue(itemAux);
|
||||
ingredients_item->tag = Packet::readNbt(dis);
|
||||
}
|
||||
|
||||
ids[i] = ingredients_item;
|
||||
}
|
||||
|
||||
return new ShapedRecipy(width, height, ids, resultItem, groupType);
|
||||
}
|
||||
|
|
@ -1,21 +1,22 @@
|
|||
#pragma once
|
||||
|
||||
class ShapedRecipy : public Recipy
|
||||
class ShapedRecipy : public Recipy
|
||||
{
|
||||
private:
|
||||
int width, height, group;
|
||||
ItemInstance **recipeItems;
|
||||
ItemInstance *result;
|
||||
ItemInstance** recipeItems;
|
||||
ItemInstance* result;
|
||||
bool _keepTag;
|
||||
public:
|
||||
const int resultId;
|
||||
|
||||
public:
|
||||
ShapedRecipy(int width, int height, ItemInstance **recipeItems, ItemInstance *result, int iGroup=Recipy::eGroupType_Decoration);
|
||||
ShapedRecipy(int width, int height, ItemInstance** recipeItems, ItemInstance* result, int iGroup = Recipy::eGroupType_Decoration);
|
||||
virtual ~ShapedRecipy() override;
|
||||
|
||||
virtual const ItemInstance *getResultItem();
|
||||
virtual const ItemInstance* getResultItem();
|
||||
virtual const int getGroup();
|
||||
virtual bool matches(shared_ptr<CraftingContainer> craftSlots, Level *level);
|
||||
virtual bool matches(shared_ptr<CraftingContainer> craftSlots, Level* level);
|
||||
|
||||
private:
|
||||
bool matches(shared_ptr<CraftingContainer> craftSlots, int xOffs, int yOffs, bool xFlip);
|
||||
|
|
@ -23,10 +24,14 @@ private:
|
|||
public:
|
||||
virtual shared_ptr<ItemInstance> assemble(shared_ptr<CraftingContainer> craftSlots);
|
||||
virtual int size();
|
||||
ShapedRecipy *keepTag();
|
||||
ShapedRecipy* keepTag();
|
||||
|
||||
// 4J-PB - to return the items required to make a recipe
|
||||
virtual bool reqs(int iRecipe);
|
||||
virtual void reqs(INGREDIENTS_REQUIRED *pIngReq);
|
||||
virtual void reqs(INGREDIENTS_REQUIRED* pIngReq);
|
||||
|
||||
virtual void writeToStream(DataOutputStream* dos);
|
||||
static ShapedRecipy* readFromStream(DataInputStream* dis);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,19 @@ ShapelessRecipy::ShapelessRecipy(ItemInstance *result, vector<ItemInstance *> *i
|
|||
{
|
||||
}
|
||||
|
||||
ShapelessRecipy::~ShapelessRecipy() {
|
||||
for (int i = 0; i < ingredients->size(); i++) {
|
||||
delete (*ingredients)[i];
|
||||
}
|
||||
|
||||
delete ingredients;
|
||||
delete result;
|
||||
|
||||
ingredients = nullptr;
|
||||
result = nullptr;
|
||||
}
|
||||
|
||||
|
||||
const int ShapelessRecipy::getGroup()
|
||||
{
|
||||
return group;
|
||||
|
|
@ -173,4 +186,61 @@ void ShapelessRecipy::reqs(INGREDIENTS_REQUIRED *pIngReq)
|
|||
delete [] TempIngReq.iIngValA;
|
||||
delete [] TempIngReq.iIngAuxValA;
|
||||
delete [] TempIngReq.uiGridA;
|
||||
}
|
||||
}
|
||||
|
||||
void ShapelessRecipy::writeToStream(DataOutputStream* dos) {
|
||||
dos->writeByte(1);
|
||||
dos->writeByte(this->group);
|
||||
|
||||
//write result item, it should always be valid
|
||||
{
|
||||
dos->writeShort(this->result->id);
|
||||
dos->writeByte(this->result->count);
|
||||
dos->writeShort(this->result->getAuxValue());
|
||||
|
||||
Packet::writeNbt(this->result->tag, dos);
|
||||
}
|
||||
|
||||
byte iCount = ingredients->size();
|
||||
dos->writeByte(iCount);
|
||||
|
||||
for (int i = 0; i < iCount; i++) {
|
||||
ItemInstance* item = (*ingredients)[i];
|
||||
dos->writeBoolean(item == nullptr);
|
||||
if (item == nullptr) continue;
|
||||
|
||||
dos->writeShort(item->id);
|
||||
dos->writeShort(item->getAuxValue());
|
||||
Packet::writeNbt(item->tag, dos);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ShapelessRecipy* ShapelessRecipy::readFromStream(DataInputStream* dis) {
|
||||
unsigned char groupType = dis->readByte();
|
||||
|
||||
int resultItemID = dis->readShort();
|
||||
int resultItemCount = dis->readByte();
|
||||
int resultItemAux = dis->readShort();
|
||||
|
||||
ItemInstance* resultItem = new ItemInstance(resultItemID, resultItemCount, 0);
|
||||
resultItem->setRawAuxValue(resultItemAux);
|
||||
resultItem->tag = Packet::readNbt(dis);
|
||||
|
||||
vector<ItemInstance*>* ingredients = new vector<ItemInstance*>();
|
||||
int iCount = dis->readByte();
|
||||
for (int i = 0; i < iCount; i++) {
|
||||
if (dis->readBoolean() == true) continue; //item is null or something weird
|
||||
|
||||
int itemID = dis->readShort();
|
||||
int itemAux = dis->readShort();
|
||||
|
||||
ItemInstance* ingredients_item = new ItemInstance(itemID, 1, 0);
|
||||
ingredients_item->setRawAuxValue(itemAux);
|
||||
ingredients_item->tag = Packet::readNbt(dis);
|
||||
|
||||
ingredients->push_back(ingredients_item);
|
||||
}
|
||||
|
||||
return new ShapelessRecipy(resultItem, ingredients, (Recipy::_eGroupType)groupType);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ private:
|
|||
|
||||
public:
|
||||
ShapelessRecipy(ItemInstance *result, vector<ItemInstance *> *ingredients, _eGroupType egroup=Recipy::eGroupType_Decoration);
|
||||
virtual ~ShapelessRecipy() override;
|
||||
|
||||
virtual const ItemInstance *getResultItem();
|
||||
virtual const int getGroup();
|
||||
|
|
@ -20,4 +21,6 @@ public:
|
|||
virtual bool reqs(int iRecipe);
|
||||
virtual void reqs(INGREDIENTS_REQUIRED *pIngReq);
|
||||
|
||||
virtual void writeToStream(DataOutputStream* dos);
|
||||
static ShapelessRecipy* readFromStream(DataInputStream* dos);
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue