Aller au contenu principal

Examples

Complete Working Example

Here's a complete example of a feature-rich neuron:

public class ServerInfoNeuron extends BukkitNeuron {

private final Plugin plugin;
private final AtomicLong lastUpdate = new AtomicLong(0);

public ServerInfoNeuron(Plugin plugin) {
super(plugin, Namespace.of("server", "srv"));
this.plugin = plugin;
registerAllPlaceholders();
}

private void registerAllPlaceholders() {
// Static placeholders
register("name", () -> Bukkit.getServerName());
register("version", () -> Bukkit.getVersion());
register("bukkit_version", () -> Bukkit.getBukkitVersion());

// Dynamic placeholders with caching
register("online", () -> Bukkit.getOnlinePlayers().size(),
options -> {
options.cache(true);
options.cacheTTL(5, TimeUnit.SECONDS);
});

register("max_players", () -> Bukkit.getMaxPlayers());

// Contextual placeholders
register("player_world", context -> {
Player player = context.user().requirePlayer();
World world = player.getWorld();
return world != null ? world.getName() : "unknown";
});

register("tps", context -> {
// Simulate TPS calculation
return String.format("%.2f", 20.0);
}, options -> {
options.cache(true);
options.cacheTTL(10, TimeUnit.SECONDS);
});

// Placeholder with arguments - using method reference for cleaner code
register("world_info", this::getWorldInfo);
}

private Object getWorldInfo(Context<BukkitUser> context) {
String[] args = context.arguments();
if (args.length == 0) {
return "Specify: players, entities, or chunks";
}

Player player = context.user().requirePlayer();
World world = player.getWorld();
if (world == null) return "No world";

return switch (args[0].toLowerCase()) {
case "players" -> world.getPlayers().size();
case "entities" -> world.getEntities().size();
case "chunks" -> world.getLoadedChunks().length;
default -> "Invalid option: " + args[0];
};
}
}

This neuron provides placeholders like:

  • ${server.name}, ${srv.name} - Server name
  • ${server.online} - Online player count (cached)
  • ${server.player_world} - Current player's world
  • ${server.world_info:players} - Players in current world

Option Usage Examples

Performance Optimization Scenarios

public class OptimizedNeuron extends BukkitNeuron {

public OptimizedNeuron(Plugin plugin) {
super(plugin, Namespace.of("optimized"));

// Heavy calculation - run async with refresh
register("server_load", () -> {
// Simulate heavy CPU calculation
return String.format("%.1f%%", calculateCPUUsage());
}, options -> {
options.async(true); // Don't block main thread
options.refresh(true); // Keep value updated
options.delay(15, TimeUnit.SECONDS); // Update every 15s
});

// Database lookup - cache per user
register("user_data", context -> {
return queryUserDatabase(context.user().getUniqueId());
}, options -> {
options.cache(true); // Cache expensive DB query
options.cacheTTL(2, TimeUnit.MINUTES); // Refresh every 2 min
});

// API call with arguments - cache with TTL
register("external_data", context -> {
String endpoint = context.arguments().length > 0
? context.arguments()[0]
: "default";
return callExternalAPI(endpoint, context.user());
}, options -> {
options.cache(true); // Cache API responses
options.cacheTTL(1, TimeUnit.MINUTES); // Short TTL for API data
});

// Relationship calculation - expensive relational operation
registerRelational("player_similarity", context -> {
// Complex algorithm comparing two players
return calculateSimilarityScore(
context.user().getUniqueId(),
context.other().getUniqueId()
);
}, options -> {
options.cache(true); // Cache relationship calculations
options.cacheTTL(30, TimeUnit.MINUTES); // Long TTL for relationships
});
}
}

Choosing the Right Options

When to use async(true) (Static only):

  • Database operations
  • File I/O operations
  • Network requests
  • Heavy computations
  • Any operation that might block for >50ms

When to use cache(true):

  • Database lookups
  • API calls
  • Complex calculations
  • File reads
  • Any operation repeated frequently with same inputs

Cache TTL Guidelines:

  • Short TTL (1-5 minutes): Frequently changing data, API responses
  • Medium TTL (5-30 minutes): User stats, rankings, moderately dynamic data
  • Long TTL (30+ minutes): Relationships, permissions, rarely changing data

Refresh Guidelines (Static only):

  • High frequency (1-10 seconds): Server stats, online counts
  • Medium frequency (30-60 seconds): Resource usage, queue lengths
  • Low frequency (5+ minutes): Configuration values, external service status

This gives you fine-grained control over performance and ensures your placeholders scale well with your server's needs!