Skip to content

Commit a22414f

Browse files
author
david
committed
added Capability api
1 parent 4c6c369 commit a22414f

File tree

11 files changed

+289
-14
lines changed

11 files changed

+289
-14
lines changed

plugin/src/main/java/net/thenextlvl/services/ServicePlugin.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,30 @@
1010
import net.thenextlvl.services.api.permission.GroupController;
1111
import net.thenextlvl.services.capability.PaperCapabilityController;
1212
import net.thenextlvl.services.chat.PaperChatController;
13+
import org.bukkit.plugin.Plugin;
1314
import org.bukkit.plugin.ServicePriority;
1415
import org.bukkit.plugin.java.JavaPlugin;
1516

17+
import java.util.HashMap;
18+
import java.util.Map;
1619
import java.util.Objects;
1720

1821
@Getter
1922
@Accessors(fluent = true)
2023
public class ServicePlugin extends JavaPlugin implements ServiceProvider {
21-
private final CapabilityController capabilityController = new PaperCapabilityController();
24+
private final Map<Plugin, CapabilityController> capabilityControllers = new HashMap<>();
2225

2326
@Override
2427
public void onLoad() {
2528
getServer().getServicesManager().register(ServiceProvider.class, this, this, ServicePriority.Highest);
2629
}
2730

31+
@Override
32+
public CapabilityController capabilityController(Plugin plugin) {
33+
return capabilityControllers().computeIfAbsent(plugin, owner ->
34+
new PaperCapabilityController(owner, this));
35+
}
36+
2837
@Override
2938
public ChatController chatController() {
3039
return Objects.requireNonNullElseGet(
@@ -43,6 +52,9 @@ public EconomyController economyController() {
4352

4453
@Override
4554
public GroupController groupController() {
46-
return null;
55+
return Preconditions.checkNotNull(
56+
getServer().getServicesManager().load(GroupController.class),
57+
"No GroupController available"
58+
);
4759
}
4860
}
Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,20 @@
11
package net.thenextlvl.services.capability;
22

3-
import net.thenextlvl.services.api.capability.Capability;
3+
import lombok.Getter;
4+
import lombok.RequiredArgsConstructor;
5+
import lombok.experimental.Accessors;
6+
import net.thenextlvl.services.api.ServiceProvider;
47
import net.thenextlvl.services.api.capability.CapabilityController;
8+
import org.bukkit.plugin.Plugin;
59

10+
@Getter
11+
@RequiredArgsConstructor
12+
@Accessors(fluent = true)
613
public class PaperCapabilityController implements CapabilityController {
7-
@Override
8-
public <C, I extends C> C registerCapability(String plugin, Capability<C, I> capability) {
9-
return null;
10-
}
14+
private final PaperCapabilityLoader loader = new PaperCapabilityLoader(this);
15+
private final PaperCapabilityRegistry registry = new PaperCapabilityRegistry(this);
16+
17+
private final Plugin owner;
18+
19+
private final ServiceProvider provider;
1120
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package net.thenextlvl.services.capability;
2+
3+
import lombok.RequiredArgsConstructor;
4+
import net.thenextlvl.services.api.capability.Capability;
5+
import net.thenextlvl.services.api.capability.CapabilityController;
6+
import net.thenextlvl.services.api.capability.CapabilityLoader;
7+
import org.bukkit.plugin.Plugin;
8+
9+
import java.util.HashSet;
10+
import java.util.Set;
11+
12+
@RequiredArgsConstructor
13+
public class PaperCapabilityLoader implements CapabilityLoader {
14+
private final Set<Capability> capabilities = new HashSet<>();
15+
private final CapabilityController controller;
16+
17+
@Override
18+
public void disableCapabilities(Plugin plugin) {
19+
controller.registry().capabilities(plugin)
20+
.forEach(this::disableCapability);
21+
}
22+
23+
@Override
24+
public void disableCapability(Capability capability) {
25+
try {
26+
capability.disable(controller);
27+
controller.owner().getComponentLogger().info(
28+
"Successfully unhooked from {}",
29+
capability.getPlugin().getName()
30+
);
31+
} catch (Exception e) {
32+
controller.owner().getComponentLogger().error(
33+
"Failed to unhook from {}",
34+
capability.getPlugin().getName(), e
35+
);
36+
}
37+
}
38+
39+
@Override
40+
public void enableCapabilities(Plugin plugin) {
41+
controller.registry().capabilityConstructors(plugin).forEach(constructor ->
42+
enableCapability(constructor.construct(controller.provider(), plugin)));
43+
}
44+
45+
@Override
46+
public void enableCapability(Capability capability) {
47+
try {
48+
capability.enable(controller);
49+
controller.owner().getComponentLogger().info(
50+
"Successfully hooked into {}",
51+
capability.getPlugin().getName()
52+
);
53+
} catch (Exception e) {
54+
controller.owner().getComponentLogger().error(
55+
"Failed to hook into {}",
56+
capability.getPlugin().getName(), e
57+
);
58+
}
59+
}
60+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package net.thenextlvl.services.capability;
2+
3+
import com.google.common.base.Preconditions;
4+
import lombok.RequiredArgsConstructor;
5+
import net.thenextlvl.services.api.capability.Capability;
6+
import net.thenextlvl.services.api.capability.CapabilityConstructor;
7+
import net.thenextlvl.services.api.capability.CapabilityController;
8+
import net.thenextlvl.services.api.capability.CapabilityRegistry;
9+
import org.bukkit.Bukkit;
10+
import org.bukkit.plugin.Plugin;
11+
12+
import java.util.Arrays;
13+
import java.util.HashSet;
14+
import java.util.Set;
15+
import java.util.stream.Collectors;
16+
17+
@RequiredArgsConstructor
18+
public class PaperCapabilityRegistry implements CapabilityRegistry {
19+
private final Set<CapabilityConstructor<?>> capabilityConstructors = new HashSet<>();
20+
private final Set<Capability> capabilities = new HashSet<>();
21+
private final CapabilityController controller;
22+
23+
@Override
24+
public boolean isRegistered(CapabilityConstructor<?> constructor) {
25+
return capabilityConstructors.contains(constructor);
26+
}
27+
28+
@Override
29+
public boolean isRegistered(Capability capability) {
30+
return capabilities.contains(capability);
31+
}
32+
33+
@Override
34+
public void registerCapability(CapabilityConstructor<?> constructor) {
35+
Preconditions.checkState(capabilityConstructors.add(constructor),
36+
"Capability constructor is already registered");
37+
Arrays.stream(Bukkit.getPluginManager().getPlugins())
38+
.filter(Plugin::isEnabled)
39+
.filter(constructor::isCapable)
40+
.map(plugin -> constructor.construct(controller.provider(), plugin))
41+
.forEach(capability -> controller.loader().enableCapability(capability));
42+
}
43+
44+
@Override
45+
public void unregisterCapability(Capability capability) {
46+
Preconditions.checkState(capabilities.remove(capability),
47+
"Capability is not registered");
48+
controller.loader().disableCapability(capability);
49+
}
50+
51+
@Override
52+
public void unregisterCapability(CapabilityConstructor<?> constructor) {
53+
Preconditions.checkState(capabilityConstructors.remove(constructor),
54+
"Capability constructor is not registered");
55+
}
56+
57+
@Override
58+
public Set<Capability> capabilities() {
59+
return Set.copyOf(capabilities);
60+
}
61+
62+
@Override
63+
public Set<Capability> capabilities(Plugin plugin) {
64+
return capabilities.stream()
65+
.filter(capability -> plugin.equals(capability.getPlugin()))
66+
.collect(Collectors.toUnmodifiableSet());
67+
}
68+
69+
@Override
70+
public Set<CapabilityConstructor<?>> capabilityConstructors() {
71+
return Set.copyOf(capabilityConstructors);
72+
}
73+
74+
@Override
75+
public Set<CapabilityConstructor<?>> capabilityConstructors(Plugin plugin) {
76+
return capabilityConstructors().stream()
77+
.filter(constructor -> constructor.isCapable(plugin))
78+
.collect(Collectors.toSet());
79+
}
80+
81+
@Override
82+
public void unregisterCapabilities() {
83+
capabilities().forEach(this::unregisterCapability);
84+
}
85+
86+
@Override
87+
public void unregisterCapabilities(Plugin plugin) {
88+
capabilities(plugin).forEach(this::unregisterCapability);
89+
}
90+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package net.thenextlvl.services.listener;
2+
3+
import lombok.RequiredArgsConstructor;
4+
import net.thenextlvl.services.ServicePlugin;
5+
import org.bukkit.event.EventHandler;
6+
import org.bukkit.event.EventPriority;
7+
import org.bukkit.event.Listener;
8+
import org.bukkit.event.server.PluginDisableEvent;
9+
import org.bukkit.event.server.PluginEnableEvent;
10+
11+
@RequiredArgsConstructor
12+
public class PluginListener implements Listener {
13+
private final ServicePlugin plugin;
14+
15+
@EventHandler(priority = EventPriority.LOWEST)
16+
public void onPluginEnable(PluginEnableEvent event) {
17+
plugin.capabilityControllers().values().forEach(controller ->
18+
controller.loader().enableCapabilities(event.getPlugin()));
19+
}
20+
21+
@EventHandler(priority = EventPriority.LOWEST)
22+
public void onPluginEnable(PluginDisableEvent event) {
23+
plugin.capabilityControllers().values().forEach(controller ->
24+
controller.loader().disableCapabilities(event.getPlugin()));
25+
}
26+
}

src/main/java/net/thenextlvl/services/api/ServiceProvider.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,20 @@
44
import net.thenextlvl.services.api.chat.ChatController;
55
import net.thenextlvl.services.api.economy.EconomyController;
66
import net.thenextlvl.services.api.permission.GroupController;
7+
import org.bukkit.plugin.Plugin;
78

89
/**
9-
* The ServiceProvider interface provides methods to retrieve instances of different controllers.
10+
* This class provides methods for retrieving instances of different controllers.
1011
*/
11-
public interface ServiceProvider {
12+
public interface ServiceProvider extends Plugin {
13+
1214
/**
13-
* Retrieves the capability controller.
15+
* Retrieves the capability controller for the given plugin.
1416
*
15-
* @return the capability controller instance
17+
* @param plugin The plugin for which to retrieve the capability controller.
18+
* @return The capability controller instance.
1619
*/
17-
CapabilityController capabilityController();
20+
CapabilityController capabilityController(Plugin plugin);
1821

1922
/**
2023
* Retrieves an instance of the chat controller.
Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,14 @@
11
package net.thenextlvl.services.api.capability;
22

3-
public record Capability<C, I extends C>(Class<C> commonInterface, I implementation) {
3+
import org.bukkit.plugin.Plugin;
4+
import org.jetbrains.annotations.ApiStatus;
5+
6+
public interface Capability {
7+
@ApiStatus.OverrideOnly
8+
void disable(CapabilityController controller);
9+
10+
@ApiStatus.OverrideOnly
11+
void enable(CapabilityController controller);
12+
13+
Plugin getPlugin();
414
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package net.thenextlvl.services.api.capability;
2+
3+
import net.thenextlvl.services.api.ServiceProvider;
4+
import org.bukkit.plugin.Plugin;
5+
6+
public interface CapabilityConstructor<C extends Capability> {
7+
// safely perform your checks here
8+
// this method cannot throw exceptions
9+
boolean isCapable(Plugin plugin);
10+
11+
// the plugin is the instance of the plugin that provides the capability
12+
// construct your object which cannot throw exceptions either
13+
C construct(ServiceProvider serviceProvider, Plugin plugin);
14+
}
Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
package net.thenextlvl.services.api.capability;
22

3+
import net.thenextlvl.services.api.ServiceProvider;
4+
import org.bukkit.plugin.Plugin;
5+
36
public interface CapabilityController {
4-
<C, I extends C> C registerCapability(String plugin, Capability<C, I> capability);
7+
CapabilityLoader loader();
8+
9+
CapabilityRegistry registry();
10+
11+
Plugin owner();
12+
13+
ServiceProvider provider();
514
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package net.thenextlvl.services.api.capability;
2+
3+
import org.bukkit.plugin.Plugin;
4+
5+
public interface CapabilityLoader {
6+
void disableCapabilities(Plugin plugin);
7+
8+
void disableCapability(Capability capability);
9+
10+
void enableCapabilities(Plugin plugin);
11+
12+
void enableCapability(Capability capability);
13+
}

0 commit comments

Comments
 (0)