mirror of
https://github.com/Samsuik/Sakura.git
synced 2025-12-30 04:09:09 +00:00
Add /mechanic command to view server mechanics
This commit is contained in:
@@ -26,6 +26,7 @@ public final class SakuraCommands {
|
||||
COMMANDS.put("fps", new FPSCommand("fps"));
|
||||
COMMANDS.put("tntvisibility", new VisualCommand(VisibilityTypes.TNT, "tnttoggle"));
|
||||
COMMANDS.put("sandvisibility", new VisualCommand(VisibilityTypes.SAND, "sandtoggle"));
|
||||
COMMANDS.put("mechanic", new MechanicCommand("mechanic"));
|
||||
SUB_COMMANDS.addAll(COMMANDS.values());
|
||||
SUB_COMMANDS.add(new DebugCommand("debug"));
|
||||
// "sakura" isn't a subcommand
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
package me.samsuik.sakura.command.subcommands;
|
||||
|
||||
import me.samsuik.sakura.command.PlayerOnlySubCommand;
|
||||
import me.samsuik.sakura.configuration.GlobalConfiguration;
|
||||
import me.samsuik.sakura.configuration.local.CachedLocalConfiguration;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.bukkit.craftbukkit.util.CraftLocation;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.FallingBlock;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.TNTPrimed;
|
||||
import org.bukkit.event.entity.EntitySpawnEvent;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@NullMarked
|
||||
public final class MechanicCommand extends PlayerOnlySubCommand {
|
||||
private static final String MECHANIC_INFORMATION_MESSAGE = """
|
||||
Mechanic Version: <yellow><mechanic_version></yellow>
|
||||
Height Parity: <yellow><height_parity></yellow>
|
||||
Tnt Spread: <yellow><tnt_spread></yellow>
|
||||
Tnt Flow: <yellow><tnt_flow></yellow>
|
||||
Redstone Implementation: <yellow><redstone_implementation></yellow>
|
||||
"optimize-explosions": <yellow><broken_explosion_behaviour></yellow>
|
||||
Consistent Radius: <yellow><consistent_radius></yellow>
|
||||
Lava Flow Speed: <yellow><lava_flow_speed></yellow>""";
|
||||
|
||||
public MechanicCommand(final String name) {
|
||||
super(name);
|
||||
this.setAliases(List.of("mechanics", "mech"));
|
||||
this.description = "Displays information related to cannon mechanics";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(final Player player, final String[] args) {
|
||||
final Location location = player.getLocation();
|
||||
final BlockPos blockPos = CraftLocation.toBlockPosition(location);
|
||||
final CraftWorld craftWorld = ((CraftWorld) location.getWorld());
|
||||
final CachedLocalConfiguration config = craftWorld.getHandle().localConfig().at(blockPos);
|
||||
|
||||
player.sendMessage(GlobalConfiguration.get().messages.mechanicInformationComponent(
|
||||
MiniMessage.miniMessage().deserialize(
|
||||
MECHANIC_INFORMATION_MESSAGE,
|
||||
Placeholder.unparsed("mechanic_version", config.mechanicsTarget.toString()),
|
||||
Placeholder.unparsed("height_parity", String.valueOf(this.hasHeightParity(location))),
|
||||
Placeholder.unparsed("tnt_spread", this.getTntSpread(location)),
|
||||
Placeholder.unparsed("tnt_flow", String.valueOf(this.hasTntFlow(location))),
|
||||
Placeholder.unparsed("redstone_implementation", config.redstoneBehaviour.implementation().getFriendlyName()),
|
||||
Placeholder.unparsed("broken_explosion_behaviour", String.valueOf(craftWorld.getHandle().paperConfig().environment.optimizeExplosions)),
|
||||
Placeholder.unparsed("consistent_radius", String.valueOf(config.consistentExplosionRadius)),
|
||||
Placeholder.unparsed("lava_flow_speed", String.valueOf(config.lavaFlowSpeed))
|
||||
)
|
||||
));
|
||||
}
|
||||
|
||||
private boolean hasHeightParity(final Location location) {
|
||||
final FallingBlock fallingBlock = this.createTestEntity(location, FallingBlock.class);
|
||||
return fallingBlock != null && fallingBlock.getHeightParity();
|
||||
}
|
||||
|
||||
private String getTntSpread(final Location location) {
|
||||
final TNTPrimed tnt = this.createTestEntity(location, TNTPrimed.class);
|
||||
if (tnt == null) {
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
final Vector velocity = tnt.getVelocity();
|
||||
final String spread;
|
||||
if (velocity.getX() != 0.0 && velocity.getY() != 0.0) {
|
||||
spread = "ALL";
|
||||
} else if (velocity.getY() != 0.0) {
|
||||
spread = "Y";
|
||||
} else {
|
||||
spread = "NONE";
|
||||
}
|
||||
|
||||
return spread;
|
||||
}
|
||||
|
||||
private boolean hasTntFlow(final Location location) {
|
||||
final TNTPrimed tnt = this.createTestEntity(location, TNTPrimed.class);
|
||||
return tnt == null || tnt.isPushedByFluid();
|
||||
}
|
||||
|
||||
private <T extends Entity> @Nullable T createTestEntity(final Location location, final Class<T> type) {
|
||||
final T entity = location.getWorld().createEntity(location, type);
|
||||
return new EntitySpawnEvent(entity).callEvent() ? entity : null;
|
||||
}
|
||||
}
|
||||
@@ -5,8 +5,11 @@ import io.papermc.paper.configuration.Configuration;
|
||||
import io.papermc.paper.configuration.ConfigurationPart;
|
||||
import io.papermc.paper.configuration.type.number.IntOr;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.event.HoverEvent;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import net.kyori.adventure.text.minimessage.tag.Tag;
|
||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
||||
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
|
||||
import org.bukkit.Material;
|
||||
import org.slf4j.Logger;
|
||||
import org.spongepowered.configurate.objectmapping.meta.Comment;
|
||||
@@ -34,6 +37,7 @@ public final class GlobalConfiguration extends ConfigurationPart {
|
||||
public class Messages extends ConfigurationPart {
|
||||
public String durableBlockInteraction = "<dark_gray>(<light_purple>S</light_purple>) <white>This block has <gray><remaining></gray> of <gray><durability>";
|
||||
public String fpsSettingChange = "<dark_gray>(<light_purple>S</light_purple>) <gray><state> <yellow><name>";
|
||||
public String mechanicInformation = "<dark_gray>(<light_purple>S</light_purple>) <white>For mechanic information: <yellow><information><hover here></information>";
|
||||
public boolean tpsShowEntityAndChunkCount = true;
|
||||
|
||||
public Component fpsSettingChangeComponent(final String name, final String state) {
|
||||
@@ -51,6 +55,13 @@ public final class GlobalConfiguration extends ConfigurationPart {
|
||||
Placeholder.unparsed("durability", String.valueOf(durability))
|
||||
);
|
||||
}
|
||||
|
||||
public Component mechanicInformationComponent(final Component hoverComponent) {
|
||||
return MiniMessage.miniMessage().deserialize(
|
||||
this.mechanicInformation,
|
||||
TagResolver.resolver("information", Tag.styling(HoverEvent.showText(hoverComponent)))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public Fps fps;
|
||||
|
||||
Reference in New Issue
Block a user