Skip to content

Commit

Permalink
Add server config for disabling cheat mode
Browse files Browse the repository at this point in the history
  • Loading branch information
mezz committed Oct 11, 2021
1 parent 004de24 commit 574bb25
Show file tree
Hide file tree
Showing 13 changed files with 166 additions and 48 deletions.
13 changes: 9 additions & 4 deletions src/main/java/mezz/jei/JustEnoughItems.java
Expand Up @@ -2,6 +2,7 @@

import mezz.jei.api.constants.ModIds;
import mezz.jei.config.JEIClientConfig;
import mezz.jei.config.ServerConfig;
import mezz.jei.events.EventBusHelper;
import mezz.jei.gui.textures.JeiSpriteUploader;
import mezz.jei.gui.textures.Textures;
Expand All @@ -14,7 +15,9 @@
import net.minecraftforge.client.event.ColorHandlerEvent;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fml.ModLoadingContext;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.config.ModConfig;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.event.lifecycle.FMLLoadCompleteEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
Expand All @@ -29,7 +32,7 @@ public JustEnoughItems() {
}

private static void clientStart(IEventBus modEventBus, NetworkHandler networkHandler) {
JEIClientConfig.register();
JEIClientConfig.register(modEventBus);

EventBusHelper.addListener(JustEnoughItems.class, modEventBus, ColorHandlerEvent.Block.class, setupEvent -> {
Minecraft minecraft = Minecraft.getInstance();
Expand All @@ -47,8 +50,10 @@ private static void clientStart(IEventBus modEventBus, NetworkHandler networkHan
}

private static void commonStart(IEventBus modEventBus, NetworkHandler networkHandler) {
EventBusHelper.addLifecycleListener(JustEnoughItems.class, modEventBus, FMLCommonSetupEvent.class, event ->
networkHandler.createServerPacketHandler()
);
EventBusHelper.addLifecycleListener(JustEnoughItems.class, modEventBus, FMLCommonSetupEvent.class, event -> {
networkHandler.createServerPacketHandler();
ModLoadingContext modLoadingContext = ModLoadingContext.get();
ServerConfig.register(modEventBus, modLoadingContext);
});
}
}
8 changes: 4 additions & 4 deletions src/main/java/mezz/jei/config/ClientConfig.java
Expand Up @@ -33,7 +33,7 @@ public final class ClientConfig implements IJEIConfig, IClientConfig {
public static final int largestNumColumns = 100;
public static final int minRecipeGuiHeight = 175;

private final ConfigValues values;
private final ClientConfigValues values;
private List<? extends String> searchColors = Arrays.asList(ColorGetter.getColorDefaults());
public static final List<IngredientSortStage> ingredientSorterStagesDefault = Arrays.asList(
IngredientSortStage.MOD_NAME,
Expand All @@ -59,8 +59,8 @@ public final class ClientConfig implements IJEIConfig, IClientConfig {

public ClientConfig(ForgeConfigSpec.Builder builder) {
instance = this;
this.values = new ConfigValues();
ConfigValues defaultValues = new ConfigValues();
this.values = new ClientConfigValues();
ClientConfigValues defaultValues = new ClientConfigValues();

builder.push("advanced");
{
Expand Down Expand Up @@ -124,7 +124,7 @@ public static IClientConfig getInstance() {

@Override
public void buildSettingsGUI(ConfigGroup group) {
ConfigValues defaultVals = new ConfigValues();
ClientConfigValues defaultVals = new ClientConfigValues();

group.addBool(cfgTranslation("centerSearchBarEnabled"), values.centerSearchBarEnabled, v -> {
centerSearchBarEnabled.set(v);
Expand Down
Expand Up @@ -2,7 +2,7 @@

import mezz.jei.util.GiveMode;

public class ConfigValues {
public class ClientConfigValues {
// advanced
public boolean debugModeEnabled = false;
public boolean centerSearchBarEnabled = false;
Expand Down
9 changes: 9 additions & 0 deletions src/main/java/mezz/jei/config/IServerConfig.java
@@ -0,0 +1,9 @@
package mezz.jei.config;

public interface IServerConfig {
boolean isCheatModeEnabledForOp();

boolean isCheatModeEnabledForGive();

boolean isCheatModeEnabledForCreative();
}
17 changes: 9 additions & 8 deletions src/main/java/mezz/jei/config/JEIClientConfig.java
Expand Up @@ -3,18 +3,18 @@
import dev.ftb.mods.ftblibrary.config.ConfigGroup;
import dev.ftb.mods.ftblibrary.config.ui.EditConfigScreen;
import mezz.jei.api.constants.ModIds;
import mezz.jei.events.EventBusHelper;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screen.inventory.InventoryScreen;
import net.minecraft.util.text.Style;
import net.minecraft.util.text.TranslationTextComponent;
import net.minecraft.util.text.event.ClickEvent;
import net.minecraftforge.common.ForgeConfigSpec;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.ModList;
import net.minecraftforge.fml.ModLoadingContext;
import net.minecraftforge.fml.config.ModConfig;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;

public class JEIClientConfig {
private static final ForgeConfigSpec.Builder builder = new ForgeConfigSpec.Builder();
Expand All @@ -27,17 +27,18 @@ public class JEIClientConfig {
private static boolean ftbLibraryLoaded = false;
private static final String TRANSLATION_KEY = "config." + ModIds.JEI_ID;

public static void register() {
FMLJavaModLoadingContext.get().getModEventBus().register(JEIClientConfig.class);
ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, config);
public static void register(IEventBus modEventBus) {
EventBusHelper.addListener(modEventBus, FMLCommonSetupEvent.class, JEIClientConfig::commonSetup);
EventBusHelper.addListener(modEventBus, ModConfig.ModConfigEvent.class, JEIClientConfig::reload);

ModLoadingContext modLoadingContext = ModLoadingContext.get();
modLoadingContext.registerConfig(ModConfig.Type.CLIENT, config);
}

@SubscribeEvent
public static void commonSetup(FMLCommonSetupEvent event) {
ftbLibraryLoaded = ModList.get().isLoaded("ftblibrary");
}

@SubscribeEvent
public static void reload(ModConfig.ModConfigEvent event) {
if (event.getConfig().getSpec() != config) {
return;
Expand All @@ -50,7 +51,7 @@ public static void reload(ModConfig.ModConfigEvent event) {

public static void openSettings() {
Minecraft mc = Minecraft.getInstance();
if (mc.player == null) {
if (mc == null || mc.player == null) {
return;
}

Expand Down
62 changes: 62 additions & 0 deletions src/main/java/mezz/jei/config/ServerConfig.java
@@ -0,0 +1,62 @@
package mezz.jei.config;

import com.google.common.base.Preconditions;
import net.minecraftforge.common.ForgeConfigSpec;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.ModLoadingContext;
import net.minecraftforge.fml.config.ModConfig;

import javax.annotation.Nullable;

public final class ServerConfig implements IServerConfig {
@Nullable
private static IServerConfig instance;

// Forge config
private final ForgeConfigSpec.BooleanValue enableCheatModeForOp;
private final ForgeConfigSpec.BooleanValue enableCheatModeForCreative;
private final ForgeConfigSpec.BooleanValue enableCheatModeForGive;

public static void register(IEventBus modEventBus, ModLoadingContext modLoadingContext) {
modEventBus.register(ServerConfig.class);
ForgeConfigSpec.Builder builder = new ForgeConfigSpec.Builder();
instance = new ServerConfig(builder);
ForgeConfigSpec config = builder.build();
modLoadingContext.registerConfig(ModConfig.Type.SERVER, config);
}

public ServerConfig(ForgeConfigSpec.Builder builder) {
builder.push("cheat mode");
{
builder.comment("Enable Cheat Mode for Operators (/op)");
enableCheatModeForOp = builder.define("enableCheatModeForOp", true);

builder.comment("Enable Cheat Mode for users in Creative Mode");
enableCheatModeForCreative = builder.define("enableCheatModeForCreative", true);

builder.comment("Enable Cheat Mode for users who can use /give");
enableCheatModeForGive = builder.define("enableCheatModeForGive", false);
}
builder.pop();
}

public static IServerConfig getInstance() {
Preconditions.checkNotNull(instance);
return instance;
}

@Override
public boolean isCheatModeEnabledForOp() {
return enableCheatModeForOp.get();
}

@Override
public boolean isCheatModeEnabledForCreative() {
return enableCheatModeForCreative.get();
}

@Override
public boolean isCheatModeEnabledForGive() {
return enableCheatModeForGive.get();
}
}
1 change: 0 additions & 1 deletion src/main/java/mezz/jei/network/Network.java
Expand Up @@ -18,7 +18,6 @@ public class Network {
@OnlyIn(Dist.CLIENT)
public static void sendPacketToServer(PacketJei packet) {
Minecraft minecraft = Minecraft.getInstance();
//noinspection ConstantConditions
if (minecraft != null) {
ClientPlayNetHandler netHandler = minecraft.getConnection();
if (netHandler != null && ServerInfo.isJeiOnServer()) {
Expand Down
8 changes: 5 additions & 3 deletions src/main/java/mezz/jei/network/PacketHandlerClient.java
Expand Up @@ -31,9 +31,11 @@ public void onPacket(NetworkEvent.ServerCustomPayloadEvent event) {
PacketIdClient packetId = PacketIdClient.VALUES[packetIdOrdinal];
IPacketJeiHandler packetHandler = clientHandlers.get(packetId);
Minecraft minecraft = Minecraft.getInstance();
PlayerEntity player = minecraft.player;
if (player != null) {
packetHandler.readPacketData(packetBuffer, player);
if (minecraft != null) {
PlayerEntity player = minecraft.player;
if (player != null) {
packetHandler.readPacketData(packetBuffer, player);
}
}
} catch (Throwable e) {
LOGGER.error("Packet error", e);
Expand Down
30 changes: 28 additions & 2 deletions src/main/java/mezz/jei/network/packets/PacketCheatPermission.java
Expand Up @@ -4,11 +4,16 @@
import net.minecraft.network.PacketBuffer;
import net.minecraft.util.text.TextFormatting;

import mezz.jei.config.IServerConfig;
import mezz.jei.config.ServerConfig;
import mezz.jei.config.IWorldConfig;
import mezz.jei.network.IPacketId;
import mezz.jei.network.PacketIdClient;
import mezz.jei.util.CommandUtilServer;

import java.util.ArrayList;
import java.util.List;

public class PacketCheatPermission extends PacketJei {
private final boolean hasPermission;

Expand All @@ -28,9 +33,30 @@ public void writePacketData(PacketBuffer buf) {

public static void readPacketData(PacketBuffer buf, PlayerEntity player, IWorldConfig worldConfig) {
boolean hasPermission = buf.readBoolean();
if (!hasPermission && worldConfig.isCheatItemsEnabled()) {
if (!hasPermission) {
CommandUtilServer.writeChatMessage(player, "jei.chat.error.no.cheat.permission.1", TextFormatting.RED);
CommandUtilServer.writeChatMessage(player, "jei.chat.error.no.cheat.permission.2", TextFormatting.RED);

IServerConfig serverConfig = ServerConfig.getInstance();
List<String> allowedCheatingMethods = new ArrayList<>();
if (serverConfig.isCheatModeEnabledForOp()) {
allowedCheatingMethods.add("jei.chat.error.no.cheat.permission.op");
}
if (serverConfig.isCheatModeEnabledForCreative()) {
allowedCheatingMethods.add("jei.chat.error.no.cheat.permission.creative");
}
if (serverConfig.isCheatModeEnabledForGive()) {
allowedCheatingMethods.add("jei.chat.error.no.cheat.permission.give");
}

if (allowedCheatingMethods.isEmpty()) {
CommandUtilServer.writeChatMessage(player, "jei.chat.error.no.cheat.permission.disabled", TextFormatting.RED);
} else {
CommandUtilServer.writeChatMessage(player, "jei.chat.error.no.cheat.permission.enabled", TextFormatting.RED);
for (String allowedCheatingMethod : allowedCheatingMethods) {
CommandUtilServer.writeChatMessage(player, allowedCheatingMethod, TextFormatting.RED);
}
}

worldConfig.setCheatItemsEnabled(false);
player.closeContainer();
}
Expand Down
Expand Up @@ -28,7 +28,7 @@ public void writePacketData(PacketBuffer buf) {

public static void readPacketData(PacketBuffer buf, PlayerEntity player) {
Item item = buf.readRegistryIdUnsafe(ForgeRegistries.ITEMS);
if (CommandUtilServer.hasPermission(player)) {
if (CommandUtilServer.hasPermissionForCheatMode(player)) {
ItemStack playerItem = player.inventory.getCarried();
if (playerItem.getItem() == item) {
player.inventory.setCarried(ItemStack.EMPTY);
Expand Down
Expand Up @@ -23,7 +23,7 @@ public void writePacketData(PacketBuffer buf) {
public static void readPacketData(PacketBuffer buf, PlayerEntity player) {
if (player instanceof ServerPlayerEntity) {
ServerPlayerEntity sender = (ServerPlayerEntity) player;
boolean hasPermission = CommandUtilServer.hasPermission(sender);
boolean hasPermission = CommandUtilServer.hasPermissionForCheatMode(sender);
PacketCheatPermission packetCheatPermission = new PacketCheatPermission(hasPermission);

Network.sendPacketToClient(packetCheatPermission, sender);
Expand Down
53 changes: 31 additions & 22 deletions src/main/java/mezz/jei/util/CommandUtilServer.java
@@ -1,15 +1,12 @@
package mezz.jei.util;

import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import net.minecraft.util.Util;
import net.minecraftforge.items.ItemHandlerHelper;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.tree.CommandNode;
import com.mojang.brigadier.tree.RootCommandNode;
import mezz.jei.config.IServerConfig;
import mezz.jei.config.ServerConfig;
import mezz.jei.network.Network;
import mezz.jei.network.packets.PacketCheatPermission;
import net.minecraft.command.CommandSource;
import net.minecraft.command.Commands;
import net.minecraft.command.arguments.ItemInput;
Expand All @@ -25,15 +22,19 @@
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.SoundEvents;
import net.minecraft.util.Util;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.util.text.TranslationTextComponent;

import mezz.jei.network.Network;
import mezz.jei.network.packets.PacketCheatPermission;
import net.minecraftforge.items.ItemHandlerHelper;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
* Server-side-safe utilities for commands.
*/
Expand Down Expand Up @@ -70,29 +71,37 @@ public static void writeChatMessage(PlayerEntity player, String translationKey,
player.sendMessage(component, Util.NIL_UUID);
}

public static boolean hasPermission(PlayerEntity sender) {
if (sender.isCreative()) {
public static boolean hasPermissionForCheatMode(PlayerEntity sender) {
IServerConfig serverConfig = ServerConfig.getInstance();
if (serverConfig.isCheatModeEnabledForCreative() &&
sender.isCreative()) {
return true;
}
CommandNode<CommandSource> giveCommand = getGiveCommand(sender);

CommandSource commandSource = sender.createCommandSourceStack();
if (giveCommand != null) {
return giveCommand.canUse(commandSource);
} else {
if (serverConfig.isCheatModeEnabledForOp()) {
MinecraftServer minecraftServer = sender.getServer();
if (minecraftServer == null) {
return false;
if (minecraftServer != null) {
int opPermissionLevel = minecraftServer.getOperatorUserPermissionLevel();
return commandSource.hasPermission(opPermissionLevel);
}
}

if (serverConfig.isCheatModeEnabledForGive()) {
CommandNode<CommandSource> giveCommand = getGiveCommand(sender);
if (giveCommand != null) {
return giveCommand.canUse(commandSource);
}
int opPermissionLevel = minecraftServer.getOperatorUserPermissionLevel();
return commandSource.hasPermission(opPermissionLevel);
}

return false;
}

/**
* Gives a player an item.
*/
public static void executeGive(ServerPlayerEntity sender, ItemStack itemStack, GiveMode giveMode) {
if (hasPermission(sender)) {
if (hasPermissionForCheatMode(sender)) {
if (giveMode == GiveMode.INVENTORY) {
giveToInventory(sender, itemStack);
} else if (giveMode == GiveMode.MOUSE_PICKUP) {
Expand All @@ -104,7 +113,7 @@ public static void executeGive(ServerPlayerEntity sender, ItemStack itemStack, G
}

public static void setHotbarSlot(ServerPlayerEntity sender, ItemStack itemStack, int hotbarSlot) {
if (hasPermission(sender)) {
if (hasPermissionForCheatMode(sender)) {
if (!PlayerInventory.isHotbarSlot(hotbarSlot)) {
LOGGER.error("Tried to set slot that is not in the hotbar: {}", hotbarSlot);
return;
Expand Down

0 comments on commit 574bb25

Please sign in to comment.