Skip to content

Commit

Permalink
Merge branch 'master' into fix_commandPlayerChunkLoadingLoginIssue
Browse files Browse the repository at this point in the history
  • Loading branch information
wendavid552 authored Aug 3, 2024
2 parents 9fcf47f + 55db82e commit 2e3c62e
Show file tree
Hide file tree
Showing 12 changed files with 276 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@
package club.mcams.carpet.commands.rule.commandCustomCommandPermissionLevel;

import club.mcams.carpet.AmsServerSettings;
import club.mcams.carpet.commands.suggestionProviders.ListSuggestionProvider;
import club.mcams.carpet.commands.suggestionProviders.LiteralCommandSuggestionProvider;
import club.mcams.carpet.commands.suggestionProviders.SetSuggestionProvider;
import club.mcams.carpet.mixin.rule.commandCustomCommandPermissionLevel.CommandNodeInvoker;
import club.mcams.carpet.translations.Translator;
import club.mcams.carpet.utils.CommandHelper;
import club.mcams.carpet.utils.Messenger;
Expand All @@ -30,18 +34,19 @@
import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType;

import com.mojang.brigadier.tree.CommandNode;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.command.CommandManager;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.Formatting;

import java.util.HashMap;
import java.util.Map;

public class CustomCommandPermissionLevelRegistry {
private static final Translator translator = new Translator("command.customCommandPermissionLevel");
private static final String needRestartServerMessage = translator.tr("need_restart_server_msg").getString();
private static final String MSG_HEAD = "<customCommandPermissionLevel> ";
public static final Map<String, Integer> COMMAND_PERMISSION_MAP = new HashMap<>();

Expand All @@ -50,8 +55,9 @@ public static void register(CommandDispatcher<ServerCommandSource> dispatcher) {
CommandManager.literal("customCommandPermissionLevel")
.requires(source -> CommandHelper.canUseCommand(source, AmsServerSettings.commandCustomCommandPermissionLevel))
.then(CommandManager.literal("set")
.then(CommandManager.argument("command", StringArgumentType.string())
.then(CommandManager.argument("command", StringArgumentType.string()).suggests(new LiteralCommandSuggestionProvider())
.then(CommandManager.argument("permissionLevel", IntegerArgumentType.integer())
.suggests(ListSuggestionProvider.of(CommandHelper.permissionLevels))
.executes(context -> set(
context.getSource().getServer(),
context.getSource().getPlayer(),
Expand All @@ -60,6 +66,7 @@ public static void register(CommandDispatcher<ServerCommandSource> dispatcher) {
)))))
.then(CommandManager.literal("remove")
.then(CommandManager.argument("command", StringArgumentType.string())
.suggests(SetSuggestionProvider.of(COMMAND_PERMISSION_MAP.keySet()))
.executes(context -> remove(
context.getSource().getServer(),
context.getSource().getPlayer(),
Expand All @@ -73,29 +80,36 @@ public static void register(CommandDispatcher<ServerCommandSource> dispatcher) {
.executes(context -> help(context.getSource().getPlayer()))));
}

private static int set(MinecraftServer server, PlayerEntity player, String command, int permissionLevel) {
private static int set(MinecraftServer server, ServerPlayerEntity player, String command, int permissionLevel) {
if (COMMAND_PERMISSION_MAP.containsKey(command)) {
int oldPermissionLevel = COMMAND_PERMISSION_MAP.get(command);
player.sendMessage(
Messenger.s(
String.format("%s%s %d -> %d", MSG_HEAD, command, oldPermissionLevel, permissionLevel)
).formatted(Formatting.GREEN), false
);
sendNeedRestartServerMessage(player);
} else {
player.sendMessage(
Messenger.s(
String.format("%s+ %s/%d", MSG_HEAD, command, permissionLevel)
).formatted(Formatting.GREEN), false
);
sendNeedRestartServerMessage(player);
}
COMMAND_PERMISSION_MAP.put(command, permissionLevel);
saveToJson(server);
setPermission(server,player, command, permissionLevel);
return 1;
}

private static int remove(MinecraftServer server, PlayerEntity player, String command) {
@SuppressWarnings("unchecked")
private static void setPermission(MinecraftServer server, ServerPlayerEntity player, String command, int permissionLevel) {
CommandDispatcher<ServerCommandSource> dispatcher = server.getCommandManager().getDispatcher();
CommandNode<ServerCommandSource> target = dispatcher.getRoot().getChild(command);
((CommandNodeInvoker<ServerCommandSource>)target).setRequirement(source -> source.hasPermissionLevel(permissionLevel));
CommandHelper.notifyPlayersCommandsChanged(player);
}

private static int remove(MinecraftServer server, ServerPlayerEntity player, String command) {
if (COMMAND_PERMISSION_MAP.containsKey(command)) {
COMMAND_PERMISSION_MAP.remove(command);
saveToJson(server);
Expand All @@ -104,7 +118,7 @@ private static int remove(MinecraftServer server, PlayerEntity player, String co
String.format("%s- %s", MSG_HEAD, command)
).formatted(Formatting.RED, Formatting.ITALIC), false
);
sendNeedRestartServerMessage(player);
CommandHelper.notifyPlayersCommandsChanged(player);
} else {
player.sendMessage(
Messenger.s(
Expand All @@ -115,15 +129,17 @@ private static int remove(MinecraftServer server, PlayerEntity player, String co
return 1;
}

private static int removeAll(MinecraftServer server, PlayerEntity player) {
COMMAND_PERMISSION_MAP.clear();
saveToJson(server);
private static int removeAll(MinecraftServer server, ServerPlayerEntity player) {
if (!COMMAND_PERMISSION_MAP.isEmpty()) {
COMMAND_PERMISSION_MAP.clear();
saveToJson(server);
}
player.sendMessage(
Messenger.s(
MSG_HEAD + translator.tr("removeAll").getString()
).formatted(Formatting.RED, Formatting.ITALIC), false
);
sendNeedRestartServerMessage(player);
CommandHelper.notifyPlayersCommandsChanged(player);
return 1;
}

Expand Down Expand Up @@ -162,13 +178,4 @@ private static void saveToJson(MinecraftServer server) {
final String CONFIG_PATH = CustomCommandPermissionLevelConfig.getPath(server);
CustomCommandPermissionLevelConfig.saveToJson(COMMAND_PERMISSION_MAP, CONFIG_PATH);
}

// TODO: 热重载咕咕咕
private static void sendNeedRestartServerMessage(PlayerEntity player) {
player.sendMessage(
Messenger.s(
MSG_HEAD + needRestartServerMessage
).formatted(Formatting.YELLOW), false
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public class PingCommandRegistry {

public static void register(CommandDispatcher<ServerCommandSource> dispatcher) {
dispatcher.register(
CommandManager.literal("ping")
CommandManager.literal("pings")
.requires(source -> CommandHelper.canUseCommand(source, AmsServerSettings.commandPacketInternetGroper))
.then(argument("targetIpOrDomainName", StringArgumentType.string())
.then(argument("pingQuantity", IntegerArgumentType.integer())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package club.mcams.carpet.commands.suggestionProviders;

import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.suggestion.SuggestionProvider;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;

import net.minecraft.server.command.ServerCommandSource;

import java.util.List;
import java.util.concurrent.CompletableFuture;

public class ListSuggestionProvider<E> implements SuggestionProvider<ServerCommandSource> {
private final List<E> options;

public ListSuggestionProvider(List<E> options) {
this.options = options;
}

public static ListSuggestionProvider<?> of(List<?> options) {
return new ListSuggestionProvider<>(options);
}

@Override
public CompletableFuture<Suggestions> getSuggestions(CommandContext<ServerCommandSource> context, SuggestionsBuilder builder) {
options.forEach(option -> builder.suggest(option.toString()));
return builder.buildFuture();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* This file is part of the Carpet AMS Addition project, licensed under the
* GNU Lesser General Public License v3.0
*
* Copyright (C) 2024 A Minecraft Server and contributors
*
* Carpet AMS Addition is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Carpet AMS Addition is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Carpet AMS Addition. If not, see <https://www.gnu.org/licenses/>.
*/

package club.mcams.carpet.commands.suggestionProviders;

import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.suggestion.SuggestionProvider;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;

import net.minecraft.server.command.ServerCommandSource;

import java.util.concurrent.CompletableFuture;

public class LiteralCommandSuggestionProvider implements SuggestionProvider<ServerCommandSource> {
@Override
public CompletableFuture<Suggestions> getSuggestions(CommandContext<ServerCommandSource> context, SuggestionsBuilder builder) {
context.getRootNode().getChildren().forEach(node -> {
if (node != null && node.getName() != null) {
builder.suggest(node.getName());
}
});
return builder.buildFuture();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package club.mcams.carpet.commands.suggestionProviders;

import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.suggestion.SuggestionProvider;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;

import net.minecraft.server.command.ServerCommandSource;

import java.util.Set;
import java.util.concurrent.CompletableFuture;

public class SetSuggestionProvider<E> implements SuggestionProvider<ServerCommandSource> {
private final Set<E> options;

public SetSuggestionProvider(Set<E> options) {
this.options = options;
}

public static SetSuggestionProvider<?> of(Set<?> options) {
return new SetSuggestionProvider<>(options);
}

@Override
public CompletableFuture<Suggestions> getSuggestions(CommandContext<ServerCommandSource> context, SuggestionsBuilder builder) {
options.forEach(option -> builder.suggest(option.toString()));
return builder.buildFuture();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* This file is part of the Carpet AMS Addition project, licensed under the
* GNU Lesser General Public License v3.0
*
* Copyright (C) 2024 A Minecraft Server and contributors
*
* Carpet AMS Addition is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Carpet AMS Addition is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Carpet AMS Addition. If not, see <https://www.gnu.org/licenses/>.
*/

package club.mcams.carpet.mixin.carpet;

import club.mcams.carpet.utils.compat.DummyClass;

import org.spongepowered.asm.mixin.Mixin;

import top.byteeeee.annotationtoolbox.annotation.GameVersion;

@GameVersion(version = "Minecraft >= 1.19.4", desc = "Just a fix for https://github.com/gnembon/fabric-carpet/issues/1908")
@Mixin(DummyClass.class)
public class CarpetServerMixin {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* This file is part of the Carpet AMS Addition project, licensed under the
* GNU Lesser General Public License v3.0
*
* Copyright (C) 2024 A Minecraft Server and contributors
*
* Carpet AMS Addition is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Carpet AMS Addition is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Carpet AMS Addition. If not, see <https://www.gnu.org/licenses/>.
*/

package club.mcams.carpet.mixin.rule.commandCustomCommandPermissionLevel;

import com.mojang.brigadier.tree.CommandNode;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.gen.Accessor;

import java.util.function.Predicate;

@Mixin(value = CommandNode.class, remap = false)
public interface CommandNodeInvoker<S> {
@Mutable
@Accessor("requirement")
void setRequirement(Predicate<S> requirement);
}
26 changes: 26 additions & 0 deletions src/main/java/club/mcams/carpet/utils/CommandHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,37 @@

package club.mcams.carpet.utils;

import club.mcams.carpet.AmsServer;
import club.mcams.carpet.translations.Translator;

import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.Formatting;

import java.util.Arrays;
import java.util.List;

@SuppressWarnings("EnhancedSwitchMigration")
public final class CommandHelper {
public static final List<String> permissionLevels = Arrays.asList("0", "1", "2", "3", "4");
private static final Translator translator = new Translator("command.commandHelper");

private CommandHelper() {}

public static void notifyPlayersCommandsChanged(ServerPlayerEntity player) {
try {
if (player.getServer() != null) {
player.getServer().getCommandManager().sendCommandTree(player);
player.sendMessage(
Messenger.s(translator.tr("refresh_cmd_tree").getString()).formatted(Formatting.YELLOW), false
);
}
}
catch (NullPointerException e) {
AmsServer.LOGGER.warn("Exception while refreshing commands, please report this to Carpet", e);
}
}

public static boolean canUseCommand(ServerCommandSource source, Object commandLevel) {
if (commandLevel instanceof Boolean) return (Boolean) commandLevel;
String commandLevelString = commandLevel.toString();
Expand Down
3 changes: 3 additions & 0 deletions src/main/resources/amscarpet.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"package": "club.mcams.carpet.mixin",
"compatibilityLevel": "/*JAVA_VERSION*/",
"mixins": [
"carpet.CarpetServerMixin",
"carpet.HUDControllerMixin",
"carpet.SettingsManagerMixin",
"rule.amsUpdateSuppressionCrashFix.ChainRestrictedNeighborUpdater_SixWayEntryMixin",
Expand All @@ -26,6 +27,8 @@
"rule.commandCustomBlockBlastResistance.FluidStateMixin",
"rule.commandCustomCommandPermissionLevel.CommandDispatcherMixin",
"rule.commandPlayerChunkLoadController.ChunkTicketManagerMixin",
"rule.commandCustomCommandPermissionLevel.CommandNodeInvoker",
"rule.commandPlayerChunkLoadController.ThreadedAnvilChunkStorageMixin",
"rule.creativeOneHitKill.EntityAccessorMixin",
"rule.creativeOneHitKill.PlayerEntityMixin",
"rule.creativeShulkerBoxDropsDisabled.ShulkerBoxBlockMixin",
Expand Down
Loading

0 comments on commit 2e3c62e

Please sign in to comment.