Skip to content

Commit 03f78e9

Browse files
committed
add custom containers
1 parent 093444a commit 03f78e9

18 files changed

Lines changed: 322 additions & 15 deletions

Minecraft.Server.FourKit/FourKit.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ public ref class FourKit
2424
static World^ getWorld(String^ name);
2525
static PluginCommand^ getCommand(String^ name);
2626
static void broadcastMessage(String^ message);
27+
static Inventory^ createInventory(int size);
28+
static Inventory^ createInventory(int size, String^ title);
29+
static Inventory^ createInventory(InventoryType type);
30+
static Inventory^ createInventory(InventoryType type, String^ title);
2731
private:
2832
static List<ServerPlugin^>^ pluginList;
2933
static Dictionary<String^, PluginCommand^>^ commandMap;

Minecraft.Server.FourKit/FourKitEvents.cpp

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -828,29 +828,50 @@ static Inventory^ CreateContainerInventory(String^ playerName, int containerType
828828
}
829829
}
830830

831+
String^ title = nullptr;
832+
if (openData->hasTitle && openData->title[0] != '\0')
833+
{
834+
title = gcnew String(openData->title);
835+
}
836+
831837
InventoryType type = MapContainerType(containerType);
838+
ContainerInventory^ result = nullptr;
832839

833840
switch (type)
834841
{
835842
case InventoryType::PLAYER:
836843
return gcnew PlayerInventory(playerName);
837844
case InventoryType::DOUBLE_CHEST:
838-
return gcnew DoubleChestInventory(playerName, slotCount, items);
845+
result = gcnew DoubleChestInventory(playerName, slotCount, items);
846+
break;
839847
case InventoryType::WORKBENCH:
840-
return gcnew CraftingInventory(playerName, slotCount, items);
848+
result = gcnew CraftingInventory(playerName, slotCount, items);
849+
break;
841850
case InventoryType::BREWING:
842-
return gcnew BrewerInventory(playerName, slotCount, items);
851+
result = gcnew BrewerInventory(playerName, slotCount, items);
852+
break;
843853
case InventoryType::BEACON:
844-
return gcnew BeaconInventory(playerName, slotCount, items);
854+
result = gcnew BeaconInventory(playerName, slotCount, items);
855+
break;
845856
case InventoryType::ENCHANTING:
846-
return gcnew EnchantingInventory(playerName, slotCount, items);
857+
result = gcnew EnchantingInventory(playerName, slotCount, items);
858+
break;
847859
case InventoryType::FURNACE:
848-
return gcnew FurnaceInventory(playerName, slotCount, items);
860+
result = gcnew FurnaceInventory(playerName, slotCount, items);
861+
break;
849862
case InventoryType::HORSE:
850-
return gcnew HorseInventory(playerName, slotCount, items);
863+
result = gcnew HorseInventory(playerName, slotCount, items);
864+
break;
851865
default:
852-
return gcnew ContainerInventory(playerName, type, slotCount, items);
866+
result = gcnew ContainerInventory(playerName, type, slotCount, items);
867+
break;
868+
}
869+
870+
if (title != nullptr)
871+
{
872+
result->setTitle(title);
853873
}
874+
return result;
854875
}
855876

856877
void FourKit::FireEventOnInventoryOpen(InventoryOpenData* openData, bool* cancelled)

Minecraft.Server.FourKit/FourKitExports.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,8 @@ namespace FourKitInternal
189189
X(SetThunderDuration, (int dimension, int duration), (dimension, duration)) \
190190
X(SetThundering, (int dimension, int thundering), (dimension, thundering)) \
191191
X(SetTime, (int dimension, long long time), (dimension, time)) \
192-
X(SetWeatherDuration, (int dimension, int duration), (dimension, duration))
192+
X(SetWeatherDuration, (int dimension, int duration), (dimension, duration)) \
193+
X(OpenCustomInventory, (const char *playerName, OpenCustomInventoryData *data), (playerName, data))
193194

194195
#define PB_NATIVE_VALUE_EXPORT_LIST(X) \
195196
X(BanPlayer, bool, (const char *playerName, const char *reason), false, (playerName, reason)) \

Minecraft.Server.FourKit/FourKitInterop.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@
4141
X(GetInventorySize, int, (const char* playerName)) \
4242
X(GetInventoryHeldSlot, int, (const char* playerName)) \
4343
X(FirstEmptyInventorySlot, int, (const char* playerName)) \
44-
X(AddInventoryItem, int, (const char* playerName, int itemId, int count, int data))
44+
X(AddInventoryItem, int, (const char* playerName, int itemId, int count, int data)) \
45+
X(OpenCustomInventory, void, (const char* playerName, OpenCustomInventoryData* data))
4546

4647
#define PB_BLOCK_CALLBACK_LIST(X) \
4748
X(BlockBreakNaturally, void, (int x, int y, int z, int dimension)) \
@@ -136,7 +137,8 @@
136137
FourKitSetThunderingCallback SetThundering, \
137138
FourKitSetTimeCallback SetTime, \
138139
FourKitSetWeatherDurationCallback SetWeatherDuration, \
139-
FourKitStrikeLightningCallback StrikeLightning
140+
FourKitStrikeLightningCallback StrikeLightning, \
141+
FourKitOpenCustomInventoryCallback OpenCustomInventory
140142

141143
#define PB_SET_NATIVE_CALLBACK_ARGS \
142144
SetFallDistance, \
@@ -197,7 +199,8 @@
197199
SetThundering, \
198200
SetTime, \
199201
SetWeatherDuration, \
200-
StrikeLightning
202+
StrikeLightning, \
203+
OpenCustomInventory
201204

202205
extern "C"
203206
{

Minecraft.Server.FourKit/FourKitRuntime.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,55 @@ void FourKit::broadcastMessage(String^ message)
203203
}
204204
}
205205

206+
static InventoryType SizeToInventoryType(int size)
207+
{
208+
switch (size)
209+
{
210+
case 5: return InventoryType::HOPPER;
211+
case 9: return InventoryType::DISPENSER;
212+
default: return InventoryType::CHEST;
213+
}
214+
}
215+
216+
static int InventoryTypeToDefaultSize(InventoryType type)
217+
{
218+
switch (type)
219+
{
220+
case InventoryType::CHEST: return 27;
221+
case InventoryType::DOUBLE_CHEST: return 54;
222+
case InventoryType::DISPENSER: return 9;
223+
case InventoryType::DROPPER: return 9;
224+
case InventoryType::FURNACE: return 3;
225+
case InventoryType::HOPPER: return 5;
226+
case InventoryType::BREWING: return 4;
227+
case InventoryType::BEACON: return 1;
228+
case InventoryType::ENCHANTING: return 1;
229+
case InventoryType::ANVIL: return 3;
230+
case InventoryType::WORKBENCH: return 10;
231+
default: return 27;
232+
}
233+
}
234+
235+
Inventory^ FourKit::createInventory(int size)
236+
{
237+
return gcnew ContainerInventory(nullptr, SizeToInventoryType(size), size, (String^)nullptr);
238+
}
239+
240+
Inventory^ FourKit::createInventory(int size, String^ title)
241+
{
242+
return gcnew ContainerInventory(nullptr, SizeToInventoryType(size), size, title);
243+
}
244+
245+
Inventory^ FourKit::createInventory(InventoryType type)
246+
{
247+
return gcnew ContainerInventory(nullptr, type, InventoryTypeToDefaultSize(type), (String^)nullptr);
248+
}
249+
250+
Inventory^ FourKit::createInventory(InventoryType type, String^ title)
251+
{
252+
return gcnew ContainerInventory(nullptr, type, InventoryTypeToDefaultSize(type), title);
253+
}
254+
206255
bool FourKit::DispatchPlayerCommand(String^ playerName, String^ commandLine)
207256
{
208257
String^ label = String::Empty;

Minecraft.Server.FourKit/FourKitStructs.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,13 +437,38 @@ struct InventoryOpenData
437437
const char* playerName;
438438
int containerType;
439439
int slotCount;
440+
char title[256];
441+
bool hasTitle;
440442
InventoryItemData slots[MAX_CONTAINER_SLOTS];
441443

442444
InventoryOpenData()
443445
: playerName(nullptr)
444446
, containerType(0)
445447
, slotCount(0)
448+
, hasTitle(false)
446449
{
450+
title[0] = '\0';
451+
for (int i = 0; i < MAX_CONTAINER_SLOTS; ++i)
452+
{
453+
slots[i] = InventoryItemData();
454+
}
455+
}
456+
};
457+
458+
struct OpenCustomInventoryData
459+
{
460+
const char* playerName;
461+
int slotCount;
462+
char title[256];
463+
bool hasTitle;
464+
InventoryItemData slots[MAX_CONTAINER_SLOTS];
465+
466+
OpenCustomInventoryData()
467+
: playerName(nullptr)
468+
, slotCount(0)
469+
, hasTitle(false)
470+
{
471+
title[0] = '\0';
447472
for (int i = 0; i < MAX_CONTAINER_SLOTS; ++i)
448473
{
449474
slots[i] = InventoryItemData();

Minecraft.Server.FourKit/Inventory.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ Player^ PlayerInventory::getHolder()
363363
// xcontainer
364364

365365
ContainerInventory::ContainerInventory(String^ playerName, InventoryType type, int slotCount, array<ItemStack^>^ items)
366-
: Inventory(playerName), m_type(type), m_slotCount(slotCount)
366+
: Inventory(playerName), m_type(type), m_slotCount(slotCount), m_title(nullptr)
367367
{
368368
m_items = gcnew array<ItemStack^>(slotCount);
369369
if (items != nullptr)
@@ -376,6 +376,12 @@ ContainerInventory::ContainerInventory(String^ playerName, InventoryType type, i
376376
}
377377
}
378378

379+
ContainerInventory::ContainerInventory(String^ playerName, InventoryType type, int slotCount, String^ title)
380+
: Inventory(playerName), m_type(type), m_slotCount(slotCount), m_title(title)
381+
{
382+
m_items = gcnew array<ItemStack^>(slotCount);
383+
}
384+
379385
int ContainerInventory::getSize()
380386
{
381387
return m_slotCount;

Minecraft.Server.FourKit/Inventory.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public ref class Inventory
4141
virtual void setContents(array<ItemStack^>^ items);
4242
virtual int firstEmpty();
4343
virtual int first(ItemStack^ item);
44+
virtual String^ getTitle() { return nullptr; }
4445
bool contains(ItemStack^ item);
4546
bool contains(ItemStack^ item, int amount);
4647
bool containsAtLeast(ItemStack^ item, int amount);
@@ -79,6 +80,7 @@ public ref class ContainerInventory : public Inventory
7980
{
8081
public:
8182
ContainerInventory(String^ playerName, InventoryType type, int slotCount, array<ItemStack^>^ items);
83+
ContainerInventory(String^ playerName, InventoryType type, int slotCount, String^ title);
8284

8385
InventoryType getType() override { return m_type; }
8486
int getSize() override;
@@ -88,11 +90,14 @@ public ref class ContainerInventory : public Inventory
8890
void setContents(array<ItemStack^>^ items) override;
8991
int firstEmpty() override;
9092
int first(ItemStack^ item) override;
93+
String^ getTitle() override { return m_title; }
94+
void setTitle(String^ title) { m_title = title; }
9195

9296
protected:
9397
InventoryType m_type;
9498
int m_slotCount;
9599
array<ItemStack^>^ m_items;
100+
String^ m_title;
96101
};
97102

98103
public ref class DoubleChestInventory : public ContainerInventory

Minecraft.Server.FourKit/NativePlayerCallbacks.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "NativePlayerCallbacks.h"
2+
#include <cstring>
23

34
using namespace System;
45
using namespace System::Runtime::InteropServices;
@@ -543,3 +544,52 @@ bool NativePlayerCallbacks::GetInventoryContents(String^ playerName, InventoryCo
543544
Marshal::FreeHGlobal(IntPtr((void*)namePtr));
544545
}
545546
}
547+
548+
void NativePlayerCallbacks::OpenCustomInventory(String^ playerName, ContainerInventory^ inventory)
549+
{
550+
if (inventory == nullptr) return;
551+
552+
const char* namePtr = (const char*)(Marshal::StringToHGlobalAnsi(playerName)).ToPointer();
553+
try
554+
{
555+
OpenCustomInventoryData data;
556+
data.playerName = namePtr;
557+
data.slotCount = inventory->getSize();
558+
559+
if (data.slotCount > MAX_CONTAINER_SLOTS)
560+
data.slotCount = MAX_CONTAINER_SLOTS;
561+
562+
String^ title = inventory->getTitle();
563+
if (title != nullptr && title->Length > 0)
564+
{
565+
data.hasTitle = true;
566+
const char* titlePtr = (const char*)(Marshal::StringToHGlobalAnsi(title)).ToPointer();
567+
try
568+
{
569+
strncpy_s(data.title, sizeof(data.title), titlePtr, _TRUNCATE);
570+
}
571+
finally
572+
{
573+
Marshal::FreeHGlobal(IntPtr((void*)titlePtr));
574+
}
575+
}
576+
577+
for (int i = 0; i < data.slotCount; i++)
578+
{
579+
ItemStack^ item = inventory->getItem(i);
580+
if (item != nullptr && item->getTypeId() != 0)
581+
{
582+
data.slots[i].hasItem = true;
583+
data.slots[i].itemId = item->getTypeId();
584+
data.slots[i].count = item->getAmount();
585+
data.slots[i].data = item->getData();
586+
}
587+
}
588+
589+
NativeCallback_OpenCustomInventory(namePtr, &data);
590+
}
591+
finally
592+
{
593+
Marshal::FreeHGlobal(IntPtr((void*)namePtr));
594+
}
595+
}

Minecraft.Server.FourKit/NativePlayerCallbacks.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#pragma once
22
// todo: this sucks
33
#include "FourKitInterop.h"
4+
#include "Inventory.h"
45

56
using namespace System;
67
using namespace System::Runtime::InteropServices;
@@ -50,6 +51,7 @@ private ref class NativePlayerCallbacks
5051
static int AddInventoryItem(String^ playerName, int itemId, int count, int data);
5152
static bool GetInventorySlot(String^ playerName, int slot, InventoryItemData* outData);
5253
static bool GetInventoryContents(String^ playerName, InventoryContentsData* outData);
54+
static void OpenCustomInventory(String^ playerName, ContainerInventory^ inventory);
5355

5456
private:
5557
#define PB_DECLARE_PLAYER_DLLIMPORT(Name, Ret, Sig) \
@@ -69,4 +71,5 @@ private ref class NativePlayerCallbacks
6971

7072
[DllImport("Minecraft.Server.FourKit.dll", EntryPoint = "NativeCallback_GetInventoryContents", CallingConvention = CallingConvention::Cdecl)]
7173
static bool NativeCallback_GetInventoryContents(const char* playerName, InventoryContentsData* outData);
72-
};
74+
75+
};

0 commit comments

Comments
 (0)