attempt at updating the cloud pr; todo neoforge or even general testing

This commit is contained in:
onebeastchris 2024-03-07 12:33:17 +01:00
parent f6b0f36441
commit c867b54141
23 changed files with 187 additions and 113 deletions

View File

@ -38,10 +38,7 @@ import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.geysermc.geyser.GeyserBootstrap;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.api.command.Command;
import org.geysermc.geyser.api.extension.Extension;
import org.geysermc.geyser.api.util.PlatformType;
import org.geysermc.geyser.command.GeyserCommandManager;
import org.geysermc.geyser.command.CommandSourceConverter;
import org.geysermc.geyser.command.CommandRegistry;
import org.geysermc.geyser.command.GeyserCommandSource;
@ -73,7 +70,6 @@ public class GeyserBungeePlugin extends Plugin implements GeyserBootstrap {
private GeyserBungeeInjector geyserInjector;
private GeyserBungeeLogger geyserLogger;
private IGeyserPingPassthrough geyserBungeePingPassthrough;
private GeyserImpl geyser;
@Override
@ -106,6 +102,9 @@ public class GeyserBungeePlugin extends Plugin implements GeyserBootstrap {
GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger);
this.geyser = GeyserImpl.load(PlatformType.BUNGEECORD, this);
this.geyserInjector = new GeyserBungeeInjector(this);
// Registration of listeners occurs only once
this.getProxy().getPluginManager().registerListener(this, new GeyserBungeeUpdateListener());
}
@Override

View File

@ -88,7 +88,7 @@ public class BungeeCommandSource implements GeyserCommandSource {
if (handle instanceof ProxiedPlayer player) {
Locale locale = player.getLocale();
if (locale != null) {
// Locale can be null early on in the conneciton
// Locale can be null early on in the connection
return GeyserLocale.formatLocale(locale.getLanguage() + "_" + locale.getCountry());
}
}

View File

@ -25,6 +25,9 @@ dependencies {
modImplementation(libs.fabric.permissions)
include(libs.fabric.permissions)
modImplementation(libs.cloud.fabric)
include(libs.cloud.fabric)
}
application {

View File

@ -25,6 +25,9 @@
package org.geysermc.geyser.platform.fabric;
import cloud.commandframework.CommandManager;
import cloud.commandframework.execution.CommandExecutionCoordinator;
import cloud.commandframework.fabric.FabricServerCommandManager;
import me.lucko.fabric.api.permissions.v0.Permissions;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.ModInitializer;
@ -33,9 +36,14 @@ import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.world.entity.player.Player;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.command.CommandRegistry;
import org.geysermc.geyser.command.CommandSourceConverter;
import org.geysermc.geyser.command.GeyserCommandSource;
import org.geysermc.geyser.platform.mod.GeyserModBootstrap;
import org.geysermc.geyser.platform.mod.GeyserModUpdateListener;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.geysermc.geyser.platform.mod.command.ModCommandSource;
public class GeyserFabricBootstrap extends GeyserModBootstrap implements ModInitializer {
@ -58,15 +66,24 @@ public class GeyserFabricBootstrap extends GeyserModBootstrap implements ModInit
ServerPlayConnectionEvents.JOIN.register((handler, $, $$) -> GeyserModUpdateListener.onPlayReady(handler.getPlayer()));
this.onGeyserInitialize();
// TODO: verify
var sourceConverter = CommandSourceConverter.layered(
CommandSourceStack.class,
id -> getServer().getPlayerList().getPlayer(id),
Player::createCommandSourceStack,
() -> getServer().createCommandSourceStack() // NPE if method reference is used, since server is not available yet
);
CommandManager<GeyserCommandSource> cloud = new FabricServerCommandManager<>(
CommandExecutionCoordinator.simpleCoordinator(),
ModCommandSource::new,
sourceConverter::convert
);
this.setCommandRegistry(new CommandRegistry(GeyserImpl.getInstance(), cloud));
}
@Override
public boolean hasPermission(@NonNull Player source, @NonNull String permissionNode) {
return Permissions.check(source, permissionNode);
}
@Override
public boolean hasPermission(@NonNull CommandSourceStack source, @NonNull String permissionNode, int permissionLevel) {
return Permissions.check(source, permissionNode, permissionLevel);
public boolean hasPermission(@NonNull CommandSourceStack source, @NonNull String permissionNode) {
return Permissions.check(source, permissionNode, source.getServer().getOperatorUserPermissionLevel());
}
}

View File

@ -26,7 +26,6 @@
package org.geysermc.geyser.platform.neoforge;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.world.entity.player.Player;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.fml.common.Mod;
import net.neoforged.fml.loading.FMLLoader;
@ -72,12 +71,8 @@ public class GeyserNeoForgeBootstrap extends GeyserModBootstrap {
}
@Override
public boolean hasPermission(@NonNull Player source, @NonNull String permissionNode) {
public boolean hasPermission(@NonNull CommandSourceStack source, @NonNull String permissionNode) {
return this.permissionHandler.hasPermission(source, permissionNode);
}
@Override
public boolean hasPermission(@NonNull CommandSourceStack source, @NonNull String permissionNode, int permissionLevel) {
return this.permissionHandler.hasPermission(source, permissionNode, permissionLevel);
}
}

View File

@ -27,7 +27,6 @@ package org.geysermc.geyser.platform.neoforge;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Player;
import net.neoforged.neoforge.server.permission.PermissionAPI;
import net.neoforged.neoforge.server.permission.events.PermissionGatherEvent;
import net.neoforged.neoforge.server.permission.nodes.PermissionDynamicContextKey;
@ -38,7 +37,7 @@ import org.checkerframework.checker.nullness.qual.NonNull;
import org.geysermc.geyser.Constants;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.api.command.Command;
import org.geysermc.geyser.command.GeyserCommandManager;
import org.geysermc.geyser.command.CommandRegistry;
import java.lang.reflect.Constructor;
import java.util.HashMap;
@ -69,7 +68,7 @@ public class GeyserNeoForgePermissionHandler {
public void onPermissionGather(PermissionGatherEvent.Nodes event) {
this.registerNode(Constants.UPDATE_PERMISSION, event);
GeyserCommandManager commandManager = GeyserImpl.getInstance().commandManager();
CommandRegistry commandManager = GeyserImpl.getInstance().commandRegistry();
for (Map.Entry<String, Command> entry : commandManager.commands().entrySet()) {
Command command = entry.getValue();
@ -95,27 +94,18 @@ public class GeyserNeoForgePermissionHandler {
}
}
public boolean hasPermission(@NonNull Player source, @NonNull String permissionNode) {
public boolean hasPermission(@NonNull CommandSourceStack source, @NonNull String permissionNode) {
ServerPlayer player = source.getPlayer();
if (!source.isPlayer() || player == null) {
return true;
}
PermissionNode<Boolean> node = this.permissionNodes.get(permissionNode);
if (node == null) {
GeyserImpl.getInstance().getLogger().warning("Unable to find permission node " + permissionNode);
return false;
}
return PermissionAPI.getPermission((ServerPlayer) source, node);
}
public boolean hasPermission(@NonNull CommandSourceStack source, @NonNull String permissionNode, int permissionLevel) {
if (!source.isPlayer()) {
return true;
}
assert source.getPlayer() != null;
boolean permission = this.hasPermission(source.getPlayer(), permissionNode);
if (!permission) {
return source.getPlayer().hasPermissions(permissionLevel);
}
return true;
return PermissionAPI.getPermission(player, node);
}
private void registerNode(String node, PermissionGatherEvent.Nodes event) {

View File

@ -25,31 +25,23 @@
package org.geysermc.geyser.platform.mod;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.entity.player.Player;
import org.apache.logging.log4j.LogManager;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.geysermc.geyser.GeyserBootstrap;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.GeyserLogger;
import org.geysermc.geyser.api.command.Command;
import org.geysermc.geyser.api.extension.Extension;
import org.geysermc.geyser.command.CommandRegistry;
import org.geysermc.geyser.command.GeyserCommand;
import org.geysermc.geyser.command.GeyserCommandManager;
import org.geysermc.geyser.configuration.GeyserConfiguration;
import org.geysermc.geyser.dump.BootstrapDumpInfo;
import org.geysermc.geyser.level.WorldManager;
import org.geysermc.geyser.ping.GeyserLegacyPingPassthrough;
import org.geysermc.geyser.ping.IGeyserPingPassthrough;
import org.geysermc.geyser.platform.mod.command.GeyserModCommandExecutor;
import org.geysermc.geyser.platform.mod.platform.GeyserModPlatform;
import org.geysermc.geyser.platform.mod.world.GeyserModWorldManager;
import org.geysermc.geyser.text.GeyserLocale;
@ -59,7 +51,6 @@ import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Path;
import java.util.Map;
import java.util.UUID;
@RequiredArgsConstructor
@ -73,9 +64,10 @@ public abstract class GeyserModBootstrap implements GeyserBootstrap {
private GeyserImpl geyser;
private Path dataFolder;
@Setter
@Setter @Getter
private MinecraftServer server;
@Setter
private CommandRegistry commandRegistry;
private GeyserModConfiguration geyserConfig;
private GeyserModInjector geyserInjector;
@ -94,21 +86,6 @@ public abstract class GeyserModBootstrap implements GeyserBootstrap {
this.geyserLogger = new GeyserModLogger(geyserConfig.isDebugMode());
GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger);
this.geyser = GeyserImpl.load(this.platform.platformType(), this);
// Create command manager here, since the permission handler on neo needs it
//TODO differentiate Fabric/NeoForge!?
var sourceConverter = CommandSourceConverter.layered(
CommandSourceStack.class,
id -> server.getPlayerList().getPlayer(id),
Player::createCommandSourceStack,
() -> server.createCommandSourceStack() // NPE if method reference is used, since server is not available yet
);
CommandManager<GeyserCommandSource> cloud = new FabricServerCommandManager<>(
CommandExecutionCoordinator.simpleCoordinator(),
FabricCommandSource::new,
sourceConverter::convert
);
commandRegistry = new CommandRegistry(geyser, cloud);
}
public void onGeyserEnable() {
@ -224,9 +201,7 @@ public abstract class GeyserModBootstrap implements GeyserBootstrap {
return this.platform.resolveResource(resource);
}
public abstract boolean hasPermission(@NonNull Player source, @NonNull String permissionNode);
public abstract boolean hasPermission(@NonNull CommandSourceStack source, @NonNull String permissionNode, int permissionLevel);
public abstract boolean hasPermission(@NonNull CommandSourceStack source, @NonNull String permissionNode);
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
private boolean loadConfig() {

View File

@ -34,8 +34,8 @@ import org.geysermc.geyser.util.VersionCheckUtils;
public final class GeyserModUpdateListener {
public static void onPlayReady(Player player) {
CommandSourceStack stack = player.createCommandSourceStack();
if (GeyserModBootstrap.getInstance().hasPermission(stack, Constants.UPDATE_PERMISSION, 2)) {
VersionCheckUtils.checkForGeyserUpdate(() -> new ModCommandSender(stack));
if (GeyserModBootstrap.getInstance().hasPermission(stack, Constants.UPDATE_PERMISSION)) {
VersionCheckUtils.checkForGeyserUpdate(() -> new ModCommandSource(stack));
}
}

View File

@ -0,0 +1,96 @@
/*
* 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.platform.mod.command;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.command.GeyserCommandSource;
import org.geysermc.geyser.platform.mod.GeyserModBootstrap;
import org.geysermc.geyser.text.ChatColor;
import java.util.Objects;
import java.util.UUID;
public class ModCommandSource implements GeyserCommandSource {
private final CommandSourceStack source;
public ModCommandSource(CommandSourceStack source) {
this.source = source;
}
@Override
public String name() {
return source.getTextName();
}
@Override
public void sendMessage(@NonNull String message) {
if (source.getEntity() instanceof ServerPlayer) {
((ServerPlayer) source.getEntity()).displayClientMessage(Component.literal(message), false);
} else {
GeyserImpl.getInstance().getLogger().info(ChatColor.toANSI(message + ChatColor.RESET));
}
}
@Override
public void sendMessage(net.kyori.adventure.text.Component message) {
if (source.getEntity() instanceof ServerPlayer player) {
String decoded = GsonComponentSerializer.gson().serialize(message);
player.displayClientMessage(Objects.requireNonNull(Component.Serializer.fromJson(decoded)), false);
return;
}
GeyserCommandSource.super.sendMessage(message);
}
@Override
public boolean isConsole() {
return !(source.getEntity() instanceof ServerPlayer);
}
@Override
public @Nullable UUID playerUuid() {
if (source.getEntity() instanceof ServerPlayer player) {
return player.getUUID();
}
return null;
}
@Override
public boolean hasPermission(String permission) {
return GeyserModBootstrap.getInstance().hasPermission(source, permission);
}
@Override
public Object handle() {
return source;
}
}

View File

@ -162,7 +162,12 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap {
@Override
public void onEnable() {
var sourceConverter = new CommandSourceConverter<>(CommandSender.class, Bukkit::getPlayer, Bukkit::getConsoleSender);
// Create command manager early so we can add Geyser extension commands
var sourceConverter = new CommandSourceConverter<>(
CommandSender.class,
Bukkit::getPlayer,
Bukkit::getConsoleSender
);
PaperCommandManager<GeyserCommandSource> cloud;
try {
cloud = new PaperCommandManager<>(
@ -190,7 +195,6 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap {
// Needs to be an anonymous inner class otherwise Bukkit complains about missing classes
Bukkit.getPluginManager().registerEvents(new Listener() {
@EventHandler
public void onServerLoaded(ServerLoadEvent event) {
if (event.getType() == ServerLoadEvent.LoadType.RELOAD) {
@ -230,7 +234,7 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap {
}
geyserLogger.debug("Spigot ping passthrough type: " + (this.geyserSpigotPingPassthrough == null ? null : this.geyserSpigotPingPassthrough.getClass()));
// Don't need to re-create the world manager/re-register commands/reinject when reloading
// Don't need to re-create the world manager/reinject when reloading
if (GeyserImpl.getInstance().isReloading()) {
return;
}

View File

@ -43,6 +43,7 @@ import org.geysermc.geyser.GeyserBootstrap;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.api.util.PlatformType;
import org.geysermc.geyser.command.CommandRegistry;
import org.geysermc.geyser.command.standalone.StandaloneCloudCommandManager;
import org.geysermc.geyser.configuration.GeyserConfiguration;
import org.geysermc.geyser.configuration.GeyserJacksonConfiguration;
import org.geysermc.geyser.dump.BootstrapDumpInfo;
@ -225,7 +226,7 @@ public class GeyserStandaloneBootstrap implements GeyserBootstrap {
geyser = GeyserImpl.load(PlatformType.STANDALONE, this);
// fire GeyserDefineCommandsEvent after PreInitEvent, before PostInitEvent, for consistency with other bootstraps
GeyserStandaloneCommandManager cloud = new GeyserStandaloneCommandManager(geyser);
StandaloneCloudCommandManager cloud = new StandaloneCloudCommandManager(geyser);
commandRegistry = new CommandRegistry(geyser, cloud);
GeyserImpl.start();
@ -261,7 +262,7 @@ public class GeyserStandaloneBootstrap implements GeyserBootstrap {
@Override
public void onGeyserDisable() {
// We can re-register commands on standalone, so why not
GeyserImpl.getInstance().commandManager().getCommands().clear();
commandRegistry.commands().clear();
geyser.disable();
}

View File

@ -143,22 +143,10 @@ public class GeyserVelocityPlugin implements GeyserBootstrap {
this.geyserPingPassthrough = new GeyserVelocityPingPassthrough(proxyServer);
}
// No need to re-register commands when reloading
if (GeyserImpl.getInstance().isReloading()) {
return;
// No need to re-register events
if (!GeyserImpl.getInstance().isReloading()) {
proxyServer.getEventManager().register(this, new GeyserVelocityUpdateListener());
}
this.commandManager.register("geyser", new GeyserVelocityCommandExecutor(geyser, geyserCommandManager.getCommands()));
for (Map.Entry<Extension, Map<String, Command>> entry : this.geyserCommandManager.extensionCommands().entrySet()) {
Map<String, Command> commands = entry.getValue();
if (commands.isEmpty()) {
continue;
}
this.commandManager.register(entry.getKey().description().id(), new GeyserVelocityCommandExecutor(this.geyser, commands));
}
proxyServer.getEventManager().register(this, new GeyserVelocityUpdateListener());
}
@Override

View File

@ -30,17 +30,18 @@ import net.raphimc.viaproxy.ViaProxy;
import net.raphimc.viaproxy.cli.options.Options;
import net.raphimc.viaproxy.plugins.PluginManager;
import net.raphimc.viaproxy.plugins.ViaProxyPlugin;
import net.raphimc.viaproxy.plugins.events.ConsoleCommandEvent;
import net.raphimc.viaproxy.plugins.events.ProxyStartEvent;
import net.raphimc.viaproxy.plugins.events.ProxyStopEvent;
import net.raphimc.viaproxy.plugins.events.ShouldVerifyOnlineModeEvent;
import org.apache.logging.log4j.LogManager;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.geysermc.geyser.GeyserBootstrap;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.GeyserLogger;
import org.geysermc.geyser.api.network.AuthType;
import org.geysermc.geyser.api.util.PlatformType;
import org.geysermc.geyser.command.GeyserCommandManager;
import org.geysermc.geyser.command.CommandRegistry;
import org.geysermc.geyser.command.standalone.StandaloneCloudCommandManager;
import org.geysermc.geyser.configuration.GeyserConfiguration;
import org.geysermc.geyser.dump.BootstrapDumpInfo;
import org.geysermc.geyser.ping.GeyserLegacyPingPassthrough;
@ -49,7 +50,6 @@ import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.text.GeyserLocale;
import org.geysermc.geyser.util.FileUtils;
import org.geysermc.geyser.util.LoopbackUtil;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.IOException;
@ -65,7 +65,7 @@ public class GeyserViaProxyPlugin extends ViaProxyPlugin implements GeyserBootst
private final GeyserViaProxyLogger logger = new GeyserViaProxyLogger(LogManager.getLogger("Geyser"));
private GeyserViaProxyConfiguration config;
private GeyserImpl geyser;
private GeyserCommandManager commandManager;
private CommandRegistry commandRegistry;
private IGeyserPingPassthrough pingPassthrough;
@Override
@ -83,14 +83,6 @@ public class GeyserViaProxyPlugin extends ViaProxyPlugin implements GeyserBootst
this.onGeyserShutdown();
}
@EventHandler
private void onConsoleCommand(final ConsoleCommandEvent event) {
final String command = event.getCommand().startsWith("/") ? event.getCommand().substring(1) : event.getCommand();
if (this.getGeyserCommandManager().runCommand(this.getGeyserLogger(), command + " " + String.join(" ", event.getArgs()))) {
event.setCancelled(true);
}
}
@EventHandler
private void onShouldVerifyOnlineModeEvent(final ShouldVerifyOnlineModeEvent event) {
final UUID uuid = event.getProxyConnection().getGameProfile().getId();
@ -132,8 +124,8 @@ public class GeyserViaProxyPlugin extends ViaProxyPlugin implements GeyserBootst
}
}
this.commandManager = new GeyserCommandManager(this.geyser);
this.commandManager.init();
StandaloneCloudCommandManager cloud = new StandaloneCloudCommandManager(geyser);
this.commandRegistry = new CommandRegistry(geyser, cloud);
GeyserImpl.start();
@ -164,8 +156,8 @@ public class GeyserViaProxyPlugin extends ViaProxyPlugin implements GeyserBootst
}
@Override
public GeyserCommandManager getGeyserCommandManager() {
return this.commandManager;
public CommandRegistry getCommandRegistry() {
return this.commandRegistry;
}
@Override
@ -183,7 +175,7 @@ public class GeyserViaProxyPlugin extends ViaProxyPlugin implements GeyserBootst
return new GeyserViaProxyDumpInfo();
}
@NotNull
@NonNull
@Override
public String getServerBindAddress() {
if (Options.BIND_ADDRESS instanceof InetSocketAddress socketAddress) {
@ -207,6 +199,7 @@ public class GeyserViaProxyPlugin extends ViaProxyPlugin implements GeyserBootst
return false;
}
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
private boolean loadConfig() {
try {
final File configFile = FileUtils.fileOrCopiedFromResource(new File(ROOT_FOLDER, "config.yml"), "config.yml", s -> s.replaceAll("generateduuid", UUID.randomUUID().toString()), this);

View File

@ -0,0 +1,9 @@
# Add any permissions here that all players should have.
# Permissions for builtin Geyser commands do not have to be listed here.
# If an extension/plugin registers their permissions with default values, entries here are typically unnecessary.
# If extensions don't register their permissions, permissions that everyone should have must be added here manually.
default-permissions:
- geyser.command.help # this is unnecessary

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2023 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2024 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
@ -23,7 +23,7 @@
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.geyser.platform.standalone;
package org.geysermc.geyser.command.standalone;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2023 GeyserMC. http://geysermc.org
* Copyright (c) 2019-2024 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
@ -23,7 +23,7 @@
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.geyser.platform.standalone;
package org.geysermc.geyser.command.standalone;
import cloud.commandframework.CommandManager;
import cloud.commandframework.execution.CommandExecutionCoordinator;
@ -46,7 +46,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Set;
public class GeyserStandaloneCommandManager extends CommandManager<GeyserCommandSource> {
public class StandaloneCloudCommandManager extends CommandManager<GeyserCommandSource> {
private final GeyserImpl geyser;
@ -60,7 +60,7 @@ public class GeyserStandaloneCommandManager extends CommandManager<GeyserCommand
*/
private final Set<String> basePermissions = new ObjectOpenHashSet<>();
public GeyserStandaloneCommandManager(GeyserImpl geyser) {
public StandaloneCloudCommandManager(GeyserImpl geyser) {
super(CommandExecutionCoordinator.simpleCoordinator(), CommandRegistrationHandler.nullCommandRegistrationHandler());
// simpleCoordinator: execute commands immediately on the calling thread.
// nullCommandRegistrationHandler: cloud is not responsible for handling our CommandRegistry, which is fairly decoupled.

View File

@ -48,8 +48,9 @@ public class BedrockCommandRequestTranslator extends PacketTranslator<CommandReq
// https://github.com/GeyserMC/Geyser/issues/3877
command = command.stripTrailing();
if (session.getGeyser().getPlatformType() == PlatformType.STANDALONE) {
// try to handle the command within the standalone command manager
if (session.getGeyser().getPlatformType() == PlatformType.STANDALONE ||
session.getGeyser().getPlatformType() == PlatformType.VIAPROXY) {
// try to handle the command within the standalone/viaproxy command manager
String[] args = command.split(" ");
if (args.length > 0) {

View File

@ -112,6 +112,9 @@ public class JavaAddEntityTranslator extends PacketTranslator<ClientboundAddEnti
} else {
return;
}
} else if (packet.getType() == EntityType.EXPERIENCE_ORB) {
//TODO: spawn exp orb here; we dont have a factory.
return;
} else {
entity = definition.factory().create(session, packet.getEntityId(), session.getEntityCache().getNextEntityId().incrementAndGet(),
packet.getUuid(), definition, position, motion, yaw, pitch, headYaw);

@ -1 +1 @@
Subproject commit f28856bd770f9347c0ffd63fe44d9b21b6f0492c
Subproject commit afbf78bbe0b39d0a076a42c228828c12f7f7da90