diff --git a/best_practices.md b/best_practices.md new file mode 100644 index 0000000..d253d4e --- /dev/null +++ b/best_practices.md @@ -0,0 +1,174 @@ +# Best Practices for Developing Scripts with Spectra + +This guide outlines best practices for developing scripts using Spectra, a powerful scripting framework for Bukkit plugins. By following these guidelines, you can create efficient, maintainable, and robust scripts for your Minecraft server. + +## Performance Optimization + +1. **Minimize event listener usage:** + Only register event listeners when necessary, and remove them when they're no longer needed. Excessive event listeners can impact server performance. + + ```javascript + // Good practice: Remove event listener when it's no longer needed + const listener = (event) => { + // Handle event + removeEventListener("playerJoin", listener); + }; + addEventListener("playerJoin", listener); + ``` + +2. **Use efficient data structures:** + Choose appropriate data structures for your use case. For example, use Sets for unique collections and Maps for key-value pairs. + + ```javascript + // Good practice: Using a Set for unique player names + const uniquePlayers = new Set(); + ``` + +3. **Avoid blocking operations:** + Perform long-running or blocking operations asynchronously to prevent server lag. + + ```javascript + // Good practice: Using setTimeout for delayed execution + setTimeout(() => { + // Perform resource-intensive operation + }, 0); + ``` + +## Error Handling + +1. **Use try-catch blocks:** + Wrap potentially error-prone code in try-catch blocks to gracefully handle exceptions. + + ```javascript + try { + // Potentially error-prone code + } catch (error) { + console.error("An error occurred:", error.message); + } + ``` + +2. **Validate input:** + Always validate user input and function parameters to prevent unexpected behavior. + + ```javascript + function damagePlayer(player, amount) { + if (typeof amount !== "number" || amount < 0) { + throw new Error("Invalid damage amount"); + } + // Apply damage to player + } + ``` + +3. **Provide meaningful error messages:** + When throwing errors or logging issues, include descriptive messages to aid in debugging. + + ```javascript + if (!player.hasPermission("admin")) { + throw new Error("Player does not have admin permissions"); + } + ``` + +## Code Organization + +1. **Modularize your code:** + Split your script into smaller, reusable functions and modules for better maintainability. + + ```javascript + // economy.js + export function getBalance(player) { + // Implementation + } + + export function addMoney(player, amount) { + // Implementation + } + + // main.js + import { getBalance, addMoney } from "./economy.js"; + ``` + +2. **Use consistent naming conventions:** + Adopt a consistent naming style for variables, functions, and classes throughout your scripts. + + ```javascript + // Good practice: Consistent camelCase for functions and variables + function calculateTotalDamage(baseDamage, multiplier) { + const critChance = 0.1; + // Implementation + } + ``` + +3. **Comment your code:** + Add meaningful comments to explain complex logic or non-obvious behavior. + + ```javascript + // Calculate damage based on player's equipment and buffs + function calculateDamage(player) { + let baseDamage = player.getWeaponDamage(); + + // Apply strength buff if active + if (player.hasEffect("strength")) { + baseDamage *= 1.5; + } + + // Reduce damage if player is weakened + if (player.hasEffect("weakness")) { + baseDamage *= 0.8; + } + + return baseDamage; + } + ``` + +## Example of a Well-Structured Script + +Here's an example of a well-structured script that incorporates the best practices mentioned above: + +```javascript +// playerUtils.js +export function isPlayerAdmin(player) { + return player.hasPermission("admin"); +} + +export function giveWelcomeKit(player) { + // Implementation +} + +// main.js +import { isPlayerAdmin, giveWelcomeKit } from "./playerUtils.js"; + +const WELCOME_MESSAGE = "Welcome to the server!"; + +function onPlayerJoin(event) { + const player = event.getPlayer(); + + try { + console.log(`Player ${player.getName()} joined the server`); + + player.sendMessage(WELCOME_MESSAGE); + + if (isPlayerAdmin(player)) { + player.sendMessage("You have admin privileges"); + } + + // Delay welcome kit to avoid overwhelming new players + setTimeout(() => { + giveWelcomeKit(player); + }, 5000); + } catch (error) { + console.error(`Error handling player join: ${error.message}`); + } +} + +addEventListener("playerJoin", onPlayerJoin); + +export function onEnable() { + console.log("Script enabled successfully"); +} + +export function onDisable() { + console.log("Script disabled"); +} +``` + +By following these best practices and structuring your scripts well, you'll create more efficient, maintainable, and robust code for your Spectra-powered Bukkit plugins. \ No newline at end of file diff --git a/configuration_guide.md b/configuration_guide.md new file mode 100644 index 0000000..f28dc04 --- /dev/null +++ b/configuration_guide.md @@ -0,0 +1,118 @@ +--- +title: Spectra Configuration Guide +description: Learn how to configure Spectra, including server settings, Java options, and plugin-specific configurations. +--- + +# Spectra Configuration Guide + +This guide provides detailed information on how to configure Spectra, including server settings, Java options, and plugin-specific configurations. We'll explain the purpose of each configuration option and provide examples to help you set up your Spectra environment. + +## Table of Contents + +1. [Configuration File](#configuration-file) +2. [Configuration Options](#configuration-options) + - [Build Options](#build-options) + - [Server Options](#server-options) + - [Java Options](#java-options) + - [JAR Options](#jar-options) +3. [Examples](#examples) + +## Configuration File + +Spectra uses a configuration file to define various settings for your Minecraft server. By default, Spectra looks for a configuration file named `spectra.config.mjs` or `spectra.config.js` in the current working directory. + +To create a configuration file, use the `defineConfig` function provided by Spectra: + +```javascript +import { defineConfig } from 'spectra-sdk'; + +export default defineConfig({ + // Your configuration options here +}); +``` + +## Configuration Options + +The Spectra configuration object supports the following options: + +### Build Options + +- `build`: (Optional) An object containing esbuild options for building your Spectra plugins. + +### Server Options + +- `server`: (Optional) An object containing server-specific options: + - `eula`: (Boolean, default: `false`) Set to `true` to accept the [Minecraft EULA](https://aka.ms/MinecraftEULA). You must accept the EULA before running a server. + - `dir`: (String, default: `".minecraft"`) The directory where the server files will be stored. + - `type`: (String, default: `"spigot"`) The type of Minecraft server to use. Available options are `"spigot"`, `"paper"`, or `"purpur"`. + - `version`: (String, optional) The Minecraft server version to use. If not specified, the latest version will be used. + +### Java Options + +- `server.java`: (Optional) An object containing Java-specific options: + - `path`: (String, default: `"java"`) The path to the Java executable. + - `args`: (Array of strings, default: `["-Xmx2G", "-Xms2G"]`) Arguments to pass to the Java executable. + +### JAR Options + +- `server.jar`: (Optional) An object containing JAR-specific options: + - `path`: (String, optional) The path to a custom server JAR file. If provided, this will be used instead of downloading a server JAR based on the `type` and `version` options. + - `args`: (Array of strings, default: `["nogui"]`) Arguments to pass to the server JAR. + +## Examples + +Here are some example configurations to help you get started: + +### Basic Configuration + +```javascript +import { defineConfig } from 'spectra-sdk'; + +export default defineConfig({ + server: { + eula: true, + type: 'paper', + version: '1.19.4', + }, +}); +``` + +This configuration sets up a Paper server running version 1.19.4 with the EULA accepted. + +### Advanced Configuration + +```javascript +import { defineConfig } from 'spectra-sdk'; + +export default defineConfig({ + build: { + entryPoints: ['src/index.ts'], + outfile: 'dist/plugin.js', + }, + server: { + eula: true, + dir: 'my-server', + type: 'purpur', + version: '1.20', + java: { + path: '/usr/bin/java', + args: ['-Xmx4G', '-Xms2G'], + }, + jar: { + args: ['nogui', 'max-players=50'], + }, + }, +}); +``` + +This advanced configuration: + +1. Sets up build options for a Spectra plugin. +2. Creates a Purpur server running version 1.20. +3. Specifies a custom server directory. +4. Uses a specific Java executable with custom memory allocation. +5. Passes additional arguments to the server JAR. + +Remember to adjust these configurations based on your specific needs and server requirements. + +By using the Spectra configuration system, you can easily customize your Minecraft server environment and ensure consistent settings across your development and production setups. \ No newline at end of file diff --git a/getting_started.md b/getting_started.md new file mode 100644 index 0000000..3a4dff2 --- /dev/null +++ b/getting_started.md @@ -0,0 +1,117 @@ +--- +title: Getting Started with Spectra +description: A comprehensive guide to installing, configuring, and using Spectra for Minecraft server scripting +--- + +# Getting Started with Spectra + +Welcome to Spectra, a powerful scripting framework for Minecraft servers. This guide will walk you through the process of setting up Spectra, configuring your environment, and creating your first script. + +## Table of Contents +1. [Installation](#installation) +2. [Configuration](#configuration) +3. [Creating Your First Script](#creating-your-first-script) +4. [Common Use Cases](#common-use-cases) + +## Installation + +To get started with Spectra, follow these steps: + +1. Ensure you have a compatible Minecraft server (Spigot, Paper, or Purpur) installed. +2. Download the latest version of Spectra from the official repository. +3. Place the Spectra JAR file in your server's `plugins` directory. +4. Restart your Minecraft server. + +## Configuration + +Spectra uses a configuration file to customize its behavior. Create a file named `spectra.config.js` or `spectra.config.mjs` in your server's root directory. + +Here's a basic configuration example: + +```javascript +import { defineConfig } from 'spectra-sdk'; + +export default defineConfig({ + server: { + eula: true, + dir: '.minecraft', + type: 'paper', + version: '1.19.4', + java: { + path: 'java', + args: ['-Xmx4G', '-Xms2G'] + } + } +}); +``` + +Adjust the configuration options to match your server setup. For more details on available options, refer to the `Config` interface in the `apps/spectra-sdk/src/lib/config.ts` file. + +## Creating Your First Script + +Spectra allows you to write scripts using JavaScript. Here's how to create your first script: + +1. Create a new file with a `.js` extension in your server's `plugins/Spectra/scripts` directory. +2. Open the file in your preferred text editor. +3. Add the following code to create a basic "Hello, World!" script: + +```javascript +export function onEnable() { + console.log("Hello, World! My first Spectra script is running!"); +} + +export function onDisable() { + console.log("Goodbye! My first Spectra script is shutting down."); +} + +addEventListener("PlayerJoinEvent", (event) => { + const player = event.getPlayer(); + player.sendMessage("Welcome to the server!"); +}); +``` + +4. Save the file and restart your Minecraft server or use the `/scripts reload` command in-game. + +This script demonstrates the basic structure of a Spectra script, including `onEnable` and `onDisable` functions, and an event listener for when a player joins the server. + +## Common Use Cases + +Here are some common use cases and examples to help you get started with Spectra: + +### Adding a Custom Command + +```javascript +addCommand("greet", (sender, args) => { + const playerName = args[0] || sender.getName(); + sender.sendMessage(`Hello, ${playerName}!`); +}); +``` + +### Scheduling Tasks + +```javascript +// Run a task every 5 minutes (6000 ticks) +const intervalId = setInterval(() => { + console.log("This message appears every 5 minutes"); +}, 6000); + +// Run a task after a 10-second delay +setTimeout(() => { + console.log("This message appears after 10 seconds"); +}, 200); +``` + +### Listening for Multiple Events + +```javascript +const eventHandler = (event) => { + console.log(`${event.getEventName()} occurred!`); +}; + +addEventListener("BlockBreakEvent", eventHandler); +addEventListener("BlockPlaceEvent", eventHandler); +``` + +Remember to check the Spectra API documentation for a full list of available functions and events you can use in your scripts. + +With this guide, you should now be ready to start developing powerful scripts for your Minecraft server using Spectra. Happy scripting! \ No newline at end of file diff --git a/scripting_api_reference.md b/scripting_api_reference.md new file mode 100644 index 0000000..048d156 --- /dev/null +++ b/scripting_api_reference.md @@ -0,0 +1,208 @@ +# Spectra Scripting API Reference + +This document provides a comprehensive reference for the Spectra scripting API, including methods for event listening, command creation, and task scheduling. + +## Table of Contents + +1. [Event Listening](#event-listening) +2. [Command Creation](#command-creation) +3. [Task Scheduling](#task-scheduling) + +## Event Listening + +The Spectra scripting API allows you to listen for and respond to Bukkit events in your scripts. + +### addEventListener + +Adds an event listener for a specific Bukkit event. + +```javascript +addEventListener(eventClass, callback, [priority]) +``` + +- `eventClass`: The Bukkit event class to listen for (e.g., `org.bukkit.event.player.PlayerJoinEvent`) +- `callback`: A function that will be called when the event occurs +- `priority` (optional): The event priority (default: `NORMAL`) + +Example: + +```javascript +addEventListener(org.bukkit.event.player.PlayerJoinEvent, (event) => { + const player = event.getPlayer(); + player.sendMessage("Welcome to the server!"); +}); +``` + +### removeEventListener + +Removes a previously added event listener. + +```javascript +removeEventListener(listener) +``` + +- `listener`: The listener object returned by `addEventListener` + +Example: + +```javascript +const listener = addEventListener(org.bukkit.event.player.PlayerQuitEvent, (event) => { + console.log(`${event.getPlayer().getName()} left the server`); +}); + +// Later, when you want to remove the listener +removeEventListener(listener); +``` + +## Command Creation + +Spectra allows you to create custom commands that players can use in-game. + +### addCommand + +Adds a new command to the server. + +```javascript +addCommand(options, executor, [tabCompleter]) +``` + +- `options`: An object or string containing command properties + - If a string, it represents the command name + - If an object, it can include: + - `name`: The command name (required) + - `permission`: The permission required to use the command + - `aliases`: An array of alternative command names + - `description`: A description of the command + - `usage`: Usage instructions for the command +- `executor`: A function that executes when the command is run +- `tabCompleter` (optional): A function that provides tab completion suggestions + +Example: + +```javascript +addCommand({ + name: "greet", + permission: "myserver.greet", + description: "Greet a player", + usage: "/greet " +}, (sender, command, label, args) => { + if (args.length < 1) { + sender.sendMessage("Please specify a player name."); + return false; + } + const targetPlayer = Bukkit.getPlayer(args[0]); + if (targetPlayer) { + targetPlayer.sendMessage(`${sender.getName()} says hello!`); + sender.sendMessage(`You greeted ${targetPlayer.getName()}.`); + } else { + sender.sendMessage("Player not found."); + } + return true; +}, (sender, command, alias, args) => { + if (args.length == 1) { + return Bukkit.getOnlinePlayers().map(player => player.getName()); + } + return []; +}); +``` + +### removeCommand + +Removes a previously added command. + +```javascript +removeCommand(command) +``` + +- `command`: The command object returned by `addCommand` + +Example: + +```javascript +const greetCommand = addCommand("greet", (sender, command, label, args) => { + // Command logic here +}); + +// Later, when you want to remove the command +removeCommand(greetCommand); +``` + +## Task Scheduling + +Spectra provides methods for scheduling tasks to run at specified intervals or after a delay. + +### setInterval + +Schedules a task to run repeatedly at fixed time intervals. + +```javascript +setInterval(callback, delay) +``` + +- `callback`: The function to be executed at each interval +- `delay`: The time in milliseconds between each execution + +Example: + +```javascript +const intervalId = setInterval(() => { + Bukkit.broadcastMessage("This message is sent every 5 minutes."); +}, 5 * 60 * 1000); +``` + +### clearInterval + +Stops a previously scheduled interval task. + +```javascript +clearInterval(intervalId) +``` + +- `intervalId`: The identifier returned by `setInterval` + +Example: + +```javascript +clearInterval(intervalId); +``` + +### setTimeout + +Schedules a task to run once after a specified delay. + +```javascript +setTimeout(callback, delay) +``` + +- `callback`: The function to be executed after the delay +- `delay`: The time in milliseconds to wait before executing the callback + +Example: + +```javascript +setTimeout(() => { + Bukkit.broadcastMessage("This message is sent 10 seconds after the script starts."); +}, 10 * 1000); +``` + +### clearTimeout + +Cancels a previously scheduled timeout task. + +```javascript +clearTimeout(timeoutId) +``` + +- `timeoutId`: The identifier returned by `setTimeout` + +Example: + +```javascript +const timeoutId = setTimeout(() => { + // This will never run +}, 5000); + +clearTimeout(timeoutId); +``` + +By using these API methods, you can create powerful and interactive scripts for your Bukkit server using Spectra. Remember to handle errors appropriately and consider performance implications when using these features in your scripts. \ No newline at end of file diff --git a/troubleshooting_guide.md b/troubleshooting_guide.md new file mode 100644 index 0000000..0f0e3f4 --- /dev/null +++ b/troubleshooting_guide.md @@ -0,0 +1,113 @@ +# Troubleshooting Guide + +This guide will help you diagnose and resolve common issues you might encounter when using Spectra. We'll cover script loading problems, configuration errors, and performance issues. + +## Script Loading Problems + +### Scripts Not Being Detected + +If your scripts are not being detected by Spectra: + +1. Ensure your scripts are in the correct directory: `/scripts/` +2. Check that your script files have the correct extension: `.js` or `.mjs` +3. Verify that the `ScriptManager` is enabled in the Spectra configuration + +If the issue persists: + +```java +// Check if ScriptManager is null +if (scriptManager == null) { + getLogger().severe("ScriptManager is not initialized"); + return; +} + +// Log the number of detected scripts +getLogger().info("Detected scripts: " + scriptManager.getScripts().size()); +``` + +### Script Syntax Errors + +If a script fails to load due to syntax errors: + +1. Check the server console for error messages +2. Review the script for any syntax issues +3. Test the script in a JavaScript runtime outside of Spectra to isolate the problem + +## Configuration Errors + +### Plugin Not Loading + +If the Spectra plugin isn't loading: + +1. Ensure the plugin JAR file is in the server's `plugins` folder +2. Check the server startup logs for any Spectra-related error messages +3. Verify that the plugin is compatible with your server version + +### ScriptPluginLoader Issues + +If you're experiencing problems with `ScriptPluginLoader`: + +1. Make sure Spectra is properly registered in the server's `plugin.yml` +2. Check if the `ScriptPluginLoader` is being registered correctly: + +```java +PluginManager pluginManager = getServer().getPluginManager(); +pluginManager.registerInterface(ScriptPluginLoader.class); +``` + +3. Verify that Spectra plugins are being detected: + +```java +int totalPlugins = pluginLoader == null ? 0 : pluginLoader.getPlugins().size(); +getLogger().info("Loaded " + totalPlugins + " Spectra plugins"); +``` + +## Performance Issues + +### High CPU Usage + +If you're experiencing high CPU usage: + +1. Check which scripts are currently running using the `/scripts list` command +2. Review your scripts for infinite loops or heavy computations +3. Consider using async operations for time-consuming tasks: + +```javascript +// Example of using async operations +Bukkit.getScheduler().runTaskAsynchronously(plugin, () => { + // Perform heavy computation here + // Use Bukkit.getScheduler().runTask() to run code on the main thread when needed +}); +``` + +### Memory Leaks + +To identify and resolve memory leaks: + +1. Use a profiling tool like VisualVM to monitor memory usage +2. Check for scripts that create large data structures without proper cleanup +3. Ensure that event listeners are properly unregistered when scripts are disabled: + +```javascript +// Example of proper event listener cleanup +const listener = (event) => { + // Event handling code +}; + +plugin.registerEvent("PlayerJoinEvent", listener); + +// Cleanup when the script is disabled +plugin.on("disable", () => { + HandlerList.unregisterAll(listener); +}); +``` + +## Advanced Troubleshooting + +For more complex issues: + +1. Enable debug logging in Spectra's configuration +2. Review the `plugins/Spectra/logs` directory for detailed log files +3. Use the `/scripts reload` command to reload scripts without restarting the server + +If you continue to experience issues after trying these troubleshooting steps, please report the problem on our GitHub issue tracker, providing as much detail as possible about your setup and the steps to reproduce the issue. \ No newline at end of file