Skip to content

Commit

Permalink
Added a void init method to CraftingStats in CoreMod to prevent Froze…
Browse files Browse the repository at this point in the history
…nException when previously late-initializing PlayerStats

Added a Permission (and allowed Op level) that allows admins to right-click on Death chests to clean them up
Added a method that allows suggesting the username of offline Friends in commands
Added a subcommand for locating the Waystones of Friends
Added a check for automatically crafting simple recipes when selling to admin shops
  • Loading branch information
GStefanowich committed Apr 25, 2022
1 parent 451c468 commit 5580e4f
Show file tree
Hide file tree
Showing 15 changed files with 274 additions and 71 deletions.
10 changes: 6 additions & 4 deletions src/main/java/net/TheElm/project/CoreMod.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,7 @@
import net.TheElm.project.blocks.entities.LecternGuideBlockEntity;
import net.TheElm.project.blocks.entities.LecternWarpsBlockEntity;
import net.TheElm.project.config.SewConfig;
import net.TheElm.project.protections.claiming.Claimant;
import net.TheElm.project.protections.claiming.ClaimantPlayer;
import net.TheElm.project.protections.claiming.ClaimantTown;
import net.TheElm.project.objects.ShopStats;
import net.TheElm.project.protections.logging.EventLogger;
import net.TheElm.project.utilities.DevUtils;
import net.fabricmc.api.EnvType;
Expand Down Expand Up @@ -108,9 +106,13 @@ public static MySQLHost getSQL() {
}

public void initialize() {
// Log that we're starting!
CoreMod.logInfo("Sewing Machine utilities mod is starting.");

// Register our server-side block entity
// Make sure the Stats we're using are in the Registry before it gets Frozen
ShopStats.init();

// Register our block entities for use
CoreMod.GUIDE_BLOCK_ENTITY = Registry.register(Registry.BLOCK_ENTITY_TYPE, CoreMod.modIdentifier("guide_lectern"), FabricBlockEntityTypeBuilder.create(LecternGuideBlockEntity::new, Blocks.LECTERN).build(null));
CoreMod.WARPS_BLOCK_ENTITY = Registry.register(Registry.BLOCK_ENTITY_TYPE, CoreMod.modIdentifier("warps_lectern"), FabricBlockEntityTypeBuilder.create(LecternWarpsBlockEntity::new, Blocks.LECTERN).build(null));
}
Expand Down
67 changes: 46 additions & 21 deletions src/main/java/net/TheElm/project/commands/AdminCommands.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import net.TheElm.project.CoreMod;
import net.TheElm.project.ServerCore;
import net.TheElm.project.config.ConfigOption;
import net.TheElm.project.config.SewConfig;
Expand All @@ -48,6 +47,7 @@
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.network.ServerPlayerEntity;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Collection;
import java.util.stream.Stream;
Expand Down Expand Up @@ -128,7 +128,7 @@ public static void register(@NotNull CommandDispatcher<ServerCommandSource> disp

private static int selfFlying(@NotNull CommandContext<ServerCommandSource> context) throws CommandSyntaxException {
ServerCommandSource source = context.getSource();
AdminCommands.toggleFlying(source.getPlayer());
AdminCommands.toggleFlying(source, source.getPlayer());
return Command.SINGLE_SUCCESS;
}
private static int targetFlying(@NotNull CommandContext<ServerCommandSource> context) throws CommandSyntaxException {
Expand All @@ -139,20 +139,26 @@ private static int targetFlying(@NotNull CommandContext<ServerCommandSource> con
return AdminCommands.toggleFlying(source, players.stream());
}
private static int toggleFlying(@NotNull ServerCommandSource source, @NotNull Stream<ServerPlayerEntity> players) {
players.forEach(player -> TranslatableServerSide.send(source, "player.abilities.flying_other." + (AdminCommands.toggleFlying(player) ? "enabled" : "disabled"), player.getDisplayName()));
players.forEach(player -> {
if (source.getEntity() == player)
AdminCommands.toggleFlying(source, player);
else TranslatableServerSide.send(source, "player.abilities.flying_other." + (AdminCommands.toggleFlying(null, player) ? "enabled" : "disabled"), player.getDisplayName());
});
return Command.SINGLE_SUCCESS;
}
private static boolean toggleFlying(@NotNull ServerPlayerEntity player) {
private static boolean toggleFlying(@Nullable ServerCommandSource source, @NotNull ServerPlayerEntity player) {
PlayerAbilities abilities = player.getAbilities();

// Toggle flying for the player
abilities.allowFlying = !abilities.allowFlying;
player.setNoGravity(false);

// Tell the player
TranslatableServerSide.send(player, "player.abilities.flying_self." + (abilities.allowFlying ? "enabled" : "disabled"));
if (source == null)
TranslatableServerSide.send(player, "player.abilities.flying_self." + (abilities.allowFlying ? "enabled" : "disabled"));
else TranslatableServerSide.send(source, "player.abilities.flying_self." + (abilities.allowFlying ? "enabled" : "disabled"));

// If flying was turned off, stop the playing mid-flight
// If flying was turned off, stop the player mid-flight
if (!abilities.allowFlying)
abilities.flying = false;

Expand All @@ -162,7 +168,7 @@ private static boolean toggleFlying(@NotNull ServerPlayerEntity player) {

private static int selfGod(@NotNull CommandContext<ServerCommandSource> context) throws CommandSyntaxException {
ServerCommandSource source = context.getSource();
AdminCommands.toggleGod(source.getPlayer());
AdminCommands.toggleGod(source, source.getPlayer());
return Command.SINGLE_SUCCESS;
}
private static int targetGod(@NotNull CommandContext<ServerCommandSource> context) throws CommandSyntaxException {
Expand All @@ -174,24 +180,31 @@ private static int targetGod(@NotNull CommandContext<ServerCommandSource> contex
return AdminCommands.toggleGod(source, players.stream());
}
private static int toggleGod(@NotNull ServerCommandSource source, @NotNull Stream<ServerPlayerEntity> players) {
players.forEach(player -> TranslatableServerSide.send(source, "player.abilities.godmode_other." + (AdminCommands.toggleGod(player) ? "enabled" : "disabled"), player.getDisplayName()));
players.forEach(player -> {
if (source.getEntity() == player)
AdminCommands.toggleGod(source, player);
else TranslatableServerSide.send(source, "player.abilities.godmode_other." + (AdminCommands.toggleGod(null, player) ? "enabled" : "disabled"), player.getDisplayName());
});
return Command.SINGLE_SUCCESS;
}
private static boolean toggleGod(ServerPlayerEntity player) {
private static boolean toggleGod(@Nullable ServerCommandSource source, @NotNull ServerPlayerEntity player) {
PlayerAbilities abilities = player.getAbilities();

// Toggle god mode for the player
abilities.invulnerable = !abilities.invulnerable;
player.sendAbilitiesUpdate();

// Tell the player
TranslatableServerSide.send(player, "player.abilities.godmode_self." + (abilities.invulnerable ? "enabled" : "disabled"));
if (source == null)
TranslatableServerSide.send(player, "player.abilities.godmode_self." + (abilities.invulnerable ? "enabled" : "disabled"));
else TranslatableServerSide.send(source, "player.abilities.godmode_self." + (abilities.invulnerable ? "enabled" : "disabled"));

return abilities.invulnerable;
}

private static int selfHeal(@NotNull CommandContext<ServerCommandSource> context) throws CommandSyntaxException {
ServerCommandSource source = context.getSource();
AdminCommands.healPlayer(source.getPlayer());
AdminCommands.healPlayer(source, source.getPlayer());
return Command.SINGLE_SUCCESS;
}
private static int targetHeal(@NotNull CommandContext<ServerCommandSource> context) throws CommandSyntaxException {
Expand All @@ -203,24 +216,30 @@ private static int targetHeal(@NotNull CommandContext<ServerCommandSource> conte
return AdminCommands.healPlayer(source, players.stream());
}
private static int healPlayer(@NotNull ServerCommandSource source, @NotNull Stream<ServerPlayerEntity> players) {
players.forEach(player -> TranslatableServerSide.send(source, (AdminCommands.healPlayer(player) ? "player.abilities.healed_other" : "player.abilities.healed_dead"), player.getDisplayName()));
players.forEach(player -> {
if (source.getEntity() == player)
AdminCommands.healPlayer(source, player);
else TranslatableServerSide.send(source, (AdminCommands.healPlayer(null, player) ? "player.abilities.healed_other" : "player.abilities.healed_dead"), player.getDisplayName());
});
return Command.SINGLE_SUCCESS;
}
private static boolean healPlayer(@NotNull ServerPlayerEntity player) {
boolean alive;
if (alive = player.isAlive()) {
private static boolean healPlayer(@Nullable ServerCommandSource source, @NotNull ServerPlayerEntity player) {
boolean alive = player.isAlive();
if (alive) {
// Heal the player
player.setHealth(player.getMaxHealth());

// Tell the player
TranslatableServerSide.send(player, "player.abilities.healed_self");
if (source == null)
TranslatableServerSide.send(player, "player.abilities.healed_self");
else TranslatableServerSide.send(source, "player.abilities.healed_self");
}
return alive;
}

private static int selfFeed(@NotNull CommandContext<ServerCommandSource> context) throws CommandSyntaxException {
ServerCommandSource source = context.getSource();
AdminCommands.feedPlayer(source.getPlayer());
AdminCommands.feedPlayer(source, source.getPlayer());
return Command.SINGLE_SUCCESS;
}
private static int targetFeed(@NotNull CommandContext<ServerCommandSource> context) throws CommandSyntaxException {
Expand All @@ -232,10 +251,14 @@ private static int targetFeed(@NotNull CommandContext<ServerCommandSource> conte
return AdminCommands.feedPlayer(source, players.stream());
}
private static int feedPlayer(@NotNull ServerCommandSource source, @NotNull Stream<ServerPlayerEntity> players) {
players.forEach(player -> TranslatableServerSide.send(source, (AdminCommands.feedPlayer(player) ? "player.abilities.fed_other" : "player.abilities.fed_dead"), player.getDisplayName()));
players.forEach(player -> {
if (source.getEntity() == player)
AdminCommands.feedPlayer(source, player);
else TranslatableServerSide.send(source, (AdminCommands.feedPlayer(null, player) ? "player.abilities.fed_other" : "player.abilities.fed_dead"), player.getDisplayName());
});
return Command.SINGLE_SUCCESS;
}
private static boolean feedPlayer(@NotNull ServerPlayerEntity player) {
private static boolean feedPlayer(@Nullable ServerCommandSource source, @NotNull ServerPlayerEntity player) {
boolean alive;
if (alive = player.isAlive()) {
HungerManager hungerManager = player.getHungerManager();
Expand All @@ -244,7 +267,9 @@ private static boolean feedPlayer(@NotNull ServerPlayerEntity player) {
hungerManager.setFoodLevel(20);

// Tell the player
TranslatableServerSide.send(player, "player.abilities.fed_self");
if (source == null)
TranslatableServerSide.send(player, "player.abilities.fed_self");
else TranslatableServerSide.send(source, "player.abilities.fed_self");
}
return alive;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ public static void register(@NotNull CommandDispatcher<ServerCommandSource> disp
)
)
.then(CommandManager.argument("player", EntityArgumentType.player())
.suggests(CommandUtils::getOnlinePlayerNames)
.suggests(CommandUtils::getOnlineNames)
.then(CommandManager.literal("global")
.requires(CommandPredicate.isEnabled(SewConfig.CHAT_MUTE_OP)
.and(
Expand Down
77 changes: 65 additions & 12 deletions src/main/java/net/TheElm/project/commands/ClaimCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
Expand Down Expand Up @@ -260,8 +261,7 @@ public static void register(@NotNull CommandDispatcher<ServerCommandSource> disp
.suggests(CommandUtils::getFriendPlayerNames)
.then(CommandManager.argument("location", StringArgumentType.string())
.suggests(ClaimCommand::playerHomeNamesOfFriend)
// TODO: Allow players to LOCATE to another players Waystone
.executes(a -> 0)
.executes(ClaimCommand::findFriendWarp)
)
.executes(ClaimCommand::findFriend)
)
Expand Down Expand Up @@ -475,9 +475,8 @@ private static int claimChunkTownRadius(@NotNull CommandContext<ServerCommandSou
}
private static int claimChunkOther(@NotNull CommandContext<ServerCommandSource> context) throws CommandSyntaxException {
// Get the target player
Collection<GameProfile> gameProfiles = GameProfileArgumentType.getProfileArgument(context, "target");
GameProfile targetPlayer = gameProfiles.stream().findAny()
.orElseThrow(GameProfileArgumentType.UNKNOWN_PLAYER_EXCEPTION::create);
GameProfile targetPlayer = GameProfileArgumentType.getProfileArgument(context, "target").stream()
.findAny().orElseThrow(GameProfileArgumentType.UNKNOWN_PLAYER_EXCEPTION::create);

// Claim the chunk for other player
return ClaimCommand.claimChunk(
Expand Down Expand Up @@ -1171,27 +1170,81 @@ private static int listFriends(@NotNull CommandContext<ServerCommandSource> cont
}
private static int findFriend(@NotNull CommandContext<ServerCommandSource> context) throws CommandSyntaxException {
ServerCommandSource source = context.getSource();
ServerPlayerEntity player = source.getPlayer();
MinecraftServer server = source.getServer();

// Get the GameProfile of the Target
GameProfile friend = GameProfileArgumentType.getProfileArgument(context, "friend").stream()
.findAny().orElseThrow(GameProfileArgumentType.UNKNOWN_PLAYER_EXCEPTION::create);

// Get the Claims handler
ClaimCache claimCache = ((ClaimsAccessor)source.getServer())
.getClaimManager();

// Check if the command player and the target are friends
ClaimantPlayer friendData = claimCache.getPlayerClaim(friend);
if (!friendData.isFriend(player.getUuid()))
throw ClaimCommand.PLAYER_NOT_FRIENDS.create(player);

// Try to get the entity to target
Entity target = Optional.ofNullable(server.getPlayerManager()
.getPlayer(friend.getId())).orElseThrow(EntityArgumentType.PLAYER_NOT_FOUND_EXCEPTION::create);
if (player.world != target.world || target.isInvisible())
throw ClaimCommand.PLAYER_DIFFERENT_WORLD.create(player);

return ClaimCommand.pathPlayerToTarget(player, target);
}
private static int findFriendWarp(@NotNull CommandContext<ServerCommandSource> context) throws CommandSyntaxException {
ServerCommandSource source = context.getSource();
ServerWorld world = source.getWorld();
ServerPlayerEntity player = source.getPlayer();
ServerPlayerEntity friend = EntityArgumentType.getPlayer(context, "friend");

// Get the GameProfile of the Target
GameProfile friend = GameProfileArgumentType.getProfileArgument(context, "friend").stream()
.findAny().orElseThrow(GameProfileArgumentType.UNKNOWN_PLAYER_EXCEPTION::create);

// Get the name of the warp to target to
String name = StringArgumentType.getString(context, "location");

// Get the Claims handler
ClaimCache claimCache = ((ClaimsAccessor)source.getServer())
.getClaimManager();

// Check if the command player and the target are friends
ClaimantPlayer friendData = claimCache.getPlayerClaim(friend);
if (!friendData.isFriend(player.getUuid()))
throw ClaimCommand.PLAYER_NOT_FRIENDS.create(player);
if (player.world != friend.world || friend.isInvisible())

// Try to get the warp
WarpUtils.Warp warp = WarpUtils.getWarp(friend.getId(), name);
if (warp == null)
throw TeleportsCommand.TARGET_NO_WARP.create(player);

// Check that the player is in the world for the warp
if (!world.getRegistryKey().equals(warp.world))
throw ClaimCommand.PLAYER_DIFFERENT_WORLD.create(player);
return ClaimCommand.findFriend(player, friend);

// Locate to the Targets Waystone
return ClaimCommand.pathPlayerToTarget(player, warp.warpPos);
}
private static int stopFindingPos(@NotNull CommandContext<ServerCommandSource> context) throws CommandSyntaxException {
ServerCommandSource source = context.getSource();
ServerPlayerEntity player = source.getPlayer();
return ClaimCommand.pathPlayerToTarget(player, player);
}
private static int findFriend(@NotNull ServerPlayerEntity player, @NotNull ServerPlayerEntity target) {
private static int pathPlayerToTarget(@NotNull ServerPlayerEntity player, @NotNull Entity target) {
Path navigator = ((PlayerData)player).findPathTo(target, 3);
if (navigator != null)
EffectUtils.summonBreadcrumbs(ParticleTypes.FALLING_OBSIDIAN_TEAR, player, navigator);
else CoreMod.logInfo("Could not find path.");
return navigator == null ? 0 : 1;
}
private static int stopFindingPos(@NotNull CommandContext<ServerCommandSource> context) throws CommandSyntaxException {
ServerCommandSource source = context.getSource();
return ClaimCommand.findFriend(source.getPlayer(), source.getPlayer());
private static int pathPlayerToTarget(@NotNull ServerPlayerEntity player, @NotNull BlockPos position) {
Path navigator = ((PlayerData)player).findPathTo(position, 3);
if (navigator != null)
EffectUtils.summonBreadcrumbs(ParticleTypes.FALLING_OBSIDIAN_TEAR, player, navigator);
else CoreMod.logInfo("Could not find path.");
return navigator == null ? 0 : 1;
}

private static @NotNull CompletableFuture<Suggestions> playerHomeNamesOfFriend(@NotNull CommandContext<ServerCommandSource> context, @NotNull SuggestionsBuilder builder) throws CommandSyntaxException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -314,12 +314,12 @@ private static int tpaToPlayer(@NotNull MinecraftServer server, @NotNull ServerP

// Check if player is within spawn
if (!ChunkUtils.isPlayerWithinSpawn(porter))
throw PLAYER_NOT_IN_SPAWN.create(porter);
throw TeleportsCommand.PLAYER_NOT_IN_SPAWN.create(porter);

Warp warp;
// If the player to teleport to does not have a warp
if ((warp = WarpUtils.getWarp(target.getId(), location)) == null)
throw TARGET_NO_WARP.create(porter);
Warp warp = WarpUtils.getWarp(target.getId(), location);
if (warp == null)
throw TeleportsCommand.TARGET_NO_WARP.create(porter);

ServerPlayerEntity targetPlayer = manager.getPlayer(target.getId());

Expand Down
3 changes: 3 additions & 0 deletions src/main/java/net/TheElm/project/enums/Permissions.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ public class Permissions {
*/

public static final @NotNull PermissionNode INTERACT_WORLD = addPermission("interact.world", "Allows players to interact with the world");

public static final @NotNull PermissionNode INTERACT_OTHER_DEATHCHEST = addPermission("interact.death_chest.other", "Allows players to take other players death chests");

public static final @NotNull PermissionNode PLAYER_NICKNAME = addPermission("player.nick", "Allows players to set their own nickname");
public static final @NotNull PermissionNode PLAYER_NICKNAME_COLOR = addPermission("player.nick.color", "Allows players to set their own nickname with a color");
public static final @NotNull PermissionNode PLAYER_NICKNAME_COLOR_GRADIENT = addPermission("player.nick.color.gradient", "Allows players to set their own nickname using a color gradient");
Expand Down
Loading

0 comments on commit 5580e4f

Please sign in to comment.