From f0551727ca2f29fc2d9f662e5dd26de843091043 Mon Sep 17 00:00:00 2001 From: EOT3000 <43685885+EOT3000@users.noreply.github.com> Date: Mon, 22 Jul 2019 10:20:49 -0400 Subject: [PATCH] First Event! --- .../org/geysermc/api/events/EventHandler.java | 32 ++++++++++++ .../org/geysermc/api/events/Listener.java | 8 +++ .../geysermc/api/events/player/PingEvent.java | 29 +++++++++++ .../java/org/geysermc/api/plugin/Plugin.java | 13 ++++- .../geysermc/api/plugin/PluginManager.java | 21 ++++++++ .../org/geysermc/api/session/AuthData.java | 9 ++++ .../network/ConnectorServerEventHandler.java | 21 ++++++-- .../network/session/GeyserSession.java | 8 +-- .../connector/plugin/GeyserPluginLoader.java | 16 +++++- .../connector/plugin/GeyserPluginManager.java | 52 ++++++++++++++++--- .../connector/plugin/PluginListener.java | 28 ++++++++++ .../geysermc/connector/utils/GeyserUtils.java | 9 ++++ 12 files changed, 232 insertions(+), 14 deletions(-) create mode 100644 api/src/main/java/org/geysermc/api/events/EventHandler.java create mode 100644 api/src/main/java/org/geysermc/api/events/Listener.java create mode 100644 api/src/main/java/org/geysermc/api/events/player/PingEvent.java create mode 100644 api/src/main/java/org/geysermc/api/session/AuthData.java create mode 100644 connector/src/main/java/org/geysermc/connector/plugin/PluginListener.java diff --git a/api/src/main/java/org/geysermc/api/events/EventHandler.java b/api/src/main/java/org/geysermc/api/events/EventHandler.java new file mode 100644 index 000000000..920a4222b --- /dev/null +++ b/api/src/main/java/org/geysermc/api/events/EventHandler.java @@ -0,0 +1,32 @@ +package org.geysermc.api.events; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * The annotation to put on all methods that are events. + */ + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface EventHandler { + + /** + * @return the order to execute events. + * @see EventPriority + */ + EventPriority value() default EventPriority.NORMAL; + + /** + * When an eventHandler should be run. + * The names mostly explain. + */ + enum EventPriority { + FIRST, + NORMAL, + LAST, + READ_ONLY; + } +} diff --git a/api/src/main/java/org/geysermc/api/events/Listener.java b/api/src/main/java/org/geysermc/api/events/Listener.java new file mode 100644 index 000000000..e08b373a5 --- /dev/null +++ b/api/src/main/java/org/geysermc/api/events/Listener.java @@ -0,0 +1,8 @@ +package org.geysermc.api.events; + +/** + * A marker class which says that a specific class uses events. + * @see EventHandler + */ +public interface Listener { +} diff --git a/api/src/main/java/org/geysermc/api/events/player/PingEvent.java b/api/src/main/java/org/geysermc/api/events/player/PingEvent.java new file mode 100644 index 000000000..21ff49e7f --- /dev/null +++ b/api/src/main/java/org/geysermc/api/events/player/PingEvent.java @@ -0,0 +1,29 @@ +package org.geysermc.api.events.player; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; + +import java.net.InetSocketAddress; + +@Getter +@Setter +public class PingEvent { + public PingEvent(InetSocketAddress address) { + this.address = address; + } + + private InetSocketAddress address; + + private String edition; + private String motd; + private int protocolVersion; + private String version; + private int playerCount; + private int maximumPlayerCount; + private long serverId; + private String subMotd; + private String gameType; + private boolean nintendoLimited; +} diff --git a/api/src/main/java/org/geysermc/api/plugin/Plugin.java b/api/src/main/java/org/geysermc/api/plugin/Plugin.java index 1cc995d35..2758eca04 100644 --- a/api/src/main/java/org/geysermc/api/plugin/Plugin.java +++ b/api/src/main/java/org/geysermc/api/plugin/Plugin.java @@ -33,6 +33,8 @@ import lombok.Setter; * The first init point is the constructor, followed by onLoad, and finally onEnable. */ public class Plugin { + protected String name; + protected String version; @Getter @Setter @@ -60,9 +62,18 @@ public class Plugin { } /** - * Called when th server is reloaded + * Called when the server is reloaded */ public void onReload() { } + + public final String getName() { + return name; + } + + @Override + public final String toString() { + return getName(); + } } diff --git a/api/src/main/java/org/geysermc/api/plugin/PluginManager.java b/api/src/main/java/org/geysermc/api/plugin/PluginManager.java index dfa9a52f9..2cc183046 100644 --- a/api/src/main/java/org/geysermc/api/plugin/PluginManager.java +++ b/api/src/main/java/org/geysermc/api/plugin/PluginManager.java @@ -25,6 +25,8 @@ package org.geysermc.api.plugin; +import org.geysermc.api.events.Listener; + import java.util.Set; public interface PluginManager { @@ -63,4 +65,23 @@ public interface PluginManager { * @return a set of the loaded plugins */ Set getPlugins(); + + /** + * @param name The name of the plugin you want to get. + * @return The plugin with the String name in the parameters. + */ + Plugin getPluginByName(String name); + + /** + * Registers a listener to be run when an event is executed + * @param plugin the plugin registering the listener + * @param listener the listener which will contain the event methods + */ + void registerEventListener(Plugin plugin, Listener listener); + + /** + * Run an event + * @param o the event object. + */ + void runEvent(Object o); } diff --git a/api/src/main/java/org/geysermc/api/session/AuthData.java b/api/src/main/java/org/geysermc/api/session/AuthData.java new file mode 100644 index 000000000..3b4ffc73f --- /dev/null +++ b/api/src/main/java/org/geysermc/api/session/AuthData.java @@ -0,0 +1,9 @@ +package org.geysermc.api.session; + +public interface AuthData { + void getXUID(); + + void getUUID(); + + void getName(); +} diff --git a/connector/src/main/java/org/geysermc/connector/network/ConnectorServerEventHandler.java b/connector/src/main/java/org/geysermc/connector/network/ConnectorServerEventHandler.java index b43025acf..2963bd2d9 100644 --- a/connector/src/main/java/org/geysermc/connector/network/ConnectorServerEventHandler.java +++ b/connector/src/main/java/org/geysermc/connector/network/ConnectorServerEventHandler.java @@ -30,6 +30,7 @@ import com.nukkitx.protocol.bedrock.BedrockPong; import com.nukkitx.protocol.bedrock.BedrockServerEventHandler; import com.nukkitx.protocol.bedrock.BedrockServerSession; import com.nukkitx.protocol.bedrock.v361.Bedrock_v361; +import org.geysermc.api.events.player.PingEvent; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.configuration.GeyserConfiguration; import org.geysermc.connector.console.GeyserLogger; @@ -54,15 +55,14 @@ public class ConnectorServerEventHandler implements BedrockServerEventHandler { @Override public BedrockPong onQuery(InetSocketAddress inetSocketAddress) { + PingEvent pong = new PingEvent(inetSocketAddress); GeyserLogger.DEFAULT.debug(inetSocketAddress + " has pinged you!"); GeyserConfiguration config = connector.getConfig(); - BedrockPong pong = new BedrockPong(); pong.setEdition("MCPE"); pong.setGameType("Default"); pong.setNintendoLimited(false); pong.setProtocolVersion(GeyserConnector.BEDROCK_PACKET_CODEC.getProtocolVersion()); pong.setVersion("1.12.0"); - pong.setIpv4Port(19132); if (connector.getConfig().isPingPassthrough()) { ServerStatusInfo serverInfo = connector.getPassthroughThread().getInfo(); @@ -79,7 +79,22 @@ public class ConnectorServerEventHandler implements BedrockServerEventHandler { pong.setMotd(config.getBedrock().getMotd1()); pong.setSubMotd(config.getBedrock().getMotd2()); } - return pong; + + BedrockPong c = new BedrockPong(); + + c.setEdition(pong.getEdition()); + c.setGameType(pong.getGameType()); + c.setNintendoLimited(pong.isNintendoLimited()); + c.setProtocolVersion(pong.getProtocolVersion()); + c.setVersion(pong.getVersion()); + + c.setMotd(pong.getMotd()); + c.setSubMotd(pong.getSubMotd()); + c.setPlayerCount(pong.getPlayerCount()); + c.setMaximumPlayerCount(pong.getMaximumPlayerCount()); + + return c; + } @Override diff --git a/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java b/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java index 42f965479..d2d5b6021 100644 --- a/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java +++ b/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java @@ -38,9 +38,11 @@ import com.nukkitx.protocol.PlayerSession; import com.nukkitx.protocol.bedrock.BedrockServerSession; import lombok.AllArgsConstructor; import lombok.Getter; +import org.geysermc.api.session.AuthData; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.network.remote.RemoteJavaServer; import org.geysermc.connector.network.translators.Registry; +import sun.security.krb5.internal.AuthorizationData; import java.util.UUID; @@ -128,10 +130,10 @@ public class GeyserSession implements PlayerSession { @Getter @AllArgsConstructor - public class AuthenticationData { + public class AuthenticationData implements AuthData { private String name; - private UUID uuid; - private String xboxUUID; + private UUID UUID; + private String XUID; } } \ No newline at end of file diff --git a/connector/src/main/java/org/geysermc/connector/plugin/GeyserPluginLoader.java b/connector/src/main/java/org/geysermc/connector/plugin/GeyserPluginLoader.java index 7df06ee88..894b34475 100644 --- a/connector/src/main/java/org/geysermc/connector/plugin/GeyserPluginLoader.java +++ b/connector/src/main/java/org/geysermc/connector/plugin/GeyserPluginLoader.java @@ -32,6 +32,7 @@ import org.geysermc.api.Connector; import org.geysermc.api.plugin.Plugin; import java.io.File; import java.io.InputStream; +import java.lang.reflect.Field; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; @@ -51,7 +52,7 @@ public class GeyserPluginLoader extends ClassLoader { } for (File f : dir.listFiles()) { - if (!f.getName().endsWith(".jar")) + if (!f.getName().toLowerCase().endsWith(".jar")) continue; try { @@ -83,6 +84,19 @@ public class GeyserPluginLoader extends ClassLoader { PluginYML yml = mapper.readValue(is, PluginYML.class); is.close(); Plugin plugin = (Plugin) Class.forName(yml.main, true, this).newInstance(); + + Class cl = Plugin.class; + + Field name = cl.getDeclaredField("name"); + name.setAccessible(true); + + Field version = cl.getDeclaredField("version"); + version.setAccessible(true); + + name.set(plugin, yml.name); + + version.set(plugin, yml.version); + connector.getLogger().info("Loading plugin " + yml.name + " version " + yml.version); connector.getPluginManager().loadPlugin(plugin); } catch (Exception e) { diff --git a/connector/src/main/java/org/geysermc/connector/plugin/GeyserPluginManager.java b/connector/src/main/java/org/geysermc/connector/plugin/GeyserPluginManager.java index f9096bd5a..470dd23e0 100644 --- a/connector/src/main/java/org/geysermc/connector/plugin/GeyserPluginManager.java +++ b/connector/src/main/java/org/geysermc/connector/plugin/GeyserPluginManager.java @@ -26,19 +26,23 @@ package org.geysermc.connector.plugin; import lombok.Getter; +import org.geysermc.api.events.EventHandler; +import org.geysermc.api.events.Listener; import org.geysermc.api.plugin.Plugin; import org.geysermc.api.plugin.PluginManager; -import java.util.HashSet; -import java.util.Set; +import java.awt.*; +import java.lang.reflect.Method; +import java.util.*; +import java.util.List; public class GeyserPluginManager implements PluginManager { + private final List EVENTS = new ArrayList<>(); @Getter private GeyserPluginLoader loader; - @Getter - private Set plugins = new HashSet(); + private Map plugins = new HashMap<>(); public GeyserPluginManager(GeyserPluginLoader loader) { this.loader = loader; @@ -46,7 +50,7 @@ public class GeyserPluginManager implements PluginManager { public void loadPlugin(Plugin plugin) { loader.loadPlugin(plugin); - plugins.add(plugin); + plugins.put(plugin.getName(), plugin); } public void unloadPlugin(Plugin plugin) { @@ -62,6 +66,42 @@ public class GeyserPluginManager implements PluginManager { } public Set getPlugins() { - return plugins; + return new HashSet<>(plugins.values()); + } + + @Override + public void registerEventListener(Plugin p, Listener l) { + try { + Class clazz = l.getClass(); + + for(Method m : clazz.getMethods()) { + if(m.getAnnotation(EventHandler.class) != null) { + PluginListener listener = new PluginListener(); + + listener.plugin = p; + listener.listener = l; + listener.clazz = m.getParameterTypes()[0]; + listener.priority = m.getAnnotation(EventHandler.class).value(); + listener.run = m; + EVENTS.add(listener); + } + } + } catch (Exception e) { + // + } + } + + @Override + public void runEvent(Object o) { + for(EventHandler.EventPriority p : EventHandler.EventPriority.values()) { + for (PluginListener listener : EVENTS) { + listener.runIfNeeded(p, o); + } + } + } + + @Override + public Plugin getPluginByName(String name) { + return plugins.get(name); } } \ No newline at end of file diff --git a/connector/src/main/java/org/geysermc/connector/plugin/PluginListener.java b/connector/src/main/java/org/geysermc/connector/plugin/PluginListener.java new file mode 100644 index 000000000..605572f19 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/plugin/PluginListener.java @@ -0,0 +1,28 @@ +package org.geysermc.connector.plugin; + +import org.geysermc.api.events.EventHandler; +import org.geysermc.api.events.Listener; +import org.geysermc.api.plugin.Plugin; +import org.geysermc.connector.console.GeyserLogger; + +import java.lang.reflect.Method; + +public class PluginListener { + Method run; + Plugin plugin; + Listener listener; + Class clazz; + EventHandler.EventPriority priority; + + void runIfNeeded(EventHandler.EventPriority p, Object o) { + if(p.equals(priority) && clazz.isInstance(o)) { + try { + run.invoke(listener, o); + } catch (ReflectiveOperationException ex) { + GeyserLogger.DEFAULT.severe("Exception while trying to run event! Contact the maintainer of " + plugin.getName()); + + ex.printStackTrace(); + } + } + } +} diff --git a/connector/src/main/java/org/geysermc/connector/utils/GeyserUtils.java b/connector/src/main/java/org/geysermc/connector/utils/GeyserUtils.java index 1e95a3e3f..13a188205 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/GeyserUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/GeyserUtils.java @@ -649,5 +649,14 @@ public class GeyserUtils { } + public static boolean instanceOf(Class clazz, Object o) { + try { + T t = (T) o; + return true; + } catch (Exception e) { + return false; + } + } + }