Skip to content

Commit

Permalink
Merge pull request #79 from FTBTeam/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
desht authored Jan 14, 2025
2 parents dfe8747 + 3f974c3 commit 69ca01a
Show file tree
Hide file tree
Showing 10 changed files with 150 additions and 23 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
* Now fires an `EntityTeleportEvent.TeleportCommand` event on NeoForge when any teleportation is done
* Note: There isn't a Fabric API equivalent for this event
* The `/rtp` command can now optionally take minimum and maximum distance arguments - thanks @CanadianBaconBoi
* Note that to use these arguments, players must either be admins (permission >= 2) or have the `ftbessentials.rtp.custom_min_max` and/or `ftbessentials.rtp.custom_max` ranks nodes
* Added dimension blacklist for teleportation commands - thanks @CanadianBaconBoi
* This is in addition to the existing RTP blacklist config
* See new `blacklists` config section within the `teleportation` section of the config
* `from` can be used to prohibit teleportation by players who are _in_ the listed dimension IDs
* `to` can be used to prohibit teleportation by players _to_ any of the listed dimension IDs
* Dimensions can be wildcarded, e.g. `somemod:*` matches all dimensions registered by mod `somemod`

### Fixed
* Fixed problem on SMP where player data (e.g. home location) wasn't always written for the player
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package dev.ftb.mods.ftbessentials.commands.groups;

import com.mojang.authlib.GameProfile;
import com.mojang.brigadier.arguments.IntegerArgumentType;
import dev.architectury.event.EventResult;
import dev.ftb.mods.ftbessentials.FTBEssentials;
import dev.ftb.mods.ftbessentials.FTBEssentialsEvents;
Expand Down Expand Up @@ -60,7 +61,17 @@ public class TeleportingCommands {

// Random teleport command
new SimpleConfigurableCommand(FTBEConfig.RTP, Commands.literal("rtp")
.executes(context -> rtp(context.getSource().getPlayerOrException()))),
.then(Commands.argument("maxDistance", IntegerArgumentType.integer(FTBEConfig.RTP_MIN_DISTANCE.get(), FTBEConfig.RTP_MAX_DISTANCE.get()))
.requires(context -> FTBEConfig.RTP_MAX_DISTANCE_CUSTOM.get(context.getPlayer()))
.executes(context -> rtp(context.getSource().getPlayerOrException(), FTBEConfig.RTP_MIN_DISTANCE.get(), IntegerArgumentType.getInteger(context, "maxDistance")))
)
.then(Commands.argument("minDistance", IntegerArgumentType.integer(0, FTBEConfig.RTP_MAX_DISTANCE.get()))
.requires(context -> FTBEConfig.RTP_MIN_DISTANCE_CUSTOM.get(context.getPlayer()))
.then(Commands.argument("maxDistance", IntegerArgumentType.integer(0, FTBEConfig.RTP_MAX_DISTANCE.get()))
.executes(context -> rtp(context.getSource().getPlayerOrException(), IntegerArgumentType.getInteger(context, "minDistance"), IntegerArgumentType.getInteger(context, "maxDistance")))
)
)
.executes(context -> rtp(context.getSource().getPlayerOrException(), FTBEConfig.RTP_MIN_DISTANCE.get(), FTBEConfig.RTP_MAX_DISTANCE.get()))),

// Teleport to the last location of a player
new SimpleConfigurableCommand(FTBEConfig.TPL, Commands.literal("teleport_last")
Expand Down Expand Up @@ -109,21 +120,25 @@ private static int spawn(ServerPlayer player) {
}

//#region RTP
private static int rtp(ServerPlayer player) {
if (!player.hasPermissions(2) && !DimensionFilter.isDimensionOK(player.level().dimension())) {
private static int rtp(ServerPlayer player, int minDistance, int maxDistance) {
if (maxDistance < minDistance) {
player.displayClientMessage(Component.literal("Maximum teleport distance cannot be less than minimum!"), false);
return 0;
}
if (!player.hasPermissions(2) && !DimensionFilter.isRtpDimensionOK(player.level().dimension())) {
player.displayClientMessage(Component.literal("You may not use /rtp in this dimension!").withStyle(ChatFormatting.RED), false);
return 0;
}
return FTBEPlayerData.getOrCreate(player).map(data -> data.rtpTeleporter.teleport(player, p -> {
p.displayClientMessage(Component.literal("Looking for random location..."), false);
return findBlockPos((ServerLevel) player.level(), p);
return findBlockPos((ServerLevel) player.level(), p, minDistance, maxDistance);
}).runCommand(player))
.orElse(0);
}

private static TeleportPos findBlockPos(ServerLevel world, ServerPlayer player) {
private static TeleportPos findBlockPos(ServerLevel world, ServerPlayer player, int minDistance, int maxDistance) {
for (int attempt = 0; attempt < FTBEConfig.RTP_MAX_TRIES.get(); attempt++) {
double dist = FTBEConfig.RTP_MIN_DISTANCE.get() + world.random.nextDouble() * (FTBEConfig.RTP_MAX_DISTANCE.get() - FTBEConfig.RTP_MIN_DISTANCE.get());
double dist = minDistance + world.random.nextDouble() * (maxDistance - minDistance);
double angle = world.random.nextDouble() * Math.PI * 2D;

int x = Mth.floor(Math.cos(angle) * dist);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,18 @@ public interface FTBEConfig {
StringListValue RTP_DIMENSION_BLACKLIST = RTP.config.addStringList("dimension_blacklist", List.of("minecraft:the_end"))
.comment("Blacklisted dimension ID's for /rtp (player *must not* be in any of these dimensions)",
"Wildcarded dimensions (e.g. 'somemod:*') are supported");

PermissionBasedBooleanValue RTP_MAX_DISTANCE_CUSTOM = new PermissionBasedBooleanValue(
RTP.config.addBoolean("allow_custom_max_distance", false),
"ftbessentials.rtp.custom_max",
"Allow player to specify (only) custom max distance in rtp command"
);

PermissionBasedBooleanValue RTP_MIN_DISTANCE_CUSTOM = new PermissionBasedBooleanValue(
RTP.config.addBoolean("allow_custom_min_max_distance", false),
"ftbessentials.rtp.custom_min_max",
"Allow player to specify custom min and max distance in rtp command"
);
// tpl
ToggleableConfig TPL = new ToggleableConfig(TELEPORTATION, "tpl")
.comment("Allows admins to teleport to the location a user was last seen at");
Expand All @@ -71,6 +83,14 @@ public interface FTBEConfig {
.comment("Allows admins to teleport to dimension");
ToggleableConfig JUMP = new ToggleableConfig(TELEPORTATION, "jump")
.comment("Allows admins to jump (teleport) to the focused block");

SNBTConfig TELEPORTATION_BLACKLISTS = TELEPORTATION.addGroup("blacklists")
.comment("Blacklists for all teleport commands",
"Wildcarded dimensions (e.g. 'somemod:*') are supported");
StringListValue TELEPORTATION_BLACKLIST_FROM = TELEPORTATION_BLACKLISTS.addStringList("from", List.of())
.comment("Dimensions players aren't permitted to run teleport commands in.");
StringListValue TELEPORTATION_BLACKLIST_TO = TELEPORTATION_BLACKLISTS.addStringList("to", List.of())
.comment("Dimensions players aren't permitted to teleport into.");

SNBTConfig ADMIN = CONFIG.addGroup("admin").comment("Admin commands for cheating and moderation");
ToggleableConfig HEAL = new ToggleableConfig(ADMIN, "heal")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package dev.ftb.mods.ftbessentials.config;

import dev.ftb.mods.ftbessentials.integration.PermissionsHelper;
import dev.ftb.mods.ftblibrary.snbt.config.BooleanValue;
import net.minecraft.server.level.ServerPlayer;

public class PermissionBasedBooleanValue {
public final BooleanValue value;
public final String permission;

public PermissionBasedBooleanValue(BooleanValue value, String permission, String... comment) {
this.value = value
.comment(comment)
.comment("You can override this with FTB Ranks using " + permission);
this.permission = permission;
}

public boolean get(ServerPlayer player) {
return PermissionsHelper.getInstance().getBool(player, value.get(), permission);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,8 @@ public class FTBRanksIntegration implements PermissionsProvider {
public int getInt(ServerPlayer player, int def, String node) {
return Math.max(FTBRanksAPI.getPermissionValue(player, node).asInteger().orElse(def), 0);
}

public boolean getBool(ServerPlayer player, boolean def, String node) {
return FTBRanksAPI.getPermissionValue(player, node).asBoolean().orElse(def);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ public class LuckPermsIntegration implements PermissionsProvider {
public int getInt(ServerPlayer player, int def, String node) {
return Math.max(getMetaData(player.getUUID(), node).map(Integer::parseInt).orElse(def), 0);
}

public boolean getBool(ServerPlayer player, boolean def, String node) {
return getMetaData(player.getUUID(), node).map(Boolean::parseBoolean).orElse(def);
}

private static Optional<String> getMetaData(UUID uuid, String meta) {
LuckPerms luckperms = LuckPermsProvider.get();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,8 @@ public interface PermissionsProvider {
default int getInt(ServerPlayer player, int def, String node) {
return def;
}

default boolean getBool(ServerPlayer player, boolean def, String node) {
return def;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,31 +11,61 @@
import java.util.function.Predicate;

public class DimensionFilter {
private static WildcardedRLMatcher dimensionMatcherB = null;
private static WildcardedRLMatcher dimensionMatcherW = null;
private static WildcardedRLMatcher rtpDimensionMatcherB = null;
private static WildcardedRLMatcher rtpDimensionMatcherW = null;

public static boolean isDimensionOK(ResourceKey<Level> levelKey) {
private static WildcardedRLMatcher allDimensionMatcherBTo = null;
private static WildcardedRLMatcher allDimensionMatcherBFrom = null;

public static boolean isRtpDimensionOK(ResourceKey<Level> levelKey) {
ResourceLocation name = levelKey.location();
return !getRtpDimensionBlacklist().test(name) && (getRtpDimensionWhitelist().isEmpty() || getRtpDimensionWhitelist().test(name));
}

public static boolean isDimensionOKFrom(ResourceKey<Level> levelKey) {
ResourceLocation name = levelKey.location();
return !getDimensionBlacklist().test(name) && (getDimensionWhitelist().isEmpty() || getDimensionWhitelist().test(name));
return !getAllCommandDimensionBlacklistFrom().test(name);
}

private static WildcardedRLMatcher getDimensionWhitelist() {
if (dimensionMatcherW == null) {
dimensionMatcherW = new WildcardedRLMatcher(FTBEConfig.RTP_DIMENSION_WHITELIST.get());
}
return dimensionMatcherW;
public static boolean isDimensionOKTo(ResourceKey<Level> levelKey) {
ResourceLocation name = levelKey.location();
return !getAllCommandDimensionBlacklistTo().test(name);
}

private static WildcardedRLMatcher getDimensionBlacklist() {
if (dimensionMatcherB == null) {
dimensionMatcherB = new WildcardedRLMatcher(FTBEConfig.RTP_DIMENSION_BLACKLIST.get());
private static WildcardedRLMatcher getRtpDimensionWhitelist() {
if (rtpDimensionMatcherW == null) {
rtpDimensionMatcherW = new WildcardedRLMatcher(FTBEConfig.RTP_DIMENSION_WHITELIST.get());
}
return dimensionMatcherB;
return rtpDimensionMatcherW;
}

private static WildcardedRLMatcher getRtpDimensionBlacklist() {
if (rtpDimensionMatcherB == null) {
rtpDimensionMatcherB = new WildcardedRLMatcher(FTBEConfig.RTP_DIMENSION_BLACKLIST.get());
}
return rtpDimensionMatcherB;
}

private static WildcardedRLMatcher getAllCommandDimensionBlacklistFrom() {
if (allDimensionMatcherBFrom == null) {
allDimensionMatcherBFrom = new WildcardedRLMatcher(FTBEConfig.TELEPORTATION_BLACKLIST_FROM.get());
}
return allDimensionMatcherBFrom;
}

private static WildcardedRLMatcher getAllCommandDimensionBlacklistTo() {
if (allDimensionMatcherBTo == null) {
allDimensionMatcherBTo = new WildcardedRLMatcher(FTBEConfig.TELEPORTATION_BLACKLIST_TO.get());
}
return allDimensionMatcherBTo;
}

public static void clearMatcherCaches() {
dimensionMatcherB = null;
dimensionMatcherW = null;
rtpDimensionMatcherB = null;
rtpDimensionMatcherW = null;

allDimensionMatcherBFrom = null;
allDimensionMatcherBTo = null;
}

private static class WildcardedRLMatcher implements Predicate<ResourceLocation> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;

public class TeleportPos {
Expand Down Expand Up @@ -47,6 +48,15 @@ public TeleportPos(CompoundTag tag) {
time = tag.getLong("time");
}

public TeleportResult checkDimensionBlacklist(Player player) {
if (!DimensionFilter.isDimensionOKTo(this.dimension)) {
return TeleportResult.DIMENSION_NOT_ALLOWED_TO;
} else if(!DimensionFilter.isDimensionOKFrom(player.level().dimension())) {
return TeleportResult.DIMENSION_NOT_ALLOWED_FROM;
}
return TeleportResult.SUCCESS;
}

public TeleportResult teleport(ServerPlayer player) {
ServerLevel level = player.server.getLevel(dimension);
if (level == null) {
Expand Down Expand Up @@ -128,6 +138,10 @@ static TeleportResult failed(Component msg) {
TeleportResult DIMENSION_NOT_FOUND = failed(Component.literal("Dimension not found!"));

TeleportResult UNKNOWN_DESTINATION = failed(Component.literal("Unknown destination!"));

TeleportResult DIMENSION_NOT_ALLOWED_FROM = failed(Component.literal("Teleportation from your dimension is not allowed!"));

TeleportResult DIMENSION_NOT_ALLOWED_TO = failed(Component.literal("Teleportation to this dimension is not allowed!"));

int runCommand(ServerPlayer player);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,18 @@ public TeleportResult teleport(ServerPlayer player, Function<ServerPlayer, Telep
return cooldownResult;
}

TeleportPos pos = positionGetter.apply(player);

TeleportResult blacklistedResult = pos.checkDimensionBlacklist(player);
if (!blacklistedResult.isSuccess()) {
return blacklistedResult;
}

CompoundEventResult<Component> result = TeleportEvent.TELEPORT.invoker().teleport(player);
if (result.isFalse()) {
return TeleportResult.failed(result.object());
}

TeleportPos pos = positionGetter.apply(player);

if (!firePlatformTeleportEvent(player, Vec3.atBottomCenterOf(pos.getPos()))) {
return TeleportResult.failed(Component.translatable("ftbessentials.teleport_prevented"));
}
Expand Down

0 comments on commit 69ca01a

Please sign in to comment.