Skip to content

Separate the API away from the plugin #125

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
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
35 changes: 35 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,38 @@
For information about this Spigot/Bukkit API, go to https://www.spigotmc.org/resources/noteblockapi.19287/

Dev builds are available at [Jenkins](http://ci.haprosgames.com/job/NoteBlockAPI/ "Jenkins")

#### Maven Dependency
```xml
<repository>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repository>
<dependencies>
<dependency>
<groupId>com.xxmicloxx</groupId>
<artifactId>NoteBlockAPI</artifactId>
<version>1.6.5-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
```
#### Gradle Dependency
```groovy
repositories {
maven {
url 'https://jitpack.io/'
}
}

dependencies {
compileOnly "com.xxmicloxx:NoteBlockAPI:1.6.5-SNAPSHOT"
}
```

You can also shade the API into your existing plugin and initialize it using
```java
NoteBlockAPI.initializeAPI(this)
```
Comment on lines +38 to +41
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I personally wouldn't mind this, but strictly speaking it would be a violation of the LGPL license chosen by the original author of the NoteBlockAPI. If you shade the library and use a relocation (which you should always do in this case), then it is no longer possible to replace it with a modified version unless your plugin is open source, because Java has no mechanism that would allow that. I suggest to remove this part of the README or to mention the fact that plugins that shade the API have to be open source.

2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<groupId>com.xxmicloxx</groupId>
<artifactId>NoteBlockAPI</artifactId>
<version>1.6.4-SNAPSHOT</version>
<version>1.6.5-SNAPSHOT</version>
<name>NoteBlockAPI</name>

<properties>
Expand Down
153 changes: 82 additions & 71 deletions src/main/java/com/xxmicloxx/NoteBlockAPI/NoteBlockAPI.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.xxmicloxx.NoteBlockAPI;

import com.xxmicloxx.NoteBlockAPI.songplayer.SongPlayer;
import com.xxmicloxx.NoteBlockAPI.utils.MathUtils;
import com.xxmicloxx.NoteBlockAPI.utils.Updater;
import org.bstats.bukkit.Metrics;
import org.bstats.charts.DrilldownPie;
Expand All @@ -11,7 +10,6 @@
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.RegisteredListener;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitTask;
import org.bukkit.scheduler.BukkitWorker;

import java.io.IOException;
Expand All @@ -23,9 +21,10 @@
/**
* Main class; contains methods for playing and adjusting songs for players
*/
public class NoteBlockAPI extends JavaPlugin {
public class NoteBlockAPI {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, there are plugins that rely on the fact that NoteBlockAPI class is JavaPlugin. Therefore, this would be a breaking change.


private static NoteBlockAPI plugin;
private static NoteBlockAPI instance;
private static Plugin plugin;

private Map<UUID, ArrayList<SongPlayer>> playingSongs = new ConcurrentHashMap<UUID, ArrayList<SongPlayer>>();
private Map<UUID, Byte> playerVolume = new ConcurrentHashMap<UUID, Byte>();
Expand All @@ -49,7 +48,7 @@ public static boolean isReceivingSong(Player player) {
* @return is receiving a song
*/
public static boolean isReceivingSong(UUID uuid) {
ArrayList<SongPlayer> songs = plugin.playingSongs.get(uuid);
ArrayList<SongPlayer> songs = instance.playingSongs.get(uuid);
return (songs != null && !songs.isEmpty());
}

Expand All @@ -66,7 +65,7 @@ public static void stopPlaying(Player player) {
* @param uuid
*/
public static void stopPlaying(UUID uuid) {
ArrayList<SongPlayer> songs = plugin.playingSongs.get(uuid);
ArrayList<SongPlayer> songs = instance.playingSongs.get(uuid);
if (songs == null) {
return;
}
Expand All @@ -90,7 +89,7 @@ public static void setPlayerVolume(Player player, byte volume) {
* @param volume
*/
public static void setPlayerVolume(UUID uuid, byte volume) {
plugin.playerVolume.put(uuid, volume);
instance.playerVolume.put(uuid, volume);
}

/**
Expand All @@ -108,10 +107,10 @@ public static byte getPlayerVolume(Player player) {
* @return volume (byte)
*/
public static byte getPlayerVolume(UUID uuid) {
Byte byteObj = plugin.playerVolume.get(uuid);
Byte byteObj = instance.playerVolume.get(uuid);
if (byteObj == null) {
byteObj = 100;
plugin.playerVolume.put(uuid, byteObj);
instance.playerVolume.put(uuid, byteObj);
}
return byteObj;
}
Expand All @@ -121,90 +120,94 @@ public static ArrayList<SongPlayer> getSongPlayersByPlayer(Player player){
}

public static ArrayList<SongPlayer> getSongPlayersByPlayer(UUID player){
return plugin.playingSongs.get(player);
return instance.playingSongs.get(player);
}

public static void setSongPlayersByPlayer(Player player, ArrayList<SongPlayer> songs){
setSongPlayersByPlayer(player.getUniqueId(), songs);
}

public static void setSongPlayersByPlayer(UUID player, ArrayList<SongPlayer> songs){
plugin.playingSongs.put(player, songs);
instance.playingSongs.put(player, songs);
}

@Override
public void onEnable() {
plugin = this;

for (Plugin pl : getServer().getPluginManager().getPlugins()){
/**
* Initialize the API. Useful for shading this plugin into another plugin.
* @param plugin Parent plugin that you're initializing via
*/
public void initAPI(JavaPlugin plugin) {
instance = this;
NoteBlockAPI.plugin = plugin;

for (Plugin pl : plugin.getServer().getPluginManager().getPlugins()){
if (pl.getDescription().getDepend().contains("NoteBlockAPI") || pl.getDescription().getSoftDepend().contains("NoteBlockAPI")){
dependentPlugins.put(pl, false);
}
}

Metrics metrics = new Metrics(this, 1083);



Metrics metrics = new Metrics(plugin, 1083);

new NoteBlockPlayerMain().onEnable();
getServer().getScheduler().runTaskLater(this, new Runnable() {

plugin.getServer().getScheduler().runTaskLater(plugin, new Runnable() {

@Override
public void run() {
Plugin[] plugins = getServer().getPluginManager().getPlugins();
Type[] types = new Type[]{PlayerRangeStateChangeEvent.class, SongDestroyingEvent.class, SongEndEvent.class, SongStoppedEvent.class };
for (Plugin plugin : plugins) {
ArrayList<RegisteredListener> rls = HandlerList.getRegisteredListeners(plugin);
for (RegisteredListener rl : rls) {
Method[] methods = rl.getListener().getClass().getDeclaredMethods();
for (Method m : methods) {
Type[] params = m.getParameterTypes();
param:
for (Type paramType : params) {
for (Type type : types){
if (paramType.equals(type)) {
dependentPlugins.put(plugin, true);
break param;
}
}
}
}
Plugin[] plugins = plugin.getServer().getPluginManager().getPlugins();
Type[] types = new Type[]{PlayerRangeStateChangeEvent.class, SongDestroyingEvent.class, SongEndEvent.class, SongStoppedEvent.class };
for (Plugin plugin : plugins) {
ArrayList<RegisteredListener> rls = HandlerList.getRegisteredListeners(plugin);
for (RegisteredListener rl : rls) {
Method[] methods = rl.getListener().getClass().getDeclaredMethods();
for (Method m : methods) {
Type[] params = m.getParameterTypes();
param:
for (Type paramType : params) {
for (Type type : types){
if (paramType.equals(type)) {
dependentPlugins.put(plugin, true);
break param;
}
}
}
}

}
}
metrics.addCustomChart(new DrilldownPie("deprecated", () -> {
Map<String, Map<String, Integer>> map = new HashMap<>();
for (Plugin pl : dependentPlugins.keySet()){
String deprecated = dependentPlugins.get(pl) ? "yes" : "no";
Map<String, Integer> entry = new HashMap<>();
entry.put(pl.getDescription().getFullName(), 1);
map.put(deprecated, entry);
}
return map;
}));
}
}

metrics.addCustomChart(new DrilldownPie("deprecated", () -> {
Map<String, Map<String, Integer>> map = new HashMap<>();
for (Plugin pl : dependentPlugins.keySet()){
String deprecated = dependentPlugins.get(pl) ? "yes" : "no";
Map<String, Integer> entry = new HashMap<>();
entry.put(pl.getDescription().getFullName(), 1);
map.put(deprecated, entry);
}
return map;
}));
}
}, 1);

getServer().getScheduler().runTaskTimerAsynchronously(this, new Runnable() {

@Override
public void run() {
try {
if (Updater.checkUpdate("19287", getDescription().getVersion())){
Bukkit.getLogger().info(String.format("[%s] New update available!", plugin.getDescription().getName()));

if (plugin instanceof NoteBlockPlugin) {
plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, new Runnable() {

@Override
public void run() {
try {
if (Updater.checkUpdate("19287", plugin.getDescription().getVersion())){
Bukkit.getLogger().info(String.format("[%s] New update available!", plugin.getDescription().getName()));
}
} catch (IOException e) {
Bukkit.getLogger().info(String.format("[%s] Cannot receive update from Spigot resource page!", plugin.getDescription().getName()));
}
} catch (IOException e) {
Bukkit.getLogger().info(String.format("[%s] Cannot receive update from Spigot resource page!", plugin.getDescription().getName()));
}
}
}, 20*10, 20 * 60 * 60 * 24);
}, 20*10, 20 * 60 * 60 * 24);
}
}

@Override
public void onDisable() {
public void onDisable(Plugin plugin) {
disabling = true;
Bukkit.getScheduler().cancelTasks(this);
Bukkit.getScheduler().cancelTasks(plugin);
List<BukkitWorker> workers = Bukkit.getScheduler().getActiveWorkers();
for (BukkitWorker worker : workers){
if (!worker.getOwner().equals(this))
Expand All @@ -215,18 +218,22 @@ public void onDisable() {
}

public void doSync(Runnable runnable) {
getServer().getScheduler().runTask(this, runnable);
plugin.getServer().getScheduler().runTask(plugin, runnable);
}

public void doAsync(Runnable runnable) {
getServer().getScheduler().runTaskAsynchronously(this, runnable);
plugin.getServer().getScheduler().runTaskAsynchronously(plugin, runnable);
}

public boolean isDisabling() {
return disabling;
}

public static NoteBlockAPI getAPI(){
return instance;
}

public static Plugin getPlugin(){
return plugin;
}

Expand Down Expand Up @@ -266,5 +273,9 @@ protected void handleDeprecated(StackTraceElement[] ste){
dependentPlugins.put(plugins.get(0), true);
}
}

public static void initializeAPI(JavaPlugin plugin) {
new NoteBlockAPI().initAPI(plugin);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,11 @@ public void onDisable() {
}

public void doSync(Runnable runnable) {
Bukkit.getServer().getScheduler().runTask(NoteBlockAPI.getAPI(), runnable);
Bukkit.getServer().getScheduler().runTask(NoteBlockAPI.getPlugin(), runnable);
}

public void doAsync(Runnable runnable) {
Bukkit.getServer().getScheduler().runTaskAsynchronously(NoteBlockAPI.getAPI(), runnable);
Bukkit.getServer().getScheduler().runTaskAsynchronously(NoteBlockAPI.getPlugin(), runnable);
}

public boolean isDisabling() {
Expand Down
25 changes: 25 additions & 0 deletions src/main/java/com/xxmicloxx/NoteBlockAPI/NoteBlockPlugin.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.xxmicloxx.NoteBlockAPI;

import org.bukkit.event.EventHandler;
import org.bukkit.plugin.java.JavaPlugin;

public class NoteBlockPlugin extends JavaPlugin {

private static NoteBlockAPI api;
public static NoteBlockAPI getAPI() {
return api;
}

@EventHandler
public void onEnable() {
api = new NoteBlockAPI();
api.initAPI(this);
}

@EventHandler
public void onDisable() {
api.onDisable(this);
}


}