Skip to content
Turretedash7 edited this page Oct 11, 2025 · 2 revisions

πŸ”Œ BlockRevive API

BlockRevive provides a comprehensive API for developers to integrate with the block regeneration system. This allows you to create custom plugins that interact with regeneration regions, control block regeneration, and listen to custom events.


πŸ“¦ Adding BlockRevive to Your Project

Maven

Add this to your pom.xml:

<dependencies>
    <dependency>
        <groupId>com.blockregen</groupId>
        <artifactId>BlockRevive</artifactId>
        <version>1.0.0</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

Gradle

Add this to your build.gradle:

dependencies {
    compileOnly 'com.blockregen:BlockRevive:1.0.0'
}

Plugin Dependency

Add BlockRevive as a dependency in your plugin.yml:

depend: [BlockRevive]
# or for soft dependency:
softdepend: [BlockRevive]

πŸš€ Getting Started

Accessing the API

import com.blockrevive.api.BlockReviveAPI;

public class MyPlugin extends JavaPlugin {
    
    private BlockReviveAPI blockReviveAPI;
    
    @Override
    public void onEnable() {
        // Get the API instance
        blockReviveAPI = BlockReviveAPI.getInstance();
        
        if (blockReviveAPI == null) {
            getLogger().severe("BlockRevive API not available!");
            getServer().getPluginManager().disablePlugin(this);
            return;
        }
        
        getLogger().info("Hooked into BlockRevive API v" + blockReviveAPI.getAPIVersion());
    }
}

πŸ“– API Methods

Region Management

Get a Region by Name

Optional<RegenerationRegion> region = api.getRegion("mining_area");
if (region.isPresent()) {
    player.sendMessage("Found region: " + region.get().getName());
}

Get All Regions

Collection<RegenerationRegion> regions = api.getAllRegions();
for (RegenerationRegion region : regions) {
    getLogger().info("Region: " + region.getName());
}

Get Region at Location

Location location = player.getLocation();
Optional<RegenerationRegion> region = api.getRegionAt(location);
if (region.isPresent()) {
    player.sendMessage("You are in: " + region.get().getName());
}

Create a New Region

Location pos1 = new Location(world, 100, 64, 100);
Location pos2 = new Location(world, 150, 80, 150);

if (api.createRegion("my_custom_region", pos1, pos2)) {
    player.sendMessage("Region created successfully!");
}

Remove a Region

if (api.removeRegion("old_region")) {
    player.sendMessage("Region removed!");
}

Check if Location is in Any Region

if (api.isInRegion(block.getLocation())) {
    player.sendMessage("This block is in a regeneration region!");
}

Block Regeneration Control

Schedule Block Regeneration

Block block = location.getBlock();
BlockData originalData = block.getBlockData();

// Save the original data, turn block to bedrock, and schedule regeneration
api.scheduleBlockRegeneration(block, originalData);

Cancel Block Regeneration

api.cancelBlockRegeneration(location);
player.sendMessage("Regeneration cancelled!");

Check if Block is Regenerating

if (api.isBlockRegenerating(location)) {
    player.sendMessage("This block is currently regenerating!");
}

Get Remaining Time

long remainingMillis = api.getRegenerationTimeRemaining(location);
if (remainingMillis > 0) {
    long seconds = remainingMillis / 1000;
    player.sendMessage("Block will regenerate in " + seconds + " seconds");
} else {
    player.sendMessage("Block is not regenerating");
}

Force Regenerate Immediately

if (api.forceRegenerate(location)) {
    player.sendMessage("Block regenerated immediately!");
} else {
    player.sendMessage("Block was not regenerating");
}

Region Groups

Get a Group

Optional<RegionGroup> group = api.getGroup("mining_zones");
if (group.isPresent()) {
    player.sendMessage("Group has " + group.get().getRegionCount() + " regions");
}

Get All Groups

Collection<RegionGroup> groups = api.getAllGroups();
for (RegionGroup group : groups) {
    getLogger().info("Group: " + group.getName());
}

Create a New Group

if (api.createGroup("new_group")) {
    player.sendMessage("Group created!");
}

Delete a Group

if (api.deleteGroup("old_group")) {
    player.sendMessage("Group deleted!");
}

Database πŸ†•

BlockRevive supports MySQL database storage for improved performance and scalability. Use these methods to check database status and adapt your plugin's behavior accordingly.

Check if Database is Enabled

if (api.isDatabaseEnabled()) {
    player.sendMessage("Β§aBlockRevive is using database storage!");
} else {
    player.sendMessage("Β§eBlockRevive is using YAML file storage");
}

Get Database Type

String dbType = api.getDatabaseType();
if (dbType.equals("MySQL")) {
    getLogger().info("Connected to MySQL database");
} else if (dbType.equals("None")) {
    getLogger().info("Database is disabled");
}

Check if Database is Enabled in Config

// Useful for detecting connection issues
if (api.isDatabaseEnabledInConfig() && !api.isDatabaseEnabled()) {
    getLogger().warning("Database is configured but not connected!");
    getLogger().warning("Check database credentials and connection");
} else if (api.isDatabaseEnabled()) {
    getLogger().info("Database is active: " + api.getDatabaseType());
}

Complete Database Status Check

public void checkDatabaseStatus(CommandSender sender) {
    boolean enabledInConfig = api.isDatabaseEnabledInConfig();
    boolean connected = api.isDatabaseEnabled();
    String type = api.getDatabaseType();
    
    sender.sendMessage("Β§e=== Database Status ===");
    sender.sendMessage("Β§7Enabled in Config: Β§f" + enabledInConfig);
    sender.sendMessage("Β§7Connected: Β§f" + connected);
    sender.sendMessage("Β§7Type: Β§f" + type);
    
    if (enabledInConfig && !connected) {
        sender.sendMessage("§c⚠ Database connection failed!");
        sender.sendMessage("Β§7Check server logs for details");
    } else if (connected) {
        sender.sendMessage("Β§aβœ“ Database is operational");
    } else {
        sender.sendMessage("Β§7Using file-based storage");
    }
}

Working with RegenerationRegion Objects

Once you have a RegenerationRegion object, you can access various properties:

RegenerationRegion region = api.getRegion("mining_area").orElse(null);
if (region != null) {
    // Basic info
    String name = region.getName();
    UUID worldUuid = region.getWorldUuid();
    int blockCount = region.getBlockCount();
    
    // Check if location is in region
    boolean contains = region.contains(someLocation);
    
    // Pause/unpause regeneration
    region.setPaused(true);   // Stop all regeneration in this region
    region.setPaused(false);  // Resume regeneration
    boolean isPaused = region.isPaused();
    
    // Permission requirements
    boolean requiresPermission = region.requiresPermission();
    region.setRequiresPermission(true);  // Require permission to mine
    
    // Block type information
    Map<String, Integer> blockCounts = region.getBlockTypeCounts();
    Set<String> nexoBlocks = region.getNexoBlockIds();
    int nexoBlockCount = region.getNexoBlockCount();
    
    // Hologram settings
    Location holoLoc = region.getHologramLocation();
    String title = region.getHologramTitle();
}

Utility Methods

Reload Configuration

api.reload();
getLogger().info("BlockRevive configuration reloaded!");

Check Feature Availability

if (api.isFaweEnabled()) {
    getLogger().info("WorldEdit/FAWE schematics available!");
}

if (api.isNexoEnabled()) {
    getLogger().info("Nexo custom blocks supported!");
}

if (api.isDatabaseEnabled()) {
    getLogger().info("MySQL database storage active!");
}

Get API Version

String version = api.getAPIVersion();
getLogger().info("BlockRevive API version: " + version);

🎯 Custom Events

BlockRevive fires custom events that you can listen to in your plugin.

BlockRegenerationEvent

Called when a block is about to regenerate. Cancellable.

import com.blockrevive.api.events.BlockRegenerationEvent;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;

public class MyListener implements Listener {
    
    @EventHandler
    public void onBlockRegenerate(BlockRegenerationEvent event) {
        Block block = event.getBlock();
        BlockData originalData = event.getOriginalBlockData();
        RegenerationRegion region = event.getRegion();
        
        // Cancel regeneration
        if (someCondition) {
            event.setCancelled(true);
        }
        
        // Add effects when block regenerates
        block.getWorld().strikeLightningEffect(block.getLocation());
        
        // Send message to nearby players
        for (Player nearby : block.getLocation().getNearbyPlayers(10)) {
            nearby.sendMessage("A block regenerated nearby!");
        }
    }
}

RegionBlockBreakEvent

Called when a player breaks a block in a regeneration region (before regeneration is scheduled). Cancellable.

import com.blockrevive.api.events.RegionBlockBreakEvent;

@EventHandler
public void onRegionBlockBreak(RegionBlockBreakEvent event) {
    Player player = event.getPlayer();
    Block block = event.getBlock();
    RegenerationRegion region = event.getRegion();
    
    // Cancel the event to prevent regeneration
    if (!player.hasPermission("custom.permission")) {
        event.setCancelled(true);
        player.sendMessage("You don't have permission to mine here!");
        return;
    }
    
    // Give bonus rewards in specific regions
    if (region.getName().equalsIgnoreCase("bonus_mine")) {
        player.getInventory().addItem(new ItemStack(Material.DIAMOND, 5));
        player.sendMessage("Β§6Bonus diamonds awarded!");
    }
    
    // Track statistics
    incrementPlayerMiningStats(player, region.getName());
}

RegionCreateEvent

Called when a new regeneration region is created. Cancellable.

import com.blockrevive.api.events.RegionCreateEvent;

@EventHandler
public void onRegionCreate(RegionCreateEvent event) {
    RegenerationRegion region = event.getRegion();
    Player creator = event.getCreator();  // May be null if created via API/console
    
    // Prevent regions that are too large
    if (region.getBlockCount() > 100000) {
        event.setCancelled(true);
        if (creator != null) {
            creator.sendMessage("Β§cRegion is too large! Maximum 100,000 blocks.");
        }
        return;
    }
    
    // Log to database or file
    getLogger().info("New region created: " + region.getName() + 
                    " with " + region.getBlockCount() + " blocks");
    
    // Announce to staff
    if (creator != null) {
        for (Player staff : Bukkit.getOnlinePlayers()) {
            if (staff.hasPermission("blockrevive.notify")) {
                staff.sendMessage("Β§e" + creator.getName() + " created region: " + region.getName());
            }
        }
    }
}

RegionDeleteEvent

Called when a regeneration region is deleted. Cancellable.

import com.blockrevive.api.events.RegionDeleteEvent;

@EventHandler
public void onRegionDelete(RegionDeleteEvent event) {
    RegenerationRegion region = event.getRegion();
    Player deleter = event.getDeleter();  // May be null if deleted via API/console
    
    // Prevent deletion of protected regions
    if (region.getName().equals("spawn_mining")) {
        event.setCancelled(true);
        if (deleter != null) {
            deleter.sendMessage("Β§cThis region is protected and cannot be deleted!");
        }
        return;
    }
    
    // Cleanup custom data
    cleanupDatabase(region.getName());
    
    getLogger().info("Region deleted: " + region.getName());
}

πŸ’‘ Complete Example Plugin

Here's a complete example showing various API features:

package com.example.blockreviveaddon;

import com.blockrevive.api.BlockReviveAPI;
import com.blockrevive.api.events.BlockRegenerationEvent;
import com.blockrevive.api.events.RegionBlockBreakEvent;
import com.blockrevive.model.RegenerationRegion;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.java.JavaPlugin;

import java.util.Optional;

public class BlockReviveAddon extends JavaPlugin implements Listener {
    
    private BlockReviveAPI api;
    
    @Override
    public void onEnable() {
        // Get API instance
        api = BlockReviveAPI.getInstance();
        
        if (api == null) {
            getLogger().severe("BlockRevive API not found! Disabling...");
            getServer().getPluginManager().disablePlugin(this);
            return;
        }
        
        // Register events
        getServer().getPluginManager().registerEvents(this, this);
        
        // Log database status
        if (api.isDatabaseEnabled()) {
            getLogger().info("BlockRevive is using " + api.getDatabaseType() + " database");
        } else {
            getLogger().info("BlockRevive is using file-based storage");
        }
        
        getLogger().info("Successfully hooked into BlockRevive API v" + api.getAPIVersion());
    }
    
    @Override
    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
        if (!(sender instanceof Player)) {
            sender.sendMessage("Players only!");
            return true;
        }
        
        Player player = (Player) sender;
        
        if (command.getName().equalsIgnoreCase("regeninfo")) {
            Location loc = player.getTargetBlock(null, 5).getLocation();
            
            if (api.isBlockRegenerating(loc)) {
                long timeLeft = api.getRegenerationTimeRemaining(loc);
                player.sendMessage("Β§aBlock will regenerate in " + (timeLeft / 1000) + " seconds");
            } else {
                player.sendMessage("Β§cThis block is not regenerating");
            }
            
            return true;
        }
        
        if (command.getName().equalsIgnoreCase("regioninfo")) {
            Optional<RegenerationRegion> region = api.getRegionAt(player.getLocation());
            
            if (region.isPresent()) {
                RegenerationRegion r = region.get();
                player.sendMessage("Β§e=== Region Info ===");
                player.sendMessage("Β§7Name: Β§f" + r.getName());
                player.sendMessage("Β§7Blocks: Β§f" + r.getBlockCount());
                player.sendMessage("Β§7Paused: Β§f" + r.isPaused());
                player.sendMessage("Β§7Requires Permission: Β§f" + r.requiresPermission());
            } else {
                player.sendMessage("Β§cYou are not in a regeneration region");
            }
            
            return true;
        }
        
        if (command.getName().equalsIgnoreCase("blockrevive") && args.length > 0 && args[0].equalsIgnoreCase("database")) {
            // NEW: Show database status
            player.sendMessage("Β§e=== Database Status ===");
            player.sendMessage("Β§7Type: Β§f" + api.getDatabaseType());
            player.sendMessage("Β§7Enabled: Β§f" + api.isDatabaseEnabled());
            
            if (api.isDatabaseEnabledInConfig() && !api.isDatabaseEnabled()) {
                player.sendMessage("§c⚠ Database connection failed!");
            }
            
            return true;
        }
        
        return false;
    }
    
    @EventHandler
    public void onRegionBlockBreak(RegionBlockBreakEvent event) {
        Player player = event.getPlayer();
        RegenerationRegion region = event.getRegion();
        
        // Give bonus rewards in VIP mine
        if (region.getName().equalsIgnoreCase("vip_mine")) {
            if (player.hasPermission("mine.vip")) {
                // 10% chance for bonus diamonds
                if (Math.random() < 0.1) {
                    player.getInventory().addItem(new ItemStack(Material.DIAMOND, 3));
                    player.sendMessage("§b§l✦ §6Bonus diamonds from VIP mine!");
                }
            }
        }
        
        // Track mining statistics
        player.sendActionBar("Β§7Mined in region: Β§e" + region.getName());
    }
    
    @EventHandler
    public void onBlockRegenerate(BlockRegenerationEvent event) {
        // Add particle effects when blocks regenerate
        Location loc = event.getBlock().getLocation();
        loc.getWorld().spawnParticle(org.bukkit.Particle.VILLAGER_HAPPY, 
                                     loc.add(0.5, 0.5, 0.5), 20, 0.3, 0.3, 0.3, 0);
        
        // Play sound to nearby players
        for (Player nearby : loc.getNearbyPlayers(15)) {
            nearby.playSound(loc, org.bukkit.Sound.BLOCK_AMETHYST_BLOCK_CHIME, 0.5f, 1.2f);
        }
    }
}

βš™οΈ Best Practices

1. Always Check for Null

The API instance may be null if BlockRevive is not loaded or disabled.

BlockReviveAPI api = BlockReviveAPI.getInstance();
if (api == null) {
    // Handle gracefully
    return;
}

2. Use Optional Patterns

Many methods return Optional<> to handle cases where entities don't exist.

api.getRegion("mining").ifPresent(region -> {
    // Do something with region
});

3. Listen to Events

Use BlockRevive's custom events instead of checking manually when possible.

@EventHandler
public void onBlockRegenerate(BlockRegenerationEvent event) {
    // React to regeneration
}

4. Respect Cancellations

If you cancel an event, be aware of the implications on the regeneration system.

@EventHandler
public void onRegionBlockBreak(RegionBlockBreakEvent event) {
    if (shouldPreventMining(event.getPlayer())) {
        event.setCancelled(true);  // Block won't turn to bedrock or regenerate
    }
}

5. Handle Async Carefully

The API is designed for synchronous use on the main server thread. If you need to use it from async tasks, schedule sync tasks:

Bukkit.getScheduler().runTask(plugin, () -> {
    api.forceRegenerate(location);
});

6. Check Database Status πŸ†•

If your plugin needs to know about storage backend, check database status:

if (api.isDatabaseEnabled()) {
    // Database is available - maybe use your own MySQL connection
    // or adjust caching strategy
} else {
    // File-based storage - be aware of potential I/O delays
}

πŸ“š API Reference

BlockReviveAPI Methods

Method Return Type Description
getInstance() BlockReviveAPI Get the API instance (static)
getPlugin() BlockRevivePlugin Get the plugin instance
getAPIVersion() String Get the API version

Region Management

Method Return Type Description
getRegion(String) Optional<RegenerationRegion> Get region by name
getAllRegions() Collection<RegenerationRegion> Get all regions
getRegionAt(Location) Optional<RegenerationRegion> Get region at location
createRegion(String, Location, Location) boolean Create a new region
removeRegion(String) boolean Remove a region
isInRegion(Location) boolean Check if location is in any region

Block Regeneration

Method Return Type Description
scheduleBlockRegeneration(Block, BlockData) void Schedule a block to regenerate
cancelBlockRegeneration(Location) void Cancel block regeneration
isBlockRegenerating(Location) boolean Check if block is regenerating
getRegenerationTimeRemaining(Location) long Get time until regeneration (ms)
forceRegenerate(Location) boolean Force immediate regeneration

Region Groups

Method Return Type Description
getGroup(String) Optional<RegionGroup> Get group by name
getAllGroups() Collection<RegionGroup> Get all groups
createGroup(String) boolean Create a new group
deleteGroup(String) boolean Delete a group

Database πŸ†•

Method Return Type Description
isDatabaseEnabled() boolean Check if database is enabled and connected
getDatabaseType() String Get database type ("MySQL" or "None")
isDatabaseEnabledInConfig() boolean Check if database is configured (regardless of connection)

Utilities

Method Return Type Description
reload() void Reload configuration
isFaweEnabled() boolean Check if FAWE is available
isNexoEnabled() boolean Check if Nexo is available

πŸ”— Useful Links


πŸ’¬ Support

Need help? Join our Discord.


Last Updated: October 11, 2025 | API Version: 1.0.0

Clone this wiki locally