Modifying the creative content via CreativeContentPacket is unreliable and often crashes the client.
(by EventListener in your plugin)
This patch implements a permission-based filtering system for creative items. It allows server administrators and plugin developers to control which items appear in the creative menu based on player permissions, without breaking client compatibility.
- Permission-Based Filtering: Hide specific items or groups of items from players.
- Plugin API: Easily register custom item groups and define complex logic via Java predicates.
- Safe Integration: Modifies minimally to prevent client crashes while maintaining full functionality.
- Quick-Crafts Support: Adjusts to the game mode and sends all creative items (if survival).
-
Clone the patch repository:
git clone https://github.com/labarjni/Nukkit-MOT-CF-Patch.git
-
Navigate to the directory:
cd Nukkit-MOT-CF-Patch -
Clone the target Nukkit-MOT repository:
git clone https://github.com/MemoriesOfTime/Nukkit-MOT.git
-
Apply the patches:
./gradlew applyPatches
✅ Done! You can now build Nukkit-MOT (./gradlew build) and the creative filter system will be active.
This patch introduces a new class ItemCreativePermissions and modifies Item.java and PlayerInventory.java to intercept creative item list generation.
- New Class:
cn.nukkit.item.ItemCreativePermissions- Manages a registry of
Predicate<Item>linked to permission nodes. - Base permission format:
nukkit.creativeitem.<suffix>
- Manages a registry of
- Modified
Item.java:- Overloaded
getCreativeItems()andgetCreativeItemsAndGroups()to accept aPlayerinstance. - Filters the item list dynamically based on the player's permissions before sending it to the client.
- Added
getCreativeItemsAndGroupsRaw()to access the unfiltered list internally.
- Overloaded
- Modified
PlayerInventory.java:- Updated the creative content packet logic to pass the
Playerobject to the item retrieval methods, enabling per-player filtering.
- Updated the creative content packet logic to pass the
You can integrate this system into your own plugins to restrict access to specific items (e.g., admin-only tools).
Or create specific tabs with items of different accessibility
Use ItemCreativePermissions.registerPermissionGroup to define items and the permission required to see them.
Example: Restricting Bedrock to Admins
import cn.nukkit.item.Item;
import cn.nukkit.plugin.PluginBase;
public class MyPlugin extends PluginBase {
@Override
public void onEnable() {
ItemCreativePermissions.registerPermissionGroup("admin.bedrock", item -> item.getId() == Item.BEDROCK);
getLogger().info("Bedrock is now restricted to players with 'nukkit.creativeitem.admin.bedrock'");
}
}Players will need the permission node nukkit.creativeitem.admin.bedrock to see Bedrock in the creative.
You can check for multiple IDs, meta values, or even custom names.
Example: Restricting all "Command Blocks" and "Structure Blocks"
import cn.nukkit.item.Item;
ItemCreativePermissions.registerPermissionGroup("builder.structure",item ->{
int id = item.getId();
return id == Item.COMMAND_BLOCK ||
id == Item.CHAIN_COMMAND_BLOCK ||
id == Item.REPEATING_COMMAND_BLOCK ||
id == Item.STRUCTURE_BLOCK;
});Required permission: nukkit.creativeitem.builder.structure
Since the condition is a java.util.function.Predicate<Item>, you can implement any logic you want.
Example: Hiding items with a specific custom name (e.g., "Dev Tool")
import cn.nukkit.item.Item;
ItemCreativePermissions.registerPermissionGroup("dev.tools",item ->{
if (!item.hasCustomName()) return false;
return item.getCustomName().contains("[DEV]");
});Required permission: nukkit.creativeitem.dev.tools
Besides registering global groups, you can manually check if a specific player is allowed to have a specific item using ItemCreativePermissions.hasPermission(Item, Player). This is useful for custom GUIs, event listeners, or command executors.
Example: Blocking item pickup in Creative mode via Event Listener
import cn.nukkit.event.EventHandler;
import cn.nukkit.event.Listener;
import cn.nukkit.event.player.PlayerInventoryTransactionEvent;
import cn.nukkit.item.Item;
import cn.nukkit.plugin.PluginBase;
public class CreativeGuard extends PluginBase implements Listener {
@Override
public void onEnable() {
getServer().getPluginManager().registerEvents(this, this);
}
@EventHandler
public void onTransaction(PlayerInventoryTransactionEvent event) {
if (!event.getPlayer().isCreative()) {
return;
}
Item item = event.getTransaction().getSourceItem();
if (!ItemCreativePermissions.hasPermission(item, event.getPlayer())) {
event.setCancelled();
event.getPlayer().sendMessage("§cYou do not have permission to use this item");
}
}
}When you register a group with the suffix my.suffix, the system automatically requires:
nukkit.creativeitem.my.suffix
If the player does not have this permission, any item matching your predicate will be hidden from their creative.
- Gradle Structure: Thanks to LuminiaDev/Nukkit-MOT-UUID-Patch for the gradle patch structure.
- Issues: If the patches do not work, please create a new issue with a description of the problem.