Skip to content

Commit 10bc85a

Browse files
authored
Merge pull request #82 from FTBTeam/dev
Dev
2 parents 6784024 + de26e28 commit 10bc85a

29 files changed

+519
-319
lines changed

CHANGELOG.md

+18
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,24 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
## [2101.1.5]
8+
9+
### Added
10+
* Added `admins_exempt_dimension_blacklists` config setting in the `teleportation` section of `ftbessentials.snbt`
11+
* Default is true; controls whether players with permission level >=2 should be subject to teleporting dimension blacklists
12+
* Added new `/give_me_kit` command for better permission control
13+
* `/give_me_kit <kit>` is equivalent to `/kit give @s <kit>` but is usable by non-op players by default
14+
* In addition, the boolean permission node `ftbessentials.give_me_kit.<kit>` is now checked if the player using the command is not admin-level
15+
* In this way, regular players can be given the ability via permission nodes to give themselves specific kits
16+
* Added `home_min_y` config setting, which sets a minimum Y-value accepted by the `/sethome` command
17+
* All hardcoded player-visible messages in the mod are now translatable; many more translations are now in `en_us.json`
18+
19+
### Fixed
20+
* Fixed itemstack serialization not working correctly when saving kits
21+
* Fixed destination pos being unnecessarily recomputed when running teleporting commands
22+
* Most important for `/rtp` behaviour, which is non-deterministic
23+
* Active flight is no longer immediately switched off by the `/fly` command if player is in creative/spectator mode
24+
725
## [2101.1.4]
826

927
### Fixed

common/src/main/java/dev/ftb/mods/ftbessentials/FTBEEventHandler.java

+11-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package dev.ftb.mods.ftbessentials;
22

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

100101
KitManager.getInstance().allKits().forEach(kit -> {
101102
if (kit.isAutoGrant()) {
102-
kit.giveToPlayer(serverPlayer, data, false);
103-
}
103+
try {
104+
kit.giveToPlayer(serverPlayer, data, false);
105+
} catch (CommandSyntaxException ignored) {
106+
}
107+
}
104108
});
105109
});
106110
}
@@ -143,11 +147,11 @@ private static void serverTickPost(MinecraftServer server) {
143147
ServerPlayer target = server.getPlayerList().getPlayer(r.target().getUuid());
144148

145149
if (source != null) {
146-
source.sendSystemMessage(Component.literal("TPA request expired!"));
150+
source.sendSystemMessage(Component.translatable("ftbessentials.tpa.expired"));
147151
}
148152

149153
if (target != null) {
150-
target.sendSystemMessage(Component.literal("TPA request expired!"));
154+
target.sendSystemMessage(Component.translatable("ftbessentials.tpa.expired"));
151155
}
152156

153157
iterator.remove();
@@ -166,11 +170,11 @@ private static EventResult playerChat(@Nullable ServerPlayer serverPlayer, Compo
166170
if (data.isMuted()) {
167171
// serverPlayer must be non-null if we got the player data
168172
//noinspection DataFlowIssue
169-
serverPlayer.displayClientMessage(Component.literal("You can't use chat, you've been muted by an admin!")
170-
.withStyle(ChatFormatting.RED), false);
173+
serverPlayer.displayClientMessage(Component.translatable("ftbessentials.muted").withStyle(ChatFormatting.RED), false);
171174
FTBEWorldData.instance.getMuteTimeout(serverPlayer).ifPresent(expiry -> {
172175
long left = (expiry - System.currentTimeMillis()) / 1000L;
173-
serverPlayer.displayClientMessage(Component.literal("Mute expiry in: " + TimeUtils.prettyTimeString(left)).withStyle(ChatFormatting.RED), false);
176+
serverPlayer.displayClientMessage(Component.translatable("ftbessentials.mute_expiry",
177+
TimeUtils.prettyTimeString(left)).withStyle(ChatFormatting.RED), false);
174178
});
175179
return EventResult.interruptFalse();
176180
}

common/src/main/java/dev/ftb/mods/ftbessentials/commands/groups/CheatCommands.java

+9-9
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package dev.ftb.mods.ftbessentials.commands.groups;
22

33
import com.mojang.brigadier.context.CommandContext;
4-
import com.mojang.brigadier.exceptions.CommandSyntaxException;
54
import dev.ftb.mods.ftbessentials.FTBEssentialsPlatform;
65
import dev.ftb.mods.ftbessentials.commands.FTBCommand;
76
import dev.ftb.mods.ftbessentials.commands.SimpleCommandPlayer;
@@ -15,7 +14,6 @@
1514
import net.minecraft.network.chat.MutableComponent;
1615
import net.minecraft.server.level.ServerPlayer;
1716
import net.minecraft.world.SimpleMenuProvider;
18-
import net.minecraft.world.entity.player.Player;
1917
import net.minecraft.world.inventory.ChestMenu;
2018

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

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

7270
if (data.canFly()) {
7371
data.setCanFly(false);
74-
abilities.mayfly = false;
75-
abilities.flying = false;
76-
player.displayClientMessage(Component.literal("Flight disabled"), true);
72+
if (player.gameMode.isSurvival()) {
73+
abilities.mayfly = false;
74+
abilities.flying = false;
75+
}
76+
player.displayClientMessage(Component.translatable("ftbessentials.flight.disabled"), true);
7777
} else {
7878
data.setCanFly(true);
7979
abilities.mayfly = true;
80-
player.displayClientMessage(Component.literal("Flight enabled"), true);
80+
player.displayClientMessage(Component.translatable("ftbessentials.flight.enabled"), true);
8181
}
8282

8383
player.onUpdateAbilities();
@@ -91,11 +91,11 @@ private static void god(ServerPlayer player) {
9191
if (data.isGod()) {
9292
data.setGod(false);
9393
abilities.invulnerable = false;
94-
player.displayClientMessage(Component.literal("God mode disabled"), true);
94+
player.displayClientMessage(Component.translatable("ftbessentials.god_mode.disabled"), true);
9595
} else {
9696
data.setGod(true);
9797
abilities.invulnerable = true;
98-
player.displayClientMessage(Component.literal("God mode enabled"), true);
98+
player.displayClientMessage(Component.translatable("ftbessentials.god_mode.enabled"), true);
9999
}
100100

101101
player.onUpdateAbilities();
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
package dev.ftb.mods.ftbessentials.commands.groups;
22

33
import dev.ftb.mods.ftbessentials.commands.FTBCommand;
4-
import dev.ftb.mods.ftbessentials.commands.impl.KitCommand;
4+
import dev.ftb.mods.ftbessentials.commands.impl.kit.GiveMeKitCommand;
5+
import dev.ftb.mods.ftbessentials.commands.impl.kit.KitCommand;
56

67
import java.util.List;
78

@@ -11,6 +12,7 @@
1112
*/
1213
public class FeatureCommands {
1314
public static final List<FTBCommand> COMMANDS = List.of(
14-
new KitCommand()
15+
new KitCommand(),
16+
new GiveMeKitCommand()
1517
);
1618
}

common/src/main/java/dev/ftb/mods/ftbessentials/commands/groups/TeleportingCommands.java

+27-27
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22

33
import com.mojang.authlib.GameProfile;
44
import com.mojang.brigadier.arguments.IntegerArgumentType;
5+
import com.mojang.brigadier.exceptions.CommandSyntaxException;
56
import dev.architectury.event.EventResult;
67
import dev.ftb.mods.ftbessentials.FTBEssentials;
78
import dev.ftb.mods.ftbessentials.FTBEssentialsEvents;
89
import dev.ftb.mods.ftbessentials.commands.CommandUtils;
910
import dev.ftb.mods.ftbessentials.commands.FTBCommand;
1011
import dev.ftb.mods.ftbessentials.commands.SimpleConfigurableCommand;
12+
import dev.ftb.mods.ftbessentials.commands.impl.kit.KitCommand;
1113
import dev.ftb.mods.ftbessentials.commands.impl.teleporting.HomeCommand;
1214
import dev.ftb.mods.ftbessentials.commands.impl.teleporting.OfflineTeleportCommand;
1315
import dev.ftb.mods.ftbessentials.commands.impl.teleporting.TPACommand;
@@ -89,7 +91,7 @@ public class TeleportingCommands {
8991

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

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

@@ -122,15 +124,16 @@ private static int spawn(ServerPlayer player) {
122124
//#region RTP
123125
private static int rtp(ServerPlayer player, int minDistance, int maxDistance) {
124126
if (maxDistance < minDistance) {
125-
player.displayClientMessage(Component.literal("Maximum teleport distance cannot be less than minimum!"), false);
127+
player.displayClientMessage(Component.translatable("ftbessentials.teleport.max_less_than_min"), false);
126128
return 0;
127129
}
128-
if (!player.hasPermissions(2) && !DimensionFilter.isRtpDimensionOK(player.level().dimension())) {
129-
player.displayClientMessage(Component.literal("You may not use /rtp in this dimension!").withStyle(ChatFormatting.RED), false);
130+
if ((!player.hasPermissions(Commands.LEVEL_GAMEMASTERS) || !FTBEConfig.ADMINS_EXEMPT_DIMENSION_BLACKLISTS.get())
131+
&& !DimensionFilter.isRtpDimensionOK(player.level().dimension())) {
132+
player.displayClientMessage(Component.translatable("ftbessentials.rtp.not_here").withStyle(ChatFormatting.RED), false);
130133
return 0;
131134
}
132135
return FTBEPlayerData.getOrCreate(player).map(data -> data.rtpTeleporter.teleport(player, p -> {
133-
p.displayClientMessage(Component.literal("Looking for random location..."), false);
136+
p.displayClientMessage(Component.translatable("ftbessentials.rtp.looking"), false);
134137
return findBlockPos((ServerLevel) player.level(), p, minDistance, maxDistance);
135138
}).runCommand(player))
136139
.orElse(0);
@@ -152,7 +155,7 @@ private static TeleportPos findBlockPos(ServerLevel world, ServerPlayer player,
152155
if (world.getBiome(currentPos).is(IGNORE_RTP_BIOMES)) {
153156
continue;
154157
}
155-
// TODO: FTB Chunks will listen to RTPEvent and cancel it if position is inside a claimed chunk
158+
// FTB Chunks (via FTB XMod Compat) listens to this. Other mods can too.
156159
EventResult res = FTBEssentialsEvents.RTP_EVENT.invoker().teleport(world, player, currentPos, attempt);
157160
if (res.isFalse()) {
158161
continue;
@@ -177,12 +180,13 @@ private static TeleportPos findBlockPos(ServerLevel world, ServerPlayer player,
177180
}
178181
}
179182
if (goodPos != null) {
180-
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);
183+
String pos = String.format(" @ [x %d, y %d, z %d]", goodPos.getX(), goodPos.getY(), goodPos.getZ());
184+
player.displayClientMessage(Component.translatable("ftbessentials.rtp.found", attempt + 1, pos), false);
181185
return new TeleportPos(world.dimension(), goodPos.above());
182186
}
183187
}
184188
}
185-
player.displayClientMessage(Component.literal("Could not find a valid location to teleport to!").withStyle(ChatFormatting.RED), false);
189+
player.displayClientMessage(Component.translatable("ftbessentials.rtp.failed").withStyle(ChatFormatting.RED), false);
186190
return new TeleportPos(player);
187191
}
188192
//#endregion
@@ -210,25 +214,21 @@ private static int tpx(ServerPlayer player, ServerLevel to) {
210214
return 1;
211215
}
212216

213-
private static int jump(CommandSourceStack source) {
214-
try {
215-
ServerPlayer player = source.getPlayerOrException();
216-
217-
BlockHitResult res = BlockUtil.getFocusedBlock(player, player.getServer().getPlayerList().getViewDistance() * 16)
218-
.orElseThrow(() -> new IllegalArgumentException("Not looking at a block"));
219-
// want to land the player on top of the focused block, so scan up as far as needed
220-
BlockPos.MutableBlockPos mPos = res.getBlockPos().above().mutable();
221-
while (true) {
222-
Level level = player.level();
223-
if (isEmptyShape(level, mPos.above()) && isEmptyShape(level, mPos.above(2)) || mPos.getY() >= level.getMaxBuildHeight())
224-
break;
225-
mPos.move(Direction.UP, 2);
226-
}
227-
Vec3 vec = Vec3.atBottomCenterOf(mPos);
228-
player.teleportTo(vec.x(), vec.y(), vec.z());
229-
} catch (Exception e) {
230-
source.sendFailure(Component.literal("Can't jump: " + e.getMessage()));
217+
private static int jump(CommandSourceStack source) throws CommandSyntaxException {
218+
ServerPlayer player = source.getPlayerOrException();
219+
220+
BlockHitResult res = BlockUtil.getFocusedBlock(player, player.getServer().getPlayerList().getViewDistance() * 16)
221+
.orElseThrow(KitCommand.NOT_LOOKING_AT_BLOCK::create);
222+
// want to land the player on top of the focused block, so scan up as far as needed
223+
BlockPos.MutableBlockPos mPos = res.getBlockPos().above().mutable();
224+
while (true) {
225+
Level level = player.level();
226+
if (isEmptyShape(level, mPos.above()) && isEmptyShape(level, mPos.above(2)) || mPos.getY() >= level.getMaxBuildHeight())
227+
break;
228+
mPos.move(Direction.UP, 2);
231229
}
230+
Vec3 vec = Vec3.atBottomCenterOf(mPos);
231+
player.teleportTo(vec.x(), vec.y(), vec.z());
232232
return 0;
233233
}
234234

common/src/main/java/dev/ftb/mods/ftbessentials/commands/impl/admin/NicknameForCommand.java

+6-5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import dev.ftb.mods.ftbessentials.util.FTBEPlayerData;
88
import dev.ftb.mods.ftblibrary.util.PlayerDisplayNameUtil;
99
import net.minecraft.commands.CommandSourceStack;
10+
import net.minecraft.commands.Commands;
1011
import net.minecraft.commands.arguments.EntityArgument;
1112
import net.minecraft.network.chat.Component;
1213
import net.minecraft.server.level.ServerPlayer;
@@ -28,18 +29,18 @@ public List<LiteralArgumentBuilder<CommandSourceStack>> register() {
2829
return Collections.singletonList(literal("nicknamefor")
2930
.requires(FTBEConfig.NICK.enabledAndOp())
3031
.then(argument("player", EntityArgument.player())
31-
.requires(source -> source.hasPermission(2))
32+
.requires(source -> source.hasPermission(Commands.LEVEL_GAMEMASTERS))
3233
.executes(context -> nicknameFor(context.getSource(), EntityArgument.getPlayer(context, "player"), ""))
3334
.then(argument("nickname", StringArgumentType.greedyString())
34-
.requires(source -> source.hasPermission(2))
35+
.requires(source -> source.hasPermission(Commands.LEVEL_GAMEMASTERS))
3536
.executes(context -> nicknameFor(context.getSource(), EntityArgument.getPlayer(context, "player"), StringArgumentType.getString(context, "nickname")))
3637
)
3738
));
3839
}
3940

4041
public int nicknameFor(CommandSourceStack source, ServerPlayer player, String nick) {
4142
if (nick.length() > 30) {
42-
player.displayClientMessage(Component.literal("Nickname too long!"), false);
43+
player.displayClientMessage(Component.translatable("ftbessentials.nick.too_long"), false);
4344
return 0;
4445
}
4546

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

5152
if (data.getNick().isEmpty()) {
52-
source.sendSuccess(() -> Component.literal("Nickname reset!"), true);
53+
source.sendSuccess(() -> Component.translatable("ftbessentials.nick.reset"), true);
5354
} else {
54-
source.sendSuccess(() -> Component.literal("Nickname changed to '" + data.getNick() + "'"), true);
55+
source.sendSuccess(() -> Component.translatable("ftbessentials.nick.changed", data.getNick()), true);
5556
}
5657

5758
data.sendTabName(source.getServer());

common/src/main/java/dev/ftb/mods/ftbessentials/commands/impl/chat/MuteCommand.java

+10-21
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.mojang.brigadier.arguments.StringArgumentType;
44
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
5+
import com.mojang.brigadier.exceptions.CommandSyntaxException;
56
import dev.ftb.mods.ftbessentials.commands.CommandUtils;
67
import dev.ftb.mods.ftbessentials.commands.FTBCommand;
78
import dev.ftb.mods.ftbessentials.config.FTBEConfig;
@@ -11,7 +12,6 @@
1112
import net.minecraft.commands.CommandSourceStack;
1213
import net.minecraft.commands.arguments.EntityArgument;
1314
import net.minecraft.network.chat.Component;
14-
import net.minecraft.network.chat.MutableComponent;
1515
import net.minecraft.server.level.ServerPlayer;
1616
import net.minecraft.world.entity.player.Player;
1717

@@ -46,25 +46,17 @@ public List<LiteralArgumentBuilder<CommandSourceStack>> register() {
4646
);
4747
}
4848

49-
private int mute(CommandSourceStack source, ServerPlayer player, String duration) {
49+
private int mute(CommandSourceStack source, ServerPlayer player, String duration) throws CommandSyntaxException {
50+
DurationInfo info = DurationInfo.fromString(duration);
51+
5052
return FTBEPlayerData.getOrCreate(player).map(data -> {
51-
try {
52-
DurationInfo info = DurationInfo.fromString(duration);
53-
data.setMuted(true);
54-
FTBEWorldData.instance.setMuteTimeout(player, info.until());
53+
data.setMuted(true);
54+
FTBEWorldData.instance.setMuteTimeout(player, info.until());
5555

56-
MutableComponent msg = player.getDisplayName().copy()
57-
.append(" has been muted by ")
58-
.append(source.getDisplayName())
59-
.append(", ")
60-
.append(info.desc());
61-
notifyMuting(source, player, msg);
56+
Component msg = Component.translatable("ftbessentials.muted.muted", player.getDisplayName(), source.getDisplayName(), info.desc());
57+
notifyMuting(source, player, msg);
6258

63-
return 1;
64-
} catch (IllegalArgumentException e) {
65-
source.sendFailure(Component.literal("Invalid duration syntax: '" + duration + "': " + e.getMessage()));
66-
return 0;
67-
}
59+
return 1;
6860
}).orElse(0);
6961
}
7062

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

76-
MutableComponent msg = player.getDisplayName().copy()
77-
.append(" has been unmuted by ")
78-
.append(source.getDisplayName());
79-
notifyMuting(source, player, msg);
68+
notifyMuting(source, player, Component.translatable("ftbessentials.muted.unmuted", player.getDisplayName(), source.getDisplayName()));
8069

8170
return 1;
8271
}).orElse(0);

0 commit comments

Comments
 (0)