Internal Documentation
MCCraft System Logic
A deep dive into the custom crafting engine, explaining the async database architecture, memory caching, and event-driven GUI interactions.
System Overview
MCCraft creates specific "Station Types" (e.g., a Magic Bench). Each station has a unique "Head Item". When a player interacts with this item, a custom GUI opens. The system matches the player's 3x3 grid against a loaded cache of recipes to produce a result.
1. Data Persistence & Caching
To ensure server performance, the plugin avoids querying the database during gameplay events.
-
Startup Logic: When the plugin enables,
MCCraftProviderinitializes the database (MySQL or SQLite) and immediately runspopulateCache(). This pulls every registered recipe and station type into the RAM (Heap). -
The Recipe Cache: The
RecipeCachesingleton stores data in aConcurrentHashMap.
Key: Station Type string.
Value: A list ofCachedRecipeobjects (which contain the pre-parsed ItemStacks). - Saving (Upsert): When an admin saves a recipe, it is written Asynchronously to the DB to prevent lag, but the Cache is updated Synchronously immediately. This ensures the recipe works instantly without waiting for the DB write to finish.
-
Serialization: Items are not stored as JSON. The entire 3x3 grid + Result item (10 items total) are serialized into a binary byte array and converted to a Base64 string. This string is what is stored in the
contentscolumn of the database.
2. Owner / Admin Workflow
How new stations and recipes are managed.
Step A: Define a Type
Command: /craft type create <name> <hand|base64>
This registers a "Category". You must provide a specific item (texture) that represents this station. This is saved to the mccraft_type table.
Step B: Create Recipe
Command: /craft create <type> <id>
This opens the Editor GUI. The plugin recognizes this GUI because the window title contains the Recipe ID in brackets (e.g., [my_sword]).
Step C: The Save Logic
There is no "Save" button. The CraftingGUIListener listens for the InventoryCloseEvent.
If the closed inventory is an Editor:
1. It scans the 3x3 grid and the Result slot.
2. Serializes them to Base64.
3. Pushes to DB and Cache automatically.
Step D: Bulk Editing (The Editor List)
Command: /craft editor <type>
Purpose: Lists all registered recipes for a specific station type in a GUI.
Logic:
1. EditorListGUI queries the DB for all recipes of that type.
2. It displays the Result Item of each recipe as a clickable icon.
3. Listener: EditorListGUIListener detects clicks on these icons.
4. Action: It fetches the full recipe data and re-opens the Editor GUI (from Step B) pre-filled with that recipe's grid.
5. Closing this new window saves any edits back to the existing ID.
3. Player Workflow
How players interact with the system.
Step A: Getting the Station
Players obtain the station item (usually distributed by admins via /craft get).
Logic: This item has a hidden NBT tag (PersistentDataContainer) storing the mccraft_type key.
Step B: Opening the Interface
Listener: HeadItemInteractListener.
When a player Right Clicks holding the station item:
1. The event cancels (block is not placed).
2. The system checks if recipes exist for this type.
3. CraftingGUI.openCraftingView is triggered.
Step C: Crafting Logic
Listener: CraftingGUIListener (Click/Drag events).
Every time the player places an item in the grid, the plugin runs a Matrix Match against cached recipes.
If Match: The result slot is populated visually.
If Pickup: Ingredients are decremented.
Consumption Rule:
If the station type is default, the station item is not consumed.
For all other types, one unit of the station item is consumed from the player's inventory each time they craft a result item.
4. Security & Validation Listeners
-
ItemDropProtectionListener: Blocks Q-drop / drag-drop of station items with the
mccraft_typekey only while the crafting GUI is open (non-editor). Outside the crafting view (and inside the editor), drops are allowed. This keeps the crafting tool safe without blocking normal gameplay. - HeadItemInteractListener (BlockPlace): Ensures that if a player tries to place the Head Item against a wall or floor, the action is cancelled. The item is meant to be a handheld "key" to open the GUI, not a physical block in the world.
- Inventory Permissions: The Editor GUI fills unused slots with Red Stained Glass. The Listener cancels any click on these filler items to prevent players from stealing GUI elements.