Implementation Updates

This commit is contained in:
Paul Reilly
2023-05-13 22:08:26 -05:00
parent 90c5f2a6f8
commit f278ec17d4
23 changed files with 917 additions and 77 deletions

View File

@ -1,15 +1,14 @@
package me.totalfreedom.base;
import me.totalfreedom.event.EventBus;
import org.bukkit.Bukkit;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.ServicePriority;
import me.totalfreedom.service.FreedomExecutor;
import org.bukkit.plugin.java.JavaPlugin;
public class CommonsBase extends JavaPlugin
{
private final EventBus eventBus = new EventBus(this);
private final Registration registration = new Registration();
private final FreedomExecutor executor = new FreedomExecutor();
public static CommonsBase getInstance()
{
@ -19,24 +18,27 @@ public class CommonsBase extends JavaPlugin
@Override
public void onEnable()
{
Bukkit.getServicesManager().register(EventBus.class,
eventBus,
this,
ServicePriority.High);
getRegistrations().getServiceRegistry().register(this, eventBus);
getExecutor().getSync()
.execute(() -> getRegistrations()
.getServiceRegistry()
.startAll());
}
@Override
public void onDisable()
{
getRegistrations().getServiceRegistry().stopAll();
getRegistrations().getServiceRegistry().unregister(EventBus.class, eventBus);
}
public RegisteredServiceProvider<EventBus> getEventBus()
public Registration getRegistrations()
{
return Bukkit.getServicesManager().getRegistration(EventBus.class);
}
public Registration getRegistrations() {
return registration;
}
public FreedomExecutor getExecutor()
{
return executor;
}
}

View File

@ -9,6 +9,7 @@ public class Registration
private final UserRegistry userRegistry;
private final ServiceRegistry serviceRegistry;
private final ModuleRegistry moduleRegistry;
private final GroupRegistry groupRegistry;
public Registration()
{
@ -17,6 +18,7 @@ public class Registration
this.userRegistry = new UserRegistry();
this.serviceRegistry = new ServiceRegistry();
this.moduleRegistry = new ModuleRegistry();
this.groupRegistry = new GroupRegistry();
}
public ModuleRegistry getModuleRegistry()
@ -43,4 +45,9 @@ public class Registration
{
return serviceRegistry;
}
public GroupRegistry getGroupRegistry()
{
return groupRegistry;
}
}

View File

@ -0,0 +1,40 @@
package me.totalfreedom.data;
import me.totalfreedom.security.Group;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import java.util.ArrayList;
import java.util.List;
public class GroupRegistry
{
private final List<Group> groups;
public GroupRegistry()
{
this.groups = new ArrayList<>();
}
public boolean registerGroup(Group group) {
return groups.add(group);
}
public boolean unregisterGroup(Group group) {
return groups.remove(group);
}
public Group getGroup(String name) {
PlainTextComponentSerializer s = PlainTextComponentSerializer.plainText();
for (Group group : groups) {
String n = s.serialize(group.getName());
if (n.equalsIgnoreCase(name)) {
return group;
}
}
return null;
}
public List<Group> getGroups() {
return groups;
}
}

View File

@ -61,4 +61,10 @@ public class ServiceRegistry
{
return Bukkit.getServicesManager().getRegistration(clazz);
}
public void unregister(Class<? extends Service> clazz, Service service)
{
this.services.remove(service);
Bukkit.getServicesManager().unregister(clazz, service);
}
}

View File

@ -1,5 +1,37 @@
package me.totalfreedom.data;
import me.totalfreedom.user.User;
import me.totalfreedom.user.UserData;
import java.util.HashMap;
import java.util.Map;
public class UserRegistry
{
private final Map<User, UserData> userDataMap;
public UserRegistry()
{
this.userDataMap = new HashMap<>();
}
public UserData getUserData(User user)
{
return userDataMap.get(user);
}
public void registerUserData(User user, UserData userData)
{
userDataMap.put(user, userData);
}
public void unregisterUserData(User user)
{
userDataMap.remove(user);
}
public Map<User, UserData> getUserDataMap()
{
return userDataMap;
}
}

View File

@ -0,0 +1,7 @@
package me.totalfreedom.event;
@FunctionalInterface
public interface Callback<T extends FEvent>
{
void call(T event);
}

View File

@ -1,74 +1,58 @@
package me.totalfreedom.event;
import me.totalfreedom.api.Context;
import me.totalfreedom.base.CommonsBase;
import org.bukkit.event.Listener;
import me.totalfreedom.service.Service;
import java.lang.reflect.Executable;
import java.util.*;
import java.util.stream.Collectors;
import java.util.HashSet;
import java.util.Set;
public class EventBus
public class EventBus extends Service
{
private final Set<Listener> listenerSet = new HashSet<>();
private final Map<Listener, Set<FEvent>> listenerEventMap = new HashMap<>();
private final CommonsBase plugin;
private final Set<FEvent> eventSet = new HashSet<>();
private final SubscriptionBox<?> runningSubscriptions = new SubscriptionBox<>();
public EventBus(CommonsBase plugin)
{
super("event_bus");
this.plugin = plugin;
}
void registerListener(Listener listener)
public void addEvent(FEvent event)
{
Set<FEvent> eventSet = Arrays.stream(listener.getClass().getDeclaredMethods())
.filter(m -> m.isAnnotationPresent(Handler.class))
.map(Executable::getParameters)
.filter(p -> p.length == 1)
.filter(p -> FEvent.class.isAssignableFrom(p[0].getType()))
.map(p ->
{
try
{
return (FEvent) p[0].getType().getDeclaredConstructor().newInstance();
} catch (Exception exception)
{
exception.printStackTrace();
return null;
}
})
.filter(Objects::nonNull)
.collect(Collectors.toSet());
listenerEventMap.put(listener, eventSet);
eventSet.add(event);
}
void unregisterListener(Listener listener)
public <T extends FEvent> EventSubscription<T> subscribe(Class<T> eventClass, Callback<T> callback)
{
listenerEventMap.remove(listener);
Context<T> eventContext = () -> eventSet.stream()
.filter(event -> event.getEventClass().equals(eventClass))
.findFirst()
.map(eventClass::cast)
.orElse(null);
if (eventContext.get() == null)
{
throw new IllegalArgumentException("Event class " + eventClass.getName() + " is not registered.");
}
return new EventSubscription<>(eventContext.get(), callback);
}
public void startListening()
public void unsubscribe(EventSubscription<?> subscription)
{
listenerSet().forEach(this::registerListener);
}
public void stopListening()
{
listenerSet().forEach(this::unregisterListener);
}
public Set<Listener> listenerSet()
{
return listenerSet;
}
public Map<Listener, Set<FEvent>> listenerEventMap()
{
return listenerEventMap;
runningSubscriptions.removeSubscription(subscription);
}
public CommonsBase getCommonsBase()
{
return plugin;
}
@Override
public void tick()
{
runningSubscriptions.tick();
}
}

View File

@ -0,0 +1,36 @@
package me.totalfreedom.event;
import me.totalfreedom.api.Context;
import java.util.function.Supplier;
public final class EventSubscription<T extends FEvent>
{
private final T event;
private final Callback<T> callback;
public EventSubscription(T event, Callback<T> callback)
{
this.event = event;
this.callback = callback;
}
public T getEvent()
{
return event;
}
public boolean cancel()
{
return getEvent().cancel();
}
public boolean isCancelled()
{
return getEvent().isCancelled();
}
public Callback<T> getCallback() {
return callback;
}
}

View File

@ -4,11 +4,25 @@ import me.totalfreedom.api.Context;
public abstract class FEvent
{
private boolean isCancelled;
protected FEvent()
{
this.isCancelled = false;
}
public abstract void call(Context<?>... contexts);
public abstract void call(Callback<FEvent> callback);
public abstract void cancel();
public boolean cancel()
{
this.isCancelled = true;
return isCancelled();
}
public boolean isCancelled()
{
return isCancelled;
}
public abstract Class<? extends FEvent> getEventClass();
}

View File

@ -1,10 +0,0 @@
package me.totalfreedom.event;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface Handler
{
// This is a marker annotation
}

View File

@ -0,0 +1,25 @@
package me.totalfreedom.event;
import java.util.ArrayList;
import java.util.List;
class SubscriptionBox<T extends FEvent>
{
private final List<EventSubscription<T>> subscriptions;
public SubscriptionBox() {
this.subscriptions = new ArrayList<>();
}
public void addSubscription(EventSubscription<T> subscription) {
subscriptions.add(subscription);
}
public void removeSubscription(EventSubscription<?> subscription) {
subscriptions.remove(subscription);
}
public void tick() {
subscriptions.forEach(s -> s.getCallback().call(s.getEvent()));
}
}

View File

@ -0,0 +1,58 @@
package me.totalfreedom.service;
import me.totalfreedom.base.CommonsBase;
import org.bukkit.Bukkit;
import java.util.concurrent.Executor;
public class FreedomExecutor
{
private final Executor syncExecutor;
private final Executor asyncExecutor;
public FreedomExecutor()
{
syncExecutor = r -> Bukkit.getScheduler().runTask(CommonsBase.getInstance(), r);
asyncExecutor = r -> Bukkit.getScheduler().runTaskAsynchronously(CommonsBase.getInstance(), r);
}
public Executor getSync()
{
return syncExecutor;
}
public Executor getAsync()
{
return asyncExecutor;
}
public Executor scheduled(long delay, long period)
{
return r -> Bukkit.getScheduler()
.runTaskTimer(
CommonsBase.getInstance(),
r,
delay,
period);
}
public Executor scheduledAsync(long delay, long period)
{
return r -> Bukkit.getScheduler()
.runTaskTimerAsynchronously(
CommonsBase.getInstance(),
r,
delay,
period);
}
public void runSync(Task task)
{
getSync().execute(task);
}
public void runAsync(Task task)
{
getAsync().execute(task);
}
}

View File

@ -1,8 +1,11 @@
package me.totalfreedom.service;
import me.totalfreedom.base.CommonsBase;
public abstract class Service
{
private final String name;
private boolean isActive = false;
protected Service(String name)
{
@ -10,7 +13,35 @@ public abstract class Service
}
public abstract void start();
public void start()
{
isActive = true;
CommonsBase.getInstance()
.getExecutor()
.getSync()
.execute(() ->
{
while (isActive)
{
tick();
}
});
}
public abstract void stop();
public void stop()
{
isActive = false;
}
public abstract void tick();
public String getName()
{
return name;
}
public boolean isActive()
{
return isActive;
}
}

View File

@ -5,6 +5,8 @@ import net.kyori.adventure.text.Component;
public interface User extends PermissionHolder
{
UserData getUserData();
Component getDisplayName();
boolean isOnline();

View File

@ -0,0 +1,40 @@
package me.totalfreedom.user;
import me.totalfreedom.security.Group;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.UUID;
public interface UserData
{
@NotNull UUID getUniqueId();
String getUsername();
User getUser();
@Nullable Group getGroup();
void setGroup(@Nullable Group group);
long getPlaytime();
void setPlaytime(long playtime);
void addPlaytime(long playtime);
void resetPlaytime();
boolean isFrozen();
void setFrozen(boolean frozen);
boolean canInteract();
void setInteractionState(boolean canInteract);
boolean isCaged();
void setCaged(boolean caged);
}

View File

@ -0,0 +1,40 @@
package me.totalfreedom.utils;
import org.bukkit.Location;
import org.bukkit.World;
import java.util.LinkedList;
import java.util.List;
import java.util.function.DoubleUnaryOperator;
public class Shaper
{
private final double start;
private final double end;
private final World world;
public Shaper(World world, double start, double end)
{
this.start = start;
this.end = end;
this.world = world;
}
public List<Location> generate(int count, DoubleUnaryOperator x, DoubleUnaryOperator y, DoubleUnaryOperator z)
{
double step = (start - end) / (count - 1);
LinkedList<Location> lset = new LinkedList<>();
for (int i = 0; i < count; i++)
{
double t = start + i * step;
double xp = x.applyAsDouble(t);
double yp = y.applyAsDouble(t);
double zp = z.applyAsDouble(t);
lset.add(new Location(world, xp, yp, zp));
}
return lset;
}
}