Developer API Overview
Integration APIs and development resources for extending Showcase mod
Developer API Overview
Showcase provides comprehensive APIs for mod developers, plugin creators, and server administrators to integrate with and extend the mod's functionality.
Available APIs
PlaceholderAPI
Integrate with other mods using placeholder variables
Event System
Listen to and handle Showcase events
Java API
Direct integration with Showcase's Java classes
Data API
Access and manipulate share data programmatically
Quick Start
Adding Showcase as Dependency
repositories {
maven {
name = "Modrinth"
url = "https://api.modrinth.com/maven"
}
}
dependencies {
// Showcase API
modImplementation "maven.modrinth:showcase:2.3.1+mc1.21.6"
// Optional: Include in mod
include "maven.modrinth:showcase:2.3.1+mc1.21.6"
}
<repositories>
<repository>
<id>modrinth</id>
<name>Modrinth</name>
<url>https://api.modrinth.com/maven</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>maven.modrinth</groupId>
<artifactId>showcase</artifactId>
<version>2.3.1+mc1.21.6</version>
</dependency>
</dependencies>
{
"depends": {
"showcase": ">=2.3.0"
},
"suggests": {
"showcase": "2.3.1"
}
}
Basic API Usage
import com.showcase.api.ShowcaseAPI;
import com.showcase.api.data.ShareData;
import com.showcase.api.events.ShareCreateEvent;
public class ExampleIntegration {
public void createItemShare(ServerPlayerEntity player) {
// Get the Showcase API instance
ShowcaseAPI api = ShowcaseAPI.getInstance();
// Create a new item share
ShareData share = api.createShare(
player,
ShareType.ITEM,
Duration.ofMinutes(30),
"My custom share"
);
// Share was created successfully
if (share != null) {
player.sendMessage(Text.literal("Share created: " + share.getId()));
}
}
@EventHandler
public void onShareCreate(ShareCreateEvent event) {
// Listen to share creation events
ServerPlayerEntity player = event.getPlayer();
ShareData share = event.getShare();
// Custom logic here
System.out.println("Player " + player.getName() + " created share: " + share.getId());
}
}
Core API Classes
ShowcaseAPI
The main entry point for all Showcase functionality:
public class ShowcaseAPI {
// Get API instance
public static ShowcaseAPI getInstance();
// Share management
public ShareData createShare(ServerPlayerEntity player, ShareType type, Duration duration, String description);
public Optional<ShareData> getShare(String shareId);
public List<ShareData> getPlayerShares(ServerPlayerEntity player);
public boolean cancelShare(String shareId);
// Permission checking
public boolean hasPermission(ServerPlayerEntity player, String permission);
public Set<String> getPlayerPermissions(ServerPlayerEntity player);
// Configuration access
public ShowcaseConfig getConfig();
public void reloadConfig();
// Statistics
public PlayerStats getPlayerStats(ServerPlayerEntity player);
public void updatePlayerStats(ServerPlayerEntity player);
}
ShareData
Represents a created share:
public class ShareData {
public String getId();
public ServerPlayerEntity getCreator();
public ShareType getType();
public Instant getCreatedAt();
public Instant getExpiresAt();
public String getDescription();
public Set<UUID> getReceivers();
public ItemStack[] getItems(); // For inventory shares
public ItemStack getItem(); // For item shares
public PlayerStats getStats(); // For stats shares
// Utility methods
public boolean isExpired();
public boolean canView(ServerPlayerEntity player);
public Duration getTimeRemaining();
}
ShareType Enum
public enum ShareType {
ITEM,
INVENTORY,
HOTBAR,
ENDERCHEST,
CONTAINER,
MERCHANT,
STATS;
// Utility methods
public String getPermissionNode();
public Duration getDefaultDuration();
public boolean requiresContainer();
}
Event System
Available Events
All events are fired on the server thread and can be cancelled:
// Fired when a player uses a chat keyword
public class ChatKeywordEvent extends Event implements Cancellable {
public ServerPlayerEntity getPlayer();
public String getKeyword();
public String getOriginalMessage();
public String getReplacementText();
public void setReplacementText(String text);
}
// Fired when player statistics are collected
public class StatsCollectEvent extends Event {
public ServerPlayerEntity getPlayer();
public PlayerStats getStats();
// Modify stats before sharing
public void addCustomStat(String category, String key, Object value);
}
// Fired when configuration is reloaded
public class ConfigReloadEvent extends Event {
public ShowcaseConfig getOldConfig();
public ShowcaseConfig getNewConfig();
public List<String> getChangedKeys();
}
// Fired during cleanup operations
public class CleanupEvent extends Event {
public int getExpiredShares();
public int getRemovedShares();
public Duration getCleanupTime();
}
Event Registration
// In your mod initializer
public void onInitialize() {
// Register event listeners
ShowcaseAPI.getInstance().getEventBus().register(new MyEventHandler());
}
public class MyEventHandler {
@EventHandler(priority = EventPriority.HIGH)
public void onShareCreate(ShareCreateEvent event) {
ServerPlayerEntity player = event.getPlayer();
// Example: Prevent sharing in certain worlds
if (player.getWorld().getRegistryKey().getValue().getPath().equals("spawn")) {
event.setCancelled(true);
player.sendMessage(Text.literal("Sharing is not allowed in spawn!"));
}
}
@EventHandler
public void onChatKeyword(ChatKeywordEvent event) {
// Example: Custom keyword processing
if (event.getKeyword().equals("custom")) {
event.setReplacementText("§6[Custom Item]§r");
}
}
}
Configuration Integration
Accessing Configuration
ShowcaseConfig config = ShowcaseAPI.getInstance().getConfig();
// Get specific settings
Duration defaultDuration = config.getDefaultDuration(ShareType.ITEM);
boolean chatKeywordsEnabled = config.isChatKeywordsEnabled();
int maxSharesPerPlayer = config.getMaxSharesPerPlayer();
// Check feature availability
if (config.isShareTypeEnabled(ShareType.STATS)) {
// Statistics sharing is enabled
}
Custom Configuration Sections
Add your own configuration sections:
// Register custom config section
ShowcaseAPI.getInstance().registerConfigSection("mymod", MyModConfig.class);
// Access custom config
MyModConfig myConfig = config.getSection("mymod", MyModConfig.class);
Data Storage Integration
Custom Data Providers
Implement custom storage backends:
public class MyDataProvider implements DataProvider {
@Override
public void saveShare(ShareData share) {
// Custom save logic (e.g., to database)
}
@Override
public Optional<ShareData> loadShare(String id) {
// Custom load logic
return Optional.empty();
}
@Override
public List<ShareData> getPlayerShares(UUID playerId) {
// Get shares for specific player
return Collections.emptyList();
}
@Override
public void cleanup() {
// Remove expired shares
}
}
// Register your provider
ShowcaseAPI.getInstance().registerDataProvider(new MyDataProvider());
Performance Considerations
Async Operations
Use async operations for expensive tasks:
// Async share creation
CompletableFuture<ShareData> future = ShowcaseAPI.getInstance()
.createShareAsync(player, ShareType.STATS, duration, description);
future.thenAccept(share -> {
// Handle result on main thread
player.sendMessage(Text.literal("Stats share created!"));
});
Caching
Leverage Showcase's caching system:
// Cache custom data
ShowcaseAPI.getInstance().getCache().put("mykey", myData, Duration.ofMinutes(5));
// Retrieve cached data
Optional<MyData> cached = ShowcaseAPI.getInstance().getCache().get("mykey", MyData.class);
Example Integrations
Logging Integration
public class LoggingIntegration {
public void registerEvents() {
ShowcaseEvents.SHOWCASE_CREATED.register((sender, sourcePlayer, receivers, shareType, shareEntry, shareId, description, duration) -> {
// Log share creation to server logs
String message = String.format("Player %s created a %s share (ID: %s)",
sender.getName().getString(),
shareType.name().toLowerCase(),
shareId);
logShareActivity(message);
return ActionResult.PASS;
});
}
private void logShareActivity(String message) {
// Log to file or database
System.out.println("[Showcase] " + message);
}
}
Economy Integration
public class EconomyIntegration {
@EventHandler
public void onShareCreate(ShareCreateEvent event) {
ServerPlayerEntity player = event.getPlayer();
ShareType type = event.getType();
// Charge players for premium shares
if (type == ShareType.STATS) {
if (!hasBalance(player, 100)) {
event.setCancelled(true);
player.sendMessage(Text.literal("Insufficient funds!"));
} else {
withdrawMoney(player, 100);
}
}
}
}
Statistics Integration
public class StatsIntegration {
@EventHandler
public void onStatsCollect(StatsCollectEvent event) {
PlayerStats stats = event.getStats();
ServerPlayerEntity player = event.getPlayer();
// Add custom statistics
event.addCustomStat("Economy", "Balance", getBalance(player));
event.addCustomStat("Playtime", "Hours", getPlaytimeHours(player));
event.addCustomStat("Custom", "My Stat", getMyCustomStat(player));
}
}
Error Handling
Exception Types
// Showcase-specific exceptions
try {
ShareData share = api.createShare(player, type, duration, description);
} catch (ShareCreationException e) {
// Handle share creation failure
logger.error("Failed to create share: " + e.getMessage());
} catch (PermissionException e) {
// Handle permission issues
player.sendMessage(Text.literal("No permission!"));
} catch (RateLimitException e) {
// Handle rate limiting
player.sendMessage(Text.literal("Please wait before sharing again"));
}
Best Practices
- Always check permissions before API calls
- Handle exceptions gracefully with user-friendly messages
- Use async operations for expensive tasks
- Cache frequently accessed data
- Register event handlers properly to avoid memory leaks
- Validate input data before processing
Migration and Compatibility
Version Compatibility
// Check Showcase version
String version = ShowcaseAPI.getInstance().getVersion();
if (Version.parse(version).isOlderThan("2.3.0")) {
throw new UnsupportedOperationException("Showcase 2.3.0+ required");
}
API Deprecation
Monitor deprecation warnings and update code accordingly:
// Deprecated method (will be removed in 3.0)
@Deprecated(since = "2.3.0", forRemoval = true)
public void oldMethod() {
// Use newMethod() instead
}
Related Topics
- PlaceholderAPI - Placeholder integration details
- Events Reference - Complete event documentation
- Java API - Direct API integration
- Configuration - Configuration options