Skip to content
Carlo Maria Cardí edited this page Dec 18, 2025 · 6 revisions

VirtualShulker Wiki

Welcome to the official documentation for the VirtualShulker plugin. Here you'll find setup instructions, usage guides, command references, and customization tips for VirtualShulker.


Table of Contents


Getting Started

VirtualShulker allows Minecraft players to access shulker box inventories directly from their inventory without needing to place them in the world. The plugin features a cutting-edge anti-duplication system with multiple security layers.

System Requirements

  • Minecraft Version: 1.21.8+
  • Server Software: Paper/Purpur (recommended) or Spigot
  • Java Version: 21+

Installation

  1. Download the latest release from GitHub Releases
  2. Place the vshulker.jar file in your server's plugins folder
  3. Restart your Minecraft server
  4. The plugin will automatically create a VirtualShulker folder with config.yml
  5. (Optional) Customize the configuration and reload with /vs reload

First Use

  1. Get a shulker box (any color)
  2. Hold it in your main hand or off hand
  3. Shift + Right Click to open the virtual inventory
  4. Modify contents as needed
  5. Close the inventory (ESC) to save changes

How It Works

Opening Virtual Shulker Boxes

Method: Hold a shulker box and press Shift + Right Click

The plugin will:

  • Validate the shulker box and its contents (NBT validation)
  • Create a snapshot of your inventory state
  • Open a virtual inventory with the shulker's contents
  • Start continuous session validation (every tick)

Automatic Closing

The virtual shulker will automatically close when:

  • You take damage
  • You teleport or change worlds
  • You disconnect from the server
  • You die
  • The system detects manipulation attempts

Content Saving

Auto-save triggers:

  • Every inventory modification (2-tick delay for batching)
  • When closing the inventory
  • During session validation checks

Security checks before saving:

  • Transaction pattern analysis
  • Inventory snapshot comparison
  • NBT validation
  • Impossible modification detection

⚠️ Important: If the anti-duplication system detects suspicious activity, changes will NOT be saved and you'll receive a notification.


Commands

All commands support the /vs alias as a shortcut for /virtualshulker.

Available Commands

Command Permission Required Description
/vs help virtualshulker.command.help Display all available commands
/vs reload virtualshulker.command.reload Reload plugin configuration
/vs debug [player] virtualshulker.command.debug Show debug information for a player
/vs cleanup [player] virtualshulker.command.cleanup Force cleanup player session state
/vs stats virtualshulker.command.stats Display system statistics

Examples:

# Give admin group full access
/lp group admin permission set virtualshulker.* true

Give moderator group all commands but not use

/lp group moderator permission set virtualshulker.command.* true

Give specific player full access

/lp user Steve permission set virtualshulker.* true


Quick Reference Commands

Grant to Groups:

# Everyone can use virtual shulkers
/lp group default permission set virtualshulker.use true

Admins get full access

/lp group admin permission set virtualshulker.* true

Moderators get all commands

/lp group moderator permission set virtualshulker.command.* true

Grant to Players:

# Give player ability to use virtual shulkers
/lp user PlayerName permission set virtualshulker.use true

Give player full access

/lp user PlayerName permission set virtualshulker.* true

Give player specific command

/lp user PlayerName permission set virtualshulker.command.debug true

Remove Permissions:

# Remove from player
/lp user PlayerName permission unset virtualshulker.use

Remove from group

/lp group default permission unset virtualshulker.use


Permission Troubleshooting

Problem: Player can't open virtual shulkers

Solutions:

  1. Check config.yml - if use: "virtualshulker.use", player needs the permission
  2. Grant permission: /lp user PlayerName permission set virtualshulker.use true
  3. Or set use: "" in config to allow everyone

Problem: Admin can't use commands

Solutions:

  1. Make sure they're OP: /op PlayerName
  2. Or grant specific permission: /lp user PlayerName permission set virtualshulker.command.reload true
  3. Or grant all: /lp user PlayerName permission set virtualshulker.* true

Problem: Commands work but can't open shulkers

Solution: The use permission is separate from command permissions. Grant virtualshulker.use.


Backwards Compatibility

The legacy virtualshulker.admin permission from older versions is still supported but deprecated.

Old way (still works):

/lp group admin permission set virtualshulker.admin true

New way (recommended):

/lp group admin permission set virtualshulker.* true
# or for specific commands:
/lp group admin permission set virtualshulker.command.* true

ℹ️ Note: The new permission system provides better control. We recommend migrating to the new permissions for more flexibility.


Configuration

The configuration file is located at plugins/VirtualShulker/config.yml.

Complete Configuration File

# VirtualShulker Configuration

shulker:

Inventory size (must be multiple of 9: 9, 18, 27, 36, 45, 54)

size: 27

Inventory title (supports MiniMessage format)

title: "<gold><bold>Virtual Shulker"

Messages (support MiniMessage and legacy color codes)

messages: opened: "<green>Shulker opened!" closed: "<red>Shulker closed!" closed-damage: "<red>Shulker automatically closed due to damage!" no-permission: "<red>You don't have permission to use this command!" reload: "<green>Plugin reloaded successfully!"

Permissions

permissions:

Permission to use virtual shulkers (shift + right-click)

Options:

"" or "*" = Everyone can use (no permission required)

"virtualshulker.use" = Requires specific permission

use: ""

Permission for admin commands (always required)

admin: "virtualshulker.admin"

Configuration Options Explained

shulker.size

The number of slots in the virtual inventory.

  • Valid values: 9, 18, 27, 36, 45, 54 (multiples of 9)
  • Default: 27 (same as standard shulker box)
  • Note: This only affects the GUI size, not the actual storage capacity

shulker.title

The title displayed at the top of the virtual inventory.

  • Format: MiniMessage or legacy color codes
  • Default: <gold><bold>Virtual Shulker
  • Examples:
    title: "<gradient:red:blue>Rainbow Shulker"title: "<green>✦ Storage Box ✦"title: "§6§lShulker Box"
    

messages.*

Customizable messages shown to players.

  • Format: MiniMessage (<color>) or legacy codes (§, &)
  • Default: Italian messages (can be changed to any language)

permissions.use

Controls who can open virtual shulkers.

  • "" or "*" = No permission required (everyone)
  • "virtualshulker.use" = Requires specific permission

permissions.admin

Controls access to admin commands.

  • Always required regardless of use permission
  • Default: virtualshulker.admin

MiniMessage Formatting Guide

The plugin uses MiniMessage for text formatting:

Colors:

"<black>Black"
"<dark_blue>Dark Blue"
"<dark_green>Dark Green"
"<dark_aqua>Dark Aqua"
"<dark_red>Dark Red"
"<dark_purple>Dark Purple"
"<gold>Gold"
"<gray>Gray"
"<dark_gray>Dark Gray"
"<blue>Blue"
"<green>Green"
"<aqua>Aqua"
"<red>Red"
"<light_purple>Light Purple"
"<yellow>Yellow"
"<white>White"

Formatting:

"<bold>Bold Text"
"<italic>Italic Text"
"<underline>Underlined Text"
"<strikethrough>Strikethrough"
"<obfuscated>Obfuscated"

Combined:

"<gold><bold>Golden Bold"
"<red><italic>Red Italic"
"<gradient:red:blue>Rainbow Gradient"
"<rainbow>Rainbow Text"

Legacy Color Codes

Also supports legacy § and & color codes:

"§6§lGolden Bold"
"&c&oRed Italic"

Anti-Duplication System

VirtualShulker features one of the most advanced anti-duplication systems available for Minecraft plugins, with 6 independent security layers.

Security Architecture

┌─────────────────────────────────────┐
│   Layer 1: Transaction Tracking    │ ← Records every action
├─────────────────────────────────────┤
│   Layer 2: NBT Validation          │ ← Validates item data
├─────────────────────────────────────┤
│   Layer 3: Inventory Snapshot      │ ← SHA-256 hashing
├─────────────────────────────────────┤
│   Layer 4: Continuous Validation   │ ← Every tick (20Hz)
├─────────────────────────────────────┤
│   Layer 5: Session Integrity       │ ← Slot tracking
├─────────────────────────────────────┤
│   Layer 6: Multi-Point Saving      │ ← Checkpoint system
└─────────────────────────────────────┘

Protection Layers Explained

1. Transaction Tracking

Purpose: Monitor all player interactions with the inventory

Features:

  • Records every click, drag, shift-click, hotkey swap
  • Transaction timestamp tracking
  • Rate limiting: max 50 transactions per second
  • Pattern analysis for suspicious behavior

Detects:

  • Rapid-fire clicking (bot-like behavior)
  • Impossible transaction sequences
  • Packet flooding attacks

2. NBT Validation

Purpose: Ensure all items have valid data structures

Validates:

  • Display name length (max 256 characters)
  • Lore lines (max 50 lines, 256 chars each)
  • Nested shulker boxes (blocked)
  • Malformed NBT data

Prevents:

  • NBT size exploits
  • Crash items
  • Nested shulker duplication

3. Inventory Snapshot System

Purpose: Detect inventory state manipulation

How it works:

  • Creates SHA-256 hash of inventory on open
  • Tracks player inventory, shulker contents, ender chest
  • Maintains history of last 10 states
  • Compares current state against snapshot

Detects:

  • Inventory rollback exploits
  • Copy-paste manipulation (UIUtils)
  • Item count increases
  • Partial inventory restoration
  • Identical state repetition (>2 times)

4. Continuous Validation

Purpose: Real-time monitoring during session

Frequency: Every tick (20 times per second)

Checks:

  • Shulker still exists in original slot
  • Shulker hasn't been replaced
  • Shulker matches original metadata
  • Session integrity maintained

Action on failure:

  • Immediate session termination
  • No save performed
  • Player notification
  • Admin alert
  • Detailed logging

5. Session Integrity

Purpose: Prevent session hijacking and slot swapping

Tracks:

  • Original slot location (main hand, off hand, inventory, ender chest)
  • Original shulker metadata (type, display name, lore, enchantments)
  • Session start timestamp
  • Player UUID

Features:

  • 200ms cooldown between opens
  • Prevents concurrent sessions
  • Slot verification on every save

6. Multi-Point Saving

Purpose: Ensure data consistency across saves

Save Points:

  1. Auto-save after modifications (2-tick delay)
  2. Manual save on inventory close
  3. Emergency save on damage/teleport
  4. Checkpoint before any modification

Rollback Capability:

  • Original contents checkpoint created on open
  • Rollback to checkpoint if validation fails
  • No data loss on legitimate use

Detection Examples

Example 1: UIUtils Copy-Paste Exploit

Player: Steve
Action: Used UIUtils to copy items
Detection: Inventory snapshot comparison
├─ Before: 64 diamonds
├─ After: 128 diamonds (inventory + shulker)
├─ Total items increased from 1,234 to 1,298
└─ Result: BLOCKED - Changes not saved

Example 2: Shulker Replacement

Player: Alex
Action: Swapped shulker during session
Detection: Continuous validation (tick 450)
├─ Original: Blue Shulker Box
├─ Current: Red Shulker Box
├─ Session age: 22,500ms
└─ Result: BLOCKED - Session terminated

Example 3: Packet Desync

Player: Mike
Action: Delayed packet sending via mod
Detection: Transaction tracking + session integrity
├─ 73 transactions in 1000ms (suspicious rate)
├─ Shulker not in expected slot
└─ Result: BLOCKED - Pattern flagged

What Happens When Duplication is Detected

Step-by-step:

  1. Immediate Block

    • Save operation cancelled instantly
    • No data written to shulker NBT
  2. Session Termination

    • Active session removed from memory
    • Inventory closed for player
  3. Detailed Logging

    ═══════════════════════════════════════════════
    ANTI-DUPE SYSTEM TRIGGERED
    ═══════════════════════════════════════════════
    Player: Steve (UUID: xxx-xxx-xxx)
    Reason: Inventory manipulation detected
    Detection: Snapshot validation failed
    Details: Item count increased by 64
    Slot Type: MAIN_HAND
    Session Age: 15234ms
    Location: 100, 64, 200 (world)
    ═══════════════════════════════════════════════
    ACTION: Save blocked, session terminated
    ═══════════════════════════════════════════════
    
  4. Admin Notification All online players with virtualshulker.admin permission receive:

    [ANTI-DUPE] Steve attempted duplication!
    Reason: Item count increased by 64
    
  5. Player Notification The player sees:

    ANTI-DUPE: Manipulation detected!
    Reason: Item count increased by 64
    Changes NOT saved!
    

Protected Against

✅ UIUtils copy-paste exploits
✅ Packet delay manipulation
✅ Inventory rollback attacks
✅ Shulker swapping during session
✅ Nested shulker duplication
✅ NBT size exploits
✅ Concurrent session abuse
✅ Client-server desynchronization
✅ Crash items and malformed NBT
✅ Rapid transaction flooding

Performance Impact

  • Validation overhead: < 0.1ms per tick
  • Memory usage: ~500 bytes per active session
  • CPU impact: Negligible (<0.5% on average servers)

Advanced Features

NBT-Only Architecture

VirtualShulker uses a pure NBT storage system:

Benefits:

  • ✅ No database required
  • ✅ No external dependencies
  • ✅ No data migration needed
  • ✅ Portable between servers
  • ✅ Backup-friendly (standard world saves)
  • ✅ Zero data loss risk

How it works:

  • Contents stored directly in shulker box item metadata
  • Uses Minecraft's native BlockStateMeta API
  • Full compatibility with vanilla mechanics
  • Instant read/write operations

Placed Shulker Protection

The plugin tracks shulker boxes placed in the world:

Protected actions:

  • Cannot be moved by pistons
  • Cannot have items piped in/out via hoppers
  • Contents preserved during explosions
  • Proper NBT saving when broken

Implementation:

  • Location-based tracking registry
  • Automatic cleanup on break
  • Explosion handling with NBT preservation

Multi-Inventory Support

Supports shulker boxes from any inventory:

  • ✅ Main hand
  • ✅ Off hand
  • ✅ Player inventory
  • ✅ Ender chest

Automatic slot detection and saving to correct location.

Prevention Systems

Blocked actions during virtual session:

  • ❌ Moving the opened shulker
  • ❌ Dropping the opened shulker
  • ❌ Swapping hands with opened shulker
  • ❌ Hotkey swapping with opened shulker
  • ❌ Placing shulker boxes inside virtual inventory
  • ❌ Shift-clicking shulker boxes
  • ❌ Double-clicking with shulker boxes
  • ❌ Number key swaps involving shulkers

Automatic closing triggers:

  • Taking damage
  • Teleportation
  • World change
  • Player death
  • Server shutdown
  • Disconnect

Real-Time Validation

Validation frequency: Every tick (50ms)

Validates:

  • Shulker still in original slot
  • Shulker hasn't been modified externally
  • Session integrity maintained
  • No suspicious patterns

Benefits:

  • Immediate exploit detection
  • Zero-tolerance policy
  • Sub-second response time

FAQ

General Questions

Q: Does this plugin require a database?
A: No! VirtualShulker uses NBT-only storage. Everything is saved directly in the item data.

Q: Can I use this with other shulker plugins?
A: Generally yes, but test compatibility. VirtualShulker handles its own shulker boxes independently.

Q: Does this work in creative mode?
A: Yes, fully compatible with all game modes.

Q: What happens if the server crashes?
A: Contents are saved on every modification (2-tick delay). At most, you lose the last 0.1 seconds of changes.

Usage Questions

Q: Can I open a shulker while another is open?
A: No, only one virtual shulker per player at a time.

Q: Can I place shulker boxes inside the virtual inventory?
A: No, this is blocked to prevent nested shulker exploits.

Q: What happens if I drop the opened shulker?
A: The action is blocked. You must close the inventory first.

Q: Can I use this with ender chests?
A: Yes, shulker boxes in ender chests work perfectly.

Permission Questions

Q: How do I let everyone use virtual shulkers?
A: Set permissions.use: "" in config.yml.

Q: Can I restrict usage to specific worlds?
A: Use your permission plugin's world-specific permissions or install a world guard plugin.

Q: How do I give admin permissions?
A: Grant virtualshulker.admin permission via your permission plugin.

Anti-Duplication Questions

Q: Will legitimate players be flagged?
A: No. The system is designed to only flag impossible actions (item count increases, inventory rollbacks, etc.).

Q: What if I'm falsely flagged?
A: Report it as a bug with logs. The system is extensively tested but we continuously improve detection accuracy.

Q: Can I disable anti-duplication?
A: No, it's a core feature and cannot be disabled. However, it doesn't interfere with normal gameplay.

Q: Does this prevent ALL duplication methods?
A: It prevents all known client-side methods (UIUtils, packet delay, etc.). Server-side duplication bugs in Paper/Spigot are out of scope.

Technical Questions

Q: What's the performance impact?
A: Minimal. < 0.1ms validation per tick, negligible CPU usage.

Q: How much RAM does this use?
A: About 500 bytes per active session. With 100 concurrent sessions, that's ~50KB.

Q: Can this cause lag?
A: No. All operations are optimized and asynchronous where possible.

Q: Is the source code available?
A: Yes, it's open source on GitHub.


Troubleshooting

Common Issues

Issue: "You don't have permission" message

Cause: Permission not granted or misconfigured

Solution:

  1. Check config.yml - if permissions.use is set to a permission node, you need to grant it
  2. Grant the permission via your permission plugin:
    /lp user YourName permission set virtualshulker.use true
    
  3. Or set permissions.use: "" in config to allow everyone

Issue: Shulker won't open when shift-right-clicking

Possible causes:

  1. Not holding a shulker box - Make sure it's in main hand or off hand
  2. Not shift-clicking - You must hold shift while right-clicking
  3. Clicking on a block - Try clicking in the air or on a non-interactive block
  4. Permission issue - See above
  5. Cooldown - Wait 200ms between opens

Debug steps:

/vs debug YourName

Check if "Loading: true" - if stuck, use /vs cleanup YourName

Issue: Changes not being saved

Possible causes:

  1. Anti-duplication triggered - Check console for logs
  2. Shulker moved/replaced - Don't move the shulker while it's open
  3. Server crash - At most 0.1 seconds of changes can be lost

Check logs for:

ANTI-DUPE SYSTEM TRIGGERED

Issue: "Cannot move the opened shulker" message

This is intentional! You cannot move a shulker while it's open.

Solution: Close the inventory first (ESC), then move it.

Issue: Session stuck/won't close

Solution:

/vs cleanup PlayerName

This force-closes the session and cleans up the player's state.

Getting Help

Before reporting a bug:

  1. Check console for errors
  2. Try /vs cleanup for stuck sessions
  3. Verify configuration is correct
  4. Test with minimal plugins to rule out conflicts

Include in bug reports:

  1. Full server log (use pastebin)
  2. VirtualShulker version
  3. Server software and version (Paper 1.21.8, etc.)
  4. Steps to reproduce
  5. Output of /vs debug

Debug Information

Enable debug logging:

Add to bukkit.yml:

settings:
  plugin-logging:
    VirtualShulker: FINE

This will log all operations to console.

Check session state:

/vs debug PlayerName

View statistics:

/vs stats

Force cleanup:

/vs cleanup PlayerName

Performance Issues

If experiencing lag with VirtualShulker:

  1. Check active sessions: /vs stats

    • Normal: < 20 active sessions per 100 players
    • High: > 50 active sessions per 100 players
  2. Check console for spam:

    • If seeing constant validation failures, investigate player behavior
  3. Monitor server TPS:

    /tps
    

    VirtualShulker should not significantly impact TPS

  4. Check plugin conflicts:

    • Try disabling other inventory plugins temporarily

Contributing

We welcome contributions to VirtualShulker!

How to Contribute

  1. Fork the repository on GitHub
  2. Create a feature branch from main
    git checkout -b feature/your-feature-name
    
  3. Make your changes and test thoroughly
  4. Commit with clear messages
    git commit -m "Add: Description of your feature"
    
  5. Push to your fork
    git push origin feature/your-feature-name
    
  6. Submit a Pull Request with detailed description

Contribution Guidelines

  • Follow existing code style
  • Add comments for complex logic
  • Test all changes thoroughly
  • Update documentation if needed
  • One feature per pull request

Reporting Bugs

Create an issue on GitHub with:

  • Clear title describing the bug
  • Steps to reproduce
  • Expected behavior vs actual behavior
  • Server version and plugin version
  • Full error logs (use pastebin)
  • Any relevant screenshots

Suggesting Features

Create an issue on GitHub with:

  • Clear description of the feature
  • Use case / why it's needed
  • Possible implementation approach
  • Any mockups or examples

Code of Conduct

  • Be respectful and constructive
  • Help others when possible
  • Follow the contribution guidelines
  • No spam or self-promotion

Support

Getting Help

For help and support:

  1. Read this wiki - Most questions are answered here
  2. Check FAQ section - Common issues and solutions
  3. Search existing issues on GitHub
  4. Create a new issue if your problem isn't covered

Issue Tracker

Report bugs and request features on GitHub:
https://github.com/MathsAnalysis/VirtualShulker/issues

Community

  • GitHub Discussions: Ask questions and share configurations
  • Issue Tracker: Report bugs and request features
  • Pull Requests: Contribute code and improvements

Commercial Support

For commercial support, server setup assistance, or custom modifications, contact the author via GitHub.


Additional Resources

Links

Related Documentation


Thank you for using VirtualShulker!

Last updated: December 2024

# VirtualShulker Wiki

Welcome to the official documentation for the VirtualShulker plugin. Here you'll find setup instructions, usage guides, command references, and customization tips for VirtualShulker.


Table of Contents


Getting Started

VirtualShulker allows Minecraft players to access shulker box inventories directly from their inventory without needing to place them in the world. The plugin features a cutting-edge anti-duplication system with multiple security layers.

System Requirements

  • Minecraft Version: 1.21.8+
  • Server Software: Paper/Purpur (recommended) or Spigot
  • Java Version: 21+

Installation

  1. Download the latest release from [GitHub Releases](https://github.com/MathsAnalysis/VirtualShulker/releases)
  2. Place the vshulker.jar file in your server's plugins folder
  3. Restart your Minecraft server
  4. The plugin will automatically create a VirtualShulker folder with config.yml
  5. (Optional) Customize the configuration and reload with /vs reload

First Use

  1. Get a shulker box (any color)
  2. Hold it in your main hand or off hand
  3. Shift + Right Click to open the virtual inventory
  4. Modify contents as needed
  5. Close the inventory (ESC) to save changes

How It Works

Opening Virtual Shulker Boxes

Method: Hold a shulker box and press Shift + Right Click

The plugin will:

  • Validate the shulker box and its contents (NBT validation)
  • Create a snapshot of your inventory state
  • Open a virtual inventory with the shulker's contents
  • Start continuous session validation (every tick)

Automatic Closing

The virtual shulker will automatically close when:

  • You take damage
  • You teleport or change worlds
  • You disconnect from the server
  • You die
  • The system detects manipulation attempts

Content Saving

Auto-save triggers:

  • Every inventory modification (2-tick delay for batching)
  • When closing the inventory
  • During session validation checks

Security checks before saving:

  • Transaction pattern analysis
  • Inventory snapshot comparison
  • NBT validation
  • Impossible modification detection

⚠️ Important: If the anti-duplication system detects suspicious activity, changes will NOT be saved and you'll receive a notification.


Commands

All commands support the /vs alias as a shortcut for /virtualshulker.

Available Commands

Command Permission Required Description
/vs help virtualshulker.command.help Display all available commands
/vs reload virtualshulker.command.reload Reload plugin configuration
/vs debug [player] virtualshulker.command.debug Show debug information for a player
/vs cleanup [player] virtualshulker.command.cleanup Force cleanup player session state
/vs stats virtualshulker.command.stats Display system statistics

Note: All admin commands (reload, debug, cleanup, stats) default to OP-only unless explicitly granted.

Command Examples

# View server statistics
/vs stats

# Debug your own session
/vs debug

# Debug another player's session
/vs debug Steve

# Force cleanup if a player is stuck
/vs cleanup Steve

# Reload configuration after editing config.yml
/vs reload

Command Output Examples

/vs stats output:

╔═══════════════════════════════════════╗
║    VIRTUALSHULKER STATISTICS         ║
╠═══════════════════════════════════════╣
  Online players: 5
  Active sessions: 2
  System: NBT-ONLY (Direct Save)
  Database: NONE
  Cache: NONE
╚═══════════════════════════════════════╝

/vs debug Steve output:

╔═══════════════════════════════════════╗
║  DEBUG INFO: Steve                    ║
╠═══════════════════════════════════════╣
  Shulker open: true
  Loading: false
╚═══════════════════════════════════════╝

🔐 Permissions

VirtualShulker uses a granular permission system that allows fine-tuned control over who can access which features.

Permission Overview

Permission Description Default
Core Permissions
virtualshulker.use Open virtual shulker boxes (Shift + Right Click) Configurable
Command Permissions
virtualshulker.command.use Access to base /vs command Everyone
virtualshulker.command.help Access to /vs help command Everyone
virtualshulker.command.reload Access to /vs reload command OP only
virtualshulker.command.debug Access to /vs debug command OP only
virtualshulker.command.cleanup Access to /vs cleanup command OP only
virtualshulker.command.stats Access to /vs stats command OP only
Wildcard Permissions
virtualshulker.* All permissions (core + commands) OP only
virtualshulker.command.* All command permissions OP only

Core Permission: Virtual Shulker Usage

The virtualshulker.use permission controls who can open virtual shulker boxes.

Configuration in config.yml:

permissions:
  use: ""  # Empty = everyone can use (no permission required)
  # OR
  use: "virtualshulker.use"  # Specific permission required

Option 1: Allow Everyone (Recommended for most servers)

permissions:
  use: ""

No permission management needed - all players can use virtual shulkers.

Option 2: Permission-Based Access

permissions:
  use: "virtualshulker.use"

Then grant the permission:

# LuckPerms
/lp group default permission set virtualshulker.use true

# PermissionsEx
/pex group default add virtualshulker.use

Command Permissions

Each command has its own permission for granular access control.

Public Commands

These commands are accessible to everyone by default:

  • virtualshulker.command.use - Base command access
  • virtualshulker.command.help - View help menu

Admin Commands

These commands require explicit permission (OP by default):

  • virtualshulker.command.reload - Reload plugin configuration
  • virtualshulker.command.debug - View player debug information
  • virtualshulker.command.cleanup - Force cleanup player sessions
  • virtualshulker.command.stats - View system statistics

Permission Setup Examples

Basic Setup: Everyone Can Use Virtual Shulkers

# config.yml
permissions:
  use: ""
# No additional permissions needed!

✅ Result: All players can open virtual shulkers, only OPs can use admin commands.


Intermediate Setup: Permission-Based with Moderators

# Everyone can use virtual shulkers
/lp group default permission set virtualshulker.use true

# Moderators can view stats and debug
/lp group moderator permission set virtualshulker.command.stats true
/lp group moderator permission set virtualshulker.command.debug true

# Admins get full access
/lp group admin permission set virtualshulker.* true

✅ Result:

  • Default players: Can use virtual shulkers
  • Moderators: Can use + view stats/debug
  • Admins: Full access to everything

Advanced Setup: Granular Control

# Helper staff can only cleanup stuck players
/lp group helper permission set virtualshulker.command.cleanup true

# Moderators get stats + debug
/lp group moderator permission set virtualshulker.command.stats true
/lp group moderator permission set virtualshulker.command.debug true

# Senior mods can reload config
/lp group seniormod permission set virtualshulker.command.reload true

# Admins get everything
/lp group admin permission set virtualshulker.* true

✅ Result: Each rank has exactly the permissions they need.


Wildcard Permissions

Use wildcards for easier permission management:

Wildcard Grants Use Case
virtualshulker.* Everything (use + all commands) Admin groups
virtualshulker.command.* All commands (but not use) Command-only access

Examples:

# Give admin group full access
/lp group admin permission set virtualshulker.* true

# Give moderator group all commands but not use
/lp group moderator permission set virtualshulker.command.* true

# Give specific player full access
/lp user Steve permission set virtualshulker.* true

Quick Reference Commands

Grant to Groups:

# Everyone can use virtual shulkers
/lp group default permission set virtualshulker.use true

# Admins get full access
/lp group admin permission set virtualshulker.* true

# Moderators get all commands
/lp group moderator permission set virtualshulker.command.* true

Grant to Players:

# Give player ability to use virtual shulkers
/lp user PlayerName permission set virtualshulker.use true

# Give player full access
/lp user PlayerName permission set virtualshulker.* true

# Give player specific command
/lp user PlayerName permission set virtualshulker.command.debug true

Remove Permissions:

# Remove from player
/lp user PlayerName permission unset virtualshulker.use

# Remove from group
/lp group default permission unset virtualshulker.use

Permission Troubleshooting

Problem: Player can't open virtual shulkers

Solutions:

  1. Check config.yml - if use: "virtualshulker.use", player needs the permission
  2. Grant permission: /lp user PlayerName permission set virtualshulker.use true
  3. Or set use: "" in config to allow everyone

Problem: Admin can't use commands

Solutions:

  1. Make sure they're OP: /op PlayerName
  2. Or grant specific permission: /lp user PlayerName permission set virtualshulker.command.reload true
  3. Or grant all: /lp user PlayerName permission set virtualshulker.* true

Problem: Commands work but can't open shulkers

Solution: The use permission is separate from command permissions. Grant virtualshulker.use.


Backwards Compatibility

The legacy virtualshulker.admin permission from older versions is still supported but deprecated.

Old way (still works):

/lp group admin permission set virtualshulker.admin true

New way (recommended):

/lp group admin permission set virtualshulker.* true
# or for specific commands:
/lp group admin permission set virtualshulker.command.* true

ℹ️ Note: The new permission system provides better control. We recommend migrating to the new permissions for more flexibility.


Configuration

The configuration file is located at plugins/VirtualShulker/config.yml.

Complete Configuration File

# VirtualShulker Configuration

shulker:
  # Inventory size (must be multiple of 9: 9, 18, 27, 36, 45, 54)
  size: 27
  
  # Inventory title (supports [MiniMessage](https://docs.advntr.dev/minimessage/format.html) format)
  title: "<gold><bold>Virtual Shulker"

# Messages (support MiniMessage and legacy color codes)
messages:
  opened: "<green>Shulker opened!"
  closed: "<red>Shulker closed!"
  closed-damage: "<red>Shulker automatically closed due to damage!"
  no-permission: "<red>You don't have permission to use this command!"
  reload: "<green>Plugin reloaded successfully!"

# Permissions
permissions:
  # Permission to use virtual shulkers (shift + right-click)
  # Options:
  #   ""  or "*"                 = Everyone can use (no permission required)
  #   "virtualshulker.use"       = Requires specific permission
  use: ""
  
  # Permission for admin commands (always required)
  admin: "virtualshulker.admin"

Configuration Options Explained

shulker.size

The number of slots in the virtual inventory.

  • Valid values: 9, 18, 27, 36, 45, 54 (multiples of 9)
  • Default: 27 (same as standard shulker box)
  • Note: This only affects the GUI size, not the actual storage capacity

shulker.title

The title displayed at the top of the virtual inventory.

  • Format: MiniMessage or legacy color codes
  • Default: <gold><bold>Virtual Shulker
  • Examples:
    title: "<gradient:red:blue>Rainbow Shulker"
    title: "<green>✦ Storage Box ✦"
    title: "§6§lShulker Box"

messages.*

Customizable messages shown to players.

  • Format: MiniMessage (<color>) or legacy codes (§, &)
  • Default: Italian messages (can be changed to any language)

permissions.use

Controls who can open virtual shulkers.

  • "" or "*" = No permission required (everyone)
  • "virtualshulker.use" = Requires specific permission

permissions.admin

Controls access to admin commands.

  • Always required regardless of use permission
  • Default: virtualshulker.admin

MiniMessage Formatting Guide

The plugin uses MiniMessage for text formatting:

Colors:

"<black>Black"
"<dark_blue>Dark Blue"
"<dark_green>Dark Green"
"<dark_aqua>Dark Aqua"
"<dark_red>Dark Red"
"<dark_purple>Dark Purple"
"<gold>Gold"
"<gray>Gray"
"<dark_gray>Dark Gray"
"<blue>Blue"
"<green>Green"
"<aqua>Aqua"
"<red>Red"
"<light_purple>Light Purple"
"<yellow>Yellow"
"<white>White"

Formatting:

"<bold>Bold Text"
"<italic>Italic Text"
"<underline>Underlined Text"
"<strikethrough>Strikethrough"
"<obfuscated>Obfuscated"

Combined:

"<gold><bold>Golden Bold"
"<red><italic>Red Italic"
"<gradient:red:blue>Rainbow Gradient"
"<rainbow>Rainbow Text"

Legacy Color Codes

Also supports legacy § and & color codes:

"§6§lGolden Bold"
"&c&oRed Italic"

Anti-Duplication System

VirtualShulker features one of the most advanced anti-duplication systems available for Minecraft plugins, with 6 independent security layers.

Security Architecture

┌─────────────────────────────────────┐
│   Layer 1: Transaction Tracking     │ ← Records every action
├─────────────────────────────────────┤
│   Layer 2: NBT Validation           │ ← Validates item data
├─────────────────────────────────────┤
│   Layer 3: Inventory Snapshot       │ ← SHA-256 hashing
├─────────────────────────────────────┤
│   Layer 4: Continuous Validation    │ ← Every tick (20Hz)
├─────────────────────────────────────┤
│   Layer 5: Session Integrity        │ ← Slot tracking
├─────────────────────────────────────┤
│   Layer 6: Multi-Point Saving       │ ← Checkpoint system
└─────────────────────────────────────┘

Protection Layers Explained

1. Transaction Tracking

Purpose: Monitor all player interactions with the inventory

Features:

  • Records every click, drag, shift-click, hotkey swap
  • Transaction timestamp tracking
  • Rate limiting: max 50 transactions per second
  • Pattern analysis for suspicious behavior

Detects:

  • Rapid-fire clicking (bot-like behavior)
  • Impossible transaction sequences
  • Packet flooding attacks

2. NBT Validation

Purpose: Ensure all items have valid data structures

Validates:

  • Display name length (max 256 characters)
  • Lore lines (max 50 lines, 256 chars each)
  • Nested shulker boxes (blocked)
  • Malformed NBT data

Prevents:

  • NBT size exploits
  • Crash items
  • Nested shulker duplication

3. Inventory Snapshot System

Purpose: Detect inventory state manipulation

How it works:

  • Creates SHA-256 hash of inventory on open
  • Tracks player inventory, shulker contents, ender chest
  • Maintains history of last 10 states
  • Compares current state against snapshot

Detects:

  • Inventory rollback exploits
  • Copy-paste manipulation (UIUtils)
  • Item count increases
  • Partial inventory restoration
  • Identical state repetition (>2 times)

4. Continuous Validation

Purpose: Real-time monitoring during session

Frequency: Every tick (20 times per second)

Checks:

  • Shulker still exists in original slot
  • Shulker hasn't been replaced
  • Shulker matches original metadata
  • Session integrity maintained

Action on failure:

  • Immediate session termination
  • No save performed
  • Player notification
  • Admin alert
  • Detailed logging

5. Session Integrity

Purpose: Prevent session hijacking and slot swapping

Tracks:

  • Original slot location (main hand, off hand, inventory, ender chest)
  • Original shulker metadata (type, display name, lore, enchantments)
  • Session start timestamp
  • Player UUID

Features:

  • 200ms cooldown between opens
  • Prevents concurrent sessions
  • Slot verification on every save

6. Multi-Point Saving

Purpose: Ensure data consistency across saves

Save Points:

  1. Auto-save after modifications (2-tick delay)
  2. Manual save on inventory close
  3. Emergency save on damage/teleport
  4. Checkpoint before any modification

Rollback Capability:

  • Original contents checkpoint created on open
  • Rollback to checkpoint if validation fails
  • No data loss on legitimate use

Detection Examples

Example 1: UIUtils Copy-Paste Exploit

Player: Steve
Action: Used UIUtils to copy items
Detection: Inventory snapshot comparison
├─ Before: 64 diamonds
├─ After: 128 diamonds (inventory + shulker)
├─ Total items increased from 1,234 to 1,298
└─ Result: BLOCKED - Changes not saved

Example 2: Shulker Replacement

Player: Alex
Action: Swapped shulker during session
Detection: Continuous validation (tick 450)
├─ Original: Blue Shulker Box
├─ Current: Red Shulker Box
├─ Session age: 22,500ms
└─ Result: BLOCKED - Session terminated

Example 3: Packet Desync

Player: Mike
Action: Delayed packet sending via mod
Detection: Transaction tracking + session integrity
├─ 73 transactions in 1000ms (suspicious rate)
├─ Shulker not in expected slot
└─ Result: BLOCKED - Pattern flagged

What Happens When Duplication is Detected

Step-by-step:

  1. Immediate Block

    • Save operation cancelled instantly
    • No data written to shulker NBT
  2. Session Termination

    • Active session removed from memory
    • Inventory closed for player
  3. Detailed Logging

    ═══════════════════════════════════════════════
    ANTI-DUPE SYSTEM TRIGGERED
    ═══════════════════════════════════════════════
    Player: Steve (UUID: xxx-xxx-xxx)
    Reason: Inventory manipulation detected
    Detection: Snapshot validation failed
    Details: Item count increased by 64
    Slot Type: MAIN_HAND
    Session Age: 15234ms
    Location: 100, 64, 200 (world)
    ═══════════════════════════════════════════════
    ACTION: Save blocked, session terminated
    ═══════════════════════════════════════════════
    
  4. Admin Notification All online players with virtualshulker.admin permission receive:

    [ANTI-DUPE] Steve attempted duplication!
    Reason: Item count increased by 64
    
  5. Player Notification The player sees:

    ANTI-DUPE: Manipulation detected!
    Reason: Item count increased by 64
    Changes NOT saved!
    

Protected Against

✅ UIUtils copy-paste exploits
✅ Packet delay manipulation
✅ Inventory rollback attacks
✅ Shulker swapping during session
✅ Nested shulker duplication
✅ NBT size exploits
✅ Concurrent session abuse
✅ Client-server desynchronization
✅ Crash items and malformed NBT
✅ Rapid transaction flooding

Performance Impact

  • Validation overhead: < 0.1ms per tick
  • Memory usage: ~500 bytes per active session
  • CPU impact: Negligible (<0.5% on average servers)

Advanced Features

NBT-Only Architecture

VirtualShulker uses a pure NBT storage system:

Benefits:

  • ✅ No database required
  • ✅ No external dependencies
  • ✅ No data migration needed
  • ✅ Portable between servers
  • ✅ Backup-friendly (standard world saves)
  • ✅ Zero data loss risk

How it works:

  • Contents stored directly in shulker box item metadata
  • Uses Minecraft's native BlockStateMeta API
  • Full compatibility with vanilla mechanics
  • Instant read/write operations

Placed Shulker Protection

The plugin tracks shulker boxes placed in the world:

Protected actions:

  • Cannot be moved by pistons
  • Cannot have items piped in/out via hoppers
  • Contents preserved during explosions
  • Proper NBT saving when broken

Implementation:

  • Location-based tracking registry
  • Automatic cleanup on break
  • Explosion handling with NBT preservation

Multi-Inventory Support

Supports shulker boxes from any inventory:

  • ✅ Main hand
  • ✅ Off hand
  • ✅ Player inventory
  • ✅ Ender chest

Automatic slot detection and saving to correct location.

Prevention Systems

Blocked actions during virtual session:

  • ❌ Moving the opened shulker
  • ❌ Dropping the opened shulker
  • ❌ Swapping hands with opened shulker
  • ❌ Hotkey swapping with opened shulker
  • ❌ Placing shulker boxes inside virtual inventory
  • ❌ Shift-clicking shulker boxes
  • ❌ Double-clicking with shulker boxes
  • ❌ Number key swaps involving shulkers

Automatic closing triggers:

  • Taking damage
  • Teleportation
  • World change
  • Player death
  • Server shutdown
  • Disconnect

Real-Time Validation

Validation frequency: Every tick (50ms)

Validates:

  • Shulker still in original slot
  • Shulker hasn't been modified externally
  • Session integrity maintained
  • No suspicious patterns

Benefits:

  • Immediate exploit detection
  • Zero-tolerance policy
  • Sub-second response time

FAQ

General Questions

Q: Does this plugin require a database?
A: No! VirtualShulker uses NBT-only storage. Everything is saved directly in the item data.

Q: Can I use this with other shulker plugins?
A: Generally yes, but test compatibility. VirtualShulker handles its own shulker boxes independently.

Q: Does this work in creative mode?
A: Yes, fully compatible with all game modes.

Q: What happens if the server crashes?
A: Contents are saved on every modification (2-tick delay). At most, you lose the last 0.1 seconds of changes.

Usage Questions

Q: Can I open a shulker while another is open?
A: No, only one virtual shulker per player at a time.

Q: Can I place shulker boxes inside the virtual inventory?
A: No, this is blocked to prevent nested shulker exploits.

Q: What happens if I drop the opened shulker?
A: The action is blocked. You must close the inventory first.

Q: Can I use this with ender chests?
A: Yes, shulker boxes in ender chests work perfectly.

Permission Questions

Q: How do I let everyone use virtual shulkers?
A: Set permissions.use: "" in config.yml.

Q: Can I restrict usage to specific worlds?
A: Use your permission plugin's world-specific permissions or install a world guard plugin.

Q: How do I give admin permissions?
A: Grant virtualshulker.admin permission via your permission plugin.

Anti-Duplication Questions

Q: Will legitimate players be flagged?
A: No. The system is designed to only flag impossible actions (item count increases, inventory rollbacks, etc.).

Q: What if I'm falsely flagged?
A: Report it as a bug with logs. The system is extensively tested but we continuously improve detection accuracy.

Q: Can I disable anti-duplication?
A: No, it's a core feature and cannot be disabled. However, it doesn't interfere with normal gameplay.

Q: Does this prevent ALL duplication methods?
A: It prevents all known client-side methods (UIUtils, packet delay, etc.). Server-side duplication bugs in Paper/Spigot are out of scope.

Technical Questions

Q: What's the performance impact?
A: Minimal. < 0.1ms validation per tick, negligible CPU usage.

Q: How much RAM does this use?
A: About 500 bytes per active session. With 100 concurrent sessions, that's ~50KB.

Q: Can this cause lag?
A: No. All operations are optimized and asynchronous where possible.

Q: Is the source code available?
A: Yes, it's open source on GitHub.


Troubleshooting

Common Issues

Issue: "You don't have permission" message

Cause: Permission not granted or misconfigured

Solution:

  1. Check config.yml - if permissions.use is set to a permission node, you need to grant it
  2. Grant the permission via your permission plugin:
    /lp user YourName permission set virtualshulker.use true
  3. Or set permissions.use: "" in config to allow everyone

Issue: Shulker won't open when shift-right-clicking

Possible causes:

  1. Not holding a shulker box - Make sure it's in main hand or off hand
  2. Not shift-clicking - You must hold shift while right-clicking
  3. Clicking on a block - Try clicking in the air or on a non-interactive block
  4. Permission issue - See above
  5. Cooldown - Wait 200ms between opens

Debug steps:

/vs debug YourName

Check if "Loading: true" - if stuck, use /vs cleanup YourName

Issue: Changes not being saved

Possible causes:

  1. Anti-duplication triggered - Check console for logs
  2. Shulker moved/replaced - Don't move the shulker while it's open
  3. Server crash - At most 0.1 seconds of changes can be lost

Check logs for:

ANTI-DUPE SYSTEM TRIGGERED

Issue: "Cannot move the opened shulker" message

This is intentional! You cannot move a shulker while it's open.

Solution: Close the inventory first (ESC), then move it.

Issue: Session stuck/won't close

Solution:

/vs cleanup PlayerName

This force-closes the session and cleans up the player's state.

Getting Help

Before reporting a bug:

  1. Check console for errors
  2. Try /vs cleanup for stuck sessions
  3. Verify configuration is correct
  4. Test with minimal plugins to rule out conflicts

Include in bug reports:

  1. Full server log (use pastebin)
  2. VirtualShulker version
  3. Server software and version (Paper 1.21.8, etc.)
  4. Steps to reproduce
  5. Output of /vs debug

Debug Information

Enable debug logging:

Add to bukkit.yml:

settings:
  plugin-logging:
    VirtualShulker: FINE

This will log all operations to console.

Check session state:

/vs debug PlayerName

View statistics:

/vs stats

Force cleanup:

/vs cleanup PlayerName

Performance Issues

If experiencing lag with VirtualShulker:

  1. Check active sessions: /vs stats

    • Normal: < 20 active sessions per 100 players
    • High: > 50 active sessions per 100 players
  2. Check console for spam:

    • If seeing constant validation failures, investigate player behavior
  3. Monitor server TPS:

    /tps

    VirtualShulker should not significantly impact TPS

  4. Check plugin conflicts:

    • Try disabling other inventory plugins temporarily

Contributing

We welcome contributions to VirtualShulker!

How to Contribute

  1. Fork the repository on GitHub
  2. Create a feature branch from main
    git checkout -b feature/your-feature-name
  3. Make your changes and test thoroughly
  4. Commit with clear messages
    git commit -m "Add: Description of your feature"
  5. Push to your fork
    git push origin feature/your-feature-name
  6. Submit a Pull Request with detailed description

Contribution Guidelines

  • Follow existing code style
  • Add comments for complex logic
  • Test all changes thoroughly
  • Update documentation if needed
  • One feature per pull request

Reporting Bugs

Create an issue on GitHub with:

  • Clear title describing the bug
  • Steps to reproduce
  • Expected behavior vs actual behavior
  • Server version and plugin version
  • Full error logs (use pastebin)
  • Any relevant screenshots

Suggesting Features

Create an issue on GitHub with:

  • Clear description of the feature
  • Use case / why it's needed
  • Possible implementation approach
  • Any mockups or examples

Code of Conduct

  • Be respectful and constructive
  • Help others when possible
  • Follow the contribution guidelines
  • No spam or self-promotion

Support

Getting Help

For help and support:

  1. Read this wiki - Most questions are answered here
  2. Check FAQ section - Common issues and solutions
  3. Search existing issues on GitHub
  4. Create a new issue if your problem isn't covered

Issue Tracker

Report bugs and request features on GitHub:
https://github.com/MathsAnalysis/VirtualShulker/issues

Community

  • GitHub Discussions: Ask questions and share configurations
  • Issue Tracker: Report bugs and request features
  • Pull Requests: Contribute code and improvements

Commercial Support

For commercial support, server setup assistance, or custom modifications, contact the author via GitHub.


Additional Resources

Links

Related Documentation


Thank you for using VirtualShulker!

Last updated: December 2024

Clone this wiki locally