Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Server whitelist/blacklist #146

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and Freecam's versioning is based on [Semantic Versioning](https://semver.org/sp
### Added

- Added a way to configure key bindings from Freecam's config menu ([#143](https://github.com/MinecraftFreecam/Freecam/pull/143)).
- Added an optional server whitelist/blacklist ([#146](https://github.com/MinecraftFreecam/Freecam/pull/146)).

### Changed

Expand Down
41 changes: 39 additions & 2 deletions common/src/main/java/net/xolt/freecam/Freecam.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import net.minecraft.client.CameraType;
import net.minecraft.client.KeyMapping;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ServerData;
import net.minecraft.client.player.Input;
import net.minecraft.client.player.KeyboardInput;
import net.minecraft.client.renderer.texture.Tickable;
Expand Down Expand Up @@ -33,8 +34,9 @@ public class Freecam {
private static CameraType rememberedF5 = null;

public static void preTick(Minecraft mc) {
// Disable if the previous tick asked us to
if (disableNextTick && isEnabled()) {
// Disable if the previous tick asked us to,
// or Freecam is restricted on the current server
if ((disableNextTick || isRestrictedOnServer()) && isEnabled()) {
toggle();
}
disableNextTick = false;
Expand Down Expand Up @@ -85,6 +87,13 @@ public static boolean resetTripodHandler() {
}

public static void toggle() {
if (isRestrictedOnServer()) {
if (ModConfig.INSTANCE.notification.notifyFreecam) {
MC.player.displayClientMessage(Component.translatable("msg.freecam.restrictedByConfig", MC.getCurrentServer().ip), true);
}
return;
}

if (tripodEnabled) {
toggleTripod(activeTripod);
return;
Expand All @@ -106,6 +115,13 @@ private static void toggleTripod(TripodSlot tripod) {
return;
}

if (isRestrictedOnServer()) {
if (ModConfig.INSTANCE.notification.notifyTripod) {
MC.player.displayClientMessage(Component.translatable("msg.freecam.restrictedByConfig", MC.getCurrentServer().ip), true);
}
return;
}

if (tripodEnabled) {
if (activeTripod == tripod) {
onDisableTripod();
Expand Down Expand Up @@ -295,4 +311,25 @@ public static boolean isEnabled() {
public static boolean isPlayerControlEnabled() {
return playerControlEnabled;
}

public static boolean isRestrictedOnServer() {
ServerData server = MC.getCurrentServer();
ModConfig.ServerRestriction mode = ModConfig.INSTANCE.servers.mode;
if (mode == ModConfig.ServerRestriction.NONE || server == null || MC.isSingleplayer()) {
return false;
}

String ip = server.ip.trim().toLowerCase();
return switch (mode) {
case WHITELIST -> ModConfig.INSTANCE.servers.whitelist.stream()
.map(String::trim)
.map(String::toLowerCase)
.noneMatch(ip::equals);
case BLACKLIST -> ModConfig.INSTANCE.servers.blacklist.stream()
.map(String::trim)
.map(String::toLowerCase)
.anyMatch(ip::equals);
default -> throw new IllegalStateException("Unexpected mode value in Freecam.isRestrictedOnServer: " + mode);
};
}
}
26 changes: 26 additions & 0 deletions common/src/main/java/net/xolt/freecam/config/ModConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
import net.xolt.freecam.config.gui.ModBindingsConfig;
import net.xolt.freecam.config.gui.VariantTooltip;
import net.xolt.freecam.variant.api.BuildVariant;
import org.jetbrains.annotations.NotNull;

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

@Config(name = "freecam")
public class ModConfig implements ConfigData {
Expand Down Expand Up @@ -109,6 +113,19 @@ public static class UtilityConfig {
public InteractionMode interactionMode = InteractionMode.CAMERA;
}

@ConfigEntry.Gui.Tooltip
@ConfigEntry.Gui.CollapsibleObject
public ServerConfig servers = new ServerConfig();
public static class ServerConfig {
@ConfigEntry.Gui.Tooltip(count = 2)
@ConfigEntry.Gui.EnumHandler(option = EnumDisplayOption.BUTTON)
public ServerRestriction mode = ServerRestriction.NONE;

// These must be mutable lists, so no Collections.emptyList()
public List<String> whitelist = new ArrayList<>();
public List<String> blacklist = new ArrayList<>();
}

@ConfigEntry.Gui.Tooltip
@ConfigEntry.Gui.CollapsibleObject
public NotificationConfig notification = new NotificationConfig();
Expand Down Expand Up @@ -169,4 +186,13 @@ public enum Perspective implements SelectionListEntry.Translatable {
return key;
}
}

public enum ServerRestriction implements SelectionListEntry.Translatable {
NONE, WHITELIST, BLACKLIST;

@Override
public @NotNull String getKey() {
return "text.autoconfig.freecam.option.servers.mode." + toString().toLowerCase();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
import me.shedaniel.clothconfig2.api.ConfigEntryBuilder;
import net.minecraft.network.chat.Component;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.function.Predicate;

/**
* Extensions and modifications to AutoConfig.
*
Expand All @@ -26,5 +30,10 @@ public static void apply(Class<? extends ConfigData> configClass) {
ModBindingsConfigImpl.apply(registry);
VariantTooltipImpl.apply(registry);
BoundedContinuousImpl.apply(registry);
ServerRestrictionDependencies.apply(registry);
}

static Predicate<Field> isField(Class<?> declaringClass, String... fieldNames) {
return field -> field.getDeclaringClass().equals(declaringClass) && Arrays.asList(fieldNames).contains(field.getName());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package net.xolt.freecam.config.gui;

import me.shedaniel.autoconfig.gui.registry.GuiRegistry;
import me.shedaniel.clothconfig2.gui.entries.SelectionListEntry;
import net.xolt.freecam.config.ModConfig;

import static net.xolt.freecam.config.ModConfig.ServerRestriction.BLACKLIST;
import static net.xolt.freecam.config.ModConfig.ServerRestriction.WHITELIST;
import static net.xolt.freecam.config.gui.AutoConfigExtensions.isField;

class ServerRestrictionDependencies {

private static SelectionListEntry<ModConfig.ServerRestriction> mode;

@SuppressWarnings("UnstableApiUsage")
static void apply(GuiRegistry registry) {
// Capture a reference to the mode entry
registry.registerPredicateTransformer(
(guis, i18n, field, config, defaults, guiProvider) -> {
//noinspection unchecked
mode = guis.stream()
.filter(SelectionListEntry.class::isInstance)
.map(SelectionListEntry.class::cast)
.filter(entry -> entry.getValue() instanceof ModConfig.ServerRestriction)
.reduce((prev, next) -> { throw new IllegalStateException("Multiple SelectionListEntries added to %s.mode".formatted(ModConfig.ServerConfig.class.getSimpleName())); })
.orElseThrow(() -> new IllegalStateException("No SelectionListEntries added to %s.mode".formatted(ModConfig.ServerConfig.class.getSimpleName())));
return guis;
},
isField(ModConfig.ServerConfig.class, "mode")
);

// Whitelist dependency
registry.registerPredicateTransformer(
(guis, i18n, field, config, defaults, guiProvider) -> {
guis.forEach(gui -> gui.setDisplayRequirement(() -> mode == null || mode.getValue() == WHITELIST));
return guis;
},
isField(ModConfig.ServerConfig.class, "whitelist")
);

// Blacklist dependency
registry.registerPredicateTransformer(
(guis, i18n, field, config, defaults, guiProvider) -> {
guis.forEach(gui -> gui.setDisplayRequirement(() -> mode == null || mode.getValue() == BLACKLIST));
return guis;
},
isField(ModConfig.ServerConfig.class, "blacklist")
);
}
}
11 changes: 11 additions & 0 deletions common/src/main/resources/assets/freecam/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"key.freecam.configGui": "Config GUI",
"msg.freecam.enable": "Freecam has been enabled.",
"msg.freecam.disable": "Freecam has been disabled.",
"msg.freecam.restrictedByConfig": "Freecam is restricted on the current server (%s).",
"msg.freecam.openTripod": "Opening camera %s",
"msg.freecam.closeTripod": "Closing camera %s",
"msg.freecam.tripodReset": "Reset camera %s",
Expand Down Expand Up @@ -68,6 +69,16 @@
"text.autoconfig.freecam.option.utility.interactionMode.@Tooltip": "The source of block/entity interactions.",
"text.autoconfig.freecam.option.utility.interactionMode.camera": "Camera",
"text.autoconfig.freecam.option.utility.interactionMode.player": "Player",
"text.autoconfig.freecam.option.servers": "Multiplayer Options",
"text.autoconfig.freecam.option.servers.@Tooltip": "Options relating to multiplayer servers.",
"text.autoconfig.freecam.option.servers.mode": "Restriction mode",
"text.autoconfig.freecam.option.servers.mode.@Tooltip[0]": "Allow or disallow use of freecam on certain servers.",
"text.autoconfig.freecam.option.servers.mode.@Tooltip[1]": "(using either a whitelist or blacklist).",
"text.autoconfig.freecam.option.servers.mode.none": "No restriction",
"text.autoconfig.freecam.option.servers.mode.whitelist": "Whitelist",
"text.autoconfig.freecam.option.servers.mode.blacklist": "Blacklist",
"text.autoconfig.freecam.option.servers.whitelist": "Whitelist:",
"text.autoconfig.freecam.option.servers.blacklist": "Blacklist:",
"text.autoconfig.freecam.option.notification": "Notification Options",
"text.autoconfig.freecam.option.notification.@Tooltip": "Show or hide notifications.",
"text.autoconfig.freecam.option.notification.notifyFreecam": "Freecam Notifications",
Expand Down