Skip to content

Commit

Permalink
Merge pull request #82 from FTBTeam/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
desht authored Feb 10, 2025
2 parents 6784024 + de26e28 commit 10bc85a
Show file tree
Hide file tree
Showing 29 changed files with 519 additions and 319 deletions.
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,24 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [2101.1.5]

### Added
* Added `admins_exempt_dimension_blacklists` config setting in the `teleportation` section of `ftbessentials.snbt`
* Default is true; controls whether players with permission level >=2 should be subject to teleporting dimension blacklists
* Added new `/give_me_kit` command for better permission control
* `/give_me_kit <kit>` is equivalent to `/kit give @s <kit>` but is usable by non-op players by default
* In addition, the boolean permission node `ftbessentials.give_me_kit.<kit>` is now checked if the player using the command is not admin-level
* In this way, regular players can be given the ability via permission nodes to give themselves specific kits
* Added `home_min_y` config setting, which sets a minimum Y-value accepted by the `/sethome` command
* All hardcoded player-visible messages in the mod are now translatable; many more translations are now in `en_us.json`

### Fixed
* Fixed itemstack serialization not working correctly when saving kits
* Fixed destination pos being unnecessarily recomputed when running teleporting commands
* Most important for `/rtp` behaviour, which is non-deterministic
* Active flight is no longer immediately switched off by the `/fly` command if player is in creative/spectator mode

## [2101.1.4]

### Fixed
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package dev.ftb.mods.ftbessentials;

import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import dev.architectury.event.EventResult;
import dev.architectury.event.events.common.*;
import dev.ftb.mods.ftbessentials.api.records.TPARequest;
Expand Down Expand Up @@ -99,8 +100,11 @@ private static void playerLoggedIn(ServerPlayer serverPlayer) {

KitManager.getInstance().allKits().forEach(kit -> {
if (kit.isAutoGrant()) {
kit.giveToPlayer(serverPlayer, data, false);
}
try {
kit.giveToPlayer(serverPlayer, data, false);
} catch (CommandSyntaxException ignored) {
}
}
});
});
}
Expand Down Expand Up @@ -143,11 +147,11 @@ private static void serverTickPost(MinecraftServer server) {
ServerPlayer target = server.getPlayerList().getPlayer(r.target().getUuid());

if (source != null) {
source.sendSystemMessage(Component.literal("TPA request expired!"));
source.sendSystemMessage(Component.translatable("ftbessentials.tpa.expired"));
}

if (target != null) {
target.sendSystemMessage(Component.literal("TPA request expired!"));
target.sendSystemMessage(Component.translatable("ftbessentials.tpa.expired"));
}

iterator.remove();
Expand All @@ -166,11 +170,11 @@ private static EventResult playerChat(@Nullable ServerPlayer serverPlayer, Compo
if (data.isMuted()) {
// serverPlayer must be non-null if we got the player data
//noinspection DataFlowIssue
serverPlayer.displayClientMessage(Component.literal("You can't use chat, you've been muted by an admin!")
.withStyle(ChatFormatting.RED), false);
serverPlayer.displayClientMessage(Component.translatable("ftbessentials.muted").withStyle(ChatFormatting.RED), false);
FTBEWorldData.instance.getMuteTimeout(serverPlayer).ifPresent(expiry -> {
long left = (expiry - System.currentTimeMillis()) / 1000L;
serverPlayer.displayClientMessage(Component.literal("Mute expiry in: " + TimeUtils.prettyTimeString(left)).withStyle(ChatFormatting.RED), false);
serverPlayer.displayClientMessage(Component.translatable("ftbessentials.mute_expiry",
TimeUtils.prettyTimeString(left)).withStyle(ChatFormatting.RED), false);
});
return EventResult.interruptFalse();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package dev.ftb.mods.ftbessentials.commands.groups;

import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import dev.ftb.mods.ftbessentials.FTBEssentialsPlatform;
import dev.ftb.mods.ftbessentials.commands.FTBCommand;
import dev.ftb.mods.ftbessentials.commands.SimpleCommandPlayer;
Expand All @@ -15,7 +14,6 @@
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.SimpleMenuProvider;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.ChestMenu;

import java.util.List;
Expand Down Expand Up @@ -54,7 +52,7 @@ private static void enderChest(CommandContext<CommandSourceStack> ctx, ServerPla
title.append(" × ").append(player.getDisplayName());
srcPlayer.openMenu(new SimpleMenuProvider((i, inv, p) -> ChestMenu.threeRows(i, inv, player.getEnderChestInventory()), title));
} else {
ctx.getSource().sendFailure(Component.literal("Unable to open enderchest inventory!"));
ctx.getSource().sendFailure(Component.translatable("ftbessentials.enderchest.unable"));
}
}

Expand All @@ -71,13 +69,15 @@ private static void fly(ServerPlayer player) {

if (data.canFly()) {
data.setCanFly(false);
abilities.mayfly = false;
abilities.flying = false;
player.displayClientMessage(Component.literal("Flight disabled"), true);
if (player.gameMode.isSurvival()) {
abilities.mayfly = false;
abilities.flying = false;
}
player.displayClientMessage(Component.translatable("ftbessentials.flight.disabled"), true);
} else {
data.setCanFly(true);
abilities.mayfly = true;
player.displayClientMessage(Component.literal("Flight enabled"), true);
player.displayClientMessage(Component.translatable("ftbessentials.flight.enabled"), true);
}

player.onUpdateAbilities();
Expand All @@ -91,11 +91,11 @@ private static void god(ServerPlayer player) {
if (data.isGod()) {
data.setGod(false);
abilities.invulnerable = false;
player.displayClientMessage(Component.literal("God mode disabled"), true);
player.displayClientMessage(Component.translatable("ftbessentials.god_mode.disabled"), true);
} else {
data.setGod(true);
abilities.invulnerable = true;
player.displayClientMessage(Component.literal("God mode enabled"), true);
player.displayClientMessage(Component.translatable("ftbessentials.god_mode.enabled"), true);
}

player.onUpdateAbilities();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package dev.ftb.mods.ftbessentials.commands.groups;

import dev.ftb.mods.ftbessentials.commands.FTBCommand;
import dev.ftb.mods.ftbessentials.commands.impl.KitCommand;
import dev.ftb.mods.ftbessentials.commands.impl.kit.GiveMeKitCommand;
import dev.ftb.mods.ftbessentials.commands.impl.kit.KitCommand;

import java.util.List;

Expand All @@ -11,6 +12,7 @@
*/
public class FeatureCommands {
public static final List<FTBCommand> COMMANDS = List.of(
new KitCommand()
new KitCommand(),
new GiveMeKitCommand()
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@

import com.mojang.authlib.GameProfile;
import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import dev.architectury.event.EventResult;
import dev.ftb.mods.ftbessentials.FTBEssentials;
import dev.ftb.mods.ftbessentials.FTBEssentialsEvents;
import dev.ftb.mods.ftbessentials.commands.CommandUtils;
import dev.ftb.mods.ftbessentials.commands.FTBCommand;
import dev.ftb.mods.ftbessentials.commands.SimpleConfigurableCommand;
import dev.ftb.mods.ftbessentials.commands.impl.kit.KitCommand;
import dev.ftb.mods.ftbessentials.commands.impl.teleporting.HomeCommand;
import dev.ftb.mods.ftbessentials.commands.impl.teleporting.OfflineTeleportCommand;
import dev.ftb.mods.ftbessentials.commands.impl.teleporting.TPACommand;
Expand Down Expand Up @@ -89,7 +91,7 @@ public class TeleportingCommands {

// Jump to command, allows you to jump to the top of the block you're looking at
new SimpleConfigurableCommand(FTBEConfig.JUMP, Commands.literal("jump")
.requires(CommandUtils.isGamemaster())
.requires(CommandUtils.isGamemaster())
.executes(ctx -> jump(ctx.getSource())))
);

Expand All @@ -99,7 +101,7 @@ public static void register() {
private static int back(ServerPlayer player) {
return FTBEPlayerData.getOrCreate(player).map(data -> {
if (data.teleportHistory.isEmpty()) {
player.displayClientMessage(Component.literal("Teleportation history is empty!").withStyle(ChatFormatting.RED), false);
player.displayClientMessage(Component.translatable("ftbessentials.teleport.history_empty").withStyle(ChatFormatting.RED), false);
return 0;
}

Expand All @@ -122,15 +124,16 @@ private static int spawn(ServerPlayer player) {
//#region RTP
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);
player.displayClientMessage(Component.translatable("ftbessentials.teleport.max_less_than_min"), 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);
if ((!player.hasPermissions(Commands.LEVEL_GAMEMASTERS) || !FTBEConfig.ADMINS_EXEMPT_DIMENSION_BLACKLISTS.get())
&& !DimensionFilter.isRtpDimensionOK(player.level().dimension())) {
player.displayClientMessage(Component.translatable("ftbessentials.rtp.not_here").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);
p.displayClientMessage(Component.translatable("ftbessentials.rtp.looking"), false);
return findBlockPos((ServerLevel) player.level(), p, minDistance, maxDistance);
}).runCommand(player))
.orElse(0);
Expand All @@ -152,7 +155,7 @@ private static TeleportPos findBlockPos(ServerLevel world, ServerPlayer player,
if (world.getBiome(currentPos).is(IGNORE_RTP_BIOMES)) {
continue;
}
// TODO: FTB Chunks will listen to RTPEvent and cancel it if position is inside a claimed chunk
// FTB Chunks (via FTB XMod Compat) listens to this. Other mods can too.
EventResult res = FTBEssentialsEvents.RTP_EVENT.invoker().teleport(world, player, currentPos, attempt);
if (res.isFalse()) {
continue;
Expand All @@ -177,12 +180,13 @@ private static TeleportPos findBlockPos(ServerLevel world, ServerPlayer player,
}
}
if (goodPos != null) {
player.displayClientMessage(Component.literal(String.format("Found good location after %d " + (attempt == 1 ? "attempt" : "attempts") + " @ [x %d, y %d, z %d]", attempt, goodPos.getX(), goodPos.getY(), goodPos.getZ())), false);
String pos = String.format(" @ [x %d, y %d, z %d]", goodPos.getX(), goodPos.getY(), goodPos.getZ());
player.displayClientMessage(Component.translatable("ftbessentials.rtp.found", attempt + 1, pos), false);
return new TeleportPos(world.dimension(), goodPos.above());
}
}
}
player.displayClientMessage(Component.literal("Could not find a valid location to teleport to!").withStyle(ChatFormatting.RED), false);
player.displayClientMessage(Component.translatable("ftbessentials.rtp.failed").withStyle(ChatFormatting.RED), false);
return new TeleportPos(player);
}
//#endregion
Expand Down Expand Up @@ -210,25 +214,21 @@ private static int tpx(ServerPlayer player, ServerLevel to) {
return 1;
}

private static int jump(CommandSourceStack source) {
try {
ServerPlayer player = source.getPlayerOrException();

BlockHitResult res = BlockUtil.getFocusedBlock(player, player.getServer().getPlayerList().getViewDistance() * 16)
.orElseThrow(() -> new IllegalArgumentException("Not looking at a block"));
// want to land the player on top of the focused block, so scan up as far as needed
BlockPos.MutableBlockPos mPos = res.getBlockPos().above().mutable();
while (true) {
Level level = player.level();
if (isEmptyShape(level, mPos.above()) && isEmptyShape(level, mPos.above(2)) || mPos.getY() >= level.getMaxBuildHeight())
break;
mPos.move(Direction.UP, 2);
}
Vec3 vec = Vec3.atBottomCenterOf(mPos);
player.teleportTo(vec.x(), vec.y(), vec.z());
} catch (Exception e) {
source.sendFailure(Component.literal("Can't jump: " + e.getMessage()));
private static int jump(CommandSourceStack source) throws CommandSyntaxException {
ServerPlayer player = source.getPlayerOrException();

BlockHitResult res = BlockUtil.getFocusedBlock(player, player.getServer().getPlayerList().getViewDistance() * 16)
.orElseThrow(KitCommand.NOT_LOOKING_AT_BLOCK::create);
// want to land the player on top of the focused block, so scan up as far as needed
BlockPos.MutableBlockPos mPos = res.getBlockPos().above().mutable();
while (true) {
Level level = player.level();
if (isEmptyShape(level, mPos.above()) && isEmptyShape(level, mPos.above(2)) || mPos.getY() >= level.getMaxBuildHeight())
break;
mPos.move(Direction.UP, 2);
}
Vec3 vec = Vec3.atBottomCenterOf(mPos);
player.teleportTo(vec.x(), vec.y(), vec.z());
return 0;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import dev.ftb.mods.ftbessentials.util.FTBEPlayerData;
import dev.ftb.mods.ftblibrary.util.PlayerDisplayNameUtil;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.commands.arguments.EntityArgument;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
Expand All @@ -28,18 +29,18 @@ public List<LiteralArgumentBuilder<CommandSourceStack>> register() {
return Collections.singletonList(literal("nicknamefor")
.requires(FTBEConfig.NICK.enabledAndOp())
.then(argument("player", EntityArgument.player())
.requires(source -> source.hasPermission(2))
.requires(source -> source.hasPermission(Commands.LEVEL_GAMEMASTERS))
.executes(context -> nicknameFor(context.getSource(), EntityArgument.getPlayer(context, "player"), ""))
.then(argument("nickname", StringArgumentType.greedyString())
.requires(source -> source.hasPermission(2))
.requires(source -> source.hasPermission(Commands.LEVEL_GAMEMASTERS))
.executes(context -> nicknameFor(context.getSource(), EntityArgument.getPlayer(context, "player"), StringArgumentType.getString(context, "nickname")))
)
));
}

public int nicknameFor(CommandSourceStack source, ServerPlayer player, String nick) {
if (nick.length() > 30) {
player.displayClientMessage(Component.literal("Nickname too long!"), false);
player.displayClientMessage(Component.translatable("ftbessentials.nick.too_long"), false);
return 0;
}

Expand All @@ -49,9 +50,9 @@ public int nicknameFor(CommandSourceStack source, ServerPlayer player, String ni
PlayerDisplayNameUtil.refreshDisplayName(player);

if (data.getNick().isEmpty()) {
source.sendSuccess(() -> Component.literal("Nickname reset!"), true);
source.sendSuccess(() -> Component.translatable("ftbessentials.nick.reset"), true);
} else {
source.sendSuccess(() -> Component.literal("Nickname changed to '" + data.getNick() + "'"), true);
source.sendSuccess(() -> Component.translatable("ftbessentials.nick.changed", data.getNick()), true);
}

data.sendTabName(source.getServer());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import dev.ftb.mods.ftbessentials.commands.CommandUtils;
import dev.ftb.mods.ftbessentials.commands.FTBCommand;
import dev.ftb.mods.ftbessentials.config.FTBEConfig;
Expand All @@ -11,7 +12,6 @@
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.arguments.EntityArgument;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Player;

Expand Down Expand Up @@ -46,25 +46,17 @@ public List<LiteralArgumentBuilder<CommandSourceStack>> register() {
);
}

private int mute(CommandSourceStack source, ServerPlayer player, String duration) {
private int mute(CommandSourceStack source, ServerPlayer player, String duration) throws CommandSyntaxException {
DurationInfo info = DurationInfo.fromString(duration);

return FTBEPlayerData.getOrCreate(player).map(data -> {
try {
DurationInfo info = DurationInfo.fromString(duration);
data.setMuted(true);
FTBEWorldData.instance.setMuteTimeout(player, info.until());
data.setMuted(true);
FTBEWorldData.instance.setMuteTimeout(player, info.until());

MutableComponent msg = player.getDisplayName().copy()
.append(" has been muted by ")
.append(source.getDisplayName())
.append(", ")
.append(info.desc());
notifyMuting(source, player, msg);
Component msg = Component.translatable("ftbessentials.muted.muted", player.getDisplayName(), source.getDisplayName(), info.desc());
notifyMuting(source, player, msg);

return 1;
} catch (IllegalArgumentException e) {
source.sendFailure(Component.literal("Invalid duration syntax: '" + duration + "': " + e.getMessage()));
return 0;
}
return 1;
}).orElse(0);
}

Expand All @@ -73,10 +65,7 @@ private int unmute(CommandSourceStack source, ServerPlayer player) {
data.setMuted(false);
FTBEWorldData.instance.setMuteTimeout(player, -1);

MutableComponent msg = player.getDisplayName().copy()
.append(" has been unmuted by ")
.append(source.getDisplayName());
notifyMuting(source, player, msg);
notifyMuting(source, player, Component.translatable("ftbessentials.muted.unmuted", player.getDisplayName(), source.getDisplayName()));

return 1;
}).orElse(0);
Expand Down
Loading

0 comments on commit 10bc85a

Please sign in to comment.