Java API Reference
Direct integration with Showcase's Java classes and methods
Java API Reference
MC 1.21.1MC 1.21.2MC 1.21.4MC 1.21.5MC 1.21.6
The Showcase Java API provides direct access to all mod functionality, allowing developers to create shares programmatically, manage player data, and integrate deeply with the mod's core systems.
Getting Started
Dependency Versions for MC 1.21.6
dependencies { minecraft "1.21.6" mappings "net.fabricmc:yarn:1.21.6+build.1:v2" modImplementation "net.fabricmc:fabric-loader:0.16.14" modImplementation "net.fabricmc.fabric-api:fabric-api:0.128.0+1.21.6" // Optional dependencies modImplementation "eu.pb4:placeholder-api:2.7.0+1.21.6" }
API Access
import com.showcase.api.ShowcaseAPI;
public class MyShowcaseIntegration {
public void initialize() {
// Get the API instance
ShowcaseAPI api = ShowcaseAPI.getInstance();
// Check if Showcase is available
if (api == null) {
throw new IllegalStateException("Showcase API not available");
}
// Verify API version compatibility
String version = api.getModVersion();
if (!isCompatibleVersion(version)) {
throw new IllegalStateException("Incompatible Showcase version: " + version);
}
}
}
Maven Dependency
For Minecraft 1.21.6Auto-generated
<dependency>
<groupId>maven.modrinth</groupId>
<artifactId>showcase</artifactId>
<version>2.3.1+mc1.21.6</version>
<scope>provided</scope>
</dependency>
Gradle Dependency
For Minecraft 1.21.6Auto-generated
dependencies {
minecraft "1.21.6"
mappings "net.fabricmc:yarn:1.21.6+build.1:v2"
modImplementation "net.fabricmc:fabric-loader:0.16.14"
modImplementation "net.fabricmc.fabric-api:fabric-api:0.128.0+1.21.6"
// Showcase mod
modImplementation "maven.modrinth:showcase:2.3.1+mc1.21.6"
// Optional dependencies
modImplementation "eu.pb4:placeholder-api:2.7.0+1.21.6"
}
Core API Classes
ShowcaseAPI - Main Entry Point
Working with Player Shares:
public class PlayerDataAPI {
public void getPlayerData(ServerPlayerEntity player) {
ShowcaseAPI api = ShowcaseAPI.getInstance();
ShowcaseManagerWrapper manager = api.getShowcaseManager();
String playerUuid = player.getUuidAsString();
// Get player's shares
List<ShareEntry> playerShares = api.getPlayerShares(playerUuid);
System.out.println("Player has " + playerShares.size() + " active shares");
// Check cooldown status for different share types
for (ShowcaseManager.ShareType type : ShowcaseManager.ShareType.values()) {
if (manager.isOnCooldown(player, type)) {
long remaining = manager.getRemainingCooldown(player, type);
System.out.println(type + " cooldown: " + remaining + " seconds");
}
}
// Display share details
for (ShareEntry share : playerShares) {
System.out.println("Share ID: " + share.getId());
System.out.println("Type: " + share.getType());
System.out.println("Created: " + new Date(share.getTimestamp()));
System.out.println("Duration: " + share.getDuration() + " seconds");
System.out.println("Views: " + share.getViewCount());
}
}
}
Configuration Access:
public class ConfigurationAPI {
public void accessConfiguration() {
ShowcaseAPI api = ShowcaseAPI.getInstance();
ModConfig config = api.getConfig();
// Access main configuration sections
System.out.println("Share link min expiry: " + config.shareLinkMinExpiry);
System.out.println("Share link max expiry: " + config.shareLinkMaxExpiry);
System.out.println("Chat keywords enabled: " + config.chatKeywordDetection);
// Access share settings for different types
ModConfig.ShareSettings itemSettings = config.shareSettings.get("item");
if (itemSettings != null) {
System.out.println("Item share cooldown: " + itemSettings.cooldown);
System.out.println("Item share default expiry: " + itemSettings.defaultExpiry);
}
// Check placeholder settings
if (config.placeholderSettings != null) {
System.out.println("Max shares per player: " + config.placeholderSettings.maxSharesPerPlayer);
System.out.println("Statistics tracking: " + config.placeholderSettings.enableStatisticsTracking);
}
}
}
</Tab>
<Tab value="Statistics">
**Event Handling**:
```java
public class EventHandling {
public void registerEventListeners() {
ShowcaseAPI api = ShowcaseAPI.getInstance();
// Listen for showcase creation events
api.onShowcaseCreated((sender, sourcePlayer, receivers, shareType, shareEntry, shareId, description, duration) -> {
System.out.println("Showcase created by " + sender.getName().getString());
System.out.println("Share ID: " + shareId);
System.out.println("Share Type: " + shareType);
// You can return ActionResult.FAIL to cancel the creation
// or ActionResult.SUCCESS/PASS to allow it
return ActionResult.PASS;
});
// Listen for showcase viewing events
api.onShowcaseViewed((viewer, shareEntry, shareId, originalOwner) -> {
System.out.println("Showcase viewed by " + viewer.getName().getString());
System.out.println("Original owner: " + originalOwner.getName().getString());
System.out.println("Share ID: " + shareId);
// You can return ActionResult.FAIL to prevent viewing
return ActionResult.PASS;
});
}
}
Version Information:
public class ModInformation {
public void getModInfo() {
ShowcaseAPI api = ShowcaseAPI.getInstance();
// Get mod version
String version = api.getModVersion();
System.out.println("Showcase mod version: " + version);
// Check if API is available
if (api != null) {
System.out.println("Showcase API is available");
}
}
}
Server Statistics:
public class ServerStatsAPI {
public void getServerStatistics() {
ShowcaseAPI api = ShowcaseAPI.getInstance();
// Get server-wide statistics
ServerStats stats = api.getServerStats();
System.out.println("Total active shares: " + stats.getActiveShareCount());
System.out.println("Total shares created: " + stats.getTotalSharesCreated());
System.out.println("Average response time: " + stats.getAverageResponseTime() + "ms");
System.out.println("Cache hit rate: " + stats.getCacheHitRate() + "%");
// Get performance metrics
PerformanceMetrics performance = stats.getPerformanceMetrics();
System.out.println("Memory usage: " + performance.getMemoryUsage() + "MB");
System.out.println("CPU usage: " + performance.getCpuUsage() + "%");
}
public void getUsageAnalytics(Duration period) {
ShowcaseAPI api = ShowcaseAPI.getInstance();
// Get analytics for specific time period
AnalyticsData analytics = api.getAnalytics(period);
Map<ShareType, Integer> sharesByType = analytics.getSharesByType();
Map<UUID, Integer> sharesByPlayer = analytics.getSharesByPlayer();
List<String> topSharedItems = analytics.getTopSharedItems();
System.out.println("Shares by type: " + sharesByType);
System.out.println("Top shared items: " + topSharedItems);
}
}
ShareData - Share Information
public class ShareDataUsage {
public void examineShareData(ShareData share) {
// Basic information
String id = share.getId();
ServerPlayerEntity creator = share.getCreator();
ShareType type = share.getType();
Instant createdAt = share.getCreatedAt();
Instant expiresAt = share.getExpiresAt();
String description = share.getDescription();
// Receiver information
Set<UUID> receivers = share.getReceivers();
boolean isPublic = share.isPublic(); // true if receivers is empty/contains @a
// Content access
switch (type) {
case ITEM:
ItemStack item = share.getItem();
System.out.println("Shared item: " + item.getName().getString());
break;
case INVENTORY:
case HOTBAR:
case ENDERCHEST:
ItemStack[] items = share.getItems();
System.out.println("Shared " + items.length + " items");
break;
case STATS:
PlayerStats stats = share.getStats();
System.out.println("Shared stats for: " + creator.getName());
break;
case CONTAINER:
ContainerData container = share.getContainer();
System.out.println("Container type: " + container.getType());
break;
}
// Utility methods
boolean expired = share.isExpired();
Duration timeRemaining = share.getTimeRemaining();
boolean canView = share.canView(somePlayer);
// View tracking
int viewCount = share.getViewCount();
List<UUID> viewers = share.getViewers();
Instant lastViewed = share.getLastViewedAt();
}
}
ShareType Enum
public class ShareTypeUsage {
public void workWithShareTypes() {
// All available share types
for (ShareType type : ShareType.values()) {
System.out.println("Type: " + type.name());
System.out.println("Permission: " + type.getPermissionNode());
System.out.println("Default duration: " + type.getDefaultDuration());
System.out.println("Requires container: " + type.requiresContainer());
}
// Type-specific operations
if (ShareType.ITEM.isItemBased()) {
System.out.println("Item type requires held item");
}
if (ShareType.CONTAINER.requiresContainer()) {
System.out.println("Container type requires recent container interaction");
}
// Permission checks
String itemPermission = ShareType.ITEM.getPermissionNode(); // "showcase.command.item"
String statsPermission = ShareType.STATS.getPermissionNode(); // "showcase.command.stats"
}
}
Async Operations
Async Share Creation
public class AsyncOperations {
public void createShareAsync(ServerPlayerEntity player) {
ShowcaseAPI api = ShowcaseAPI.getInstance();
// Create share asynchronously
CompletableFuture<ShareData> future = api.createShareAsync(
player,
ShareType.STATS,
Duration.ofMinutes(30),
"Async stats share"
);
future.thenAccept(share -> {
// Handle success on main thread
if (share != null) {
player.sendMessage(Text.literal("Stats share created: " + share.getId()));
} else {
player.sendMessage(Text.literal("Failed to create stats share"));
}
}).exceptionally(throwable -> {
// Handle errors
player.sendMessage(Text.literal("Error: " + throwable.getMessage()));
return null;
});
}
public void getStatsAsync(ServerPlayerEntity player) {
ShowcaseAPI api = ShowcaseAPI.getInstance();
CompletableFuture<PlayerStats> future = api.getPlayerStatsAsync(player);
future.thenAccept(stats -> {
// Process stats on main thread
displayStatsToPlayer(player, stats);
});
}
}
Batch Operations
public class BatchOperations {
public void batchCreateShares(List<ServerPlayerEntity> players) {
ShowcaseAPI api = ShowcaseAPI.getInstance();
List<CompletableFuture<ShareData>> futures = players.stream()
.map(player -> api.createShareAsync(player, ShareType.ITEM, Duration.ofMinutes(15), null))
.collect(Collectors.toList());
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
.thenRun(() -> {
System.out.println("All shares created successfully");
});
}
public void batchCancelShares(List<String> shareIds) {
ShowcaseAPI api = ShowcaseAPI.getInstance();
List<CompletableFuture<Boolean>> futures = shareIds.stream()
.map(api::cancelShareAsync)
.collect(Collectors.toList());
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
.thenRun(() -> {
System.out.println("Batch cancellation completed");
});
}
}
Custom Data Storage
Data Providers
public class CustomDataProvider implements DataProvider {
@Override
public void saveShare(ShareData share) {
// Custom storage implementation
try (Connection conn = getConnection()) {
PreparedStatement stmt = conn.prepareStatement(
"INSERT INTO shares (id, creator, type, data, expires_at) VALUES (?, ?, ?, ?, ?)"
);
stmt.setString(1, share.getId());
stmt.setString(2, share.getCreator().getUuidAsString());
stmt.setString(3, share.getType().name());
stmt.setString(4, serializeShareData(share));
stmt.setTimestamp(5, Timestamp.from(share.getExpiresAt()));
stmt.executeUpdate();
} catch (SQLException e) {
throw new DataStorageException("Failed to save share", e);
}
}
@Override
public Optional<ShareData> loadShare(String id) {
try (Connection conn = getConnection()) {
PreparedStatement stmt = conn.prepareStatement(
"SELECT * FROM shares WHERE id = ?"
);
stmt.setString(1, id);
ResultSet rs = stmt.executeQuery();
if (rs.next()) {
return Optional.of(deserializeShareData(rs));
}
} catch (SQLException e) {
throw new DataStorageException("Failed to load share", e);
}
return Optional.empty();
}
@Override
public List<ShareData> getPlayerShares(UUID playerId) {
// Implementation for loading player shares
return Collections.emptyList();
}
@Override
public void cleanup() {
// Remove expired shares
try (Connection conn = getConnection()) {
PreparedStatement stmt = conn.prepareStatement(
"DELETE FROM shares WHERE expires_at < ?"
);
stmt.setTimestamp(1, Timestamp.from(Instant.now()));
int deleted = stmt.executeUpdate();
System.out.println("Cleaned up " + deleted + " expired shares");
} catch (SQLException e) {
throw new DataStorageException("Failed to cleanup shares", e);
}
}
}
// Register the custom provider
ShowcaseAPI.getInstance().registerDataProvider(new CustomDataProvider());
Caching Integration
public class CacheIntegration {
public void useCaching() {
ShowcaseAPI api = ShowcaseAPI.getInstance();
CacheManager cache = api.getCacheManager();
// Store custom data in cache
cache.put("my-key", myData, Duration.ofMinutes(5));
// Retrieve cached data
Optional<MyData> cached = cache.get("my-key", MyData.class);
if (cached.isPresent()) {
System.out.println("Found cached data: " + cached.get());
}
// Compute if absent
MyData data = cache.computeIfAbsent("expensive-key", key -> {
return computeExpensiveData();
}, Duration.ofMinutes(10));
// Invalidate cache entries
cache.invalidate("my-key");
cache.invalidateAll();
}
}
Error Handling
Exception Types
public class ErrorHandling {
public void handleExceptions(ServerPlayerEntity player) {
ShowcaseAPI api = ShowcaseAPI.getInstance();
try {
ShareData share = api.createShare(
player,
ShareType.ITEM,
Duration.ofMinutes(30),
"Test share"
);
} catch (ShareCreationException e) {
// Handle share creation failure
switch (e.getErrorType()) {
case NO_ITEM_IN_HAND:
player.sendMessage(Text.literal("No item to share"));
break;
case PERMISSION_DENIED:
player.sendMessage(Text.literal("No permission to share"));
break;
case COOLDOWN_ACTIVE:
player.sendMessage(Text.literal("Please wait before sharing again"));
break;
case SHARE_LIMIT_REACHED:
player.sendMessage(Text.literal("Too many active shares"));
break;
case INVALID_DURATION:
player.sendMessage(Text.literal("Invalid share duration"));
break;
default:
player.sendMessage(Text.literal("Unknown error occurred"));
break;
}
} catch (PermissionException e) {
player.sendMessage(Text.literal("Permission error: " + e.getMessage()));
} catch (RateLimitException e) {
player.sendMessage(Text.literal("Rate limited: " + e.getMessage()));
} catch (ConfigurationException e) {
// Log configuration errors
System.err.println("Configuration error: " + e.getMessage());
}
}
}
Validation
public class ValidationHelpers {
public boolean validateShareCreation(ServerPlayerEntity player, ShareType type) {
ShowcaseAPI api = ShowcaseAPI.getInstance();
// Check basic permission
if (!api.hasPermission(player, type.getPermissionNode())) {
return false;
}
// Check cooldown
Duration cooldown = api.getCooldown(player, type);
if (!cooldown.isZero()) {
return false;
}
// Check share limit
List<ShareData> existing = api.getPlayerShares(player);
ShowcaseConfig config = api.getConfig();
if (existing.size() >= config.getMaxSharesPerPlayer()) {
return false;
}
// Type-specific validation
switch (type) {
case ITEM:
return player.getMainHandStack() != null && !player.getMainHandStack().isEmpty();
case STATS:
return config.isShareTypeEnabled(ShareType.STATS);
case CONTAINER:
return hasRecentContainerInteraction(player);
default:
return true;
}
}
}
Performance Optimization
Best Practices
public class PerformanceOptimization {
public void optimizedOperations() {
ShowcaseAPI api = ShowcaseAPI.getInstance();
// Use async operations for expensive tasks
CompletableFuture<PlayerStats> statsFuture = api.getPlayerStatsAsync(player);
// Batch operations when possible
List<String> shareIds = getShareIds();
api.batchCancelShares(shareIds);
// Cache frequently accessed data
CacheManager cache = api.getCacheManager();
PlayerStats stats = cache.computeIfAbsent("stats-" + player.getUuid(),
key -> api.getPlayerStats(player), Duration.ofMinutes(5));
// Use pagination for large datasets
List<ShareData> shares = api.getPlayerShares(player, 0, 10); // page 0, size 10
}
public void monitorPerformance() {
ShowcaseAPI api = ShowcaseAPI.getInstance();
PerformanceMonitor monitor = api.getPerformanceMonitor();
// Track operation timing
try (PerformanceTimer timer = monitor.startTimer("custom-operation")) {
// Your expensive operation here
performExpensiveOperation();
}
// Get performance metrics
PerformanceMetrics metrics = monitor.getMetrics();
System.out.println("Average operation time: " + metrics.getAverageTime("custom-operation"));
}
}
Integration Examples
Command Integration
public class CustomShowcaseCommand {
@Command("myshare")
@Permission("mymod.share")
public void myShareCommand(ServerPlayerEntity player,
@Argument("type") ShareType type,
@Argument("duration") @Optional Duration duration) {
ShowcaseAPI api = ShowcaseAPI.getInstance();
Duration shareDuration = duration != null ? duration : Duration.ofMinutes(30);
try {
ShareData share = api.createShare(player, type, shareDuration, "Custom share");
player.sendMessage(Text.literal("Custom share created: " + share.getId()));
} catch (ShareCreationException e) {
player.sendMessage(Text.literal("Failed to create share: " + e.getMessage()));
}
}
}
GUI Integration
public class ShowcaseGUI extends SimpleGui {
public ShowcaseGUI(ServerPlayerEntity player) {
super(ScreenHandlerType.GENERIC_9X6, player, false);
this.setTitle(Text.literal("My Shares"));
ShowcaseAPI api = ShowcaseAPI.getInstance();
List<ShareData> shares = api.getPlayerShares(player);
int slot = 0;
for (ShareData share : shares) {
ItemStack displayItem = createDisplayItem(share);
this.setSlot(slot++, displayItem, (type, action) -> {
// Handle click - open share or show details
openShareDetails(share);
});
}
}
private ItemStack createDisplayItem(ShareData share) {
ItemStack item = new ItemStack(Material.PAPER);
ItemMeta meta = item.getItemMeta();
meta.setDisplayName(Text.literal("§6Share: " + share.getType().name()));
meta.setLore(Arrays.asList(
Text.literal("§7Created: " + formatTime(share.getCreatedAt())),
Text.literal("§7Expires: " + formatTime(share.getExpiresAt())),
Text.literal("§7Views: " + share.getViewCount())
));
item.setItemMeta(meta);
return item;
}
}
Related Topics
- Events - Event system integration
- PlaceholderAPI - Placeholder integration
- Data API - Data storage and retrieval
- API Overview - Complete developer guide