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 1/5] 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; + } + } + } From 81ad1542eecfea64c276e607983e1746f21f3d1d Mon Sep 17 00:00:00 2001 From: RednedEpic Date: Sun, 21 Jul 2019 20:11:55 -0500 Subject: [PATCH 2/5] Add some entity translators --- .../network/translators/TranslatorsInit.java | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java b/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java index 55107a5a3..61e2b1354 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java @@ -32,6 +32,10 @@ import com.github.steveice10.mc.protocol.data.message.TranslationMessage; import com.github.steveice10.mc.protocol.packet.ingame.server.ServerChatPacket; import com.github.steveice10.mc.protocol.packet.ingame.server.ServerJoinGamePacket; import com.github.steveice10.mc.protocol.packet.ingame.server.ServerTitlePacket; +import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityPositionPacket; +import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityPositionRotationPacket; +import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityTeleportPacket; +import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityVelocityPacket; import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerUpdateTimePacket; import com.nukkitx.nbt.CompoundTagBuilder; import com.nukkitx.nbt.NbtUtils; @@ -70,6 +74,7 @@ public class TranslatorsInit { addChatPackets(); addTitlePackets(); addTimePackets(); + addEntityPackets(); } private static void addLoginPackets() { @@ -223,4 +228,47 @@ public class TranslatorsInit { session.getUpstream().sendPacket(setTimePacket); }); } + + public static void addEntityPackets() { + Registry.add(ServerEntityPositionPacket.class, (packet, session) -> { + MoveEntityAbsolutePacket moveEntityPacket = new MoveEntityAbsolutePacket(); + moveEntityPacket.setRuntimeEntityId(packet.getEntityId()); + moveEntityPacket.setPosition(new Vector3f(packet.getMovementX(), packet.getMovementY(), packet.getMovementZ())); + moveEntityPacket.setRotation(new Vector3f(packet.getMovementX(), packet.getMovementY(), packet.getMovementZ())); + moveEntityPacket.setOnGround(packet.isOnGround()); + moveEntityPacket.setTeleported(false); + + session.getUpstream().sendPacket(moveEntityPacket); + }); + + Registry.add(ServerEntityPositionRotationPacket.class, (packet, session) -> { + MoveEntityAbsolutePacket moveEntityPacket = new MoveEntityAbsolutePacket(); + moveEntityPacket.setRuntimeEntityId(packet.getEntityId()); + moveEntityPacket.setPosition(new Vector3f(packet.getMovementX(), packet.getMovementY(), packet.getMovementZ())); + moveEntityPacket.setRotation(new Vector3f(packet.getMovementX(), packet.getMovementY(), packet.getMovementZ())); + moveEntityPacket.setOnGround(true); + moveEntityPacket.setTeleported(false); + + session.getUpstream().sendPacket(moveEntityPacket); + }); + + Registry.add(ServerEntityTeleportPacket.class, (packet, session) -> { + MoveEntityAbsolutePacket moveEntityPacket = new MoveEntityAbsolutePacket(); + moveEntityPacket.setRuntimeEntityId(packet.getEntityId()); + moveEntityPacket.setPosition(new Vector3f(packet.getX(), packet.getY(), packet.getZ())); + moveEntityPacket.setRotation(new Vector3f(packet.getX(), packet.getY(), packet.getZ())); + moveEntityPacket.setOnGround(packet.isOnGround()); + moveEntityPacket.setTeleported(true); + + session.getUpstream().sendPacket(moveEntityPacket); + }); + + Registry.add(ServerEntityVelocityPacket.class, (packet, session) -> { + SetEntityMotionPacket entityMotionPacket = new SetEntityMotionPacket(); + entityMotionPacket.setRuntimeEntityId(packet.getEntityId()); + entityMotionPacket.setMotion(new Vector3f(packet.getMotionX(), packet.getMotionY(), packet.getMotionZ())); + + session.getUpstream().sendPacket(entityMotionPacket); + }); + } } From caebb8e4f4b7f2f6c8fbe290766c5c7a12592c89 Mon Sep 17 00:00:00 2001 From: RednedEpic Date: Tue, 23 Jul 2019 11:47:20 -0500 Subject: [PATCH 3/5] Add weather packets --- .../network/translators/TranslatorsInit.java | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java b/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java index 61e2b1354..da8a344e6 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java @@ -36,6 +36,7 @@ import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntit import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityPositionRotationPacket; import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityTeleportPacket; import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityVelocityPacket; +import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerNotifyClientPacket; import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerUpdateTimePacket; import com.nukkitx.nbt.CompoundTagBuilder; import com.nukkitx.nbt.NbtUtils; @@ -49,6 +50,7 @@ import org.geysermc.connector.utils.Toolbox; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.util.concurrent.ThreadLocalRandom; public class TranslatorsInit { @@ -75,6 +77,7 @@ public class TranslatorsInit { addTitlePackets(); addTimePackets(); addEntityPackets(); + addNotifyPackets(); } private static void addLoginPackets() { @@ -271,4 +274,35 @@ public class TranslatorsInit { session.getUpstream().sendPacket(entityMotionPacket); }); } + + public static void addNotifyPackets() { + Registry.add(ServerNotifyClientPacket.class, (packet, session) -> { + switch (packet.getNotification()) { + case START_RAIN: + LevelEventPacket startRainPacket = new LevelEventPacket(); + startRainPacket.setEvent(LevelEventPacket.Event.START_RAIN); + startRainPacket.setData(ThreadLocalRandom.current().nextInt(50000) + 10000); + startRainPacket.setPosition(new Vector3f(0, 0, 0)); + + session.getUpstream().sendPacket(startRainPacket); + break; + case STOP_RAIN: + LevelEventPacket stopRainPacket = new LevelEventPacket(); + stopRainPacket.setEvent(LevelEventPacket.Event.STOP_RAIN); + stopRainPacket.setData(ThreadLocalRandom.current().nextInt(50000) + 10000); + stopRainPacket.setPosition(new Vector3f(0, 0, 0)); + + session.getUpstream().sendPacket(stopRainPacket); + break; + case ENTER_CREDITS: + // ShowCreditsPacket showCreditsPacket = new ShowCreditsPacket(); + // showCreditsPacket.setStatus(ShowCreditsPacket.Status.START_CREDITS); + // showCreditsPacket.setRuntimeEntityId(runtimeEntityId); + // session.getUpstream().sendPacket(showCreditsPacket); + break; + default: + break; + } + }); + } } From ff11a55884996aa0c678de9c7160a2f7145e95ae Mon Sep 17 00:00:00 2001 From: RednedEpic Date: Tue, 23 Jul 2019 11:53:39 -0500 Subject: [PATCH 4/5] Call the PingEvent --- .../geysermc/connector/network/ConnectorServerEventHandler.java | 1 + 1 file changed, 1 insertion(+) 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 2963bd2d9..c7df18327 100644 --- a/connector/src/main/java/org/geysermc/connector/network/ConnectorServerEventHandler.java +++ b/connector/src/main/java/org/geysermc/connector/network/ConnectorServerEventHandler.java @@ -64,6 +64,7 @@ public class ConnectorServerEventHandler implements BedrockServerEventHandler { pong.setProtocolVersion(GeyserConnector.BEDROCK_PACKET_CODEC.getProtocolVersion()); pong.setVersion("1.12.0"); + connector.getPluginManager().runEvent(pong); if (connector.getConfig().isPingPassthrough()) { ServerStatusInfo serverInfo = connector.getPassthroughThread().getInfo(); From 657f12654b04ba182a5b8002f2a69e1ba6ad7bf7 Mon Sep 17 00:00:00 2001 From: RednedEpic Date: Tue, 23 Jul 2019 18:16:25 -0500 Subject: [PATCH 5/5] Add form API and other small changes --- api/pom.xml | 6 + .../main/java/org/geysermc/api/Player.java | 71 ++++++++ .../java/org/geysermc/api/RemoteServer.java | 43 +++++ .../org/geysermc/api/events/EventHandler.java | 26 ++- .../org/geysermc/api/events/Listener.java | 25 +++ .../org/geysermc/api/events/PingEvent.java | 53 ++++++ .../geysermc/api/events/player/PingEvent.java | 29 ---- .../api/events/player/PlayerEvent.java | 39 +++++ .../player/PlayerFormResponseEvent.java | 76 +++++++++ .../java/org/geysermc/api/plugin/Plugin.java | 5 + .../org/geysermc/api/session/AuthData.java | 33 +++- .../api/window/CustomFormBuilder.java | 70 ++++++++ .../geysermc/api/window/CustomFormWindow.java | 161 ++++++++++++++++++ .../org/geysermc/api/window/FormWindow.java | 57 +++++++ .../geysermc/api/window/ModalFormWindow.java | 77 +++++++++ .../geysermc/api/window/SimpleFormWindow.java | 89 ++++++++++ .../api/window/button/FormButton.java | 53 ++++++ .../geysermc/api/window/button/FormImage.java | 62 +++++++ .../window/component/DropdownComponent.java | 56 ++++++ .../api/window/component/FormComponent.java | 38 +++++ .../api/window/component/InputComponent.java | 52 ++++++ .../api/window/component/LabelComponent.java | 42 +++++ .../api/window/component/SliderComponent.java | 65 +++++++ .../window/component/StepSliderComponent.java | 69 ++++++++ .../api/window/component/ToggleComponent.java | 43 +++++ .../window/response/CustomFormResponse.java | 44 +++++ .../api/window/response/FormResponse.java | 29 ++++ .../api/window/response/FormResponseData.java | 37 ++++ .../window/response/ModalFormResponse.java | 37 ++++ .../window/response/SimpleFormResponse.java | 38 +++++ .../network/ConnectorServerEventHandler.java | 2 +- .../network/UpstreamPacketHandler.java | 29 +++- .../network/remote/RemoteJavaServer.java | 3 +- .../network/session/GeyserSession.java | 38 +++-- .../network/session/auth/BedrockAuthData.java | 16 ++ .../network/session/cache/WindowCache.java | 54 ++++++ 36 files changed, 1613 insertions(+), 54 deletions(-) create mode 100644 api/src/main/java/org/geysermc/api/Player.java create mode 100644 api/src/main/java/org/geysermc/api/RemoteServer.java create mode 100644 api/src/main/java/org/geysermc/api/events/PingEvent.java delete mode 100644 api/src/main/java/org/geysermc/api/events/player/PingEvent.java create mode 100644 api/src/main/java/org/geysermc/api/events/player/PlayerEvent.java create mode 100644 api/src/main/java/org/geysermc/api/events/player/PlayerFormResponseEvent.java create mode 100644 api/src/main/java/org/geysermc/api/window/CustomFormBuilder.java create mode 100644 api/src/main/java/org/geysermc/api/window/CustomFormWindow.java create mode 100644 api/src/main/java/org/geysermc/api/window/FormWindow.java create mode 100644 api/src/main/java/org/geysermc/api/window/ModalFormWindow.java create mode 100644 api/src/main/java/org/geysermc/api/window/SimpleFormWindow.java create mode 100644 api/src/main/java/org/geysermc/api/window/button/FormButton.java create mode 100644 api/src/main/java/org/geysermc/api/window/button/FormImage.java create mode 100644 api/src/main/java/org/geysermc/api/window/component/DropdownComponent.java create mode 100644 api/src/main/java/org/geysermc/api/window/component/FormComponent.java create mode 100644 api/src/main/java/org/geysermc/api/window/component/InputComponent.java create mode 100644 api/src/main/java/org/geysermc/api/window/component/LabelComponent.java create mode 100644 api/src/main/java/org/geysermc/api/window/component/SliderComponent.java create mode 100644 api/src/main/java/org/geysermc/api/window/component/StepSliderComponent.java create mode 100644 api/src/main/java/org/geysermc/api/window/component/ToggleComponent.java create mode 100644 api/src/main/java/org/geysermc/api/window/response/CustomFormResponse.java create mode 100644 api/src/main/java/org/geysermc/api/window/response/FormResponse.java create mode 100644 api/src/main/java/org/geysermc/api/window/response/FormResponseData.java create mode 100644 api/src/main/java/org/geysermc/api/window/response/ModalFormResponse.java create mode 100644 api/src/main/java/org/geysermc/api/window/response/SimpleFormResponse.java create mode 100644 connector/src/main/java/org/geysermc/connector/network/session/auth/BedrockAuthData.java create mode 100644 connector/src/main/java/org/geysermc/connector/network/session/cache/WindowCache.java diff --git a/api/pom.xml b/api/pom.xml index 31487d7c7..a0cbdf87f 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -16,5 +16,11 @@ 1.18.4 compile + + com.google.code.gson + gson + 2.8.2 + compile + \ No newline at end of file diff --git a/api/src/main/java/org/geysermc/api/Player.java b/api/src/main/java/org/geysermc/api/Player.java new file mode 100644 index 000000000..7df58f46a --- /dev/null +++ b/api/src/main/java/org/geysermc/api/Player.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2019 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.api; + +import org.geysermc.api.command.CommandSender; +import org.geysermc.api.session.AuthData; +import org.geysermc.api.window.FormWindow; + +public interface Player extends CommandSender { + + /** + * Connects the player to the remote server + * + * @param remoteServer the remote server to connect to + */ + void connect(RemoteServer remoteServer); + + /** + * Disconnect the player for the specified reason + * + * @param reason the reason to disconnect the player for + */ + void disconnect(String reason); + + /** + * Returns the authentication data of the player. This is not the + * player's Minecraft credentials; it's simply what is given to the server + * (Name, UUID, Xbox UUID) to verify the player can/actually exists. + * + * @return the authentication data of the player + */ + AuthData getAuthenticationData(); + + /** + * Sends a form window + * + * @param window the window form to send + */ + void sendForm(FormWindow window); + + /** + * Sends a form window with the given ID + * + * @param window the window to send + * @param id the id of the window + */ + void sendForm(FormWindow window, int id); +} diff --git a/api/src/main/java/org/geysermc/api/RemoteServer.java b/api/src/main/java/org/geysermc/api/RemoteServer.java new file mode 100644 index 000000000..8004cbd16 --- /dev/null +++ b/api/src/main/java/org/geysermc/api/RemoteServer.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2019 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.api; + +public interface RemoteServer { + + /** + * Returns the IP address of the remote server + * + * @return the IP address of the remote server + */ + String getAddress(); + + /** + * Returns the port of the remote server + * + * @return the port of the remote server + */ + int getPort(); +} diff --git a/api/src/main/java/org/geysermc/api/events/EventHandler.java b/api/src/main/java/org/geysermc/api/events/EventHandler.java index 920a4222b..d25c14ff1 100644 --- a/api/src/main/java/org/geysermc/api/events/EventHandler.java +++ b/api/src/main/java/org/geysermc/api/events/EventHandler.java @@ -1,3 +1,28 @@ +/* + * Copyright (c) 2019 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + package org.geysermc.api.events; import java.lang.annotation.ElementType; @@ -8,7 +33,6 @@ import java.lang.annotation.Target; /** * The annotation to put on all methods that are events. */ - @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface EventHandler { diff --git a/api/src/main/java/org/geysermc/api/events/Listener.java b/api/src/main/java/org/geysermc/api/events/Listener.java index e08b373a5..3288c6821 100644 --- a/api/src/main/java/org/geysermc/api/events/Listener.java +++ b/api/src/main/java/org/geysermc/api/events/Listener.java @@ -1,3 +1,28 @@ +/* + * Copyright (c) 2019 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + package org.geysermc.api.events; /** diff --git a/api/src/main/java/org/geysermc/api/events/PingEvent.java b/api/src/main/java/org/geysermc/api/events/PingEvent.java new file mode 100644 index 000000000..541657d81 --- /dev/null +++ b/api/src/main/java/org/geysermc/api/events/PingEvent.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2019 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.api.events; + +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/events/player/PingEvent.java b/api/src/main/java/org/geysermc/api/events/player/PingEvent.java deleted file mode 100644 index 21ff49e7f..000000000 --- a/api/src/main/java/org/geysermc/api/events/player/PingEvent.java +++ /dev/null @@ -1,29 +0,0 @@ -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/events/player/PlayerEvent.java b/api/src/main/java/org/geysermc/api/events/player/PlayerEvent.java new file mode 100644 index 000000000..ab4e98a61 --- /dev/null +++ b/api/src/main/java/org/geysermc/api/events/player/PlayerEvent.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2019 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.api.events.player; + +import lombok.Getter; +import org.geysermc.api.Player; + +public class PlayerEvent { + + @Getter + private Player player; + + public PlayerEvent(Player player) { + this.player = player; + } +} diff --git a/api/src/main/java/org/geysermc/api/events/player/PlayerFormResponseEvent.java b/api/src/main/java/org/geysermc/api/events/player/PlayerFormResponseEvent.java new file mode 100644 index 000000000..b68170b2a --- /dev/null +++ b/api/src/main/java/org/geysermc/api/events/player/PlayerFormResponseEvent.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2019 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.api.events.player; + +import lombok.Getter; +import org.geysermc.api.Player; +import org.geysermc.api.window.FormWindow; +import org.geysermc.api.window.response.FormResponse; + +/** + * Called when a player interacts with a form + */ +public class PlayerFormResponseEvent extends PlayerEvent { + + @Getter + private int formID; + + @Getter + private FormWindow window; + + /** + * Constructs a new PlayerFormResponseEvent instance + * + * @param player the player interacting with the form + * @param formID the id of the form + * @param window the window + */ + public PlayerFormResponseEvent(Player player, int formID, FormWindow window) { + super(player); + + this.formID = formID; + this.window = window; + } + + /** + * Returns the response of the window, can be null + * if the player closed the window + * + * @return the response of the window + */ + public FormResponse getResponse() { + return window.getResponse(); + } + + /** + * Returns if the window is closed + * + * @return if the window is closed + */ + public boolean isClosed() { + return window.isClosed(); + } +} 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 2758eca04..8209cade0 100644 --- a/api/src/main/java/org/geysermc/api/plugin/Plugin.java +++ b/api/src/main/java/org/geysermc/api/plugin/Plugin.java @@ -36,6 +36,11 @@ public class Plugin { protected String name; protected String version; + /** + * Returns if the plugin is enabled + * + * @return if the plugin is enabled + */ @Getter @Setter private boolean enabled = true; diff --git a/api/src/main/java/org/geysermc/api/session/AuthData.java b/api/src/main/java/org/geysermc/api/session/AuthData.java index 3b4ffc73f..a8b0a1f8a 100644 --- a/api/src/main/java/org/geysermc/api/session/AuthData.java +++ b/api/src/main/java/org/geysermc/api/session/AuthData.java @@ -1,9 +1,36 @@ +/* + * Copyright (c) 2019 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + package org.geysermc.api.session; +import java.util.UUID; + public interface AuthData { - void getXUID(); - void getUUID(); + String getName(); - void getName(); + UUID getUUID(); + String getXboxUUID(); } diff --git a/api/src/main/java/org/geysermc/api/window/CustomFormBuilder.java b/api/src/main/java/org/geysermc/api/window/CustomFormBuilder.java new file mode 100644 index 000000000..094ed5f44 --- /dev/null +++ b/api/src/main/java/org/geysermc/api/window/CustomFormBuilder.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2019 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.api.window; + +import lombok.Getter; +import org.geysermc.api.window.button.FormImage; +import org.geysermc.api.window.component.FormComponent; +import org.geysermc.api.window.response.CustomFormResponse; + +public class CustomFormBuilder { + + @Getter + private CustomFormWindow form; + + public CustomFormBuilder(String title) { + form = new CustomFormWindow(title); + } + + public CustomFormBuilder setTitle(String title) { + form.setTitle(title); + return this; + } + + public CustomFormBuilder setIcon(FormImage icon) { + form.setIcon(icon); + return this; + } + + public CustomFormBuilder setResponse(String data) { + form.setResponse(data); + return this; + } + + public CustomFormBuilder setResponse(CustomFormResponse response) { + form.setResponse(response); + return this; + } + + public CustomFormBuilder addComponent(FormComponent component) { + form.addComponent(component); + return this; + } + + public CustomFormWindow build() { + return form; + } +} diff --git a/api/src/main/java/org/geysermc/api/window/CustomFormWindow.java b/api/src/main/java/org/geysermc/api/window/CustomFormWindow.java new file mode 100644 index 000000000..afc6d72c0 --- /dev/null +++ b/api/src/main/java/org/geysermc/api/window/CustomFormWindow.java @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2019 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.api.window; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import lombok.Getter; +import lombok.Setter; +import org.geysermc.api.window.button.FormImage; +import org.geysermc.api.window.component.DropdownComponent; +import org.geysermc.api.window.component.FormComponent; +import org.geysermc.api.window.component.InputComponent; +import org.geysermc.api.window.component.LabelComponent; +import org.geysermc.api.window.component.SliderComponent; +import org.geysermc.api.window.component.StepSliderComponent; +import org.geysermc.api.window.component.ToggleComponent; +import org.geysermc.api.window.response.CustomFormResponse; +import org.geysermc.api.window.response.FormResponseData; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class CustomFormWindow extends FormWindow { + + @Getter + @Setter + private String title; + + @Getter + @Setter + private FormImage icon; + + @Getter + private List content; + + public CustomFormWindow(String title) { + this(title, new ArrayList<>()); + } + + public CustomFormWindow(String title, List content) { + this(title, content, (FormImage) null); + } + + public CustomFormWindow(String title, List content, String icon) { + this(title, content, new FormImage(FormImage.FormImageType.URL, icon)); + } + + public CustomFormWindow(String title, List content, FormImage icon) { + super("custom_form"); + + this.title = title; + this.content = content; + this.icon = icon; + } + + public void addComponent(FormComponent component) { + content.add(component); + } + + public String getJSONData() { + String toModify = new Gson().toJson(this); + //We need to replace this due to Java not supporting declaring class field 'default' + return toModify.replace("defaultOptionIndex", "default") + .replace("defaultText", "default") + .replace("defaultValue", "default") + .replace("defaultStepIndex", "default"); + } + + public void setResponse(String data) { + if (data == null || data.equalsIgnoreCase("null")) { + closed = true; + return; + } + + int i = 0; + Map dropdownResponses = new HashMap(); + Map inputResponses = new HashMap(); + Map sliderResponses = new HashMap(); + Map stepSliderResponses = new HashMap(); + Map toggleResponses = new HashMap(); + Map responses = new HashMap(); + Map labelResponses = new HashMap(); + + List componentResponses = new Gson().fromJson(data, new TypeToken>() { }.getType()); + for (String response : componentResponses) { + if (i >= content.size()) { + break; + } + + FormComponent component = content.get(i); + if (component == null) + return; + + if (component instanceof LabelComponent) { + LabelComponent labelComponent = (LabelComponent) component; + labelResponses.put(i, labelComponent.getText()); + } + + if (component instanceof DropdownComponent) { + DropdownComponent dropdownComponent = (DropdownComponent) component; + String option = dropdownComponent.getOptions().get(Integer.parseInt(response)); + + dropdownResponses.put(i, new FormResponseData(Integer.parseInt(response), option)); + responses.put(i, option); + } + + if (component instanceof InputComponent) { + inputResponses.put(i, response); + responses.put(i, response); + } + + if (component instanceof SliderComponent) { + float value = Float.parseFloat(response); + sliderResponses.put(i, value); + responses.put(i, value); + } + + if (component instanceof StepSliderComponent) { + StepSliderComponent stepSliderComponent = (StepSliderComponent) component; + String step = stepSliderComponent.getSteps().get(Integer.parseInt(response)); + stepSliderResponses.put(i, new FormResponseData(Integer.parseInt(response), step)); + responses.put(i, step); + } + + if (component instanceof ToggleComponent) { + boolean answer = Boolean.parseBoolean(response); + toggleResponses.put(i, answer); + responses.put(i, answer); + } + i++; + } + + this.response = new CustomFormResponse(responses, dropdownResponses, inputResponses, + sliderResponses, stepSliderResponses, toggleResponses, labelResponses); + } +} diff --git a/api/src/main/java/org/geysermc/api/window/FormWindow.java b/api/src/main/java/org/geysermc/api/window/FormWindow.java new file mode 100644 index 000000000..d193950ca --- /dev/null +++ b/api/src/main/java/org/geysermc/api/window/FormWindow.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2019 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.api.window; + +import lombok.Getter; +import lombok.Setter; +import org.geysermc.api.window.response.FormResponse; + +public abstract class FormWindow { + + @Getter + private final String type; + + @Getter + protected FormResponse response; + + @Getter + @Setter + protected boolean closed; + + public FormWindow(String type) { + this.type = type; + } + + // Lombok won't work here, so we need to make our own method + public void setResponse(FormResponse response) { + this.response = response; + } + + public abstract String getJSONData(); + + public abstract void setResponse(String response); + +} diff --git a/api/src/main/java/org/geysermc/api/window/ModalFormWindow.java b/api/src/main/java/org/geysermc/api/window/ModalFormWindow.java new file mode 100644 index 000000000..6a419775c --- /dev/null +++ b/api/src/main/java/org/geysermc/api/window/ModalFormWindow.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2019 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.api.window; + +import com.google.gson.Gson; +import lombok.Getter; +import lombok.Setter; +import org.geysermc.api.window.response.ModalFormResponse; + +public class ModalFormWindow extends FormWindow { + + @Getter + @Setter + private String title; + + @Getter + @Setter + private String content; + + @Getter + @Setter + private String button1; + + @Getter + @Setter + private String button2; + + public ModalFormWindow(String title, String content, String button1, String button2) { + super("modal"); + + this.title = title; + this.content = content; + this.button1 = button1; + this.button2 = button2; + } + + @Override + public String getJSONData() { + return new Gson().toJson(this); + } + + public void setResponse(String data) { + if (data == null || data.equalsIgnoreCase("null")) { + closed = true; + return; + } + + if (Boolean.parseBoolean(data)) { + response = new ModalFormResponse(0, button1); + } else { + response = new ModalFormResponse(1, button2); + } + } +} diff --git a/api/src/main/java/org/geysermc/api/window/SimpleFormWindow.java b/api/src/main/java/org/geysermc/api/window/SimpleFormWindow.java new file mode 100644 index 000000000..4a46aaf43 --- /dev/null +++ b/api/src/main/java/org/geysermc/api/window/SimpleFormWindow.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2019 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.api.window; + +import com.google.gson.Gson; +import lombok.Getter; +import lombok.Setter; +import org.geysermc.api.window.button.FormButton; +import org.geysermc.api.window.response.SimpleFormResponse; + +import java.util.ArrayList; +import java.util.List; + + +public class SimpleFormWindow extends FormWindow { + + @Getter + @Setter + private String title; + + @Getter + @Setter + private String content; + + @Getter + @Setter + private List buttons; + + public SimpleFormWindow(String title, String content) { + this(title, content, new ArrayList()); + } + + public SimpleFormWindow(String title, String content, List buttons) { + super("form"); + + this.title = title; + this.content = content; + this.buttons = buttons; + } + + @Override + public String getJSONData() { + return new Gson().toJson(this); + } + + public void setResponse(String data) { + if (data == null || data.equalsIgnoreCase("null")) { + closed = true; + return; + } + + int buttonID; + try { + buttonID = Integer.parseInt(data); + } catch (Exception ex) { + return; + } + + if (buttonID >= buttons.size()) { + response = new SimpleFormResponse(buttonID, null); + return; + } + + response = new SimpleFormResponse(buttonID, buttons.get(buttonID)); + } +} diff --git a/api/src/main/java/org/geysermc/api/window/button/FormButton.java b/api/src/main/java/org/geysermc/api/window/button/FormButton.java new file mode 100644 index 000000000..859bf9382 --- /dev/null +++ b/api/src/main/java/org/geysermc/api/window/button/FormButton.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2019 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.api.window.button; + +import lombok.Getter; +import lombok.Setter; + +public class FormButton { + + @Getter + @Setter + private String text; + + @Getter + private FormImage image; + + public FormButton(String text, FormImage image) { + this.text = text; + + if (image.getData() != null && !image.getData().isEmpty()) { + this.image = image; + } + } + + public void setImage(FormImage image) { + if (image.getData() != null && !image.getData().isEmpty()) { + this.image = image; + } + } +} diff --git a/api/src/main/java/org/geysermc/api/window/button/FormImage.java b/api/src/main/java/org/geysermc/api/window/button/FormImage.java new file mode 100644 index 000000000..17c472306 --- /dev/null +++ b/api/src/main/java/org/geysermc/api/window/button/FormImage.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2019 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.api.window.button; + +import lombok.Getter; +import lombok.Setter; + +public class FormImage { + + @Getter + @Setter + private FormImageType type; + + @Getter + @Setter + private String data; + + public FormImage(FormImageType type, String data) { + this.type = type; + this.data = data; + } + + public enum FormImageType { + PATH("path"), + URL("url"); + + @Getter + private String name; + + FormImageType(String name) { + this.name = name; + } + + @Override + public String toString() { + return name; + } + } +} diff --git a/api/src/main/java/org/geysermc/api/window/component/DropdownComponent.java b/api/src/main/java/org/geysermc/api/window/component/DropdownComponent.java new file mode 100644 index 000000000..99e1bca62 --- /dev/null +++ b/api/src/main/java/org/geysermc/api/window/component/DropdownComponent.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2019 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.api.window.component; + +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +public class DropdownComponent extends FormComponent { + + @Getter + @Setter + private String text; + + @Getter + @Setter + private List options; + + @Getter + @Setter + private int defaultOptionIndex; + + public DropdownComponent() { + super("dropdown"); + } + + public void addOption(String option, boolean isDefault) { + options.add(option); + if (isDefault) + defaultOptionIndex = options.size() - 1; + } +} diff --git a/api/src/main/java/org/geysermc/api/window/component/FormComponent.java b/api/src/main/java/org/geysermc/api/window/component/FormComponent.java new file mode 100644 index 000000000..506cae687 --- /dev/null +++ b/api/src/main/java/org/geysermc/api/window/component/FormComponent.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2019 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.api.window.component; + +import lombok.Getter; + +public abstract class FormComponent { + + @Getter + private final String type; + + public FormComponent(String type) { + this.type = type; + } +} diff --git a/api/src/main/java/org/geysermc/api/window/component/InputComponent.java b/api/src/main/java/org/geysermc/api/window/component/InputComponent.java new file mode 100644 index 000000000..12af18268 --- /dev/null +++ b/api/src/main/java/org/geysermc/api/window/component/InputComponent.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2019 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.api.window.component; + +import lombok.Getter; +import lombok.Setter; + +public class InputComponent extends FormComponent { + + @Getter + @Setter + private String text; + + @Getter + @Setter + private String placeholder; + + @Getter + @Setter + private String defaultText; + + public InputComponent(String text, String placeholder, String defaultText) { + super("input"); + + this.text = text; + this.placeholder = placeholder; + this.defaultText = defaultText; + } +} diff --git a/api/src/main/java/org/geysermc/api/window/component/LabelComponent.java b/api/src/main/java/org/geysermc/api/window/component/LabelComponent.java new file mode 100644 index 000000000..9ba68ee4a --- /dev/null +++ b/api/src/main/java/org/geysermc/api/window/component/LabelComponent.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2019 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.api.window.component; + +import lombok.Getter; +import lombok.Setter; + +public class LabelComponent extends FormComponent { + + @Getter + @Setter + private String text; + + public LabelComponent(String text) { + super("label"); + + this.text = text; + } +} diff --git a/api/src/main/java/org/geysermc/api/window/component/SliderComponent.java b/api/src/main/java/org/geysermc/api/window/component/SliderComponent.java new file mode 100644 index 000000000..468b700ec --- /dev/null +++ b/api/src/main/java/org/geysermc/api/window/component/SliderComponent.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2019 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.api.window.component; + +import lombok.Getter; +import lombok.Setter; + +public class SliderComponent extends FormComponent { + + @Getter + @Setter + private String text; + + @Getter + @Setter + private float min; + + @Getter + @Setter + private float max; + + @Getter + @Setter + private int step; + + @Getter + @Setter + private float defaultValue; + + public SliderComponent(String text, float min, float max, int step, float defaultValue) { + super("slider"); + + this.text = text; + this.min = min < 0f ? 0f : min; + this.max = max > this.min ? max : this.min; + if (step != -1f && step > 0) + this.step = step; + + if (defaultValue != -1f) + this.defaultValue = defaultValue; + } +} diff --git a/api/src/main/java/org/geysermc/api/window/component/StepSliderComponent.java b/api/src/main/java/org/geysermc/api/window/component/StepSliderComponent.java new file mode 100644 index 000000000..aa934f062 --- /dev/null +++ b/api/src/main/java/org/geysermc/api/window/component/StepSliderComponent.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2019 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.api.window.component; + +import lombok.Getter; +import lombok.Setter; + +import java.util.ArrayList; +import java.util.List; + +public class StepSliderComponent extends FormComponent { + + @Getter + @Setter + private String text; + + @Getter + private List steps; + + @Getter + @Setter + private int defaultStepIndex; + + public StepSliderComponent(String text) { + this(text, new ArrayList()); + } + + public StepSliderComponent(String text, List steps) { + this(text, steps, 0); + } + + public StepSliderComponent(String text, List steps, int defaultStepIndex) { + super("step_slider"); + + this.text = text; + this.steps = steps; + this.defaultStepIndex = defaultStepIndex; + } + + public void addStep(String step, boolean isDefault) { + steps.add(step); + + if (isDefault) + defaultStepIndex = steps.size() - 1; + } +} diff --git a/api/src/main/java/org/geysermc/api/window/component/ToggleComponent.java b/api/src/main/java/org/geysermc/api/window/component/ToggleComponent.java new file mode 100644 index 000000000..41b292a61 --- /dev/null +++ b/api/src/main/java/org/geysermc/api/window/component/ToggleComponent.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2019 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.api.window.component; + +public class ToggleComponent extends FormComponent { + + private String text; + private boolean defaultValue; + + public ToggleComponent(String text) { + this(text, false); + } + + public ToggleComponent(String text, boolean defaultValue) { + super("toggle"); + + this.text = text; + this.defaultValue = defaultValue; + } +} diff --git a/api/src/main/java/org/geysermc/api/window/response/CustomFormResponse.java b/api/src/main/java/org/geysermc/api/window/response/CustomFormResponse.java new file mode 100644 index 000000000..f32c43462 --- /dev/null +++ b/api/src/main/java/org/geysermc/api/window/response/CustomFormResponse.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2019 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.api.window.response; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Map; + +@Getter +@AllArgsConstructor +public class CustomFormResponse implements FormResponse { + + private Map responses; + private Map dropdownResponses; + private Map inputResponses; + private Map sliderResponses; + private Map stepSliderResponses; + private Map toggleResponses; + private Map labelResponses; +} diff --git a/api/src/main/java/org/geysermc/api/window/response/FormResponse.java b/api/src/main/java/org/geysermc/api/window/response/FormResponse.java new file mode 100644 index 000000000..0286bef1a --- /dev/null +++ b/api/src/main/java/org/geysermc/api/window/response/FormResponse.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2019 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.api.window.response; + +public interface FormResponse { +} diff --git a/api/src/main/java/org/geysermc/api/window/response/FormResponseData.java b/api/src/main/java/org/geysermc/api/window/response/FormResponseData.java new file mode 100644 index 000000000..b97fb0521 --- /dev/null +++ b/api/src/main/java/org/geysermc/api/window/response/FormResponseData.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2019 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.api.window.response; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +@Getter +public class FormResponseData { + + private int elementID; + private String elementContent; +} diff --git a/api/src/main/java/org/geysermc/api/window/response/ModalFormResponse.java b/api/src/main/java/org/geysermc/api/window/response/ModalFormResponse.java new file mode 100644 index 000000000..a62953b0d --- /dev/null +++ b/api/src/main/java/org/geysermc/api/window/response/ModalFormResponse.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2019 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.api.window.response; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class ModalFormResponse implements FormResponse { + + private int clickedButtonId; + private String clickedButtonText; +} diff --git a/api/src/main/java/org/geysermc/api/window/response/SimpleFormResponse.java b/api/src/main/java/org/geysermc/api/window/response/SimpleFormResponse.java new file mode 100644 index 000000000..4271d7546 --- /dev/null +++ b/api/src/main/java/org/geysermc/api/window/response/SimpleFormResponse.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2019 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.api.window.response; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.geysermc.api.window.button.FormButton; + +@Getter +@AllArgsConstructor +public class SimpleFormResponse implements FormResponse { + + private int clickedButtonId; + private FormButton clickedButton; +} 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 c7df18327..5d125dff4 100644 --- a/connector/src/main/java/org/geysermc/connector/network/ConnectorServerEventHandler.java +++ b/connector/src/main/java/org/geysermc/connector/network/ConnectorServerEventHandler.java @@ -30,7 +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.api.events.PingEvent; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.configuration.GeyserConfiguration; import org.geysermc.connector.console.GeyserLogger; diff --git a/connector/src/main/java/org/geysermc/connector/network/UpstreamPacketHandler.java b/connector/src/main/java/org/geysermc/connector/network/UpstreamPacketHandler.java index 44d69aaea..886f86fa5 100644 --- a/connector/src/main/java/org/geysermc/connector/network/UpstreamPacketHandler.java +++ b/connector/src/main/java/org/geysermc/connector/network/UpstreamPacketHandler.java @@ -34,8 +34,12 @@ import com.nukkitx.protocol.bedrock.packet.*; import net.minidev.json.JSONArray; import net.minidev.json.JSONObject; import net.minidev.json.JSONValue; +import org.geysermc.api.events.player.PlayerFormResponseEvent; +import org.geysermc.api.window.FormWindow; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.network.session.auth.BedrockAuthData; +import org.geysermc.connector.network.session.cache.WindowCache; import java.util.UUID; @@ -69,7 +73,7 @@ public class UpstreamPacketHandler implements BedrockPacketHandler { JWSObject identity = JWSObject.parse((String) identityObject); JSONObject extraData = (JSONObject) identity.getPayload().toJSONObject().get("extraData"); - session.setAuthenticationData(extraData.getAsString("displayName"), UUID.fromString(extraData.getAsString("identity")), extraData.getAsString("XUID")); + session.setAuthenticationData(new BedrockAuthData(extraData.getAsString("displayName"), UUID.fromString(extraData.getAsString("identity")), extraData.getAsString("XUID"))); } catch (Exception ex) { session.getUpstream().disconnect("An internal error occurred when connecting to this server."); ex.printStackTrace(); @@ -82,6 +86,18 @@ public class UpstreamPacketHandler implements BedrockPacketHandler { ResourcePacksInfoPacket resourcePacksInfo = new ResourcePacksInfoPacket(); session.getUpstream().sendPacketImmediately(resourcePacksInfo); + + // TODO: Implement this + /** + CustomFormWindow window = new CustomFormBuilder("Login") + .addComponent(new LabelComponent("Minecraft: Java Edition account authentication.")) + .addComponent(new LabelComponent("Enter the credentials for your Minecraft: Java Edition account below.")) + .addComponent(new InputComponent("Email/Username", "account@geysermc.org", "")) + .addComponent(new InputComponent("Password", "123456", "")) + .build(); + + session.sendForm(window, 1); + */ return true; } @@ -304,7 +320,16 @@ public class UpstreamPacketHandler implements BedrockPacketHandler { @Override public boolean handle(ModalFormResponsePacket packet) { connector.getLogger().debug("Handled packet: " + packet.getClass().getSimpleName()); - return false; + WindowCache windowCache = session.getWindowCache(); + if (!windowCache.getWindows().containsKey(packet.getFormId())) + return false; + + FormWindow window = windowCache.getWindows().remove(packet.getFormId()); + window.setResponse(packet.getFormData().trim()); + + PlayerFormResponseEvent event = new PlayerFormResponseEvent(session, packet.getFormId(), window); + connector.getPluginManager().runEvent(event); + return true; } @Override diff --git a/connector/src/main/java/org/geysermc/connector/network/remote/RemoteJavaServer.java b/connector/src/main/java/org/geysermc/connector/network/remote/RemoteJavaServer.java index ee32a8082..d335ba946 100644 --- a/connector/src/main/java/org/geysermc/connector/network/remote/RemoteJavaServer.java +++ b/connector/src/main/java/org/geysermc/connector/network/remote/RemoteJavaServer.java @@ -27,10 +27,11 @@ package org.geysermc.connector.network.remote; import lombok.AllArgsConstructor; import lombok.Getter; +import org.geysermc.api.RemoteServer; @Getter @AllArgsConstructor -public class RemoteJavaServer { +public class RemoteJavaServer implements RemoteServer { private String address; private int port; 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 07a40f4fb..2fa274765 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 @@ -36,21 +36,21 @@ import com.nukkitx.network.util.DisconnectReason; import com.nukkitx.protocol.PlayerSession; import com.nukkitx.protocol.bedrock.BedrockServerSession; import com.nukkitx.protocol.bedrock.packet.TextPacket; -import lombok.AllArgsConstructor; import lombok.Getter; -import org.geysermc.api.command.CommandSender; +import org.geysermc.api.Player; +import org.geysermc.api.RemoteServer; +import org.geysermc.api.session.AuthData; +import org.geysermc.api.window.FormWindow; import org.geysermc.connector.GeyserConnector; -import org.geysermc.connector.network.remote.RemoteJavaServer; +import org.geysermc.connector.network.session.cache.WindowCache; import org.geysermc.connector.network.translators.Registry; -import java.util.UUID; - -public class GeyserSession implements PlayerSession, CommandSender { +public class GeyserSession implements PlayerSession, Player { private GeyserConnector connector; @Getter - private RemoteJavaServer remoteServer; + private RemoteServer remoteServer; @Getter private BedrockServerSession upstream; @@ -61,16 +61,21 @@ public class GeyserSession implements PlayerSession, CommandSender { private final GeyserSession THIS = this; @Getter - private AuthenticationData authenticationData; + private AuthData authenticationData; + + @Getter + private WindowCache windowCache; private boolean closed; public GeyserSession(GeyserConnector connector, BedrockServerSession bedrockServerSession) { this.connector = connector; this.upstream = bedrockServerSession; + + this.windowCache = new WindowCache(this); } - public void connect(RemoteJavaServer remoteServer) { + public void connect(RemoteServer remoteServer) { MinecraftProtocol protocol = new MinecraftProtocol(authenticationData.getName()); downstream = new Client(remoteServer.getAddress(), remoteServer.getPort(), protocol, new TcpSessionFactory()); downstream.getSession().addListener(new SessionAdapter() { @@ -123,8 +128,8 @@ public class GeyserSession implements PlayerSession, CommandSender { downstream.getSession().disconnect("Disconnected from server. Reason: " + reason); } - public void setAuthenticationData(String name, UUID uuid, String xboxUUID) { - authenticationData = new AuthenticationData(name, uuid, xboxUUID); + public void setAuthenticationData(AuthData authData) { + authenticationData = authData; } @Override @@ -152,12 +157,11 @@ public class GeyserSession implements PlayerSession, CommandSender { } } - @Getter - @AllArgsConstructor - public class AuthenticationData { + public void sendForm(FormWindow window, int id) { + windowCache.showWindow(window, id); + } - private String name; - private UUID uuid; - private String xboxUUID; + public void sendForm(FormWindow window) { + windowCache.showWindow(window); } } \ No newline at end of file diff --git a/connector/src/main/java/org/geysermc/connector/network/session/auth/BedrockAuthData.java b/connector/src/main/java/org/geysermc/connector/network/session/auth/BedrockAuthData.java new file mode 100644 index 000000000..47d79ed85 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/session/auth/BedrockAuthData.java @@ -0,0 +1,16 @@ +package org.geysermc.connector.network.session.auth; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.geysermc.api.session.AuthData; + +import java.util.UUID; + +@Getter +@AllArgsConstructor +public class BedrockAuthData implements AuthData { + + private String name; + private UUID UUID; + private String xboxUUID; +} diff --git a/connector/src/main/java/org/geysermc/connector/network/session/cache/WindowCache.java b/connector/src/main/java/org/geysermc/connector/network/session/cache/WindowCache.java new file mode 100644 index 000000000..0ce8b7c04 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/session/cache/WindowCache.java @@ -0,0 +1,54 @@ +package org.geysermc.connector.network.session.cache; + +import com.nukkitx.protocol.bedrock.packet.ModalFormRequestPacket; +import lombok.Getter; +import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.api.window.FormWindow; + +import java.util.HashMap; +import java.util.Map; + +public class WindowCache { + + private GeyserSession session; + + public WindowCache(GeyserSession session) { + this.session = session; + } + + @Getter + private Map windows = new HashMap(); + + public void addWindow(FormWindow window) { + windows.put(windows.size() + 1, window); + } + + public void addWindow(FormWindow window, int id) { + windows.put(id, window); + } + + public void showWindow(FormWindow window) { + showWindow(window, windows.size() + 1); + } + + public void showWindow(int id) { + if (!windows.containsKey(id)) + return; + + ModalFormRequestPacket formRequestPacket = new ModalFormRequestPacket(); + formRequestPacket.setFormId(id); + formRequestPacket.setFormData(windows.get(id).getJSONData()); + + session.getUpstream().sendPacket(formRequestPacket); + } + + public void showWindow(FormWindow window, int id) { + ModalFormRequestPacket formRequestPacket = new ModalFormRequestPacket(); + formRequestPacket.setFormId(id); + formRequestPacket.setFormData(window.getJSONData()); + + session.getUpstream().sendPacket(formRequestPacket); + + addWindow(window, id); + } +}