Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 29 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ The core interface defining the identity and lifecycle of an extension.

**Methods:**

- `checkLicense(String url, String token)`: Optional method to verify the extension license. Automatically loads from `plugins/{main jar}/extensions/{ext name}/config.yml`. Returns `true` by default.

- `onLoad(JavaPlugin plugin, Executor executor)`: Triggered when the extension is loaded. Use this to register listeners or initialize logic.

- `onDisable(JavaPlugin plugin, Executor executor)`: Triggered when the extension is disabled. Use this to clean up resources.
Expand Down Expand Up @@ -54,9 +56,35 @@ public class MyExtension implements IMCExtension {
public void onDisable(JavaPlugin plugin, Executor executor) {
plugin.getLogger().info("MyExtension is shutting down.");
}

@Override
public boolean checkUpdate(String url, String token) {
// Optional: Implement your update logic here
// Return true if an update is found
return false;
}

@Override
public boolean checkLicense(String url, String token) {
// Optional: Implement license verification
// If this method returns false, the extension will not load
return token != null && !token.isEmpty();
}
}
```

### ⚙️ Configuration

For extensions that require license verification, the `MCExtensionManager` automatically looks for a configuration file at: `plugins/{HostPlugin}/extensions/{ExtensionName}/config.yml`

**Example `config.yml` structure:**

```yaml
license:
url: "https://api.yourdomain.com/verify"
token: "YOUR-LICENSE-KEY-HERE"
```

**2. Managing Extensions**

Use the `MCExtensionManager` in your main plugin to handle the loading process.
Expand Down Expand Up @@ -142,4 +170,4 @@ extension:

## 🔗 Resources

- **Example Project:** [Example Extension](https://github.com/MCEngine/extension)
- **Example Project:** [Example Extension](https://github.com/MCEngine/mcextension-example)
3 changes: 2 additions & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ git-org-repository=mcextension

# --- Artifact Identity ---
project-version=2026.0.2
project-iteration=6
project-iteration=7
project-group=io.github.mcengine
project-artifact-id=mcextension
project-artifact-name=MCExtension
project-artifact-description=This project is a library designed to allow Minecraft plugins to load their own extensions.
project-artifact-url=https://mcengine.github.io/mcextension-website


14 changes: 14 additions & 0 deletions src/main/java/io/github/mcengine/mcextension/api/IMCExtension.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,18 @@ default void onDisable(JavaPlugin plugin, Executor executor) {}
default boolean checkUpdate(String url, String token) {
return false;
}

/**
* Checks the license for this extension.
* <p>
* By default, this returns true to accommodate extensions sold via platforms
* without built-in license verification code.
* </p>
* * @param url The license server URL.
* @param token The license token or key.
* @return true if the license is valid or if no check is required; false otherwise.
*/
default boolean checkLicense(String url, String token) {
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import io.github.mcengine.mcextension.api.IMCExtension;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.java.JavaPlugin;
import org.yaml.snakeyaml.Yaml;

Expand Down Expand Up @@ -246,6 +247,22 @@ private LoadResult loadExtension(File jarFile) throws IOException, ReflectiveOpe
if (loadedExtensionsInfo.containsKey(id)) return LoadResult.FAILED;

IMCExtension extension = (IMCExtension) clazz.getDeclaredConstructor().newInstance();

// 5. License Check (loads from plugins/{main jar}/extensions/{extension name}/config.yml)
File extConfigPath = new File(extensionFolder, id + File.separator + "config.yml");
String licenseUrl = "";
String licenseToken = "";

if (extConfigPath.exists()) {
YamlConfiguration config = YamlConfiguration.loadConfiguration(extConfigPath);
licenseUrl = config.getString("license.url", "");
licenseToken = config.getString("license.token", "");
}

if (!extension.checkLicense(licenseUrl, licenseToken)) {
plugin.getLogger().severe("Extension " + id + " failed license verification! Skipping load.");
return LoadResult.FAILED;
}

try {
extension.onLoad(plugin, executor);
Expand Down