diff --git a/Plan/api/build.gradle b/Plan/api/build.gradle
index 3d22dcad4..e2b71de07 100644
--- a/Plan/api/build.gradle
+++ b/Plan/api/build.gradle
@@ -4,7 +4,7 @@ dependencies {
compileOnly "com.google.code.gson:gson:$gsonVersion"
}
-ext.apiVersion = '5.2-R0.2'
+ext.apiVersion = '5.2-R0.3'
publishing {
repositories {
diff --git a/Plan/api/src/main/java/com/djrapitops/plan/settings/ListenerService.java b/Plan/api/src/main/java/com/djrapitops/plan/settings/ListenerService.java
new file mode 100644
index 000000000..6744ea194
--- /dev/null
+++ b/Plan/api/src/main/java/com/djrapitops/plan/settings/ListenerService.java
@@ -0,0 +1,65 @@
+/*
+ * This file is part of Player Analytics (Plan).
+ *
+ * Plan is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License v3 as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Plan is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Plan. If not, see .
+ */
+package com.djrapitops.plan.settings;
+
+import java.util.Optional;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * Service for registering listeners as Plan.
+ *
+ * This is an utility service for implementing listeners for platforms that don't have
+ * static access to the listener registration.
+ */
+public interface ListenerService {
+
+ /**
+ * Obtain instance of ListenerService.
+ *
+ * @return QueryService implementation.
+ * @throws NoClassDefFoundError If Plan is not installed and this class can not be found or if older Plan version is installed.
+ * @throws IllegalStateException If Plan is installed, but not enabled.
+ */
+ static ListenerService getInstance() {
+ return Optional.ofNullable(ListenerService.Holder.service.get())
+ .orElseThrow(() -> new IllegalStateException("ListenerService has not been initialised yet."));
+ }
+
+ /**
+ * Attempts to register an event listener to the platform as Plan.
+ *
+ * This is an utility method for implementing listeners for platforms that don't have
+ * static access to the listener registration.
+ *
+ * The listener needs to fulfill the qualities required by the platform.
+ *
+ * @param listener listener object.
+ */
+ void registerListenerForPlan(Object listener);
+
+ class Holder {
+ static final AtomicReference service = new AtomicReference<>();
+
+ private Holder() {
+ /* Static variable holder */
+ }
+
+ static void set(ListenerService service) {
+ ListenerService.Holder.service.set(service);
+ }
+ }
+}
diff --git a/Plan/common/src/main/java/com/djrapitops/plan/PlanSystem.java b/Plan/common/src/main/java/com/djrapitops/plan/PlanSystem.java
index 868ffedf1..08f2272db 100644
--- a/Plan/common/src/main/java/com/djrapitops/plan/PlanSystem.java
+++ b/Plan/common/src/main/java/com/djrapitops/plan/PlanSystem.java
@@ -31,6 +31,7 @@ import com.djrapitops.plan.identification.ServerInfo;
import com.djrapitops.plan.processing.Processing;
import com.djrapitops.plan.query.QuerySvc;
import com.djrapitops.plan.settings.ConfigSystem;
+import com.djrapitops.plan.settings.ListenerSvc;
import com.djrapitops.plan.settings.SettingsSvc;
import com.djrapitops.plan.settings.locale.LocaleSystem;
import com.djrapitops.plan.storage.database.DBSystem;
@@ -75,6 +76,7 @@ public class PlanSystem implements SubSystem {
private final ResourceSvc resourceService;
private final ExtensionSvc extensionService;
private final QuerySvc queryService;
+ private final ListenerSvc listenerService;
private final SettingsSvc settingsService;
private final PluginLogger logger;
private final ErrorLogger errorLogger;
@@ -99,6 +101,7 @@ public class PlanSystem implements SubSystem {
ResourceSvc resourceService,
ExtensionSvc extensionService,
QuerySvc queryService,
+ ListenerSvc listenerService,
SettingsSvc settingsService,
PluginLogger logger,
ErrorLogger errorLogger,
@@ -122,6 +125,7 @@ public class PlanSystem implements SubSystem {
this.resourceService = resourceService;
this.extensionService = extensionService;
this.queryService = queryService;
+ this.listenerService = listenerService;
this.settingsService = settingsService;
this.logger = logger;
this.errorLogger = errorLogger;
@@ -144,6 +148,7 @@ public class PlanSystem implements SubSystem {
extensionService.register();
resolverService.register();
resourceService.register();
+ listenerService.register();
settingsService.register();
queryService.register();
diff --git a/Plan/common/src/main/java/com/djrapitops/plan/settings/ListenerSvc.java b/Plan/common/src/main/java/com/djrapitops/plan/settings/ListenerSvc.java
new file mode 100644
index 000000000..2c1f74a2f
--- /dev/null
+++ b/Plan/common/src/main/java/com/djrapitops/plan/settings/ListenerSvc.java
@@ -0,0 +1,42 @@
+/*
+ * This file is part of Player Analytics (Plan).
+ *
+ * Plan is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License v3 as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Plan is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Plan. If not, see .
+ */
+package com.djrapitops.plan.settings;
+
+import net.playeranalytics.plugin.server.Listeners;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+@Singleton
+public class ListenerSvc implements ListenerService {
+
+ private final Listeners listeners;
+
+ @Inject
+ public ListenerSvc(Listeners listeners) {
+ this.listeners = listeners;
+ }
+
+ @Override
+ public void registerListenerForPlan(Object listener) {
+ listeners.registerListener(listener);
+ }
+
+ public void register() {
+ Holder.set(this);
+ }
+}