diff --git a/api/geyser/pom.xml b/api/geyser/pom.xml
index 88f1cafdc..b2f448589 100644
--- a/api/geyser/pom.xml
+++ b/api/geyser/pom.xml
@@ -26,6 +26,12 @@
3.19.0
provided
+
+ net.kyori
+ event-api
+ 3.0.0
+ provided
+
net.kyori
adventure-api
@@ -33,10 +39,10 @@
compile
- net.kyori
- event-api
- 3.0.0
- provided
+ org.yaml
+ snakeyaml
+ 1.27
+ compile
org.geysermc
diff --git a/api/geyser/src/main/java/org/geysermc/geyser/api/GeyserApi.java b/api/geyser/src/main/java/org/geysermc/geyser/api/GeyserApi.java
index dbdee8b4e..2bddc9ef5 100644
--- a/api/geyser/src/main/java/org/geysermc/geyser/api/GeyserApi.java
+++ b/api/geyser/src/main/java/org/geysermc/geyser/api/GeyserApi.java
@@ -29,6 +29,7 @@ import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.geysermc.api.Geyser;
import org.geysermc.api.GeyserApiBase;
+import org.geysermc.geyser.api.command.CommandManager;
import org.geysermc.geyser.api.connection.GeyserConnection;
import org.geysermc.geyser.api.event.EventBus;
import org.geysermc.geyser.api.extension.ExtensionManager;
@@ -89,6 +90,13 @@ public interface GeyserApi extends GeyserApiBase {
*/
ExtensionManager extensionManager();
+ /**
+ * Gets the {@link CommandManager}.
+ *
+ * @return the command manager
+ */
+ CommandManager commandManager();
+
/**
* Gets the {@link EventBus} for handling
* Geyser events.
diff --git a/api/geyser/src/main/java/org/geysermc/geyser/api/command/Command.java b/api/geyser/src/main/java/org/geysermc/geyser/api/command/Command.java
new file mode 100644
index 000000000..2c48473c6
--- /dev/null
+++ b/api/geyser/src/main/java/org/geysermc/geyser/api/command/Command.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2019-2022 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.geyser.api.command;
+
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.geysermc.geyser.api.GeyserApi;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Represents a command.
+ */
+public interface Command {
+
+ /**
+ * Gets the command name.
+ *
+ * @return the command name
+ */
+ @NonNull
+ String name();
+
+ /**
+ * Gets the command description.
+ *
+ * @return the command description
+ */
+ @NonNull
+ String description();
+
+ /**
+ * Gets the permission node associated with
+ * this command.
+ *
+ * @return the permission node for this command
+ */
+ @NonNull
+ String permission();
+
+ /**
+ * Gets the aliases for this command.
+ *
+ * @return the aliases for this command
+ */
+ @NonNull
+ List aliases();
+
+ /**
+ * Gets if this command is executable on console.
+ *
+ * @return if this command is executable on console
+ */
+ boolean isExecutableOnConsole();
+
+ /**
+ * Gets the subcommands associated with this
+ * command. Mainly used within the Geyser Standalone
+ * GUI to know what subcommands are supported.
+ *
+ * @return the subcommands associated with this command
+ */
+ @NonNull
+ default List subCommands() {
+ return Collections.emptyList();
+ }
+
+ /**
+ * Used to send a deny message to Java players if this command can only be used by Bedrock players.
+ *
+ * @return true if this command can only be used by Bedrock players.
+ */
+ default boolean isBedrockOnly() {
+ return false;
+ }
+
+ static Command.Builder builder(Class sourceType) {
+ return GeyserApi.api().commandManager().provideBuilder(sourceType);
+ }
+
+ interface Builder {
+
+ Builder name(String name);
+
+ Builder description(String description);
+
+ Builder permission(String permission);
+
+ Builder aliases(List aliases);
+
+ Builder executableOnConsole(boolean executableOnConsole);
+
+ Builder subCommands(List subCommands);
+
+ Builder bedrockOnly(boolean bedrockOnly);
+
+ Builder executor(CommandExecutor executor);
+
+ Command build();
+ }
+}
diff --git a/api/geyser/src/main/java/org/geysermc/geyser/api/command/CommandExecutor.java b/api/geyser/src/main/java/org/geysermc/geyser/api/command/CommandExecutor.java
new file mode 100644
index 000000000..d384d097c
--- /dev/null
+++ b/api/geyser/src/main/java/org/geysermc/geyser/api/command/CommandExecutor.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2019-2022 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.geyser.api.command;
+
+/**
+ * Handles executing a command.
+ *
+ * @param the command source
+ */
+public interface CommandExecutor {
+
+ /**
+ * Executes the given {@link Command} with the given
+ * {@link CommandSource}.
+ *
+ * @param source the command source
+ * @param command the command
+ * @param args the arguments
+ */
+ void execute(T source, Command command, String[] args);
+}
diff --git a/api/geyser/src/main/java/org/geysermc/geyser/api/command/CommandManager.java b/api/geyser/src/main/java/org/geysermc/geyser/api/command/CommandManager.java
new file mode 100644
index 000000000..864ba71a4
--- /dev/null
+++ b/api/geyser/src/main/java/org/geysermc/geyser/api/command/CommandManager.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2019-2022 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.geyser.api.command;
+
+import org.checkerframework.checker.nullness.qual.NonNull;
+
+import java.util.Map;
+
+/**
+ * Manages Bedrock commands within Geyser.
+ */
+public abstract class CommandManager {
+
+ /**
+ * Provides a {@link Command.Builder}.
+ *
+ * @param sourceType the command source type
+ * @param the type
+ * @return a command builder
+ */
+ protected abstract Command.Builder provideBuilder(Class sourceType);
+
+ /**
+ * Registers the given {@link Command}.
+ *
+ * @param command the command to register
+ */
+ public abstract void register(@NonNull Command command);
+
+ /**
+ * Unregisters the given {@link Command}.
+ *
+ * @param command the command to unregister
+ */
+ public abstract void unregister(@NonNull Command command);
+
+ /**
+ * Gets all the registered {@link Command}s.
+ *
+ * @return all the registered commands
+ */
+ @NonNull
+ public abstract Map commands();
+}
diff --git a/core/src/main/java/org/geysermc/geyser/command/CommandSender.java b/api/geyser/src/main/java/org/geysermc/geyser/api/command/CommandSource.java
similarity index 66%
rename from core/src/main/java/org/geysermc/geyser/command/CommandSender.java
rename to api/geyser/src/main/java/org/geysermc/geyser/api/command/CommandSource.java
index d9d1bcfbc..aabf0c4e8 100644
--- a/core/src/main/java/org/geysermc/geyser/command/CommandSender.java
+++ b/api/geyser/src/main/java/org/geysermc/geyser/api/command/CommandSource.java
@@ -23,45 +23,57 @@
* @link https://github.com/GeyserMC/Geyser
*/
-package org.geysermc.geyser.command;
-
-import org.geysermc.geyser.text.GeyserLocale;
+package org.geysermc.geyser.api.command;
/**
- * Implemented on top of any class that can send a command.
- * For example, it wraps around Spigot's CommandSender class.
+ * Represents an instance capable of sending commands.
*/
-public interface CommandSender {
+public interface CommandSource {
+ /**
+ * The name of the command source.
+ *
+ * @return the name of the command source
+ */
String name();
+ /**
+ * Sends the given message to the command source
+ *
+ * @param message the message to send
+ */
+ void sendMessage(String message);
+
+ /**
+ * Sends the given messages to the command source
+ *
+ * @param messages the messages to send
+ */
default void sendMessage(String[] messages) {
for (String message : messages) {
sendMessage(message);
}
}
- void sendMessage(String message);
-
/**
- * @return true if the specified sender is from the console.
+ * If this source is the console.
+ *
+ * @return true if this source is the console
*/
boolean isConsole();
/**
- * Returns the locale of the command sender. Defaults to the default locale at {@link GeyserLocale#getDefaultLocale()}.
- *
- * @return the locale of the command sender.
+ * Returns the locale of the command source.
+ *
+ * @return the locale of the command source.
*/
- default String getLocale() {
- return GeyserLocale.getDefaultLocale();
- }
+ String locale();
/**
- * Checks if the CommandSender has a permission
+ * Checks if this command source has the given permission
*
* @param permission The permission node to check
- * @return true if the CommandSender has the requested permission, false if not
+ * @return true if this command source has a permission
*/
boolean hasPermission(String permission);
}
diff --git a/api/geyser/src/main/java/org/geysermc/geyser/api/connection/GeyserConnection.java b/api/geyser/src/main/java/org/geysermc/geyser/api/connection/GeyserConnection.java
index 036c7c591..13fd60407 100644
--- a/api/geyser/src/main/java/org/geysermc/geyser/api/connection/GeyserConnection.java
+++ b/api/geyser/src/main/java/org/geysermc/geyser/api/connection/GeyserConnection.java
@@ -26,9 +26,10 @@
package org.geysermc.geyser.api.connection;
import org.geysermc.api.connection.Connection;
+import org.geysermc.geyser.api.command.CommandSource;
/**
* Represents a player connection used in Geyser.
*/
-public interface GeyserConnection extends Connection {
+public interface GeyserConnection extends Connection, CommandSource {
}
diff --git a/api/geyser/src/main/java/org/geysermc/geyser/api/event/EventBus.java b/api/geyser/src/main/java/org/geysermc/geyser/api/event/EventBus.java
index a26e8c653..0352dcc9e 100644
--- a/api/geyser/src/main/java/org/geysermc/geyser/api/event/EventBus.java
+++ b/api/geyser/src/main/java/org/geysermc/geyser/api/event/EventBus.java
@@ -40,18 +40,7 @@ public interface EventBus {
/**
* Subscribes to the given event see {@link EventSubscription}.
*
- * @param eventClass the class of the event
- * @param consumer the consumer for handling the event
- * @param the event class
- * @return the event subscription
- */
- @NonNull
- EventSubscription subscribe(@NonNull Class eventClass, @NonNull Consumer super T> consumer);
-
- /**
- * Subscribes to the given event see {@link EventSubscription}.
- *
- * The difference between this method and {@link #subscribe(Class, Consumer)}
+ * The difference between this method and {@link ExtensionEventBus#subscribe(Class, Consumer)}
* is that this method takes in an extension parameter which allows for
* the event to be unsubscribed upon extension disable and reloads.
*
@@ -79,6 +68,13 @@ public interface EventBus {
*/
void register(@NonNull Extension extension, @NonNull Object eventHolder);
+ /**
+ * Unregisters all events from a given {@link Extension}.
+ *
+ * @param extension the extension
+ */
+ void unregisterAll(@NonNull Extension extension);
+
/**
* Fires the given {@link Event}.
*
diff --git a/api/geyser/src/main/java/org/geysermc/geyser/api/event/EventSubscription.java b/api/geyser/src/main/java/org/geysermc/geyser/api/event/EventSubscription.java
index daa05ab21..2870c0ba6 100644
--- a/api/geyser/src/main/java/org/geysermc/geyser/api/event/EventSubscription.java
+++ b/api/geyser/src/main/java/org/geysermc/geyser/api/event/EventSubscription.java
@@ -63,7 +63,7 @@ public interface EventSubscription {
*
* @return the extension that owns this subscription
*/
- @Nullable
+ @NonNull
Extension owner();
/**
diff --git a/api/geyser/src/main/java/org/geysermc/geyser/api/event/ExtensionEventBus.java b/api/geyser/src/main/java/org/geysermc/geyser/api/event/ExtensionEventBus.java
new file mode 100644
index 000000000..db0209e5f
--- /dev/null
+++ b/api/geyser/src/main/java/org/geysermc/geyser/api/event/ExtensionEventBus.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2019-2022 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.geyser.api.event;
+
+import org.checkerframework.checker.nullness.qual.NonNull;
+
+import java.util.function.Consumer;
+
+/**
+ * An {@link EventBus} with additional methods that implicitly
+ * set the extension instance.
+ *
+ */
+public interface ExtensionEventBus extends EventBus {
+
+ /**
+ * Subscribes to the given event see {@link EventSubscription}.
+ *
+ * @param eventClass the class of the event
+ * @param consumer the consumer for handling the event
+ * @param the event class
+ * @return the event subscription
+ */
+ @NonNull
+ EventSubscription subscribe(@NonNull Class eventClass, @NonNull Consumer super T> consumer);
+
+ /**
+ * Registers events for the given listener.
+ *
+ * @param eventHolder the listener
+ */
+ void register(@NonNull Object eventHolder);
+
+ /**
+ * Unregisters all events for this extension.
+ */
+ void unregisterAll();
+}
diff --git a/api/geyser/src/main/java/org/geysermc/geyser/api/event/connection/ConnectionEvent.java b/api/geyser/src/main/java/org/geysermc/geyser/api/event/connection/ConnectionEvent.java
new file mode 100644
index 000000000..9dcb68908
--- /dev/null
+++ b/api/geyser/src/main/java/org/geysermc/geyser/api/event/connection/ConnectionEvent.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2019-2022 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.geyser.api.event.connection;
+
+import lombok.RequiredArgsConstructor;
+import org.geysermc.geyser.api.connection.GeyserConnection;
+import org.geysermc.geyser.api.event.Event;
+
+/**
+ * An event that contains a {@link GeyserConnection}.
+ */
+@RequiredArgsConstructor
+public abstract class ConnectionEvent implements Event {
+ private final GeyserConnection connection;
+
+ /**
+ * Gets the {@link GeyserConnection}.
+ *
+ * @return the connection
+ */
+ public GeyserConnection connection() {
+ return this.connection;
+ }
+}
diff --git a/api/geyser/src/main/java/org/geysermc/geyser/api/event/downstream/ServerDefineCommandsEvent.java b/api/geyser/src/main/java/org/geysermc/geyser/api/event/downstream/ServerDefineCommandsEvent.java
new file mode 100644
index 000000000..559631acf
--- /dev/null
+++ b/api/geyser/src/main/java/org/geysermc/geyser/api/event/downstream/ServerDefineCommandsEvent.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2019-2022 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.geyser.api.event.downstream;
+
+import org.geysermc.geyser.api.connection.GeyserConnection;
+import org.geysermc.geyser.api.event.Cancellable;
+import org.geysermc.geyser.api.event.connection.ConnectionEvent;
+
+import java.util.Set;
+
+/**
+ * Called when the downstream server defines the commands available on the server.
+ */
+public class ServerDefineCommandsEvent extends ConnectionEvent implements Cancellable {
+ private final Set extends CommandInfo> commands;
+ private boolean cancelled;
+
+ public ServerDefineCommandsEvent(GeyserConnection connection, Set extends CommandInfo> commands) {
+ super(connection);
+ this.commands = commands;
+ }
+
+ /**
+ * A mutable collection of the commands sent over.
+ *
+ * @return a mutable collection of the commands sent over
+ */
+ public Set extends CommandInfo> commands() {
+ return this.commands;
+ }
+
+ @Override
+ public boolean isCancelled() {
+ return this.cancelled;
+ }
+
+ @Override
+ public void setCancelled(boolean cancelled) {
+ this.cancelled = cancelled;
+ }
+
+ public interface CommandInfo {
+
+ /**
+ * Gets the name of the command.
+ *
+ * @return the name of the command
+ */
+ String name();
+
+ /**
+ * Gets the description of the command.
+ *
+ * @return the description of the command
+ */
+ String description();
+ }
+}
diff --git a/api/geyser/src/main/java/org/geysermc/geyser/api/event/lifecycle/GeyserDefineCommandsEvent.java b/api/geyser/src/main/java/org/geysermc/geyser/api/event/lifecycle/GeyserDefineCommandsEvent.java
new file mode 100644
index 000000000..7f64a4622
--- /dev/null
+++ b/api/geyser/src/main/java/org/geysermc/geyser/api/event/lifecycle/GeyserDefineCommandsEvent.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2019-2022 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.geyser.api.event.lifecycle;
+
+import org.geysermc.geyser.api.command.Command;
+import org.geysermc.geyser.api.command.CommandManager;
+import org.geysermc.geyser.api.event.Event;
+
+import java.util.Map;
+
+/**
+ * Called when commands are defined within Geyser.
+ *
+ * @param commandManager the command manager
+ * @param commands a mutable list of the currently
+ * registered default commands
+ */
+public record GeyserDefineCommandsEvent(CommandManager commandManager, Map commands) implements Event {
+}
diff --git a/api/geyser/src/main/java/org/geysermc/geyser/api/extension/Extension.java b/api/geyser/src/main/java/org/geysermc/geyser/api/extension/Extension.java
index 097cabdc3..357165ffe 100644
--- a/api/geyser/src/main/java/org/geysermc/geyser/api/extension/Extension.java
+++ b/api/geyser/src/main/java/org/geysermc/geyser/api/extension/Extension.java
@@ -27,6 +27,7 @@ package org.geysermc.geyser.api.extension;
import org.geysermc.api.GeyserApiBase;
import org.geysermc.geyser.api.GeyserApi;
+import org.geysermc.geyser.api.event.ExtensionEventBus;
import java.nio.file.Path;
@@ -80,6 +81,15 @@ public interface Extension {
return this.extensionLoader().dataFolder(this);
}
+ /**
+ * Gets the {@link ExtensionEventBus}.
+ *
+ * @return the extension event bus
+ */
+ default ExtensionEventBus eventBus() {
+ return this.extensionLoader().eventBus(this);
+ }
+
/**
* Gets the {@link ExtensionManager}.
*
diff --git a/api/geyser/src/main/java/org/geysermc/geyser/api/extension/ExtensionLoader.java b/api/geyser/src/main/java/org/geysermc/geyser/api/extension/ExtensionLoader.java
index 651afd9eb..c84c37919 100644
--- a/api/geyser/src/main/java/org/geysermc/geyser/api/extension/ExtensionLoader.java
+++ b/api/geyser/src/main/java/org/geysermc/geyser/api/extension/ExtensionLoader.java
@@ -26,6 +26,7 @@
package org.geysermc.geyser.api.extension;
import org.checkerframework.checker.nullness.qual.NonNull;
+import org.geysermc.geyser.api.event.ExtensionEventBus;
import java.nio.file.Path;
@@ -68,6 +69,15 @@ public abstract class ExtensionLoader {
@NonNull
protected abstract ExtensionDescription description(@NonNull Extension extension);
+ /**
+ * Gets the given {@link Extension}'s {@link ExtensionEventBus}.
+ *
+ * @param extension the extension
+ * @return the extension's event bus
+ */
+ @NonNull
+ protected abstract ExtensionEventBus eventBus(@NonNull Extension extension);
+
/**
* Gets the {@link ExtensionLogger} for the given {@link Extension}.
*
diff --git a/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/GeyserBungeePlugin.java b/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/GeyserBungeePlugin.java
index f35082359..bb90e5000 100644
--- a/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/GeyserBungeePlugin.java
+++ b/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/GeyserBungeePlugin.java
@@ -30,7 +30,7 @@ import net.md_5.bungee.api.plugin.Plugin;
import org.geysermc.common.PlatformType;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.GeyserBootstrap;
-import org.geysermc.geyser.command.CommandManager;
+import org.geysermc.geyser.command.GeyserCommandManager;
import org.geysermc.geyser.session.auth.AuthType;
import org.geysermc.geyser.configuration.GeyserConfiguration;
import org.geysermc.geyser.dump.BootstrapDumpInfo;
@@ -126,6 +126,7 @@ public class GeyserBungeePlugin extends Plugin implements GeyserBootstrap {
this.geyserInjector.initializeLocalChannel(this);
this.geyserCommandManager = new GeyserBungeeCommandManager(geyser);
+ this.geyserCommandManager.init();
if (geyserConfig.isLegacyPingPassthrough()) {
this.geyserBungeePingPassthrough = GeyserLegacyPingPassthrough.init(geyser);
@@ -157,7 +158,7 @@ public class GeyserBungeePlugin extends Plugin implements GeyserBootstrap {
}
@Override
- public CommandManager getGeyserCommandManager() {
+ public GeyserCommandManager getGeyserCommandManager() {
return this.geyserCommandManager;
}
diff --git a/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/command/BungeeCommandSender.java b/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/command/BungeeCommandSource.java
similarity index 89%
rename from bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/command/BungeeCommandSender.java
rename to bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/command/BungeeCommandSource.java
index 05df8ba97..801fc8777 100644
--- a/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/command/BungeeCommandSender.java
+++ b/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/command/BungeeCommandSource.java
@@ -27,17 +27,17 @@ package org.geysermc.geyser.platform.bungeecord.command;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.connection.ProxiedPlayer;
-import org.geysermc.geyser.command.CommandSender;
+import org.geysermc.geyser.command.GeyserCommandSource;
import org.geysermc.geyser.text.GeyserLocale;
-public class BungeeCommandSender implements CommandSender {
+public class BungeeCommandSource implements GeyserCommandSource {
private final net.md_5.bungee.api.CommandSender handle;
- public BungeeCommandSender(net.md_5.bungee.api.CommandSender handle) {
+ public BungeeCommandSource(net.md_5.bungee.api.CommandSender handle) {
this.handle = handle;
// Ensure even Java players' languages are loaded
- GeyserLocale.loadGeyserLocale(getLocale());
+ GeyserLocale.loadGeyserLocale(this.locale());
}
@Override
@@ -56,7 +56,7 @@ public class BungeeCommandSender implements CommandSender {
}
@Override
- public String getLocale() {
+ public String locale() {
if (handle instanceof ProxiedPlayer player) {
String locale = player.getLocale().getLanguage() + "_" + player.getLocale().getCountry();
return GeyserLocale.formatLocale(locale);
diff --git a/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/command/GeyserBungeeCommandExecutor.java b/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/command/GeyserBungeeCommandExecutor.java
index 5bb323aac..87e5f9e13 100644
--- a/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/command/GeyserBungeeCommandExecutor.java
+++ b/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/command/GeyserBungeeCommandExecutor.java
@@ -30,7 +30,7 @@ import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.plugin.Command;
import net.md_5.bungee.api.plugin.TabExecutor;
import org.geysermc.geyser.GeyserImpl;
-import org.geysermc.geyser.command.CommandExecutor;
+import org.geysermc.geyser.command.GeyserCommandExecutor;
import org.geysermc.geyser.command.GeyserCommand;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.text.GeyserLocale;
@@ -39,30 +39,30 @@ import java.util.Arrays;
import java.util.Collections;
public class GeyserBungeeCommandExecutor extends Command implements TabExecutor {
- private final CommandExecutor commandExecutor;
+ private final GeyserCommandExecutor commandExecutor;
public GeyserBungeeCommandExecutor(GeyserImpl geyser) {
super("geyser");
- this.commandExecutor = new CommandExecutor(geyser);
+ this.commandExecutor = new GeyserCommandExecutor(geyser);
}
@Override
public void execute(CommandSender sender, String[] args) {
- BungeeCommandSender commandSender = new BungeeCommandSender(sender);
+ BungeeCommandSource commandSender = new BungeeCommandSource(sender);
GeyserSession session = this.commandExecutor.getGeyserSession(commandSender);
if (args.length > 0) {
GeyserCommand command = this.commandExecutor.getCommand(args[0]);
if (command != null) {
- if (!sender.hasPermission(command.getPermission())) {
- String message = GeyserLocale.getPlayerLocaleString("geyser.bootstrap.command.permission_fail", commandSender.getLocale());
+ if (!sender.hasPermission(command.permission())) {
+ String message = GeyserLocale.getPlayerLocaleString("geyser.bootstrap.command.permission_fail", commandSender.locale());
commandSender.sendMessage(ChatColor.RED + message);
return;
}
if (command.isBedrockOnly() && session == null) {
- String message = GeyserLocale.getPlayerLocaleString("geyser.bootstrap.command.bedrock_only", commandSender.getLocale());
+ String message = GeyserLocale.getPlayerLocaleString("geyser.bootstrap.command.bedrock_only", commandSender.locale());
commandSender.sendMessage(ChatColor.RED + message);
return;
@@ -77,7 +77,7 @@ public class GeyserBungeeCommandExecutor extends Command implements TabExecutor
@Override
public Iterable onTabComplete(CommandSender sender, String[] args) {
if (args.length == 1) {
- return commandExecutor.tabComplete(new BungeeCommandSender(sender));
+ return commandExecutor.tabComplete(new BungeeCommandSource(sender));
} else {
return Collections.emptyList();
}
diff --git a/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/command/GeyserBungeeCommandManager.java b/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/command/GeyserBungeeCommandManager.java
index 019544c28..e0fd7a4ac 100644
--- a/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/command/GeyserBungeeCommandManager.java
+++ b/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/command/GeyserBungeeCommandManager.java
@@ -26,16 +26,16 @@
package org.geysermc.geyser.platform.bungeecord.command;
import org.geysermc.geyser.GeyserImpl;
-import org.geysermc.geyser.command.CommandManager;
+import org.geysermc.geyser.command.GeyserCommandManager;
-public class GeyserBungeeCommandManager extends CommandManager {
+public class GeyserBungeeCommandManager extends GeyserCommandManager {
public GeyserBungeeCommandManager(GeyserImpl geyser) {
super(geyser);
}
@Override
- public String getDescription(String command) {
+ public String description(String command) {
return ""; // no support for command descriptions in bungee
}
}
diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java
index bdf28a203..e0ad866c8 100644
--- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java
+++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java
@@ -34,7 +34,7 @@ import org.bukkit.plugin.java.JavaPlugin;
import org.geysermc.common.PlatformType;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.GeyserBootstrap;
-import org.geysermc.geyser.command.CommandManager;
+import org.geysermc.geyser.command.GeyserCommandManager;
import org.geysermc.geyser.session.auth.AuthType;
import org.geysermc.geyser.configuration.GeyserConfiguration;
import org.geysermc.geyser.dump.BootstrapDumpInfo;
@@ -48,7 +48,7 @@ import org.geysermc.geyser.text.GeyserLocale;
import org.geysermc.geyser.adapters.spigot.SpigotAdapters;
import org.geysermc.geyser.platform.spigot.command.GeyserSpigotCommandExecutor;
import org.geysermc.geyser.platform.spigot.command.GeyserSpigotCommandManager;
-import org.geysermc.geyser.platform.spigot.command.SpigotCommandSender;
+import org.geysermc.geyser.platform.spigot.command.SpigotCommandSource;
import org.geysermc.geyser.platform.spigot.world.GeyserPistonListener;
import org.geysermc.geyser.platform.spigot.world.GeyserSpigot1_11CraftingListener;
import org.geysermc.geyser.platform.spigot.world.GeyserSpigotBlockPlaceListener;
@@ -161,6 +161,7 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap {
}
this.geyserCommandManager = new GeyserSpigotCommandManager(geyser);
+ this.geyserCommandManager.init();
boolean isViaVersion = Bukkit.getPluginManager().getPlugin("ViaVersion") != null;
if (isViaVersion) {
@@ -182,7 +183,7 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap {
boolean isPre1_12 = !isCompatible(Bukkit.getServer().getVersion(), "1.12.0");
// Set if we need to use a different method for getting a player's locale
- SpigotCommandSender.setUseLegacyLocaleMethod(isPre1_12);
+ SpigotCommandSource.setUseLegacyLocaleMethod(isPre1_12);
// We want to do this late in the server startup process to allow plugins such as ViaVersion and ProtocolLib
// To do their job injecting, then connect into *that*
@@ -267,7 +268,7 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap {
}
@Override
- public CommandManager getGeyserCommandManager() {
+ public GeyserCommandManager getGeyserCommandManager() {
return this.geyserCommandManager;
}
diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/command/GeyserSpigotCommandExecutor.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/command/GeyserSpigotCommandExecutor.java
index b1bcfcaf8..35cb2d03a 100644
--- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/command/GeyserSpigotCommandExecutor.java
+++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/command/GeyserSpigotCommandExecutor.java
@@ -30,7 +30,7 @@ import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import org.geysermc.geyser.GeyserImpl;
-import org.geysermc.geyser.command.CommandExecutor;
+import org.geysermc.geyser.command.GeyserCommandExecutor;
import org.geysermc.geyser.command.GeyserCommand;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.text.GeyserLocale;
@@ -39,7 +39,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
-public class GeyserSpigotCommandExecutor extends CommandExecutor implements TabExecutor {
+public class GeyserSpigotCommandExecutor extends GeyserCommandExecutor implements TabExecutor {
public GeyserSpigotCommandExecutor(GeyserImpl geyser) {
super(geyser);
@@ -47,20 +47,20 @@ public class GeyserSpigotCommandExecutor extends CommandExecutor implements TabE
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
- SpigotCommandSender commandSender = new SpigotCommandSender(sender);
+ SpigotCommandSource commandSender = new SpigotCommandSource(sender);
GeyserSession session = getGeyserSession(commandSender);
if (args.length > 0) {
GeyserCommand geyserCommand = getCommand(args[0]);
if (geyserCommand != null) {
- if (!sender.hasPermission(geyserCommand.getPermission())) {
- String message = GeyserLocale.getPlayerLocaleString("geyser.bootstrap.command.permission_fail", commandSender.getLocale());
+ if (!sender.hasPermission(geyserCommand.permission())) {
+ String message = GeyserLocale.getPlayerLocaleString("geyser.bootstrap.command.permission_fail", commandSender.locale());
commandSender.sendMessage(ChatColor.RED + message);
return true;
}
if (geyserCommand.isBedrockOnly() && session == null) {
- sender.sendMessage(ChatColor.RED + GeyserLocale.getPlayerLocaleString("geyser.bootstrap.command.bedrock_only", commandSender.getLocale()));
+ sender.sendMessage(ChatColor.RED + GeyserLocale.getPlayerLocaleString("geyser.bootstrap.command.bedrock_only", commandSender.locale()));
return true;
}
geyserCommand.execute(session, commandSender, args.length > 1 ? Arrays.copyOfRange(args, 1, args.length) : new String[0]);
@@ -76,7 +76,7 @@ public class GeyserSpigotCommandExecutor extends CommandExecutor implements TabE
@Override
public List onTabComplete(CommandSender sender, Command command, String label, String[] args) {
if (args.length == 1) {
- return tabComplete(new SpigotCommandSender(sender));
+ return tabComplete(new SpigotCommandSource(sender));
}
return Collections.emptyList();
}
diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/command/GeyserSpigotCommandManager.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/command/GeyserSpigotCommandManager.java
index 103390ab8..22cb95c32 100644
--- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/command/GeyserSpigotCommandManager.java
+++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/command/GeyserSpigotCommandManager.java
@@ -29,11 +29,11 @@ import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandMap;
import org.geysermc.geyser.GeyserImpl;
-import org.geysermc.geyser.command.CommandManager;
+import org.geysermc.geyser.command.GeyserCommandManager;
import java.lang.reflect.Field;
-public class GeyserSpigotCommandManager extends CommandManager {
+public class GeyserSpigotCommandManager extends GeyserCommandManager {
private static CommandMap COMMAND_MAP;
@@ -52,7 +52,7 @@ public class GeyserSpigotCommandManager extends CommandManager {
}
@Override
- public String getDescription(String command) {
+ public String description(String command) {
Command cmd = COMMAND_MAP.getCommand(command.replace("/", ""));
return cmd != null ? cmd.getDescription() : "";
}
diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/command/SpigotCommandSender.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/command/SpigotCommandSource.java
similarity index 95%
rename from bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/command/SpigotCommandSender.java
rename to bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/command/SpigotCommandSource.java
index a05a6ebe0..839e4d88e 100644
--- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/command/SpigotCommandSender.java
+++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/command/SpigotCommandSource.java
@@ -28,13 +28,13 @@ package org.geysermc.geyser.platform.spigot.command;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.Player;
import org.geysermc.geyser.GeyserImpl;
-import org.geysermc.geyser.command.CommandSender;
+import org.geysermc.geyser.command.GeyserCommandSource;
import org.geysermc.geyser.text.GeyserLocale;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
-public class SpigotCommandSender implements CommandSender {
+public class SpigotCommandSource implements GeyserCommandSource {
/**
* Whether to use {@code Player.getLocale()} or {@code Player.spigot().getLocale()}, depending on version.
@@ -46,7 +46,7 @@ public class SpigotCommandSender implements CommandSender {
private final org.bukkit.command.CommandSender handle;
private final String locale;
- public SpigotCommandSender(org.bukkit.command.CommandSender handle) {
+ public SpigotCommandSource(org.bukkit.command.CommandSender handle) {
this.handle = handle;
this.locale = getSpigotLocale();
// Ensure even Java players' languages are loaded
@@ -69,7 +69,7 @@ public class SpigotCommandSender implements CommandSender {
}
@Override
- public String getLocale() {
+ public String locale() {
return locale;
}
diff --git a/bootstrap/sponge/src/main/java/org/geysermc/geyser/platform/sponge/GeyserSpongePlugin.java b/bootstrap/sponge/src/main/java/org/geysermc/geyser/platform/sponge/GeyserSpongePlugin.java
index f5d6613c7..894368e5e 100644
--- a/bootstrap/sponge/src/main/java/org/geysermc/geyser/platform/sponge/GeyserSpongePlugin.java
+++ b/bootstrap/sponge/src/main/java/org/geysermc/geyser/platform/sponge/GeyserSpongePlugin.java
@@ -29,7 +29,7 @@ import com.google.inject.Inject;
import org.geysermc.common.PlatformType;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.GeyserBootstrap;
-import org.geysermc.geyser.command.CommandManager;
+import org.geysermc.geyser.command.GeyserCommandManager;
import org.geysermc.geyser.configuration.GeyserConfiguration;
import org.geysermc.geyser.dump.BootstrapDumpInfo;
import org.geysermc.geyser.ping.GeyserLegacyPingPassthrough;
@@ -120,6 +120,7 @@ public class GeyserSpongePlugin implements GeyserBootstrap {
}
this.geyserCommandManager = new GeyserSpongeCommandManager(Sponge.getCommandManager(), geyser);
+ this.geyserCommandManager.init();
Sponge.getCommandManager().register(this, new GeyserSpongeCommandExecutor(geyser), "geyser");
}
@@ -139,7 +140,7 @@ public class GeyserSpongePlugin implements GeyserBootstrap {
}
@Override
- public CommandManager getGeyserCommandManager() {
+ public GeyserCommandManager getGeyserCommandManager() {
return this.geyserCommandManager;
}
diff --git a/bootstrap/sponge/src/main/java/org/geysermc/geyser/platform/sponge/command/GeyserSpongeCommandExecutor.java b/bootstrap/sponge/src/main/java/org/geysermc/geyser/platform/sponge/command/GeyserSpongeCommandExecutor.java
index 825d0bf78..c8338e440 100644
--- a/bootstrap/sponge/src/main/java/org/geysermc/geyser/platform/sponge/command/GeyserSpongeCommandExecutor.java
+++ b/bootstrap/sponge/src/main/java/org/geysermc/geyser/platform/sponge/command/GeyserSpongeCommandExecutor.java
@@ -26,8 +26,8 @@
package org.geysermc.geyser.platform.sponge.command;
import org.geysermc.geyser.GeyserImpl;
-import org.geysermc.geyser.command.CommandExecutor;
-import org.geysermc.geyser.command.CommandSender;
+import org.geysermc.geyser.command.GeyserCommandExecutor;
+import org.geysermc.geyser.command.GeyserCommandSource;
import org.geysermc.geyser.command.GeyserCommand;
import org.geysermc.geyser.text.ChatColor;
import org.geysermc.geyser.session.GeyserSession;
@@ -45,7 +45,7 @@ import java.util.Collections;
import java.util.List;
import java.util.Optional;
-public class GeyserSpongeCommandExecutor extends CommandExecutor implements CommandCallable {
+public class GeyserSpongeCommandExecutor extends GeyserCommandExecutor implements CommandCallable {
public GeyserSpongeCommandExecutor(GeyserImpl geyser) {
super(geyser);
@@ -53,14 +53,14 @@ public class GeyserSpongeCommandExecutor extends CommandExecutor implements Comm
@Override
public CommandResult process(CommandSource source, String arguments) {
- CommandSender commandSender = new SpongeCommandSender(source);
+ GeyserCommandSource commandSender = new SpongeCommandSource(source);
GeyserSession session = getGeyserSession(commandSender);
String[] args = arguments.split(" ");
if (args.length > 0) {
GeyserCommand command = getCommand(args[0]);
if (command != null) {
- if (!source.hasPermission(command.getPermission())) {
+ if (!source.hasPermission(command.permission())) {
// Not ideal to use log here but we dont get a session
source.sendMessage(Text.of(ChatColor.RED + GeyserLocale.getLocaleStringLog("geyser.bootstrap.command.permission_fail")));
return CommandResult.success();
@@ -80,7 +80,7 @@ public class GeyserSpongeCommandExecutor extends CommandExecutor implements Comm
@Override
public List getSuggestions(CommandSource source, String arguments, @Nullable Location targetPosition) {
if (arguments.split(" ").length == 1) {
- return tabComplete(new SpongeCommandSender(source));
+ return tabComplete(new SpongeCommandSource(source));
}
return Collections.emptyList();
}
diff --git a/bootstrap/sponge/src/main/java/org/geysermc/geyser/platform/sponge/command/GeyserSpongeCommandManager.java b/bootstrap/sponge/src/main/java/org/geysermc/geyser/platform/sponge/command/GeyserSpongeCommandManager.java
index dce39870d..8e981f72a 100644
--- a/bootstrap/sponge/src/main/java/org/geysermc/geyser/platform/sponge/command/GeyserSpongeCommandManager.java
+++ b/bootstrap/sponge/src/main/java/org/geysermc/geyser/platform/sponge/command/GeyserSpongeCommandManager.java
@@ -26,12 +26,12 @@
package org.geysermc.geyser.platform.sponge.command;
import org.geysermc.geyser.GeyserImpl;
-import org.geysermc.geyser.command.CommandManager;
+import org.geysermc.geyser.command.GeyserCommandManager;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.command.CommandMapping;
import org.spongepowered.api.text.Text;
-public class GeyserSpongeCommandManager extends CommandManager {
+public class GeyserSpongeCommandManager extends GeyserCommandManager {
private final org.spongepowered.api.command.CommandManager handle;
public GeyserSpongeCommandManager(org.spongepowered.api.command.CommandManager handle, GeyserImpl geyser) {
@@ -41,7 +41,7 @@ public class GeyserSpongeCommandManager extends CommandManager {
}
@Override
- public String getDescription(String command) {
+ public String description(String command) {
return handle.get(command).map(CommandMapping::getCallable)
.map(callable -> callable.getShortDescription(Sponge.getServer().getConsole()).orElse(Text.EMPTY))
.orElse(Text.EMPTY).toPlain();
diff --git a/bootstrap/sponge/src/main/java/org/geysermc/geyser/platform/sponge/command/SpongeCommandSender.java b/bootstrap/sponge/src/main/java/org/geysermc/geyser/platform/sponge/command/SpongeCommandSource.java
similarity index 94%
rename from bootstrap/sponge/src/main/java/org/geysermc/geyser/platform/sponge/command/SpongeCommandSender.java
rename to bootstrap/sponge/src/main/java/org/geysermc/geyser/platform/sponge/command/SpongeCommandSource.java
index f57f3e276..664727c50 100644
--- a/bootstrap/sponge/src/main/java/org/geysermc/geyser/platform/sponge/command/SpongeCommandSender.java
+++ b/bootstrap/sponge/src/main/java/org/geysermc/geyser/platform/sponge/command/SpongeCommandSource.java
@@ -27,13 +27,13 @@ package org.geysermc.geyser.platform.sponge.command;
import lombok.AllArgsConstructor;
-import org.geysermc.geyser.command.CommandSender;
+import org.geysermc.geyser.command.GeyserCommandSource;
import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.command.source.ConsoleSource;
import org.spongepowered.api.text.Text;
@AllArgsConstructor
-public class SpongeCommandSender implements CommandSender {
+public class SpongeCommandSource implements GeyserCommandSource {
private CommandSource handle;
diff --git a/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/GeyserStandaloneBootstrap.java b/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/GeyserStandaloneBootstrap.java
index 43ab4b3fe..ca41d3c1d 100644
--- a/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/GeyserStandaloneBootstrap.java
+++ b/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/GeyserStandaloneBootstrap.java
@@ -41,15 +41,15 @@ import org.apache.logging.log4j.core.appender.ConsoleAppender;
import org.geysermc.common.PlatformType;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.GeyserBootstrap;
-import org.geysermc.geyser.command.CommandManager;
+import org.geysermc.geyser.command.GeyserCommandManager;
import org.geysermc.geyser.configuration.GeyserConfiguration;
import org.geysermc.geyser.configuration.GeyserJacksonConfiguration;
import org.geysermc.geyser.dump.BootstrapDumpInfo;
import org.geysermc.geyser.ping.GeyserLegacyPingPassthrough;
import org.geysermc.geyser.ping.IGeyserPingPassthrough;
+import org.geysermc.geyser.platform.standalone.command.GeyserStandaloneCommandManager;
import org.geysermc.geyser.util.FileUtils;
import org.geysermc.geyser.text.GeyserLocale;
-import org.geysermc.geyser.platform.standalone.command.GeyserCommandManager;
import org.geysermc.geyser.platform.standalone.gui.GeyserStandaloneGUI;
import java.io.File;
@@ -63,7 +63,7 @@ import java.util.stream.Collectors;
public class GeyserStandaloneBootstrap implements GeyserBootstrap {
- private GeyserCommandManager geyserCommandManager;
+ private GeyserStandaloneCommandManager geyserCommandManager;
private GeyserStandaloneConfiguration geyserConfig;
private GeyserStandaloneLogger geyserLogger;
private IGeyserPingPassthrough geyserPingPassthrough;
@@ -215,7 +215,8 @@ public class GeyserStandaloneBootstrap implements GeyserBootstrap {
logger.get().setLevel(geyserConfig.isDebugMode() ? Level.DEBUG : Level.INFO);
geyser = GeyserImpl.start(PlatformType.STANDALONE, this);
- geyserCommandManager = new GeyserCommandManager(geyser);
+ geyserCommandManager = new GeyserStandaloneCommandManager(geyser);
+ geyserCommandManager.init();
if (gui != null) {
gui.setupInterface(geyserLogger, geyserCommandManager);
@@ -260,7 +261,7 @@ public class GeyserStandaloneBootstrap implements GeyserBootstrap {
}
@Override
- public CommandManager getGeyserCommandManager() {
+ public GeyserCommandManager getGeyserCommandManager() {
return geyserCommandManager;
}
diff --git a/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/GeyserStandaloneLogger.java b/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/GeyserStandaloneLogger.java
index 3bd2a3960..f7ce6d052 100644
--- a/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/GeyserStandaloneLogger.java
+++ b/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/GeyserStandaloneLogger.java
@@ -31,11 +31,11 @@ import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.config.Configurator;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.GeyserLogger;
-import org.geysermc.geyser.command.CommandSender;
+import org.geysermc.geyser.command.GeyserCommandSource;
import org.geysermc.geyser.text.ChatColor;
@Log4j2
-public class GeyserStandaloneLogger extends SimpleTerminalConsole implements GeyserLogger, CommandSender {
+public class GeyserStandaloneLogger extends SimpleTerminalConsole implements GeyserLogger, GeyserCommandSource {
@Override
protected boolean isRunning() {
@@ -44,7 +44,7 @@ public class GeyserStandaloneLogger extends SimpleTerminalConsole implements Gey
@Override
protected void runCommand(String line) {
- GeyserImpl.getInstance().getCommandManager().runCommand(this, line);
+ GeyserImpl.getInstance().commandManager().runCommand(this, line);
}
@Override
diff --git a/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/command/GeyserCommandManager.java b/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/command/GeyserStandaloneCommandManager.java
similarity index 85%
rename from bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/command/GeyserCommandManager.java
rename to bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/command/GeyserStandaloneCommandManager.java
index 03d780f3c..e7b4cbe37 100644
--- a/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/command/GeyserCommandManager.java
+++ b/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/command/GeyserStandaloneCommandManager.java
@@ -26,16 +26,16 @@
package org.geysermc.geyser.platform.standalone.command;
import org.geysermc.geyser.GeyserImpl;
-import org.geysermc.geyser.command.CommandManager;
+import org.geysermc.geyser.command.GeyserCommandManager;
-public class GeyserCommandManager extends CommandManager {
+public class GeyserStandaloneCommandManager extends GeyserCommandManager {
- public GeyserCommandManager(GeyserImpl geyser) {
+ public GeyserStandaloneCommandManager(GeyserImpl geyser) {
super(geyser);
}
@Override
- public String getDescription(String command) {
+ public String description(String command) {
return ""; // this is not sent over the protocol, so we return none
}
}
diff --git a/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/gui/GeyserStandaloneGUI.java b/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/gui/GeyserStandaloneGUI.java
index 44faabdf5..5901da470 100644
--- a/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/gui/GeyserStandaloneGUI.java
+++ b/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/gui/GeyserStandaloneGUI.java
@@ -26,11 +26,12 @@
package org.geysermc.geyser.platform.standalone.gui;
import org.geysermc.geyser.GeyserImpl;
+import org.geysermc.geyser.api.command.Command;
import org.geysermc.geyser.command.GeyserCommand;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.text.GeyserLocale;
import org.geysermc.geyser.platform.standalone.GeyserStandaloneLogger;
-import org.geysermc.geyser.platform.standalone.command.GeyserCommandManager;
+import org.geysermc.geyser.platform.standalone.command.GeyserStandaloneCommandManager;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
@@ -255,33 +256,34 @@ public class GeyserStandaloneGUI {
* @param geyserStandaloneLogger The current logger
* @param geyserCommandManager The commands manager
*/
- public void setupInterface(GeyserStandaloneLogger geyserStandaloneLogger, GeyserCommandManager geyserCommandManager) {
+ public void setupInterface(GeyserStandaloneLogger geyserStandaloneLogger, GeyserStandaloneCommandManager geyserCommandManager) {
commandsMenu.removeAll();
optionsMenu.removeAll();
- for (Map.Entry command : geyserCommandManager.getCommands().entrySet()) {
+ for (Map.Entry entry : geyserCommandManager.getCommands().entrySet()) {
// Remove the offhand command and any alias commands to prevent duplicates in the list
- if (!command.getValue().isExecutableOnConsole() || command.getValue().getAliases().contains(command.getKey())) {
+ if (!entry.getValue().isExecutableOnConsole() || entry.getValue().aliases().contains(entry.getKey())) {
continue;
}
+ GeyserCommand command = (GeyserCommand) entry.getValue();
// Create the button that runs the command
- boolean hasSubCommands = command.getValue().hasSubCommands();
+ boolean hasSubCommands = !entry.getValue().subCommands().isEmpty();
// Add an extra menu if there are more commands that can be run
- JMenuItem commandButton = hasSubCommands ? new JMenu(command.getValue().getName()) : new JMenuItem(command.getValue().getName());
- commandButton.getAccessibleContext().setAccessibleDescription(command.getValue().getDescription());
+ JMenuItem commandButton = hasSubCommands ? new JMenu(entry.getValue().name()) : new JMenuItem(entry.getValue().name());
+ commandButton.getAccessibleContext().setAccessibleDescription(entry.getValue().description());
if (!hasSubCommands) {
- commandButton.addActionListener(e -> command.getValue().execute(null, geyserStandaloneLogger, new String[]{ }));
+ commandButton.addActionListener(e -> command.execute(null, geyserStandaloneLogger, new String[]{ }));
} else {
// Add a submenu that's the same name as the menu can't be pressed
- JMenuItem otherCommandButton = new JMenuItem(command.getValue().getName());
- otherCommandButton.getAccessibleContext().setAccessibleDescription(command.getValue().getDescription());
- otherCommandButton.addActionListener(e -> command.getValue().execute(null, geyserStandaloneLogger, new String[]{ }));
+ JMenuItem otherCommandButton = new JMenuItem(entry.getValue().name());
+ otherCommandButton.getAccessibleContext().setAccessibleDescription(entry.getValue().description());
+ otherCommandButton.addActionListener(e -> command.execute(null, geyserStandaloneLogger, new String[]{ }));
commandButton.add(otherCommandButton);
// Add a menu option for all possible subcommands
- for (String subCommandName : command.getValue().getSubCommands()) {
+ for (String subCommandName : entry.getValue().subCommands()) {
JMenuItem item = new JMenuItem(subCommandName);
- item.addActionListener(e -> command.getValue().execute(null, geyserStandaloneLogger, new String[]{subCommandName}));
+ item.addActionListener(e -> command.execute(null, geyserStandaloneLogger, new String[]{subCommandName}));
commandButton.add(item);
}
}
diff --git a/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/GeyserVelocityPlugin.java b/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/GeyserVelocityPlugin.java
index 6645ef595..a79fbb30b 100644
--- a/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/GeyserVelocityPlugin.java
+++ b/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/GeyserVelocityPlugin.java
@@ -38,6 +38,7 @@ import lombok.Getter;
import org.geysermc.common.PlatformType;
import org.geysermc.geyser.GeyserBootstrap;
import org.geysermc.geyser.GeyserImpl;
+import org.geysermc.geyser.command.GeyserCommandManager;
import org.geysermc.geyser.configuration.GeyserConfiguration;
import org.geysermc.geyser.dump.BootstrapDumpInfo;
import org.geysermc.geyser.ping.GeyserLegacyPingPassthrough;
@@ -145,6 +146,8 @@ public class GeyserVelocityPlugin implements GeyserBootstrap {
// Will be initialized after the proxy has been bound
this.geyserCommandManager = new GeyserVelocityCommandManager(geyser);
+ this.geyserCommandManager.init();
+
this.commandManager.register("geyser", new GeyserVelocityCommandExecutor(geyser));
if (geyserConfig.isLegacyPingPassthrough()) {
this.geyserPingPassthrough = GeyserLegacyPingPassthrough.init(geyser);
@@ -174,7 +177,7 @@ public class GeyserVelocityPlugin implements GeyserBootstrap {
}
@Override
- public org.geysermc.geyser.command.CommandManager getGeyserCommandManager() {
+ public GeyserCommandManager getGeyserCommandManager() {
return this.geyserCommandManager;
}
diff --git a/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/command/GeyserVelocityCommandExecutor.java b/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/command/GeyserVelocityCommandExecutor.java
index 30f6c2efd..d30d9ae9e 100644
--- a/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/command/GeyserVelocityCommandExecutor.java
+++ b/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/command/GeyserVelocityCommandExecutor.java
@@ -27,8 +27,8 @@ package org.geysermc.geyser.platform.velocity.command;
import com.velocitypowered.api.command.SimpleCommand;
import org.geysermc.geyser.GeyserImpl;
-import org.geysermc.geyser.command.CommandExecutor;
-import org.geysermc.geyser.command.CommandSender;
+import org.geysermc.geyser.command.GeyserCommandExecutor;
+import org.geysermc.geyser.command.GeyserCommandSource;
import org.geysermc.geyser.command.GeyserCommand;
import org.geysermc.geyser.text.ChatColor;
import org.geysermc.geyser.session.GeyserSession;
@@ -38,7 +38,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
-public class GeyserVelocityCommandExecutor extends CommandExecutor implements SimpleCommand {
+public class GeyserVelocityCommandExecutor extends GeyserCommandExecutor implements SimpleCommand {
public GeyserVelocityCommandExecutor(GeyserImpl geyser) {
super(geyser);
@@ -46,18 +46,18 @@ public class GeyserVelocityCommandExecutor extends CommandExecutor implements Si
@Override
public void execute(Invocation invocation) {
- CommandSender sender = new VelocityCommandSender(invocation.source());
+ GeyserCommandSource sender = new VelocityCommandSource(invocation.source());
GeyserSession session = getGeyserSession(sender);
if (invocation.arguments().length > 0) {
GeyserCommand command = getCommand(invocation.arguments()[0]);
if (command != null) {
- if (!invocation.source().hasPermission(getCommand(invocation.arguments()[0]).getPermission())) {
- sender.sendMessage(ChatColor.RED + GeyserLocale.getPlayerLocaleString("geyser.bootstrap.command.permission_fail", sender.getLocale()));
+ if (!invocation.source().hasPermission(getCommand(invocation.arguments()[0]).permission())) {
+ sender.sendMessage(ChatColor.RED + GeyserLocale.getPlayerLocaleString("geyser.bootstrap.command.permission_fail", sender.locale()));
return;
}
if (command.isBedrockOnly() && session == null) {
- sender.sendMessage(ChatColor.RED + GeyserLocale.getPlayerLocaleString("geyser.bootstrap.command.bedrock_only", sender.getLocale()));
+ sender.sendMessage(ChatColor.RED + GeyserLocale.getPlayerLocaleString("geyser.bootstrap.command.bedrock_only", sender.locale()));
return;
}
command.execute(session, sender, invocation.arguments().length > 1 ? Arrays.copyOfRange(invocation.arguments(), 1, invocation.arguments().length) : new String[0]);
@@ -71,7 +71,7 @@ public class GeyserVelocityCommandExecutor extends CommandExecutor implements Si
public List suggest(Invocation invocation) {
// Velocity seems to do the splitting a bit differently. This results in the same behaviour in bungeecord/spigot.
if (invocation.arguments().length == 0 || invocation.arguments().length == 1) {
- return tabComplete(new VelocityCommandSender(invocation.source()));
+ return tabComplete(new VelocityCommandSource(invocation.source()));
}
return Collections.emptyList();
}
diff --git a/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/command/GeyserVelocityCommandManager.java b/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/command/GeyserVelocityCommandManager.java
index b42c8f76e..6f9faba8f 100644
--- a/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/command/GeyserVelocityCommandManager.java
+++ b/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/command/GeyserVelocityCommandManager.java
@@ -26,16 +26,16 @@
package org.geysermc.geyser.platform.velocity.command;
import org.geysermc.geyser.GeyserImpl;
-import org.geysermc.geyser.command.CommandManager;
+import org.geysermc.geyser.command.GeyserCommandManager;
-public class GeyserVelocityCommandManager extends CommandManager {
+public class GeyserVelocityCommandManager extends GeyserCommandManager {
public GeyserVelocityCommandManager(GeyserImpl geyser) {
super(geyser);
}
@Override
- public String getDescription(String command) {
+ public String description(String command) {
return ""; // no support for command descriptions in velocity
}
}
diff --git a/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/command/VelocityCommandSender.java b/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/command/VelocityCommandSource.java
similarity index 90%
rename from bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/command/VelocityCommandSender.java
rename to bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/command/VelocityCommandSource.java
index d5e4804ee..fa70d1cf7 100644
--- a/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/command/VelocityCommandSender.java
+++ b/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/command/VelocityCommandSource.java
@@ -29,19 +29,19 @@ import com.velocitypowered.api.command.CommandSource;
import com.velocitypowered.api.proxy.ConsoleCommandSource;
import com.velocitypowered.api.proxy.Player;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
-import org.geysermc.geyser.command.CommandSender;
+import org.geysermc.geyser.command.GeyserCommandSource;
import org.geysermc.geyser.text.GeyserLocale;
import java.util.Locale;
-public class VelocityCommandSender implements CommandSender {
+public class VelocityCommandSource implements GeyserCommandSource {
private final CommandSource handle;
- public VelocityCommandSender(CommandSource handle) {
+ public VelocityCommandSource(CommandSource handle) {
this.handle = handle;
// Ensure even Java players' languages are loaded
- GeyserLocale.loadGeyserLocale(getLocale());
+ GeyserLocale.loadGeyserLocale(this.locale());
}
@Override
@@ -65,7 +65,7 @@ public class VelocityCommandSender implements CommandSender {
}
@Override
- public String getLocale() {
+ public String locale() {
if (handle instanceof Player) {
Locale locale = ((Player) handle).getPlayerSettings().getLocale();
return GeyserLocale.formatLocale(locale.getLanguage() + "_" + locale.getCountry());
diff --git a/core/src/main/java/org/geysermc/connector/network/session/GeyserSession.java b/core/src/main/java/org/geysermc/connector/network/session/GeyserSession.java
index 932761d4b..e24146cb2 100644
--- a/core/src/main/java/org/geysermc/connector/network/session/GeyserSession.java
+++ b/core/src/main/java/org/geysermc/connector/network/session/GeyserSession.java
@@ -136,7 +136,7 @@ public class GeyserSession {
}
public String getLocale() {
- return this.handle.getLocale();
+ return this.handle.locale();
}
public void sendUpstreamPacket(BedrockPacket packet) {
diff --git a/core/src/main/java/org/geysermc/geyser/GeyserBootstrap.java b/core/src/main/java/org/geysermc/geyser/GeyserBootstrap.java
index 54ca36787..bc6a07ae3 100644
--- a/core/src/main/java/org/geysermc/geyser/GeyserBootstrap.java
+++ b/core/src/main/java/org/geysermc/geyser/GeyserBootstrap.java
@@ -25,7 +25,7 @@
package org.geysermc.geyser;
-import org.geysermc.geyser.command.CommandManager;
+import org.geysermc.geyser.command.GeyserCommandManager;
import org.geysermc.geyser.configuration.GeyserConfiguration;
import org.geysermc.geyser.dump.BootstrapDumpInfo;
import org.geysermc.geyser.level.GeyserWorldManager;
@@ -72,7 +72,7 @@ public interface GeyserBootstrap {
*
* @return The current CommandManager
*/
- CommandManager getGeyserCommandManager();
+ GeyserCommandManager getGeyserCommandManager();
/**
* Returns the current PingPassthrough manager
diff --git a/core/src/main/java/org/geysermc/geyser/GeyserImpl.java b/core/src/main/java/org/geysermc/geyser/GeyserImpl.java
index 573934b91..b685741e7 100644
--- a/core/src/main/java/org/geysermc/geyser/GeyserImpl.java
+++ b/core/src/main/java/org/geysermc/geyser/GeyserImpl.java
@@ -52,7 +52,7 @@ import org.geysermc.geyser.api.GeyserApi;
import org.geysermc.geyser.api.event.EventBus;
import org.geysermc.geyser.api.event.lifecycle.GeyserPostInitializeEvent;
import org.geysermc.geyser.api.event.lifecycle.GeyserShutdownEvent;
-import org.geysermc.geyser.command.CommandManager;
+import org.geysermc.geyser.command.GeyserCommandManager;
import org.geysermc.geyser.configuration.GeyserConfiguration;
import org.geysermc.geyser.entity.EntityDefinitions;
import org.geysermc.geyser.event.GeyserEventBus;
@@ -470,12 +470,11 @@ public class GeyserImpl implements GeyserApi {
skinUploader.close();
}
newsHandler.shutdown();
- this.getCommandManager().getCommands().clear();
+ this.commandManager().getCommands().clear();
ResourcePack.PACKS.clear();
this.eventBus.fire(new GeyserShutdownEvent());
-
this.extensionManager.disableExtensions();
bootstrap.getGeyserLogger().info(GeyserLocale.getLocaleStringLog("geyser.core.shutdown.done"));
@@ -504,6 +503,11 @@ public class GeyserImpl implements GeyserApi {
return this.extensionManager;
}
+ @Override
+ public GeyserCommandManager commandManager() {
+ return this.bootstrap.getGeyserCommandManager();
+ }
+
@Override
public EventBus eventBus() {
return this.eventBus;
@@ -531,10 +535,6 @@ public class GeyserImpl implements GeyserApi {
return bootstrap.getGeyserConfig();
}
- public CommandManager getCommandManager() {
- return bootstrap.getGeyserCommandManager();
- }
-
public WorldManager getWorldManager() {
return bootstrap.getWorldManager();
}
diff --git a/core/src/main/java/org/geysermc/geyser/command/CommandManager.java b/core/src/main/java/org/geysermc/geyser/command/CommandManager.java
deleted file mode 100644
index 60af8c4e5..000000000
--- a/core/src/main/java/org/geysermc/geyser/command/CommandManager.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (c) 2019-2022 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.geyser.command;
-
-import lombok.Getter;
-
-import org.geysermc.common.PlatformType;
-import org.geysermc.geyser.GeyserImpl;
-import org.geysermc.geyser.command.defaults.*;
-import org.geysermc.geyser.session.GeyserSession;
-import org.geysermc.geyser.text.GeyserLocale;
-
-import java.util.*;
-
-public abstract class CommandManager {
-
- @Getter
- private final Map commands = new HashMap<>();
-
- private final GeyserImpl geyser;
-
- public CommandManager(GeyserImpl geyser) {
- this.geyser = geyser;
-
- registerCommand(new HelpCommand(geyser, "help", "geyser.commands.help.desc", "geyser.command.help"));
- registerCommand(new ListCommand(geyser, "list", "geyser.commands.list.desc", "geyser.command.list"));
- registerCommand(new ReloadCommand(geyser, "reload", "geyser.commands.reload.desc", "geyser.command.reload"));
- registerCommand(new OffhandCommand(geyser, "offhand", "geyser.commands.offhand.desc", "geyser.command.offhand"));
- registerCommand(new DumpCommand(geyser, "dump", "geyser.commands.dump.desc", "geyser.command.dump"));
- registerCommand(new VersionCommand(geyser, "version", "geyser.commands.version.desc", "geyser.command.version"));
- registerCommand(new SettingsCommand(geyser, "settings", "geyser.commands.settings.desc", "geyser.command.settings"));
- registerCommand(new StatisticsCommand(geyser, "statistics", "geyser.commands.statistics.desc", "geyser.command.statistics"));
- registerCommand(new AdvancementsCommand("advancements", "geyser.commands.advancements.desc", "geyser.command.advancements"));
- registerCommand(new AdvancedTooltipsCommand("tooltips", "geyser.commands.advancedtooltips.desc", "geyser.command.tooltips"));
- if (GeyserImpl.getInstance().getPlatformType() == PlatformType.STANDALONE) {
- registerCommand(new StopCommand(geyser, "stop", "geyser.commands.stop.desc", "geyser.command.stop"));
- }
- }
-
- public void registerCommand(GeyserCommand command) {
- commands.put(command.getName(), command);
- geyser.getLogger().debug(GeyserLocale.getLocaleStringLog("geyser.commands.registered", command.getName()));
-
- if (command.getAliases().isEmpty())
- return;
-
- for (String alias : command.getAliases())
- commands.put(alias, command);
- }
-
- public void runCommand(CommandSender sender, String command) {
- if (!command.startsWith("geyser "))
- return;
-
- command = command.trim().replace("geyser ", "");
- String label;
- String[] args;
-
- if (!command.contains(" ")) {
- label = command.toLowerCase();
- args = new String[0];
- } else {
- label = command.substring(0, command.indexOf(" ")).toLowerCase();
- String argLine = command.substring(command.indexOf(" ") + 1);
- args = argLine.contains(" ") ? argLine.split(" ") : new String[] { argLine };
- }
-
- GeyserCommand cmd = commands.get(label);
- if (cmd == null) {
- geyser.getLogger().error(GeyserLocale.getLocaleStringLog("geyser.commands.invalid"));
- return;
- }
-
- if (sender instanceof GeyserSession) {
- cmd.execute((GeyserSession) sender, sender, args);
- } else {
- if (!cmd.isBedrockOnly()) {
- cmd.execute(null, sender, args);
- } else {
- geyser.getLogger().error(GeyserLocale.getLocaleStringLog("geyser.bootstrap.command.bedrock_only"));
- }
- }
- }
-
- /**
- * @return a list of all subcommands under {@code /geyser}.
- */
- public List getCommandNames() {
- return Arrays.asList(geyser.getCommandManager().getCommands().keySet().toArray(new String[0]));
- }
-
- /**
- * Returns the description of the given command
- *
- * @param command Command to get the description for
- * @return Command description
- */
- public abstract String getDescription(String command);
-}
diff --git a/core/src/main/java/org/geysermc/geyser/command/GeyserCommand.java b/core/src/main/java/org/geysermc/geyser/command/GeyserCommand.java
index 20451b5e8..2b3a855aa 100644
--- a/core/src/main/java/org/geysermc/geyser/command/GeyserCommand.java
+++ b/core/src/main/java/org/geysermc/geyser/command/GeyserCommand.java
@@ -27,7 +27,9 @@ package org.geysermc.geyser.command;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
-import lombok.Setter;
+import lombok.experimental.Accessors;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.geysermc.geyser.api.command.Command;
import org.geysermc.geyser.session.GeyserSession;
import javax.annotation.Nullable;
@@ -35,9 +37,10 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+@Accessors(fluent = true)
@Getter
@RequiredArgsConstructor
-public abstract class GeyserCommand {
+public abstract class GeyserCommand implements Command {
protected final String name;
/**
@@ -46,16 +49,16 @@ public abstract class GeyserCommand {
protected final String description;
protected final String permission;
- @Setter
private List aliases = new ArrayList<>();
- public abstract void execute(@Nullable GeyserSession session, CommandSender sender, String[] args);
+ public abstract void execute(@Nullable GeyserSession session, GeyserCommandSource sender, String[] args);
/**
* If false, hides the command from being shown on the Geyser Standalone GUI.
*
* @return true if the command can be run on the server console
*/
+ @Override
public boolean isExecutableOnConsole() {
return true;
}
@@ -65,25 +68,22 @@ public abstract class GeyserCommand {
*
* @return a list of all possible subcommands, or empty if none.
*/
- public List getSubCommands() {
+ @NonNull
+ @Override
+ public List subCommands() {
return Collections.emptyList();
}
/**
- * Shortcut to {@link #getSubCommands()}{@code .isEmpty()}.
+ * Shortcut to {@link #subCommands()} ()}{@code .isEmpty()}.
*
* @return true if there are subcommand present for this command.
*/
public boolean hasSubCommands() {
- return !getSubCommands().isEmpty();
+ return !this.subCommands().isEmpty();
}
- /**
- * Used to send a deny message to Java players if this command can only be used by Bedrock players.
- *
- * @return true if this command can only be used by Bedrock players.
- */
- public boolean isBedrockOnly() {
- return false;
+ public void setAliases(List aliases) {
+ this.aliases = aliases;
}
}
\ No newline at end of file
diff --git a/core/src/main/java/org/geysermc/geyser/command/CommandExecutor.java b/core/src/main/java/org/geysermc/geyser/command/GeyserCommandExecutor.java
similarity index 85%
rename from core/src/main/java/org/geysermc/geyser/command/CommandExecutor.java
rename to core/src/main/java/org/geysermc/geyser/command/GeyserCommandExecutor.java
index 5fa5f688b..3d08600d1 100644
--- a/core/src/main/java/org/geysermc/geyser/command/CommandExecutor.java
+++ b/core/src/main/java/org/geysermc/geyser/command/GeyserCommandExecutor.java
@@ -27,6 +27,7 @@ package org.geysermc.geyser.command;
import lombok.AllArgsConstructor;
import org.geysermc.geyser.GeyserImpl;
+import org.geysermc.geyser.api.command.Command;
import org.geysermc.geyser.session.GeyserSession;
import javax.annotation.Nullable;
@@ -39,16 +40,16 @@ import java.util.Map;
* Represents helper functions for listening to {@code /geyser} commands.
*/
@AllArgsConstructor
-public class CommandExecutor {
+public class GeyserCommandExecutor {
protected final GeyserImpl geyser;
public GeyserCommand getCommand(String label) {
- return geyser.getCommandManager().getCommands().get(label);
+ return (GeyserCommand) geyser.commandManager().commands().get(label);
}
@Nullable
- public GeyserSession getGeyserSession(CommandSender sender) {
+ public GeyserSession getGeyserSession(GeyserCommandSource sender) {
if (sender.isConsole()) {
return null;
}
@@ -70,20 +71,19 @@ public class CommandExecutor {
* If the command sender does not have the permission for a given command, the command will not be shown.
* @return A list of command names to include in the tab complete
*/
- public List tabComplete(CommandSender sender) {
+ public List tabComplete(GeyserCommandSource sender) {
if (getGeyserSession(sender) != null) {
// Bedrock doesn't get tab completions or argument suggestions
return Collections.emptyList();
}
List availableCommands = new ArrayList<>();
- Map commands = geyser.getCommandManager().getCommands();
+ Map commands = geyser.commandManager().getCommands();
// Only show commands they have permission to use
- for (Map.Entry entry : commands.entrySet()) {
- GeyserCommand geyserCommand = entry.getValue();
- if (sender.hasPermission(geyserCommand.getPermission())) {
-
+ for (Map.Entry entry : commands.entrySet()) {
+ Command geyserCommand = entry.getValue();
+ if (sender.hasPermission(geyserCommand.permission())) {
if (geyserCommand.isBedrockOnly()) {
// Don't show commands the JE player can't run
continue;
diff --git a/core/src/main/java/org/geysermc/geyser/command/GeyserCommandManager.java b/core/src/main/java/org/geysermc/geyser/command/GeyserCommandManager.java
new file mode 100644
index 000000000..9cce0e9ce
--- /dev/null
+++ b/core/src/main/java/org/geysermc/geyser/command/GeyserCommandManager.java
@@ -0,0 +1,256 @@
+/*
+ * Copyright (c) 2019-2022 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.geyser.command;
+
+import lombok.Getter;
+
+import lombok.RequiredArgsConstructor;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.geysermc.common.PlatformType;
+import org.geysermc.geyser.GeyserImpl;
+import org.geysermc.geyser.api.command.Command;
+import org.geysermc.geyser.api.command.CommandExecutor;
+import org.geysermc.geyser.api.command.CommandManager;
+import org.geysermc.geyser.api.command.CommandSource;
+import org.geysermc.geyser.api.event.lifecycle.GeyserDefineCommandsEvent;
+import org.geysermc.geyser.command.defaults.*;
+import org.geysermc.geyser.session.GeyserSession;
+import org.geysermc.geyser.text.GeyserLocale;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.*;
+
+@RequiredArgsConstructor
+public abstract class GeyserCommandManager extends CommandManager {
+
+ @Getter
+ private final Map commands = new HashMap<>();
+
+ private final GeyserImpl geyser;
+
+ public void init() {
+ register(new HelpCommand(geyser, "help", "geyser.commands.help.desc", "geyser.command.help"));
+ register(new ListCommand(geyser, "list", "geyser.commands.list.desc", "geyser.command.list"));
+ register(new ReloadCommand(geyser, "reload", "geyser.commands.reload.desc", "geyser.command.reload"));
+ register(new OffhandCommand(geyser, "offhand", "geyser.commands.offhand.desc", "geyser.command.offhand"));
+ register(new DumpCommand(geyser, "dump", "geyser.commands.dump.desc", "geyser.command.dump"));
+ register(new VersionCommand(geyser, "version", "geyser.commands.version.desc", "geyser.command.version"));
+ register(new SettingsCommand(geyser, "settings", "geyser.commands.settings.desc", "geyser.command.settings"));
+ register(new StatisticsCommand(geyser, "statistics", "geyser.commands.statistics.desc", "geyser.command.statistics"));
+ register(new AdvancementsCommand("advancements", "geyser.commands.advancements.desc", "geyser.command.advancements"));
+ register(new AdvancedTooltipsCommand("tooltips", "geyser.commands.advancedtooltips.desc", "geyser.command.tooltips"));
+ if (GeyserImpl.getInstance().getPlatformType() == PlatformType.STANDALONE) {
+ register(new StopCommand(geyser, "stop", "geyser.commands.stop.desc", "geyser.command.stop"));
+ }
+
+ this.geyser.eventBus().fire(new GeyserDefineCommandsEvent(this, this.commands));
+ }
+
+ @Override
+ public void register(@NonNull Command command) {
+ this.commands.put(command.name(), command);
+ this.geyser.getLogger().debug(GeyserLocale.getLocaleStringLog("geyser.commands.registered", command.name()));
+
+ if (command.aliases().isEmpty()) {
+ return;
+ }
+
+ for (String alias : command.aliases()) {
+ this.commands.put(alias, command);
+ }
+ }
+
+ @Override
+ public void unregister(@NonNull Command command) {
+ this.commands.remove(command.name(), command);
+
+ if (command.aliases().isEmpty()) {
+ return;
+ }
+
+ for (String alias : command.aliases()) {
+ this.commands.remove(alias, command);
+ }
+ }
+
+ @NotNull
+ @Override
+ public Map commands() {
+ return Collections.unmodifiableMap(this.commands);
+ }
+
+ public void runCommand(GeyserCommandSource sender, String command) {
+ if (!command.startsWith("geyser "))
+ return;
+
+ command = command.trim().replace("geyser ", "");
+ String label;
+ String[] args;
+
+ if (!command.contains(" ")) {
+ label = command.toLowerCase();
+ args = new String[0];
+ } else {
+ label = command.substring(0, command.indexOf(" ")).toLowerCase();
+ String argLine = command.substring(command.indexOf(" ") + 1);
+ args = argLine.contains(" ") ? argLine.split(" ") : new String[] { argLine };
+ }
+
+ Command cmd = commands.get(label);
+ if (cmd == null) {
+ geyser.getLogger().error(GeyserLocale.getLocaleStringLog("geyser.commands.invalid"));
+ return;
+ }
+
+ if (cmd instanceof GeyserCommand) {
+ if (sender instanceof GeyserSession) {
+ ((GeyserCommand) cmd).execute((GeyserSession) sender, sender, args);
+ } else {
+ if (!cmd.isBedrockOnly()) {
+ ((GeyserCommand) cmd).execute(null, sender, args);
+ } else {
+ geyser.getLogger().error(GeyserLocale.getLocaleStringLog("geyser.bootstrap.command.bedrock_only"));
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns the description of the given command
+ *
+ * @param command Command to get the description for
+ * @return Command description
+ */
+ public abstract String description(String command);
+
+ @Override
+ protected Command.Builder provideBuilder(Class sourceType) {
+ return new CommandBuilder<>(sourceType);
+ }
+
+ @RequiredArgsConstructor
+ public static class CommandBuilder implements Command.Builder {
+ private final Class sourceType;
+ private String name;
+ private String description = "";
+ private String permission = "";
+ private List aliases;
+ private boolean executableOnConsole = true;
+ private List subCommands;
+ private boolean bedrockOnly;
+ private CommandExecutor executor;
+
+ public CommandBuilder name(String name) {
+ this.name = name;
+ return this;
+ }
+
+ public CommandBuilder description(String description) {
+ this.description = description;
+ return this;
+ }
+
+ public CommandBuilder permission(String permission) {
+ this.permission = permission;
+ return this;
+ }
+
+ public CommandBuilder aliases(List aliases) {
+ this.aliases = aliases;
+ return this;
+ }
+
+ public CommandBuilder executableOnConsole(boolean executableOnConsole) {
+ this.executableOnConsole = executableOnConsole;
+ return this;
+ }
+
+ public CommandBuilder subCommands(List subCommands) {
+ this.subCommands = subCommands;
+ return this;
+ }
+
+ public CommandBuilder bedrockOnly(boolean bedrockOnly) {
+ this.bedrockOnly = bedrockOnly;
+ return this;
+ }
+
+ public CommandBuilder executor(CommandExecutor executor) {
+ this.executor = executor;
+ return this;
+ }
+
+ public GeyserCommand build() {
+ if (this.name == null || this.name.isBlank()) {
+ throw new IllegalArgumentException("Command cannot be null or blank!");
+ }
+
+ return new GeyserCommand(this.name, this.description, this.permission) {
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void execute(@Nullable GeyserSession session, GeyserCommandSource sender, String[] args) {
+ Class sourceType = CommandBuilder.this.sourceType;
+ CommandExecutor executor = CommandBuilder.this.executor;
+ if (sourceType.isInstance(session)) {
+ executor.execute((T) session, this, args);
+ return;
+ }
+
+ if (sourceType.isInstance(sender)) {
+ executor.execute((T) sender, this, args);
+ return;
+ }
+
+ GeyserImpl.getInstance().getLogger().debug("Ignoring command " + this.name + " due to no suitable sender.");
+ }
+
+ @NonNull
+ @Override
+ public List aliases() {
+ return CommandBuilder.this.aliases == null ? Collections.emptyList() : CommandBuilder.this.aliases;
+ }
+
+ @NonNull
+ @Override
+ public List subCommands() {
+ return CommandBuilder.this.subCommands == null ? Collections.emptyList() : CommandBuilder.this.subCommands;
+ }
+
+ @Override
+ public boolean isBedrockOnly() {
+ return CommandBuilder.this.bedrockOnly;
+ }
+
+ @Override
+ public boolean isExecutableOnConsole() {
+ return CommandBuilder.this.executableOnConsole;
+ }
+ };
+ }
+ }
+}
diff --git a/core/src/main/java/org/geysermc/geyser/command/GeyserCommandSource.java b/core/src/main/java/org/geysermc/geyser/command/GeyserCommandSource.java
new file mode 100644
index 000000000..eabccc243
--- /dev/null
+++ b/core/src/main/java/org/geysermc/geyser/command/GeyserCommandSource.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2019-2022 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.geyser.command;
+
+import org.geysermc.geyser.api.command.CommandSource;
+import org.geysermc.geyser.text.GeyserLocale;
+
+/**
+ * Implemented on top of any class that can send a command.
+ * For example, it wraps around Spigot's CommandSender class.
+ */
+public interface GeyserCommandSource extends CommandSource {
+
+ /**
+ * {@inheritDoc}
+ */
+ default String locale() {
+ return GeyserLocale.getDefaultLocale();
+ }
+}
diff --git a/core/src/main/java/org/geysermc/geyser/command/defaults/AdvancedTooltipsCommand.java b/core/src/main/java/org/geysermc/geyser/command/defaults/AdvancedTooltipsCommand.java
index 18546c914..350b98f04 100644
--- a/core/src/main/java/org/geysermc/geyser/command/defaults/AdvancedTooltipsCommand.java
+++ b/core/src/main/java/org/geysermc/geyser/command/defaults/AdvancedTooltipsCommand.java
@@ -25,7 +25,7 @@
package org.geysermc.geyser.command.defaults;
-import org.geysermc.geyser.command.CommandSender;
+import org.geysermc.geyser.command.GeyserCommandSource;
import org.geysermc.geyser.command.GeyserCommand;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.text.MinecraftLocale;
@@ -36,11 +36,11 @@ public class AdvancedTooltipsCommand extends GeyserCommand {
}
@Override
- public void execute(GeyserSession session, CommandSender sender, String[] args) {
+ public void execute(GeyserSession session, GeyserCommandSource sender, String[] args) {
if (session != null) {
String onOrOff = session.isAdvancedTooltips() ? "off" : "on";
session.setAdvancedTooltips(!session.isAdvancedTooltips());
- session.sendMessage("§l§e" + MinecraftLocale.getLocaleString("debug.prefix", session.getLocale()) + " §r" + MinecraftLocale.getLocaleString("debug.advanced_tooltips." + onOrOff, session.getLocale()));
+ session.sendMessage("§l§e" + MinecraftLocale.getLocaleString("debug.prefix", session.locale()) + " §r" + MinecraftLocale.getLocaleString("debug.advanced_tooltips." + onOrOff, session.locale()));
session.getInventoryTranslator().updateInventory(session, session.getPlayerInventory());
}
}
diff --git a/core/src/main/java/org/geysermc/geyser/command/defaults/AdvancementsCommand.java b/core/src/main/java/org/geysermc/geyser/command/defaults/AdvancementsCommand.java
index 169158572..2aea5f4df 100644
--- a/core/src/main/java/org/geysermc/geyser/command/defaults/AdvancementsCommand.java
+++ b/core/src/main/java/org/geysermc/geyser/command/defaults/AdvancementsCommand.java
@@ -25,7 +25,7 @@
package org.geysermc.geyser.command.defaults;
-import org.geysermc.geyser.command.CommandSender;
+import org.geysermc.geyser.command.GeyserCommandSource;
import org.geysermc.geyser.command.GeyserCommand;
import org.geysermc.geyser.session.GeyserSession;
@@ -35,7 +35,7 @@ public class AdvancementsCommand extends GeyserCommand {
}
@Override
- public void execute(GeyserSession session, CommandSender sender, String[] args) {
+ public void execute(GeyserSession session, GeyserCommandSource sender, String[] args) {
if (session != null) {
session.getAdvancementsCache().buildAndShowMenuForm();
}
diff --git a/core/src/main/java/org/geysermc/geyser/command/defaults/DumpCommand.java b/core/src/main/java/org/geysermc/geyser/command/defaults/DumpCommand.java
index bd98d2b31..32382526a 100644
--- a/core/src/main/java/org/geysermc/geyser/command/defaults/DumpCommand.java
+++ b/core/src/main/java/org/geysermc/geyser/command/defaults/DumpCommand.java
@@ -29,9 +29,10 @@ import com.fasterxml.jackson.core.util.DefaultIndenter;
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
+import org.checkerframework.checker.nullness.qual.NonNull;
import org.geysermc.common.PlatformType;
import org.geysermc.geyser.GeyserImpl;
-import org.geysermc.geyser.command.CommandSender;
+import org.geysermc.geyser.command.GeyserCommandSource;
import org.geysermc.geyser.command.GeyserCommand;
import org.geysermc.geyser.text.ChatColor;
import org.geysermc.geyser.text.AsteriskSerializer;
@@ -58,10 +59,10 @@ public class DumpCommand extends GeyserCommand {
}
@Override
- public void execute(GeyserSession session, CommandSender sender, String[] args) {
+ public void execute(GeyserSession session, GeyserCommandSource sender, String[] args) {
// Only allow the console to create dumps on Geyser Standalone
if (!sender.isConsole() && geyser.getPlatformType() == PlatformType.STANDALONE) {
- sender.sendMessage(GeyserLocale.getPlayerLocaleString("geyser.bootstrap.command.permission_fail", sender.getLocale()));
+ sender.sendMessage(GeyserLocale.getPlayerLocaleString("geyser.bootstrap.command.permission_fail", sender.locale()));
return;
}
@@ -80,7 +81,7 @@ public class DumpCommand extends GeyserCommand {
AsteriskSerializer.showSensitive = showSensitive;
- sender.sendMessage(GeyserLocale.getPlayerLocaleString("geyser.commands.dump.collecting", sender.getLocale()));
+ sender.sendMessage(GeyserLocale.getPlayerLocaleString("geyser.commands.dump.collecting", sender.locale()));
String dumpData;
try {
if (offlineDump) {
@@ -92,7 +93,7 @@ public class DumpCommand extends GeyserCommand {
dumpData = MAPPER.writeValueAsString(new DumpInfo(addLog));
}
} catch (IOException e) {
- sender.sendMessage(ChatColor.RED + GeyserLocale.getPlayerLocaleString("geyser.commands.dump.collect_error", sender.getLocale()));
+ sender.sendMessage(ChatColor.RED + GeyserLocale.getPlayerLocaleString("geyser.commands.dump.collect_error", sender.locale()));
geyser.getLogger().error(GeyserLocale.getLocaleStringLog("geyser.commands.dump.collect_error_short"), e);
return;
}
@@ -100,21 +101,21 @@ public class DumpCommand extends GeyserCommand {
String uploadedDumpUrl = "";
if (offlineDump) {
- sender.sendMessage(GeyserLocale.getPlayerLocaleString("geyser.commands.dump.writing", sender.getLocale()));
+ sender.sendMessage(GeyserLocale.getPlayerLocaleString("geyser.commands.dump.writing", sender.locale()));
try {
FileOutputStream outputStream = new FileOutputStream(GeyserImpl.getInstance().getBootstrap().getConfigFolder().resolve("dump.json").toFile());
outputStream.write(dumpData.getBytes());
outputStream.close();
} catch (IOException e) {
- sender.sendMessage(ChatColor.RED + GeyserLocale.getPlayerLocaleString("geyser.commands.dump.write_error", sender.getLocale()));
+ sender.sendMessage(ChatColor.RED + GeyserLocale.getPlayerLocaleString("geyser.commands.dump.write_error", sender.locale()));
geyser.getLogger().error(GeyserLocale.getLocaleStringLog("geyser.commands.dump.write_error_short"), e);
return;
}
uploadedDumpUrl = "dump.json";
} else {
- sender.sendMessage(GeyserLocale.getPlayerLocaleString("geyser.commands.dump.uploading", sender.getLocale()));
+ sender.sendMessage(GeyserLocale.getPlayerLocaleString("geyser.commands.dump.uploading", sender.locale()));
String response;
JsonNode responseNode;
@@ -122,27 +123,28 @@ public class DumpCommand extends GeyserCommand {
response = WebUtils.post(DUMP_URL + "documents", dumpData);
responseNode = MAPPER.readTree(response);
} catch (IOException e) {
- sender.sendMessage(ChatColor.RED + GeyserLocale.getPlayerLocaleString("geyser.commands.dump.upload_error", sender.getLocale()));
+ sender.sendMessage(ChatColor.RED + GeyserLocale.getPlayerLocaleString("geyser.commands.dump.upload_error", sender.locale()));
geyser.getLogger().error(GeyserLocale.getLocaleStringLog("geyser.commands.dump.upload_error_short"), e);
return;
}
if (!responseNode.has("key")) {
- sender.sendMessage(ChatColor.RED + GeyserLocale.getPlayerLocaleString("geyser.commands.dump.upload_error_short", sender.getLocale()) + ": " + (responseNode.has("message") ? responseNode.get("message").asText() : response));
+ sender.sendMessage(ChatColor.RED + GeyserLocale.getPlayerLocaleString("geyser.commands.dump.upload_error_short", sender.locale()) + ": " + (responseNode.has("message") ? responseNode.get("message").asText() : response));
return;
}
uploadedDumpUrl = DUMP_URL + responseNode.get("key").asText();
}
- sender.sendMessage(GeyserLocale.getPlayerLocaleString("geyser.commands.dump.message", sender.getLocale()) + " " + ChatColor.DARK_AQUA + uploadedDumpUrl);
+ sender.sendMessage(GeyserLocale.getPlayerLocaleString("geyser.commands.dump.message", sender.locale()) + " " + ChatColor.DARK_AQUA + uploadedDumpUrl);
if (!sender.isConsole()) {
geyser.getLogger().info(GeyserLocale.getLocaleStringLog("geyser.commands.dump.created", sender.name(), uploadedDumpUrl));
}
}
+ @NonNull
@Override
- public List getSubCommands() {
+ public List subCommands() {
return Arrays.asList("offline", "full", "logs");
}
}
diff --git a/core/src/main/java/org/geysermc/geyser/command/defaults/HelpCommand.java b/core/src/main/java/org/geysermc/geyser/command/defaults/HelpCommand.java
index 85682b294..fccb1b267 100644
--- a/core/src/main/java/org/geysermc/geyser/command/defaults/HelpCommand.java
+++ b/core/src/main/java/org/geysermc/geyser/command/defaults/HelpCommand.java
@@ -27,7 +27,8 @@ package org.geysermc.geyser.command.defaults;
import org.geysermc.common.PlatformType;
import org.geysermc.geyser.GeyserImpl;
-import org.geysermc.geyser.command.CommandSender;
+import org.geysermc.geyser.api.command.Command;
+import org.geysermc.geyser.command.GeyserCommandSource;
import org.geysermc.geyser.command.GeyserCommand;
import org.geysermc.geyser.text.ChatColor;
import org.geysermc.geyser.session.GeyserSession;
@@ -54,25 +55,25 @@ public class HelpCommand extends GeyserCommand {
* @param args Not used.
*/
@Override
- public void execute(GeyserSession session, CommandSender sender, String[] args) {
+ public void execute(GeyserSession session, GeyserCommandSource sender, String[] args) {
int page = 1;
int maxPage = 1;
- String header = GeyserLocale.getPlayerLocaleString("geyser.commands.help.header", sender.getLocale(), page, maxPage);
+ String header = GeyserLocale.getPlayerLocaleString("geyser.commands.help.header", sender.locale(), page, maxPage);
sender.sendMessage(header);
- Map cmds = geyser.getCommandManager().getCommands();
- for (Map.Entry entry : cmds.entrySet()) {
- GeyserCommand cmd = entry.getValue();
+ Map cmds = geyser.commandManager().getCommands();
+ for (Map.Entry entry : cmds.entrySet()) {
+ Command cmd = entry.getValue();
// Standalone hack-in since it doesn't have a concept of permissions
- if (geyser.getPlatformType() == PlatformType.STANDALONE || sender.hasPermission(cmd.getPermission())) {
+ if (geyser.getPlatformType() == PlatformType.STANDALONE || sender.hasPermission(cmd.permission())) {
// Only list commands the player can actually run
if (cmd.isBedrockOnly() && session == null) {
continue;
}
sender.sendMessage(ChatColor.YELLOW + "/geyser " + entry.getKey() + ChatColor.WHITE + ": " +
- GeyserLocale.getPlayerLocaleString(cmd.getDescription(), sender.getLocale()));
+ GeyserLocale.getPlayerLocaleString(cmd.description(), sender.locale()));
}
}
}
diff --git a/core/src/main/java/org/geysermc/geyser/command/defaults/ListCommand.java b/core/src/main/java/org/geysermc/geyser/command/defaults/ListCommand.java
index f1004c3fb..8382d7a29 100644
--- a/core/src/main/java/org/geysermc/geyser/command/defaults/ListCommand.java
+++ b/core/src/main/java/org/geysermc/geyser/command/defaults/ListCommand.java
@@ -26,7 +26,7 @@
package org.geysermc.geyser.command.defaults;
import org.geysermc.geyser.GeyserImpl;
-import org.geysermc.geyser.command.CommandSender;
+import org.geysermc.geyser.command.GeyserCommandSource;
import org.geysermc.geyser.command.GeyserCommand;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.text.GeyserLocale;
@@ -44,8 +44,8 @@ public class ListCommand extends GeyserCommand {
}
@Override
- public void execute(GeyserSession session, CommandSender sender, String[] args) {
- String message = GeyserLocale.getPlayerLocaleString("geyser.commands.list.message", sender.getLocale(),
+ public void execute(GeyserSession session, GeyserCommandSource sender, String[] args) {
+ String message = GeyserLocale.getPlayerLocaleString("geyser.commands.list.message", sender.locale(),
geyser.getSessionManager().size(),
geyser.getSessionManager().getAllSessions().stream().map(GeyserSession::name).collect(Collectors.joining(" ")));
diff --git a/core/src/main/java/org/geysermc/geyser/command/defaults/OffhandCommand.java b/core/src/main/java/org/geysermc/geyser/command/defaults/OffhandCommand.java
index 1d29d5122..a9f265f6e 100644
--- a/core/src/main/java/org/geysermc/geyser/command/defaults/OffhandCommand.java
+++ b/core/src/main/java/org/geysermc/geyser/command/defaults/OffhandCommand.java
@@ -29,7 +29,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.object.Direction;
import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerAction;
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundPlayerActionPacket;
import org.geysermc.geyser.GeyserImpl;
-import org.geysermc.geyser.command.CommandSender;
+import org.geysermc.geyser.command.GeyserCommandSource;
import org.geysermc.geyser.command.GeyserCommand;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.util.BlockUtils;
@@ -41,7 +41,7 @@ public class OffhandCommand extends GeyserCommand {
}
@Override
- public void execute(GeyserSession session, CommandSender sender, String[] args) {
+ public void execute(GeyserSession session, GeyserCommandSource sender, String[] args) {
if (session == null) {
return;
}
diff --git a/core/src/main/java/org/geysermc/geyser/command/defaults/ReloadCommand.java b/core/src/main/java/org/geysermc/geyser/command/defaults/ReloadCommand.java
index b6a728382..31e17faad 100644
--- a/core/src/main/java/org/geysermc/geyser/command/defaults/ReloadCommand.java
+++ b/core/src/main/java/org/geysermc/geyser/command/defaults/ReloadCommand.java
@@ -27,7 +27,7 @@ package org.geysermc.geyser.command.defaults;
import org.geysermc.common.PlatformType;
import org.geysermc.geyser.GeyserImpl;
-import org.geysermc.geyser.command.CommandSender;
+import org.geysermc.geyser.command.GeyserCommandSource;
import org.geysermc.geyser.command.GeyserCommand;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.text.GeyserLocale;
@@ -42,12 +42,12 @@ public class ReloadCommand extends GeyserCommand {
}
@Override
- public void execute(GeyserSession session, CommandSender sender, String[] args) {
+ public void execute(GeyserSession session, GeyserCommandSource sender, String[] args) {
if (!sender.isConsole() && geyser.getPlatformType() == PlatformType.STANDALONE) {
return;
}
- String message = GeyserLocale.getPlayerLocaleString("geyser.commands.reload.message", sender.getLocale());
+ String message = GeyserLocale.getPlayerLocaleString("geyser.commands.reload.message", sender.locale());
sender.sendMessage(message);
diff --git a/core/src/main/java/org/geysermc/geyser/command/defaults/SettingsCommand.java b/core/src/main/java/org/geysermc/geyser/command/defaults/SettingsCommand.java
index 58d778ba9..a8e8a374e 100644
--- a/core/src/main/java/org/geysermc/geyser/command/defaults/SettingsCommand.java
+++ b/core/src/main/java/org/geysermc/geyser/command/defaults/SettingsCommand.java
@@ -26,7 +26,7 @@
package org.geysermc.geyser.command.defaults;
import org.geysermc.geyser.GeyserImpl;
-import org.geysermc.geyser.command.CommandSender;
+import org.geysermc.geyser.command.GeyserCommandSource;
import org.geysermc.geyser.command.GeyserCommand;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.util.SettingsUtils;
@@ -37,7 +37,7 @@ public class SettingsCommand extends GeyserCommand {
}
@Override
- public void execute(GeyserSession session, CommandSender sender, String[] args) {
+ public void execute(GeyserSession session, GeyserCommandSource sender, String[] args) {
if (session != null) {
session.sendForm(SettingsUtils.buildForm(session));
}
diff --git a/core/src/main/java/org/geysermc/geyser/command/defaults/StatisticsCommand.java b/core/src/main/java/org/geysermc/geyser/command/defaults/StatisticsCommand.java
index e54b0fb9b..c898f32a9 100644
--- a/core/src/main/java/org/geysermc/geyser/command/defaults/StatisticsCommand.java
+++ b/core/src/main/java/org/geysermc/geyser/command/defaults/StatisticsCommand.java
@@ -28,7 +28,7 @@ package org.geysermc.geyser.command.defaults;
import com.github.steveice10.mc.protocol.data.game.ClientCommand;
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundClientCommandPacket;
import org.geysermc.geyser.GeyserImpl;
-import org.geysermc.geyser.command.CommandSender;
+import org.geysermc.geyser.command.GeyserCommandSource;
import org.geysermc.geyser.command.GeyserCommand;
import org.geysermc.geyser.session.GeyserSession;
@@ -39,7 +39,7 @@ public class StatisticsCommand extends GeyserCommand {
}
@Override
- public void execute(GeyserSession session, CommandSender sender, String[] args) {
+ public void execute(GeyserSession session, GeyserCommandSource sender, String[] args) {
if (session == null) return;
session.setWaitingForStatistics(true);
diff --git a/core/src/main/java/org/geysermc/geyser/command/defaults/StopCommand.java b/core/src/main/java/org/geysermc/geyser/command/defaults/StopCommand.java
index 903e3bf4b..b038fa0ff 100644
--- a/core/src/main/java/org/geysermc/geyser/command/defaults/StopCommand.java
+++ b/core/src/main/java/org/geysermc/geyser/command/defaults/StopCommand.java
@@ -27,7 +27,7 @@ package org.geysermc.geyser.command.defaults;
import org.geysermc.common.PlatformType;
import org.geysermc.geyser.GeyserImpl;
-import org.geysermc.geyser.command.CommandSender;
+import org.geysermc.geyser.command.GeyserCommandSource;
import org.geysermc.geyser.command.GeyserCommand;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.text.GeyserLocale;
@@ -46,9 +46,9 @@ public class StopCommand extends GeyserCommand {
}
@Override
- public void execute(GeyserSession session, CommandSender sender, String[] args) {
+ public void execute(GeyserSession session, GeyserCommandSource sender, String[] args) {
if (!sender.isConsole() && geyser.getPlatformType() == PlatformType.STANDALONE) {
- sender.sendMessage(GeyserLocale.getPlayerLocaleString("geyser.bootstrap.command.permission_fail", sender.getLocale()));
+ sender.sendMessage(GeyserLocale.getPlayerLocaleString("geyser.bootstrap.command.permission_fail", sender.locale()));
return;
}
diff --git a/core/src/main/java/org/geysermc/geyser/command/defaults/VersionCommand.java b/core/src/main/java/org/geysermc/geyser/command/defaults/VersionCommand.java
index 6ec816b12..89bea3343 100644
--- a/core/src/main/java/org/geysermc/geyser/command/defaults/VersionCommand.java
+++ b/core/src/main/java/org/geysermc/geyser/command/defaults/VersionCommand.java
@@ -28,7 +28,7 @@ package org.geysermc.geyser.command.defaults;
import com.nukkitx.protocol.bedrock.BedrockPacketCodec;
import org.geysermc.common.PlatformType;
import org.geysermc.geyser.GeyserImpl;
-import org.geysermc.geyser.command.CommandSender;
+import org.geysermc.geyser.command.GeyserCommandSource;
import org.geysermc.geyser.command.GeyserCommand;
import org.geysermc.geyser.network.MinecraftProtocol;
import org.geysermc.geyser.session.GeyserSession;
@@ -54,7 +54,7 @@ public class VersionCommand extends GeyserCommand {
}
@Override
- public void execute(GeyserSession session, CommandSender sender, String[] args) {
+ public void execute(GeyserSession session, GeyserCommandSource sender, String[] args) {
String bedrockVersions;
List supportedCodecs = MinecraftProtocol.SUPPORTED_BEDROCK_CODECS;
if (supportedCodecs.size() > 1) {
@@ -70,12 +70,12 @@ public class VersionCommand extends GeyserCommand {
javaVersions = supportedJavaVersions.get(0);
}
- sender.sendMessage(GeyserLocale.getPlayerLocaleString("geyser.commands.version.version", sender.getLocale(),
+ sender.sendMessage(GeyserLocale.getPlayerLocaleString("geyser.commands.version.version", sender.locale(),
GeyserImpl.NAME, GeyserImpl.VERSION, javaVersions, bedrockVersions));
// Disable update checking in dev mode and for players in Geyser Standalone
if (GeyserImpl.getInstance().productionEnvironment() && !(!sender.isConsole() && geyser.getPlatformType() == PlatformType.STANDALONE)) {
- sender.sendMessage(GeyserLocale.getPlayerLocaleString("geyser.commands.version.checking", sender.getLocale()));
+ sender.sendMessage(GeyserLocale.getPlayerLocaleString("geyser.commands.version.checking", sender.locale()));
try (InputStream stream = GeyserImpl.getInstance().getBootstrap().getResource("git.properties")) {
Properties gitProp = new Properties();
gitProp.load(stream);
@@ -86,17 +86,17 @@ public class VersionCommand extends GeyserCommand {
int latestBuildNum = Integer.parseInt(buildXML.replaceAll("<(\\\\)?(/)?buildNumber>", "").trim());
int buildNum = Integer.parseInt(gitProp.getProperty("git.build.number"));
if (latestBuildNum == buildNum) {
- sender.sendMessage(GeyserLocale.getPlayerLocaleString("geyser.commands.version.no_updates", sender.getLocale()));
+ sender.sendMessage(GeyserLocale.getPlayerLocaleString("geyser.commands.version.no_updates", sender.locale()));
} else {
sender.sendMessage(GeyserLocale.getPlayerLocaleString("geyser.commands.version.outdated",
- sender.getLocale(), (latestBuildNum - buildNum), "https://ci.geysermc.org/"));
+ sender.locale(), (latestBuildNum - buildNum), "https://ci.geysermc.org/"));
}
} else {
throw new AssertionError("buildNumber missing");
}
} catch (IOException | AssertionError | NumberFormatException e) {
GeyserImpl.getInstance().getLogger().error(GeyserLocale.getLocaleStringLog("geyser.commands.version.failed"), e);
- sender.sendMessage(ChatColor.RED + GeyserLocale.getPlayerLocaleString("geyser.commands.version.failed", sender.getLocale()));
+ sender.sendMessage(ChatColor.RED + GeyserLocale.getPlayerLocaleString("geyser.commands.version.failed", sender.locale()));
}
}
}
diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java b/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java
index adeccdd01..77a1a199c 100644
--- a/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java
+++ b/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java
@@ -356,7 +356,7 @@ public class Entity {
public void setDisplayName(EntityMetadata, ?> entityMetadata) {
Optional name = entityMetadata.getValue();
if (name.isPresent()) {
- nametag = MessageTranslator.convertMessage(name.get(), session.getLocale());
+ nametag = MessageTranslator.convertMessage(name.get(), session.locale());
dirtyMetadata.put(EntityData.NAMETAG, nametag);
} else if (!nametag.isEmpty()) {
// Clear nametag
diff --git a/core/src/main/java/org/geysermc/geyser/event/GeyserEventBus.java b/core/src/main/java/org/geysermc/geyser/event/GeyserEventBus.java
index 93a042826..eaf71e087 100644
--- a/core/src/main/java/org/geysermc/geyser/event/GeyserEventBus.java
+++ b/core/src/main/java/org/geysermc/geyser/event/GeyserEventBus.java
@@ -25,6 +25,7 @@
package org.geysermc.geyser.event;
+import net.kyori.event.EventSubscriber;
import net.kyori.event.SimpleEventBus;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.geysermc.geyser.api.event.Event;
@@ -37,17 +38,12 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Set;
import java.util.function.Consumer;
+import java.util.function.Predicate;
import java.util.stream.Collectors;
public class GeyserEventBus implements EventBus {
private final SimpleEventBus bus = new SimpleEventBus<>(Event.class);
- @NonNull
- @Override
- public EventSubscription subscribe(@NonNull Class eventClass, @NonNull Consumer super T> consumer) {
- return this.subscribe(eventClass, consumer, null, Subscribe.Priority.NORMAL);
- }
-
@NonNull
@Override
public EventSubscription subscribe(@NonNull Extension extension, @NonNull Class eventClass, @NonNull Consumer super T> consumer) {
@@ -86,6 +82,11 @@ public class GeyserEventBus implements EventBus {
}
}
+ @Override
+ public void unregisterAll(@NonNull Extension extension) {
+ this.bus.unregister((Predicate>) subscriber -> extension.equals(((GeyserEventSubscription>) subscriber).owner()));
+ }
+
@Override
public boolean fire(@NonNull Event event) {
return this.bus.post(event).wasSuccessful();
diff --git a/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionContainer.java b/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionContainer.java
index 5b2e01842..a26415a13 100644
--- a/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionContainer.java
+++ b/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionContainer.java
@@ -29,6 +29,7 @@ import lombok.AccessLevel;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.experimental.Accessors;
+import org.geysermc.geyser.api.event.ExtensionEventBus;
import org.geysermc.geyser.api.extension.Extension;
import org.geysermc.geyser.api.extension.ExtensionDescription;
import org.geysermc.geyser.api.extension.ExtensionLoader;
@@ -45,6 +46,7 @@ public class GeyserExtensionContainer {
private final ExtensionDescription description;
private final ExtensionLoader loader;
private final ExtensionLogger logger;
+ private final ExtensionEventBus eventBus;
@Getter(AccessLevel.NONE) protected boolean enabled;
}
diff --git a/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionLoader.java b/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionLoader.java
index a539dcb15..972b106d6 100644
--- a/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionLoader.java
+++ b/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionLoader.java
@@ -28,6 +28,7 @@ package org.geysermc.geyser.extension;
import lombok.RequiredArgsConstructor;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.geysermc.geyser.GeyserImpl;
+import org.geysermc.geyser.api.event.ExtensionEventBus;
import org.geysermc.geyser.api.extension.Extension;
import org.geysermc.geyser.api.extension.ExtensionDescription;
import org.geysermc.geyser.api.extension.ExtensionLoader;
@@ -35,6 +36,7 @@ import org.geysermc.geyser.api.extension.ExtensionLogger;
import org.geysermc.geyser.api.extension.ExtensionManager;
import org.geysermc.geyser.api.extension.exception.InvalidDescriptionException;
import org.geysermc.geyser.api.extension.exception.InvalidExtensionException;
+import org.geysermc.geyser.extension.event.GeyserExtensionEventBus;
import org.geysermc.geyser.text.GeyserLocale;
import java.io.IOException;
@@ -83,12 +85,12 @@ public class GeyserExtensionLoader extends ExtensionLoader {
}
this.classLoaders.put(description.name(), loader);
- return this.setup(loader.extension(), description, dataFolder);
+ return this.setup(loader.extension(), description, dataFolder, new GeyserExtensionEventBus(GeyserImpl.getInstance().eventBus(), loader.extension()));
}
- private GeyserExtensionContainer setup(Extension extension, GeyserExtensionDescription description, Path dataFolder) {
+ private GeyserExtensionContainer setup(Extension extension, GeyserExtensionDescription description, Path dataFolder, ExtensionEventBus eventBus) {
GeyserExtensionLogger logger = new GeyserExtensionLogger(GeyserImpl.getInstance().getLogger(), description.name());
- GeyserExtensionContainer container = new GeyserExtensionContainer(extension, dataFolder, description, this, logger);
+ GeyserExtensionContainer container = new GeyserExtensionContainer(extension, dataFolder, description, this, logger, eventBus);
extension.onLoad();
return container;
}
@@ -246,6 +248,12 @@ public class GeyserExtensionLoader extends ExtensionLoader {
return this.extensionContainers.get(extension).description();
}
+ @NonNull
+ @Override
+ protected ExtensionEventBus eventBus(@NonNull Extension extension) {
+ return this.extensionContainers.get(extension).eventBus();
+ }
+
@NonNull
@Override
protected ExtensionLogger logger(@NonNull Extension extension) {
diff --git a/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionManager.java b/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionManager.java
index a72712f16..936cde471 100644
--- a/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionManager.java
+++ b/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionManager.java
@@ -90,15 +90,18 @@ public class GeyserExtensionManager extends ExtensionManager {
public void enableExtension(Extension extension) {
if (!extension.isEnabled()) {
- GeyserImpl.getInstance().getLogger().info(GeyserLocale.getLocaleStringLog("geyser.extensions.enable.success", extension.description().name()));
extension.setEnabled(true);
+ GeyserImpl.getInstance().eventBus().register(extension, extension);
+ GeyserImpl.getInstance().getLogger().info(GeyserLocale.getLocaleStringLog("geyser.extensions.enable.success", extension.description().name()));
}
}
private void disableExtension(@NonNull Extension extension) {
if (extension.isEnabled()) {
- GeyserImpl.getInstance().getLogger().info(GeyserLocale.getLocaleStringLog("geyser.extensions.disable.success", extension.description().name()));
+ GeyserImpl.getInstance().eventBus().unregisterAll(extension);
+
extension.setEnabled(false);
+ GeyserImpl.getInstance().getLogger().info(GeyserLocale.getLocaleStringLog("geyser.extensions.disable.success", extension.description().name()));
}
}
diff --git a/core/src/main/java/org/geysermc/geyser/extension/event/GeyserExtensionEventBus.java b/core/src/main/java/org/geysermc/geyser/extension/event/GeyserExtensionEventBus.java
new file mode 100644
index 000000000..4104871fa
--- /dev/null
+++ b/core/src/main/java/org/geysermc/geyser/extension/event/GeyserExtensionEventBus.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2019-2022 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.geyser.extension.event;
+
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.geysermc.geyser.api.event.Event;
+import org.geysermc.geyser.api.event.EventBus;
+import org.geysermc.geyser.api.event.EventSubscription;
+import org.geysermc.geyser.api.event.ExtensionEventBus;
+import org.geysermc.geyser.api.extension.Extension;
+
+import java.util.Set;
+import java.util.function.Consumer;
+
+public record GeyserExtensionEventBus(EventBus eventBus,
+ Extension extension) implements ExtensionEventBus {
+ @NonNull
+ @Override
+ public EventSubscription subscribe(@NonNull Class eventClass, @NonNull Consumer super T> consumer) {
+ return this.eventBus.subscribe(this.extension, eventClass, consumer);
+ }
+
+ @Override
+ public void register(@NonNull Object eventHolder) {
+ this.eventBus.register(this.extension, eventHolder);
+ }
+
+ @Override
+ public void unregisterAll() {
+ this.eventBus.unregisterAll(this.extension);
+ }
+
+ @NonNull
+ @Override
+ public EventSubscription subscribe(@NonNull Extension extension, @NonNull Class eventClass, @NonNull Consumer super T> consumer) {
+ return this.eventBus.subscribe(extension, eventClass, consumer);
+ }
+
+ @Override
+ public void unsubscribe(@NonNull EventSubscription subscription) {
+ this.eventBus.unsubscribe(subscription);
+ }
+
+ @Override
+ public void register(@NonNull Extension extension, @NonNull Object eventHolder) {
+ this.eventBus.register(extension, eventHolder);
+ }
+
+ @Override
+ public void unregisterAll(@NonNull Extension extension) {
+ this.eventBus.unregisterAll(extension);
+ }
+
+ @Override
+ public boolean fire(@NonNull Event event) {
+ return this.eventBus.fire(event);
+ }
+
+ @NonNull
+ @Override
+ public Set> subscriptions(@NonNull Class eventClass) {
+ return this.eventBus.subscriptions(eventClass);
+ }
+}
diff --git a/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java b/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java
index d6f72b8d0..d203b0311 100644
--- a/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java
+++ b/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java
@@ -115,7 +115,7 @@ public class AnvilInventoryUpdater extends InventoryUpdater {
// Changing the item in the input slot resets the name field on Bedrock, but
// does not result in a FilterTextPacket
- String originalName = MessageTranslator.convertToPlainText(ItemUtils.getCustomName(input.getNbt()), session.getLocale());
+ String originalName = MessageTranslator.convertToPlainText(ItemUtils.getCustomName(input.getNbt()), session.locale());
ServerboundRenameItemPacket renameItemPacket = new ServerboundRenameItemPacket(originalName);
session.sendDownstreamPacket(renameItemPacket);
@@ -427,7 +427,7 @@ public class AnvilInventoryUpdater extends InventoryUpdater {
String originalName = ItemUtils.getCustomName(anvilContainer.getInput().getNbt());
if (bedrock && originalName != null && anvilContainer.getNewName() != null) {
// Check text and formatting
- String legacyOriginalName = MessageTranslator.convertMessageLenient(originalName, session.getLocale());
+ String legacyOriginalName = MessageTranslator.convertMessageLenient(originalName, session.locale());
return !legacyOriginalName.equals(anvilContainer.getNewName());
}
return !Objects.equals(originalName, ItemUtils.getCustomName(anvilContainer.getResult().getNbt()));
diff --git a/core/src/main/java/org/geysermc/geyser/network/UpstreamPacketHandler.java b/core/src/main/java/org/geysermc/geyser/network/UpstreamPacketHandler.java
index f547c4dce..5686e3d98 100644
--- a/core/src/main/java/org/geysermc/geyser/network/UpstreamPacketHandler.java
+++ b/core/src/main/java/org/geysermc/geyser/network/UpstreamPacketHandler.java
@@ -112,7 +112,7 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
resourcePacksInfo.setForcedToAccept(GeyserImpl.getInstance().getConfig().isForceResourcePacks());
session.sendUpstreamPacket(resourcePacksInfo);
- GeyserLocale.loadGeyserLocale(session.getLocale());
+ GeyserLocale.loadGeyserLocale(session.locale());
return true;
}
@@ -208,7 +208,7 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
if (session.isLoggingIn()) {
SetTitlePacket titlePacket = new SetTitlePacket();
titlePacket.setType(SetTitlePacket.Type.ACTIONBAR);
- titlePacket.setText(GeyserLocale.getPlayerLocaleString("geyser.auth.login.wait", session.getLocale()));
+ titlePacket.setText(GeyserLocale.getPlayerLocaleString("geyser.auth.login.wait", session.locale()));
titlePacket.setFadeInTime(0);
titlePacket.setFadeOutTime(1);
titlePacket.setStayTime(2);
diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java
index 7ea65e49e..591934d6d 100644
--- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java
+++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java
@@ -79,7 +79,7 @@ import org.geysermc.floodgate.util.BedrockData;
import org.geysermc.geyser.Constants;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.api.connection.GeyserConnection;
-import org.geysermc.geyser.command.CommandSender;
+import org.geysermc.geyser.command.GeyserCommandSource;
import org.geysermc.geyser.configuration.EmoteOffhandWorkaroundOption;
import org.geysermc.geyser.entity.InteractiveTagManager;
import org.geysermc.geyser.entity.attribute.GeyserAttributeType;
@@ -122,7 +122,7 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
@Getter
-public class GeyserSession implements GeyserConnection, CommandSender {
+public class GeyserSession implements GeyserConnection, GeyserCommandSource {
private final GeyserImpl geyser;
private final UpstreamSession upstream;
@@ -876,7 +876,7 @@ public class GeyserSession implements GeyserConnection, CommandSender {
if (cause instanceof UnexpectedEncryptionException) {
if (remoteAuthType != AuthType.FLOODGATE) {
// Server expects online mode
- disconnectMessage = GeyserLocale.getPlayerLocaleString("geyser.network.remote.authentication_type_mismatch", getLocale());
+ disconnectMessage = GeyserLocale.getPlayerLocaleString("geyser.network.remote.authentication_type_mismatch", locale());
// Explain that they may be looking for Floodgate.
geyser.getLogger().warning(GeyserLocale.getLocaleStringLog(
geyser.getPlatformType() == PlatformType.STANDALONE ?
@@ -886,14 +886,14 @@ public class GeyserSession implements GeyserConnection, CommandSender {
));
} else {
// Likely that Floodgate is not configured correctly.
- disconnectMessage = GeyserLocale.getPlayerLocaleString("geyser.network.remote.floodgate_login_error", getLocale());
+ disconnectMessage = GeyserLocale.getPlayerLocaleString("geyser.network.remote.floodgate_login_error", locale());
if (geyser.getPlatformType() == PlatformType.STANDALONE) {
geyser.getLogger().warning(GeyserLocale.getLocaleStringLog("geyser.network.remote.floodgate_login_error_standalone"));
}
}
} else if (cause instanceof ConnectException) {
// Server is offline, probably
- disconnectMessage = GeyserLocale.getPlayerLocaleString("geyser.network.remote.server_offline", getLocale());
+ disconnectMessage = GeyserLocale.getPlayerLocaleString("geyser.network.remote.server_offline", locale());
} else {
disconnectMessage = MessageTranslator.convertMessageLenient(event.getReason());
}
@@ -1156,7 +1156,7 @@ public class GeyserSession implements GeyserConnection, CommandSender {
}
@Override
- public String getLocale() {
+ public String locale() {
return clientData.getLanguageCode();
}
diff --git a/core/src/main/java/org/geysermc/geyser/session/SessionManager.java b/core/src/main/java/org/geysermc/geyser/session/SessionManager.java
index 8cfc73d7e..fc6c37356 100644
--- a/core/src/main/java/org/geysermc/geyser/session/SessionManager.java
+++ b/core/src/main/java/org/geysermc/geyser/session/SessionManager.java
@@ -80,7 +80,7 @@ public final class SessionManager {
public void disconnectAll(String message) {
Collection sessions = getAllSessions();
for (GeyserSession session : sessions) {
- session.disconnect(GeyserLocale.getPlayerLocaleString(message, session.getLocale()));
+ session.disconnect(GeyserLocale.getPlayerLocaleString(message, session.locale()));
}
}
diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/AdvancementsCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/AdvancementsCache.java
index 9d3e4f5aa..5d5779ae7 100644
--- a/core/src/main/java/org/geysermc/geyser/session/cache/AdvancementsCache.java
+++ b/core/src/main/java/org/geysermc/geyser/session/cache/AdvancementsCache.java
@@ -72,14 +72,14 @@ public class AdvancementsCache {
public void buildAndShowMenuForm() {
SimpleForm.Builder builder =
SimpleForm.builder()
- .translator(MinecraftLocale::getLocaleString, session.getLocale())
+ .translator(MinecraftLocale::getLocaleString, session.locale())
.title("gui.advancements");
boolean hasAdvancements = false;
for (Map.Entry advancement : storedAdvancements.entrySet()) {
if (advancement.getValue().getParentId() == null) { // No parent means this is a root advancement
hasAdvancements = true;
- builder.button(MessageTranslator.convertMessage(advancement.getValue().getDisplayData().getTitle(), session.getLocale()));
+ builder.button(MessageTranslator.convertMessage(advancement.getValue().getDisplayData().getTitle(), session.locale()));
}
}
@@ -128,7 +128,7 @@ public class AdvancementsCache {
*/
public void buildAndShowListForm() {
GeyserAdvancement categoryAdvancement = storedAdvancements.get(currentAdvancementCategoryId);
- String language = session.getLocale();
+ String language = session.locale();
SimpleForm.Builder builder =
SimpleForm.builder()
@@ -190,7 +190,7 @@ public class AdvancementsCache {
*/
public void buildAndShowInfoForm(GeyserAdvancement advancement) {
// Cache language for easier access
- String language = session.getLocale();
+ String language = session.locale();
String earned = isEarned(advancement) ? "yes" : "no";
diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/BossBar.java b/core/src/main/java/org/geysermc/geyser/session/cache/BossBar.java
index 7cfeaa165..cd1bc4c98 100644
--- a/core/src/main/java/org/geysermc/geyser/session/cache/BossBar.java
+++ b/core/src/main/java/org/geysermc/geyser/session/cache/BossBar.java
@@ -57,7 +57,7 @@ public class BossBar {
BossEventPacket bossEventPacket = new BossEventPacket();
bossEventPacket.setBossUniqueEntityId(entityId);
bossEventPacket.setAction(BossEventPacket.Action.CREATE);
- bossEventPacket.setTitle(MessageTranslator.convertMessage(title, session.getLocale()));
+ bossEventPacket.setTitle(MessageTranslator.convertMessage(title, session.locale()));
bossEventPacket.setHealthPercentage(health);
bossEventPacket.setColor(color);
bossEventPacket.setOverlay(overlay);
@@ -71,7 +71,7 @@ public class BossBar {
BossEventPacket bossEventPacket = new BossEventPacket();
bossEventPacket.setBossUniqueEntityId(entityId);
bossEventPacket.setAction(BossEventPacket.Action.UPDATE_NAME);
- bossEventPacket.setTitle(MessageTranslator.convertMessage(title, session.getLocale()));
+ bossEventPacket.setTitle(MessageTranslator.convertMessage(title, session.locale()));
session.sendUpstreamPacket(bossEventPacket);
}
diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/item/ItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/item/ItemTranslator.java
index 6a2182279..34e9364ce 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/inventory/item/ItemTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/item/ItemTranslator.java
@@ -157,7 +157,7 @@ public abstract class ItemTranslator {
nbt = translateDisplayProperties(session, nbt, bedrockItem);
if (session.isAdvancedTooltips()) {
- nbt = addAdvancedTooltips(nbt, session.getItemMappings().getMapping(stack), session.getLocale());
+ nbt = addAdvancedTooltips(nbt, session.getItemMappings().getMapping(stack), session.locale());
}
ItemStack itemStack = new ItemStack(stack.getId(), stack.getAmount(), nbt);
@@ -474,7 +474,7 @@ public abstract class ItemTranslator {
String name = ((StringTag) display.get("Name")).getValue();
// Get the translated name and prefix it with a reset char
- name = MessageTranslator.convertMessageLenient(name, session.getLocale());
+ name = MessageTranslator.convertMessageLenient(name, session.locale());
// Add the new name tag
display.put(new StringTag("Name", name));
@@ -500,7 +500,7 @@ public abstract class ItemTranslator {
String translationKey = mapping.getTranslationString();
// Reset formatting since Bedrock defaults to italics
- display.put(new StringTag("Name", "§r§" + translationColor + MinecraftLocale.getLocaleString(translationKey, session.getLocale())));
+ display.put(new StringTag("Name", "§r§" + translationColor + MinecraftLocale.getLocaleString(translationKey, session.locale())));
}
return tag;
diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/item/nbt/AxolotlBucketTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/item/nbt/AxolotlBucketTranslator.java
index c3abf2495..4a91110dc 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/inventory/item/nbt/AxolotlBucketTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/item/nbt/AxolotlBucketTranslator.java
@@ -42,7 +42,7 @@ public class AxolotlBucketTranslator extends NbtItemStackTranslator {
// Bedrock Edition displays the properties of the axolotl. Java does not.
// To work around this, set the custom name to the Axolotl translation and it's displayed correctly
itemTag.put(new ByteTag("AppendCustomName", (byte) 1));
- itemTag.put(new StringTag("CustomName", MinecraftLocale.getLocaleString("entity.minecraft.axolotl", session.getLocale())));
+ itemTag.put(new StringTag("CustomName", MinecraftLocale.getLocaleString("entity.minecraft.axolotl", session.locale())));
// Boilerplate required so the nametag does not appear as "Bucket of "
itemTag.put(new StringTag("ColorID", ""));
itemTag.put(new StringTag("BodyID", ""));
diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/item/nbt/BasicItemTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/item/nbt/BasicItemTranslator.java
index 42cfc0439..d50a8c579 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/inventory/item/nbt/BasicItemTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/item/nbt/BasicItemTranslator.java
@@ -61,7 +61,7 @@ public class BasicItemTranslator extends NbtItemStackTranslator {
List lore = new ArrayList<>();
for (Tag tag : listTag.getValue()) {
if (!(tag instanceof StringTag)) continue;
- lore.add(new StringTag("", MessageTranslator.convertMessageLenient(((StringTag) tag).getValue(), session.getLocale())));
+ lore.add(new StringTag("", MessageTranslator.convertMessageLenient(((StringTag) tag).getValue(), session.locale())));
}
displayTag.put(new ListTag("Lore", lore));
}
diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/item/nbt/PlayerHeadTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/item/nbt/PlayerHeadTranslator.java
index 680be00fd..44308aeee 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/inventory/item/nbt/PlayerHeadTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/item/nbt/PlayerHeadTranslator.java
@@ -56,7 +56,7 @@ public class PlayerHeadTranslator extends NbtItemStackTranslator {
}
// Add correct name of player skull
// TODO: It's always yellow, even with a custom name. Handle?
- String displayName = "\u00a7r\u00a7e" + MinecraftLocale.getLocaleString("block.minecraft.player_head.named", session.getLocale()).replace("%s", name.getValue());
+ String displayName = "\u00a7r\u00a7e" + MinecraftLocale.getLocaleString("block.minecraft.player_head.named", session.locale()).replace("%s", name.getValue());
if (!itemTag.contains("display")) {
itemTag.put(new CompoundTag("display"));
}
diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/item/nbt/TropicalFishBucketTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/item/nbt/TropicalFishBucketTranslator.java
index dbacc75fe..5fd101e8b 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/inventory/item/nbt/TropicalFishBucketTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/item/nbt/TropicalFishBucketTranslator.java
@@ -50,7 +50,7 @@ public class TropicalFishBucketTranslator extends NbtItemStackTranslator {
public void translateToBedrock(GeyserSession session, CompoundTag itemTag, ItemMapping mapping) {
// Prevent name from appearing as "Bucket of"
itemTag.put(new ByteTag("AppendCustomName", (byte) 1));
- itemTag.put(new StringTag("CustomName", MinecraftLocale.getLocaleString("entity.minecraft.tropical_fish", session.getLocale())));
+ itemTag.put(new StringTag("CustomName", MinecraftLocale.getLocaleString("entity.minecraft.tropical_fish", session.locale())));
// Add Java's client side lore tag
Tag bucketVariantTag = itemTag.get("BucketVariantTag");
if (bucketVariantTag instanceof IntTag) {
@@ -66,10 +66,10 @@ public class TropicalFishBucketTranslator extends NbtItemStackTranslator {
int predefinedVariantId = TropicalFishEntity.getPredefinedId(varNumber);
if (predefinedVariantId != -1) {
Component tooltip = Component.translatable("entity.minecraft.tropical_fish.predefined." + predefinedVariantId, LORE_STYLE);
- lore.add(0, new StringTag("", MessageTranslator.convertMessage(tooltip, session.getLocale())));
+ lore.add(0, new StringTag("", MessageTranslator.convertMessage(tooltip, session.locale())));
} else {
Component typeTooltip = Component.translatable("entity.minecraft.tropical_fish.type." + TropicalFishEntity.getVariantName(varNumber), LORE_STYLE);
- lore.add(0, new StringTag("", MessageTranslator.convertMessage(typeTooltip, session.getLocale())));
+ lore.add(0, new StringTag("", MessageTranslator.convertMessage(typeTooltip, session.locale())));
byte baseColor = TropicalFishEntity.getBaseColor(varNumber);
byte patternColor = TropicalFishEntity.getPatternColor(varNumber);
@@ -78,7 +78,7 @@ public class TropicalFishBucketTranslator extends NbtItemStackTranslator {
colorTooltip = colorTooltip.append(Component.text(", ", LORE_STYLE))
.append(Component.translatable("color.minecraft." + TropicalFishEntity.getColorName(patternColor), LORE_STYLE));
}
- lore.add(1, new StringTag("", MessageTranslator.convertMessage(colorTooltip, session.getLocale())));
+ lore.add(1, new StringTag("", MessageTranslator.convertMessage(colorTooltip, session.locale())));
}
ListTag loreTag = displayTag.get("Lore");
diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockCommandRequestTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockCommandRequestTranslator.java
index 73ca9b222..1a955c1a8 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockCommandRequestTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockCommandRequestTranslator.java
@@ -27,7 +27,7 @@ package org.geysermc.geyser.translator.protocol.bedrock;
import org.geysermc.common.PlatformType;
import org.geysermc.geyser.GeyserImpl;
-import org.geysermc.geyser.command.CommandManager;
+import org.geysermc.geyser.command.GeyserCommandManager;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.protocol.PacketTranslator;
import org.geysermc.geyser.translator.protocol.Translator;
@@ -42,7 +42,7 @@ public class BedrockCommandRequestTranslator extends PacketTranslator
});
textPacket.setNeedsTranslation(false);
- textPacket.setMessage(MessageTranslator.convertMessage(packet.getMessage(), session.getLocale()));
+ textPacket.setMessage(MessageTranslator.convertMessage(packet.getMessage(), session.locale()));
session.sendUpstreamPacket(textPacket);
}
diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCommandsTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCommandsTranslator.java
index 28ebca926..18712dbf5 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCommandsTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCommandsTranslator.java
@@ -43,7 +43,8 @@ import lombok.Getter;
import lombok.ToString;
import net.kyori.adventure.text.format.NamedTextColor;
import org.geysermc.geyser.GeyserImpl;
-import org.geysermc.geyser.command.CommandManager;
+import org.geysermc.geyser.api.event.downstream.ServerDefineCommandsEvent;
+import org.geysermc.geyser.command.GeyserCommandManager;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.protocol.PacketTranslator;
import org.geysermc.geyser.translator.protocol.Translator;
@@ -112,7 +113,7 @@ public class JavaCommandsTranslator extends PacketTranslator commandData = new ArrayList<>();
IntSet commandNodes = new IntOpenHashSet();
@@ -141,15 +142,20 @@ public class JavaCommandsTranslator extends PacketTranslator new HashSet<>()).add(node.getName().toLowerCase());
}
+ ServerDefineCommandsEvent event = new ServerDefineCommandsEvent(session, commands.keySet());
+ session.getGeyser().eventBus().fire(event);
+ if (event.isCancelled()) {
+ return;
+ }
+
// The command flags, not sure what these do apart from break things
List flags = Collections.emptyList();
// Loop through all the found commands
-
for (Map.Entry> entry : commands.entrySet()) {
String commandName = entry.getValue().iterator().next(); // We know this has a value
@@ -236,7 +242,7 @@ public class JavaCommandsTranslator extends PacketTranslator 256) {
- session.sendMessage(GeyserLocale.getPlayerLocaleString("geyser.chat.too_long", session.getLocale(), message.length()));
+ session.sendMessage(GeyserLocale.getPlayerLocaleString("geyser.chat.too_long", session.locale(), message.length()));
return true;
}
diff --git a/core/src/main/java/org/geysermc/geyser/util/LoginEncryptionUtils.java b/core/src/main/java/org/geysermc/geyser/util/LoginEncryptionUtils.java
index 5a1063a10..8fd079702 100644
--- a/core/src/main/java/org/geysermc/geyser/util/LoginEncryptionUtils.java
+++ b/core/src/main/java/org/geysermc/geyser/util/LoginEncryptionUtils.java
@@ -226,7 +226,7 @@ public class LoginEncryptionUtils {
session.sendForm(
SimpleForm.builder()
- .translator(GeyserLocale::getPlayerLocaleString, session.getLocale())
+ .translator(GeyserLocale::getPlayerLocaleString, session.locale())
.title("geyser.auth.login.form.notice.title")
.content("geyser.auth.login.form.notice.desc")
.optionalButton("geyser.auth.login.form.notice.btn_login.mojang", isPasswordAuthEnabled)
@@ -257,14 +257,14 @@ public class LoginEncryptionUtils {
return;
}
- session.disconnect(GeyserLocale.getPlayerLocaleString("geyser.auth.login.form.disconnect", session.getLocale()));
+ session.disconnect(GeyserLocale.getPlayerLocaleString("geyser.auth.login.form.disconnect", session.locale()));
}));
}
public static void buildAndShowLoginDetailsWindow(GeyserSession session) {
session.sendForm(
CustomForm.builder()
- .translator(GeyserLocale::getPlayerLocaleString, session.getLocale())
+ .translator(GeyserLocale::getPlayerLocaleString, session.locale())
.title("geyser.auth.login.form.details.title")
.label("geyser.auth.login.form.details.desc")
.input("geyser.auth.login.form.details.email", "account@geysermc.org", "")
@@ -286,7 +286,7 @@ public class LoginEncryptionUtils {
public static void buildAndShowMicrosoftAuthenticationWindow(GeyserSession session) {
session.sendForm(
SimpleForm.builder()
- .translator(GeyserLocale::getPlayerLocaleString, session.getLocale())
+ .translator(GeyserLocale::getPlayerLocaleString, session.locale())
.title("geyser.auth.login.form.notice.btn_login.microsoft")
.button("geyser.auth.login.method.browser")
.button("geyser.auth.login.method.password")
@@ -303,7 +303,7 @@ public class LoginEncryptionUtils {
} else if (response.getClickedButtonId() == 1) {
buildAndShowLoginDetailsWindow(session);
} else {
- session.disconnect(GeyserLocale.getPlayerLocaleString("geyser.auth.login.form.disconnect", session.getLocale()));
+ session.disconnect(GeyserLocale.getPlayerLocaleString("geyser.auth.login.form.disconnect", session.locale()));
}
}));
}
@@ -326,7 +326,7 @@ public class LoginEncryptionUtils {
}
if (response.getClickedButtonId() == 1) {
- session.disconnect(GeyserLocale.getPlayerLocaleString("geyser.auth.login.form.disconnect", session.getLocale()));
+ session.disconnect(GeyserLocale.getPlayerLocaleString("geyser.auth.login.form.disconnect", session.locale()));
}
})
);
diff --git a/core/src/main/java/org/geysermc/geyser/util/SettingsUtils.java b/core/src/main/java/org/geysermc/geyser/util/SettingsUtils.java
index ea3412451..75c26cade 100644
--- a/core/src/main/java/org/geysermc/geyser/util/SettingsUtils.java
+++ b/core/src/main/java/org/geysermc/geyser/util/SettingsUtils.java
@@ -45,7 +45,7 @@ public class SettingsUtils {
*/
public static CustomForm buildForm(GeyserSession session) {
// Cache the language for cleaner access
- String language = session.getLocale();
+ String language = session.locale();
CustomForm.Builder builder = CustomForm.builder()
.translator(SettingsUtils::translateEntry, language)
diff --git a/core/src/main/java/org/geysermc/geyser/util/StatisticsUtils.java b/core/src/main/java/org/geysermc/geyser/util/StatisticsUtils.java
index 447661e21..3324ec577 100644
--- a/core/src/main/java/org/geysermc/geyser/util/StatisticsUtils.java
+++ b/core/src/main/java/org/geysermc/geyser/util/StatisticsUtils.java
@@ -53,7 +53,7 @@ public class StatisticsUtils {
*/
public static void buildAndSendStatisticsMenu(GeyserSession session) {
// Cache the language for cleaner access
- String language = session.getLocale();
+ String language = session.locale();
session.sendForm(
SimpleForm.builder()