-
Notifications
You must be signed in to change notification settings - Fork 0
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.
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>
Add this to your build.gradle
:
dependencies {
compileOnly 'com.blockregen:BlockRevive:1.0.0'
}
Add BlockRevive as a dependency in your plugin.yml
:
depend: [BlockRevive]
# or for soft dependency:
softdepend: [BlockRevive]
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());
}
}
Optional<RegenerationRegion> region = api.getRegion("mining_area");
if (region.isPresent()) {
player.sendMessage("Found region: " + region.get().getName());
}
Collection<RegenerationRegion> regions = api.getAllRegions();
for (RegenerationRegion region : regions) {
getLogger().info("Region: " + region.getName());
}
Location location = player.getLocation();
Optional<RegenerationRegion> region = api.getRegionAt(location);
if (region.isPresent()) {
player.sendMessage("You are in: " + region.get().getName());
}
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!");
}
if (api.removeRegion("old_region")) {
player.sendMessage("Region removed!");
}
if (api.isInRegion(block.getLocation())) {
player.sendMessage("This block is in a regeneration region!");
}
Block block = location.getBlock();
BlockData originalData = block.getBlockData();
// Save the original data, turn block to bedrock, and schedule regeneration
api.scheduleBlockRegeneration(block, originalData);
api.cancelBlockRegeneration(location);
player.sendMessage("Regeneration cancelled!");
if (api.isBlockRegenerating(location)) {
player.sendMessage("This block is currently regenerating!");
}
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");
}
if (api.forceRegenerate(location)) {
player.sendMessage("Block regenerated immediately!");
} else {
player.sendMessage("Block was not regenerating");
}
Optional<RegionGroup> group = api.getGroup("mining_zones");
if (group.isPresent()) {
player.sendMessage("Group has " + group.get().getRegionCount() + " regions");
}
Collection<RegionGroup> groups = api.getAllGroups();
for (RegionGroup group : groups) {
getLogger().info("Group: " + group.getName());
}
if (api.createGroup("new_group")) {
player.sendMessage("Group created!");
}
if (api.deleteGroup("old_group")) {
player.sendMessage("Group deleted!");
}
BlockRevive supports MySQL database storage for improved performance and scalability. Use these methods to check database status and adapt your plugin's behavior accordingly.
if (api.isDatabaseEnabled()) {
player.sendMessage("Β§aBlockRevive is using database storage!");
} else {
player.sendMessage("Β§eBlockRevive is using YAML file storage");
}
String dbType = api.getDatabaseType();
if (dbType.equals("MySQL")) {
getLogger().info("Connected to MySQL database");
} else if (dbType.equals("None")) {
getLogger().info("Database is disabled");
}
// 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());
}
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");
}
}
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();
}
api.reload();
getLogger().info("BlockRevive configuration reloaded!");
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!");
}
String version = api.getAPIVersion();
getLogger().info("BlockRevive API version: " + version);
BlockRevive fires custom events that you can listen to in your plugin.
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!");
}
}
}
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());
}
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());
}
}
}
}
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());
}
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);
}
}
}
The API instance may be null if BlockRevive is not loaded or disabled.
BlockReviveAPI api = BlockReviveAPI.getInstance();
if (api == null) {
// Handle gracefully
return;
}
Many methods return Optional<>
to handle cases where entities don't exist.
api.getRegion("mining").ifPresent(region -> {
// Do something with region
});
Use BlockRevive's custom events instead of checking manually when possible.
@EventHandler
public void onBlockRegenerate(BlockRegenerationEvent event) {
// React to regeneration
}
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
}
}
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);
});
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
}
Method | Return Type | Description |
---|---|---|
getInstance() |
BlockReviveAPI |
Get the API instance (static) |
getPlugin() |
BlockRevivePlugin |
Get the plugin instance |
getAPIVersion() |
String |
Get the API version |
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 |
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 |
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 |
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) |
Method | Return Type | Description |
---|---|---|
reload() |
void |
Reload configuration |
isFaweEnabled() |
boolean |
Check if FAWE is available |
isNexoEnabled() |
boolean |
Check if Nexo is available |
Need help? Join our Discord.
Last Updated: October 11, 2025 | API Version: 1.0.0