mirror of
https://github.com/GeyserMC/Geyser.git
synced 2024-08-14 23:57:35 +00:00
Merge branch 'master' into fix-fabric-world-manager-performance
This commit is contained in:
commit
293bad55bc
128 changed files with 3074 additions and 2020 deletions
|
@ -25,30 +25,21 @@
|
|||
|
||||
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.commands.Commands;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
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.GeyserCommand;
|
||||
import org.geysermc.geyser.command.GeyserCommandManager;
|
||||
import org.geysermc.geyser.command.CommandRegistry;
|
||||
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 +50,6 @@ import java.io.IOException;
|
|||
import java.io.InputStream;
|
||||
import java.net.SocketAddress;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
|
@ -70,13 +60,15 @@ public abstract class GeyserModBootstrap implements GeyserBootstrap {
|
|||
|
||||
private final GeyserModPlatform platform;
|
||||
|
||||
@Getter
|
||||
private GeyserImpl geyser;
|
||||
private Path dataFolder;
|
||||
|
||||
@Setter
|
||||
@Setter @Getter
|
||||
private MinecraftServer server;
|
||||
|
||||
private GeyserCommandManager geyserCommandManager;
|
||||
@Setter
|
||||
private CommandRegistry commandRegistry;
|
||||
private GeyserModConfiguration geyserConfig;
|
||||
private GeyserModInjector geyserInjector;
|
||||
private final GeyserModLogger geyserLogger = new GeyserModLogger();
|
||||
|
@ -94,10 +86,6 @@ public abstract class GeyserModBootstrap implements GeyserBootstrap {
|
|||
this.geyserLogger.setDebug(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
|
||||
this.geyserCommandManager = new GeyserCommandManager(geyser);
|
||||
this.geyserCommandManager.init();
|
||||
}
|
||||
|
||||
public void onGeyserEnable() {
|
||||
|
@ -130,50 +118,6 @@ public abstract class GeyserModBootstrap implements GeyserBootstrap {
|
|||
if (isServer()) {
|
||||
this.geyserInjector.initializeLocalChannel(this);
|
||||
}
|
||||
|
||||
// Start command building
|
||||
// Set just "geyser" as the help command
|
||||
GeyserModCommandExecutor helpExecutor = new GeyserModCommandExecutor(geyser,
|
||||
(GeyserCommand) geyser.commandManager().getCommands().get("help"));
|
||||
LiteralArgumentBuilder<CommandSourceStack> builder = Commands.literal("geyser").executes(helpExecutor);
|
||||
|
||||
// Register all subcommands as valid
|
||||
for (Map.Entry<String, Command> command : geyser.commandManager().getCommands().entrySet()) {
|
||||
GeyserModCommandExecutor executor = new GeyserModCommandExecutor(geyser, (GeyserCommand) command.getValue());
|
||||
builder.then(Commands.literal(command.getKey())
|
||||
.executes(executor)
|
||||
// Could also test for Bedrock but depending on when this is called it may backfire
|
||||
.requires(executor::testPermission)
|
||||
// Allows parsing of arguments; e.g. for /geyser dump logs or the connectiontest command
|
||||
.then(Commands.argument("args", StringArgumentType.greedyString())
|
||||
.executes(context -> executor.runWithArgs(context, StringArgumentType.getString(context, "args")))
|
||||
.requires(executor::testPermission)));
|
||||
}
|
||||
server.getCommands().getDispatcher().register(builder);
|
||||
|
||||
// Register extension commands
|
||||
for (Map.Entry<Extension, Map<String, Command>> extensionMapEntry : geyser.commandManager().extensionCommands().entrySet()) {
|
||||
Map<String, Command> extensionCommands = extensionMapEntry.getValue();
|
||||
if (extensionCommands.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Register help command for just "/<extensionId>"
|
||||
GeyserModCommandExecutor extensionHelpExecutor = new GeyserModCommandExecutor(geyser,
|
||||
(GeyserCommand) extensionCommands.get("help"));
|
||||
LiteralArgumentBuilder<CommandSourceStack> extCmdBuilder = Commands.literal(extensionMapEntry.getKey().description().id()).executes(extensionHelpExecutor);
|
||||
|
||||
for (Map.Entry<String, Command> command : extensionCommands.entrySet()) {
|
||||
GeyserModCommandExecutor executor = new GeyserModCommandExecutor(geyser, (GeyserCommand) command.getValue());
|
||||
extCmdBuilder.then(Commands.literal(command.getKey())
|
||||
.executes(executor)
|
||||
.requires(executor::testPermission)
|
||||
.then(Commands.argument("args", StringArgumentType.greedyString())
|
||||
.executes(context -> executor.runWithArgs(context, StringArgumentType.getString(context, "args")))
|
||||
.requires(executor::testPermission)));
|
||||
}
|
||||
server.getCommands().getDispatcher().register(extCmdBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -206,8 +150,8 @@ public abstract class GeyserModBootstrap implements GeyserBootstrap {
|
|||
}
|
||||
|
||||
@Override
|
||||
public GeyserCommandManager getGeyserCommandManager() {
|
||||
return geyserCommandManager;
|
||||
public CommandRegistry getCommandRegistry() {
|
||||
return commandRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -235,6 +179,7 @@ public abstract class GeyserModBootstrap implements GeyserBootstrap {
|
|||
return this.server.getServerVersion();
|
||||
}
|
||||
|
||||
@SuppressWarnings("ConstantConditions") // Certain IDEA installations think that ip cannot be null
|
||||
@NonNull
|
||||
@Override
|
||||
public String getServerBindAddress() {
|
||||
|
@ -270,10 +215,6 @@ 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);
|
||||
|
||||
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
||||
private boolean loadConfig() {
|
||||
try {
|
||||
|
|
|
@ -25,17 +25,18 @@
|
|||
|
||||
package org.geysermc.geyser.platform.mod;
|
||||
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import org.geysermc.geyser.Constants;
|
||||
import org.geysermc.geyser.platform.mod.command.ModCommandSender;
|
||||
import org.geysermc.geyser.Permissions;
|
||||
import org.geysermc.geyser.platform.mod.command.ModCommandSource;
|
||||
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));
|
||||
// Should be creating this in the supplier, but we need it for the permission check.
|
||||
// Not a big deal currently because ModCommandSource doesn't load locale, so don't need to try to wait for it.
|
||||
ModCommandSource source = new ModCommandSource(player.createCommandSourceStack());
|
||||
if (source.hasPermission(Permissions.CHECK_UPDATE)) {
|
||||
VersionCheckUtils.checkForGeyserUpdate(() -> source);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,75 +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.platform.mod.command;
|
||||
|
||||
import com.mojang.brigadier.Command;
|
||||
import com.mojang.brigadier.context.CommandContext;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.command.GeyserCommand;
|
||||
import org.geysermc.geyser.command.GeyserCommandExecutor;
|
||||
import org.geysermc.geyser.platform.mod.GeyserModBootstrap;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.text.ChatColor;
|
||||
import org.geysermc.geyser.text.GeyserLocale;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
public class GeyserModCommandExecutor extends GeyserCommandExecutor implements Command<CommandSourceStack> {
|
||||
private final GeyserCommand command;
|
||||
|
||||
public GeyserModCommandExecutor(GeyserImpl geyser, GeyserCommand command) {
|
||||
super(geyser, Collections.singletonMap(command.name(), command));
|
||||
this.command = command;
|
||||
}
|
||||
|
||||
public boolean testPermission(CommandSourceStack source) {
|
||||
return GeyserModBootstrap.getInstance().hasPermission(source, command.permission(), command.isSuggestedOpOnly() ? 2 : 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int run(CommandContext<CommandSourceStack> context) {
|
||||
return runWithArgs(context, "");
|
||||
}
|
||||
|
||||
public int runWithArgs(CommandContext<CommandSourceStack> context, String args) {
|
||||
CommandSourceStack source = context.getSource();
|
||||
ModCommandSender sender = new ModCommandSender(source);
|
||||
GeyserSession session = getGeyserSession(sender);
|
||||
if (!testPermission(source)) {
|
||||
sender.sendMessage(ChatColor.RED + GeyserLocale.getPlayerLocaleString("geyser.bootstrap.command.permission_fail", sender.locale()));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (command.isBedrockOnly() && session == null) {
|
||||
sender.sendMessage(ChatColor.RED + GeyserLocale.getPlayerLocaleString("geyser.bootstrap.command.bedrock_only", sender.locale()));
|
||||
return 0;
|
||||
}
|
||||
|
||||
command.execute(session, sender, args.split(" "));
|
||||
return 0;
|
||||
}
|
||||
}
|
|
@ -31,19 +31,21 @@ import net.minecraft.core.RegistryAccess;
|
|||
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 ModCommandSender implements GeyserCommandSource {
|
||||
public class ModCommandSource implements GeyserCommandSource {
|
||||
|
||||
private final CommandSourceStack source;
|
||||
|
||||
public ModCommandSender(CommandSourceStack source) {
|
||||
public ModCommandSource(CommandSourceStack source) {
|
||||
this.source = source;
|
||||
// todo find locale?
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -75,8 +77,24 @@ public class ModCommandSender implements GeyserCommandSource {
|
|||
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, source.getServer().getOperatorUserPermissionLevel());
|
||||
// Unlike other bootstraps; we delegate to cloud here too:
|
||||
// On NeoForge; we'd have to keep track of all PermissionNodes - cloud already does that
|
||||
// For Fabric, we won't need to include the Fabric Permissions API anymore - cloud already does that too :p
|
||||
return GeyserImpl.getInstance().commandRegistry().hasPermission(this, permission);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object handle() {
|
||||
return source;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* Copyright (c) 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
|
||||
* 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.mixin.server;
|
||||
|
||||
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
|
||||
import com.llamalad7.mixinextras.sugar.Share;
|
||||
import com.llamalad7.mixinextras.sugar.ref.LocalRef;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.piston.PistonBaseBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.PistonCache;
|
||||
import org.geysermc.geyser.translator.level.block.entity.PistonBlockEntity;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.block.value.PistonValueType;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
@Mixin(PistonBaseBlock.class)
|
||||
public class PistonBaseBlockMixin {
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private boolean isSticky;
|
||||
|
||||
@ModifyExpressionValue(method = "moveBlocks",
|
||||
at = @At(value = "INVOKE", target = "Lcom/google/common/collect/Maps;newHashMap()Ljava/util/HashMap;")
|
||||
)
|
||||
private HashMap<BlockPos, BlockState> geyser$onMapCreate(HashMap<BlockPos, BlockState> original, @Share("pushBlocks") LocalRef<Map<BlockPos, BlockState>> localRef) {
|
||||
localRef.set(original);
|
||||
return original;
|
||||
}
|
||||
|
||||
@Inject(method = "moveBlocks",
|
||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/piston/PistonStructureResolver;getToDestroy()Ljava/util/List;")
|
||||
)
|
||||
private void geyser$onBlocksMove(Level level, BlockPos blockPos, Direction direction, boolean isExtending, CallbackInfoReturnable<Boolean> cir, @Share("pushBlocks") LocalRef<Map<BlockPos, BlockState>> localRef) {
|
||||
PistonValueType type = isExtending ? PistonValueType.PUSHING : PistonValueType.PULLING;
|
||||
boolean sticky = this.isSticky;
|
||||
|
||||
Object2ObjectMap<Vector3i, org.geysermc.geyser.level.block.type.BlockState> attachedBlocks = new Object2ObjectArrayMap<>();
|
||||
boolean blocksFilled = false;
|
||||
|
||||
for (Map.Entry<UUID, GeyserSession> entry : GeyserImpl.getInstance().getSessionManager().getSessions().entrySet()) {
|
||||
Player player = level.getPlayerByUUID(entry.getKey());
|
||||
//noinspection resource
|
||||
if (player == null || !player.level().equals(level)) {
|
||||
continue;
|
||||
}
|
||||
GeyserSession session = entry.getValue();
|
||||
|
||||
int dX = Math.abs(blockPos.getX() - player.getBlockX()) >> 4;
|
||||
int dZ = Math.abs(blockPos.getZ() - player.getBlockZ()) >> 4;
|
||||
if ((dX * dX + dZ * dZ) > session.getServerRenderDistance() * session.getServerRenderDistance()) {
|
||||
// Ignore pistons outside the player's render distance
|
||||
continue;
|
||||
}
|
||||
|
||||
// Trying to grab the blocks from the world like other platforms would result in the moving piston block
|
||||
// being returned instead.
|
||||
if (!blocksFilled) {
|
||||
Map<BlockPos, net.minecraft.world.level.block.state.BlockState> blocks = localRef.get();
|
||||
for (Map.Entry<BlockPos, BlockState> blockStateEntry : blocks.entrySet()) {
|
||||
int blockStateId = Block.BLOCK_STATE_REGISTRY.getId(blockStateEntry.getValue());
|
||||
org.geysermc.geyser.level.block.type.BlockState state = org.geysermc.geyser.level.block.type.BlockState.of(blockStateId);
|
||||
attachedBlocks.put(geyser$fromBlockPos(blockStateEntry.getKey()), state);
|
||||
}
|
||||
blocksFilled = true;
|
||||
}
|
||||
|
||||
org.geysermc.geyser.level.physics.Direction orientation = org.geysermc.geyser.level.physics.Direction.VALUES[direction.ordinal()];
|
||||
|
||||
Vector3i position = geyser$fromBlockPos(blockPos);
|
||||
session.executeInEventLoop(() -> {
|
||||
PistonCache pistonCache = session.getPistonCache();
|
||||
PistonBlockEntity blockEntity = pistonCache.getPistons().computeIfAbsent(position, pos ->
|
||||
new PistonBlockEntity(session, position, orientation, sticky, !isExtending));
|
||||
blockEntity.setAction(type, attachedBlocks);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Unique
|
||||
private static Vector3i geyser$fromBlockPos(BlockPos pos) {
|
||||
return Vector3i.from(pos.getX(), pos.getY(), pos.getZ());
|
||||
}
|
||||
|
||||
}
|
|
@ -49,7 +49,6 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
|||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import org.geysermc.geyser.level.GeyserWorldManager;
|
||||
import org.geysermc.geyser.network.GameProtocol;
|
||||
import org.geysermc.geyser.platform.mod.GeyserModBootstrap;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.util.MinecraftKey;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.Holder;
|
||||
|
@ -113,12 +112,6 @@ public class GeyserModWorldManager extends GeyserWorldManager {
|
|||
return SharedConstants.getCurrentVersion().getProtocolVersion() == GameProtocol.getJavaProtocolVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(GeyserSession session, String permission) {
|
||||
ServerPlayer player = getPlayer(session);
|
||||
return GeyserModBootstrap.getInstance().hasPermission(player, permission);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GameMode getDefaultGameMode(GeyserSession session) {
|
||||
return GameMode.byId(server.getDefaultGameType().getId());
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
"compatibilityLevel": "JAVA_17",
|
||||
"mixins": [
|
||||
"server.BlockPlaceMixin",
|
||||
"server.PistonBaseBlockMixin",
|
||||
"server.ServerConnectionListenerMixin"
|
||||
],
|
||||
"server": [
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue