Really exciting changes, got some more packet events to play around with. Might make most of the checks packet based.

This commit is contained in:
thetrouper
2025-03-16 21:35:07 -05:00
parent ce8fc1df49
commit 2a27af00d1
44 changed files with 704 additions and 337 deletions

Binary file not shown.

Binary file not shown.

2
.idea/gradle.xml generated
View File

@@ -5,7 +5,7 @@
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="#JAVA_HOME" />
<option name="gradleJvm" value="21" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />

4
.idea/misc.xml generated
View File

@@ -1,5 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ASMSmaliIdeaPluginConfiguration">
<asm skipDebug="true" skipFrames="true" skipCode="false" expandFrames="false" />
<groovy codeStyle="LEGACY" />
</component>
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="21" project-jdk-type="JavaSDK" />
</project>

0
gradlew vendored Normal file → Executable file
View File

View File

@@ -1,10 +1,12 @@
package me.trouper.sentinel;
import com.github.retrooper.packetevents.PacketEvents;
import com.github.retrooper.packetevents.event.PacketListenerPriority;
import de.tr7zw.changeme.nbtapi.NBT;
import io.github.itzispyder.pdk.PDK;
import io.github.retrooper.packetevents.factory.spigot.SpigotPacketEventsBuilder;
import me.trouper.sentinel.server.events.extras.ShadowRealmEvents;
import me.trouper.sentinel.server.events.violations.blocks.command.CommandBlockEdit;
import me.trouper.sentinel.server.events.violations.players.PluginCloakingPacket;
import org.bukkit.Bukkit;
import org.bukkit.NamespacedKey;
@@ -56,10 +58,6 @@ public final class Sentinel extends JavaPlugin {
getLogger().info("Loading PacketEvents");
PacketEvents.getAPI().load();
getLogger().info("Registering PacketEvents");
PacketEvents.getAPI().getEventManager().registerListener(new PluginCloakingPacket());
PacketEvents.getAPI().getEventManager().registerListener(new ShadowRealmEvents());
}
@Override

View File

@@ -15,13 +15,15 @@ public class ViolationConfig implements JsonSerializable<SwearsConfig> {
return file;
}
public CommandBlockEdit commandBlockEdit = new CommandBlockEdit();
public CommandBlockWhitelist commandBlockWhitelist = new CommandBlockWhitelist();
public CommandBlockMinecartPlace commandBlockMinecartPlace = new CommandBlockMinecartPlace();
public CommandBlockMinecartUse commandBlockMinecartUse = new CommandBlockMinecartUse();
public CommandBlockMinecartEdit commandBlockMinecartEdit = new CommandBlockMinecartEdit();
public CommandBlockMinecartBreak commandBlockMinecartBreak = new CommandBlockMinecartBreak();
public CommandBlockPlace commandBlockPlace = new CommandBlockPlace();
public CommandBlockUse commandBlockUse = new CommandBlockUse();
public CommandBlockEdit commandBlockEdit = new CommandBlockEdit();
public CommandBlockBreak commandBlockBreak = new CommandBlockBreak();
public CommandExecute commandExecute = new CommandExecute();
public CreativeHotbarAction creativeHotbarAction = new CreativeHotbarAction();
@@ -122,6 +124,16 @@ public class ViolationConfig implements JsonSerializable<SwearsConfig> {
);
}
public class CommandBlockMinecartEdit {
public boolean enabled = true;
public boolean deop = true;
public boolean logToDiscord = true;
public boolean punish = false;
public List<String> punishmentCommands = Arrays.asList(
"ban %player% ]=- Sentinel -=[ \nYou have been banned for attempting a dangerous action. \nIf you believe this to be a mistake, please contact the server owner."
);
}
public class CommandBlockMinecartPlace {
public boolean enabled = true;
public boolean deop = true;

View File

@@ -19,17 +19,15 @@ public class CommandBlockStorage implements JsonSerializable<CommandBlockStorage
return file;
}
public List<CommandBlockHolder> holders = new ArrayList<>() {
@Override
public boolean add(CommandBlockHolder holder) {
for (CommandBlockHolder existing : holders) {
if (existing.loc().isSameLocation(holder.loc())) {
super.remove(existing);
}
}
return super.add(holder);
}
};
public List<CommandBlockHolder> holders = new ArrayList<>();
public synchronized boolean remove(CommandBlockHolder holder) {
return holders.removeIf(existing -> existing.loc().isSameLocation(holder.loc()));
}
public synchronized boolean add(CommandBlockHolder holder) {
holders.removeIf(existing -> existing.loc().isSameLocation(holder.loc()));
return holders.add(holder);
}
}

View File

@@ -1,29 +1,36 @@
package me.trouper.sentinel.data.types;
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientUpdateCommandBlock;
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientUpdateCommandBlockMinecart;
import me.trouper.sentinel.Sentinel;
import me.trouper.sentinel.startup.drm.Auth;
import me.trouper.sentinel.utils.DisplayUtils;
import me.trouper.sentinel.utils.ServerUtils;
import me.trouper.sentinel.utils.Text;
import me.trouper.sentinel.utils.display.BlockDisplayRaytracer;
import org.bukkit.Bukkit;
import org.bukkit.Color;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.CommandBlock;
import org.bukkit.command.Command;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.entity.minecart.CommandMinecart;
import org.bukkit.persistence.PersistentDataType;
import java.util.List;
public class CommandBlockHolder {
private final String owner;
private final SerialLocation loc;
private final String facing;
private final String type;
private final boolean auto;
private final boolean conditional;
private final String command;
private String owner;
private SerialLocation loc;
private String facing;
private String type;
private boolean auto;
private boolean conditional;
private String command;
private boolean whitelisted;
public CommandBlockHolder(String owner, SerialLocation loc, String facing, String type, boolean auto, boolean conditional, String command) {
@@ -41,28 +48,34 @@ public class CommandBlockHolder {
return owner;
}
public CommandBlockHolder setOwner(String owner) {
this.owner = owner;
Sentinel.getInstance().getDirector().io.commandBlocks.save();
return this;
}
public SerialLocation loc() {
return loc;
return this.loc;
}
public String facing() {
return facing;
return this.facing;
}
public String type() {
return type;
return this.type;
}
public boolean auto() {
return auto;
public boolean isAuto() {
return this.auto;
}
public boolean conditional() {
return conditional;
public boolean isConditional() {
return this.conditional;
}
public String command() {
return command;
return this.command;
}
public boolean present() {
@@ -76,28 +89,33 @@ public class CommandBlockHolder {
where.getChunk().load(false);
Block b = where.getBlock();
if (!(b.getState() instanceof CommandBlock c) || !(b.getBlockData() instanceof org.bukkit.block.data.type.CommandBlock cb)) {
ServerUtils.verbose("Block is not present due to not being a command block.");
if (!this.whitelisted) this.delete();
ServerUtils.verbose(1,"Block is not present due to not being a command block. Whitelisted: %s",this.isWhitelisted());
if (!this.isWhitelisted()) this.delete();
return false;
}
if (!this.command.equals(c.getCommand())) {
ServerUtils.verbose("Block is not present due to command mismatch. Should be '%s', is '%s'",this.command,c.getCommand());
if (!this.whitelisted) this.delete();
return false;
}
if (this.conditional != cb.isConditional()) {
ServerUtils.verbose("Block is not present due to conditional mismatch.");
if (!this.whitelisted) this.delete();
if (!this.getDirection().equals(cb.getFacing())) {
ServerUtils.verbose("Block is not present due to facing mismatch. Should be '%s', is '%s'",this.facing(),cb.getFacing());
if (!this.isWhitelisted()) this.delete();
return false;
}
if (!this.getType().equals(c.getType())) {
ServerUtils.verbose("Block is not present due to type mismatch. Should be '%s', is '%s'",this.type,c.getType());
if (!this.whitelisted) this.delete();
ServerUtils.verbose("Block is not present due to type mismatch. Should be '%s', is '%s'",this.type(),c.getType());
if (!this.isWhitelisted()) this.delete();
return false;
}
if (this.auto != (c.getPersistentDataContainer().getOrDefault(Sentinel.getInstance().getNamespace("auto"), PersistentDataType.BYTE,(byte) 0) == (byte) 1)) {
if (!this.command().equals(c.getCommand())) {
ServerUtils.verbose("Block is not present due to command mismatch. Should be '%s', is '%s'",this.command(),c.getCommand());
if (!this.isWhitelisted()) this.delete();
return false;
}
if (this.isConditional() != cb.isConditional()) {
ServerUtils.verbose("Block is not present due to conditional mismatch.");
if (!this.isWhitelisted()) this.delete();
return false;
}
if (this.isAuto() != (c.getPersistentDataContainer().getOrDefault(Sentinel.getInstance().getNamespace("auto"), PersistentDataType.BYTE,(byte) 0) == (byte) 1)) {
ServerUtils.verbose("Block is not present due to auto mismatch.");
if (!this.whitelisted) this.delete();
if (!this.isWhitelisted()) this.delete();
return false;
}
if (!preLoaded) where.getChunk().unload();
@@ -105,12 +123,13 @@ public class CommandBlockHolder {
}
}
public boolean whitelisted() {
return whitelisted;
public boolean isWhitelisted() {
return this.whitelisted;
}
public CommandBlockHolder setWhitelisted(boolean whitelisted) {
this.whitelisted = whitelisted;
Sentinel.getInstance().getDirector().io.commandBlocks.save();
return this;
}
@@ -119,40 +138,31 @@ public class CommandBlockHolder {
}
public BlockFace getDirection() {
try {
return BlockFace.valueOf(facing.toUpperCase());
} catch (IllegalArgumentException e) {
return BlockFace.NORTH;
}
return BlockFace.valueOf(facing().toUpperCase());
}
public Material getType() {
return switch (this.type) {
case "COMMAND_BLOCK" -> Material.COMMAND_BLOCK;
case "REPEATING_COMMAND_BLOCK" -> Material.REPEATING_COMMAND_BLOCK;
case "CHAIN_COMMAND_BLOCK" -> Material.CHAIN_COMMAND_BLOCK;
case "COMMAND_BLOCK_MINECART" -> Material.COMMAND_BLOCK_MINECART;
default -> throw new IllegalArgumentException("Unknown command block type: " + type);
};
return Material.valueOf(type().toUpperCase());
}
public void destroy() {
ServerUtils.verbose(1,"Destroying command block...");
SerialLocation.translate(this.loc).getBlock().setType(Material.AIR);
if (!whitelisted) delete();
if (!this.isWhitelisted()) delete();
}
public boolean restore() {
if (Material.COMMAND_BLOCK_MINECART.equals(this.getType())) {
ServerUtils.verbose("Cannot restore minecarts yet.");
ServerUtils.verbose(1,"Cannot restore minecarts yet.");
return false;
}
if (this.present()) return false;
if (this.present() || !this.isWhitelisted()) return false;
Block block = SerialLocation.translate(this.loc).getBlock();
block.setType(this.getType());
if (!ServerUtils.isCommandBlock(block)) {
ServerUtils.verbose("Block at the location was not a command block (You shouldn't be seeing this. Report it).");
ServerUtils.verbose(1,"Block at the location was not a command block (You shouldn't be seeing this. Report it).");
return false;
}
@@ -163,8 +173,8 @@ public class CommandBlockHolder {
block.getState().update(true, false);
org.bukkit.block.data.type.CommandBlock conditional = (org.bukkit.block.data.type.CommandBlock) cb.getBlock().getBlockData();
ServerUtils.verbose("Direction is " + this.getDirection());
ServerUtils.verbose("Conditional is " + this.conditional);
//ServerUtils.verbose("Direction is " + this.getDirection());
//ServerUtils.verbose("Conditional is " + this.conditional);
conditional.setFacing(this.getDirection());
conditional.setConditional(this.conditional);
@@ -177,7 +187,7 @@ public class CommandBlockHolder {
this.auto ? (byte) 1 : (byte) 0
);
cb.update(true,false);
cb.update(true,true);
ServerUtils.verbose("Command block at " + this.loc.toString() + " has been restored.");
return true;
}
@@ -187,14 +197,170 @@ public class CommandBlockHolder {
}
public CommandBlockHolder add() {
Sentinel.getInstance().getDirector().io.commandBlocks.holders.add(this);
ServerUtils.verbose(1,"Adding command block...");
Sentinel.getInstance().getDirector().io.commandBlocks.add(this);
Sentinel.getInstance().getDirector().io.commandBlocks.save();
return this;
}
public void delete() {
SerialLocation.translate(this.loc).getBlock().setType(Material.AIR);
Sentinel.getInstance().getDirector().io.commandBlocks.holders.removeIf(h->h.loc.isSameLocation(this.loc));
ServerUtils.verbose(1,"Deleting & Destroying command block...");
if (this.loc.isUUID() && Bukkit.getEntity(this.loc.toUIID()) != null) Bukkit.getEntity(this.loc.toUIID()).remove();
else SerialLocation.translate(this.loc).getBlock().setType(Material.AIR);
Sentinel.getInstance().getDirector().io.commandBlocks.remove(this);
Sentinel.getInstance().getDirector().io.commandBlocks.save();
}
public void highlight(Player viewer, Material color) {
if (this.loc.isUUID()) {
Color c = switch (color) {
case RED_CONCRETE_POWDER -> Color.RED;
case LIME_CONCRETE_POWDER -> Color.LIME;
case MAGENTA_CONCRETE_POWDER, PURPLE_CONCRETE_POWDER -> Color.FUCHSIA;
default -> Color.BLACK;
};
Entity cart = Bukkit.getEntity(this.loc.toUIID());
if (cart == null) return;
for (int i = 0; i < 5; i++) {
DisplayUtils.ring(cart.getLocation().clone().add(0, (double) i /5,0),0.6, (location) -> {
DisplayUtils.PLAYER_DUST_PARTICLE_FACTORY.apply(c,1F).accept(viewer,location);
},((location, integer) -> {
return integer % 36 == 0;
}));
}
} else {
BlockDisplayRaytracer.outline(color, this.loc.translate(), 0.05, 2, List.of(viewer));
}
}
public boolean update(Player updater) {
ServerUtils.verbose(1,"Processing update requested by %s",updater.getName());
if (this.isWhitelisted()) return false;
boolean changesMade = false;
if (!this.owner().equals(updater.getUniqueId().toString())) {
this.owner = updater.getUniqueId().toString();
changesMade = true;
}
if (this.loc.isUUID()) {
Entity cart = Bukkit.getEntity(this.loc.toUIID());
if (!(cart instanceof CommandMinecart cm)) return false;
if (!cm.getCommand().equals(this.command())) {
this.command = cm.getCommand();
changesMade = true;
}
} else {
Location where = loc.translate();
boolean preLoaded = where.isChunkLoaded();
where.getChunk().load(false);
Block b = where.getBlock();
if (!(b.getState() instanceof CommandBlock c) || !(b.getBlockData() instanceof org.bukkit.block.data.type.CommandBlock cb)) {
ServerUtils.verbose(1,"Block cannot be updated due to not being a command block. It will be deleted if it is not whitelisted. Whitelisted: %s",this.isWhitelisted());
if (!this.isWhitelisted()) this.delete();
return false;
}
if (!this.getDirection().equals(cb.getFacing())) {
ServerUtils.verbose("Block needs update due to facing mismatch. Should be '%s', is '%s'",this.facing(),cb.getFacing());
this.facing = cb.getFacing().toString();
changesMade = true;
}
if (!this.getType().equals(c.getType())) {
ServerUtils.verbose("Block needs update due to type mismatch. Should be '%s', is '%s'",this.type(),c.getType());
this.type = c.getType().toString();
changesMade = true;
}
if (!this.command().equals(c.getCommand())) {
ServerUtils.verbose("Block needs update due to command mismatch. Should be '%s', is '%s'",this.command(),c.getCommand());
this.command = c.getCommand();
changesMade = true;
}
if (this.isConditional() != cb.isConditional()) {
ServerUtils.verbose("Block needs update due to conditional mismatch.");
this.conditional = cb.isConditional();
changesMade = true;
}
if (this.isAuto() != (c.getPersistentDataContainer().getOrDefault(Sentinel.getInstance().getNamespace("auto"), PersistentDataType.BYTE,(byte) 0) == (byte) 1)) {
ServerUtils.verbose("Block needs update due to auto mismatch.");
this.auto = (c.getPersistentDataContainer().getOrDefault(Sentinel.getInstance().getNamespace("auto"), PersistentDataType.BYTE,(byte) 0) == (byte) 1);
changesMade = true;
}
if (!preLoaded) where.getChunk().unload();
}
if (changesMade) updater.sendMessage(Text.prefix("Successfully updated a &b%s&7.".formatted(Text.cleanName(this.type()))));
return changesMade;
}
public boolean update(Player updater, WrapperPlayClientUpdateCommandBlockMinecart packet) {
ServerUtils.verbose(1,"Processing packet update requested by %s",updater.getName());
if (this.isWhitelisted()) return false;
boolean changesMade = false;
if (!this.owner().equals(updater.getUniqueId().toString())) {
this.owner = updater.getUniqueId().toString();
changesMade = true;
}
if (!this.loc.isUUID()) {
throw new IllegalArgumentException("Cannot update block commands with this packet.");
}
if (!this.command().equals(packet.getCommand())) {
ServerUtils.verbose("Block needs update due to command mismatch. Should be '%s', is '%s'",this.command(),packet.getCommand());
this.command = packet.getCommand();
changesMade = true;
}
if (changesMade) updater.sendMessage(Text.prefix("Successfully updated a &b%s&7.".formatted(Text.cleanName(this.type()))));
return changesMade;
}
public boolean update(Player updater, WrapperPlayClientUpdateCommandBlock packet) {
ServerUtils.verbose(1,"Processing packet update requested by %s",updater.getName());
if (this.isWhitelisted()) return false;
boolean changesMade = false;
if (!this.owner().equals(updater.getUniqueId().toString())) {
this.owner = updater.getUniqueId().toString();
changesMade = true;
}
if (this.loc.isUUID()) {
throw new IllegalArgumentException("Cannot update UUID command blocks with this packet.");
}
Material t = switch (packet.getMode()) {
case AUTO -> Material.REPEATING_COMMAND_BLOCK;
case REDSTONE -> Material.COMMAND_BLOCK;
case SEQUENCE -> Material.CHAIN_COMMAND_BLOCK;
};
if (!this.getType().equals(t)) {
ServerUtils.verbose("Block needs update due to type mismatch. Should be '%s', is '%s'",this.type(),t.toString());
this.type = t.toString();
changesMade = true;
}
if (!this.command().equals(packet.getCommand())) {
ServerUtils.verbose("Block needs update due to command mismatch. Should be '%s', is '%s'",this.command(),packet.getCommand());
this.command = packet.getCommand();
changesMade = true;
}
if (this.isConditional() != packet.isConditional()) {
ServerUtils.verbose("Block needs update due to conditional mismatch.");
this.conditional = packet.isConditional();
changesMade = true;
}
if (this.isAuto() != packet.isAutomatic()) {
ServerUtils.verbose("Block needs update due to auto mismatch.");
this.auto = packet.isAutomatic();
changesMade = true;
}
if (changesMade) updater.sendMessage(Text.prefix("Successfully updated a &b%s&7.".formatted(Text.cleanName(this.type()))));
return changesMade;
}
}

View File

@@ -207,14 +207,14 @@ public class SentinelCommand implements CustomCommand {
if (p.getTargetEntity(10) instanceof CommandMinecart cm) {
Sentinel.getInstance().getDirector().whitelistManager
.generateHolder(p.getUniqueId(), cm).addToWhitelist();
.generateHolder(p.getUniqueId(), cm).addAndWhitelist();
return;
}
Block target = p.getTargetBlock(Set.of(Material.AIR), 10);
if (ServerUtils.isCommandBlock(target)) {
CommandBlock cb = (CommandBlock) target.getState();
Sentinel.getInstance().getDirector().whitelistManager
.generateHolder(p.getUniqueId(), cb).addToWhitelist();
.generateHolder(p.getUniqueId(), cb).addAndWhitelist();
} else {
sender.sendMessage(Text.prefix(Sentinel.getInstance().getDirector().io.lang.commandBlock.notCommandBlock
.formatted(Text.cleanName(target.getType().toString()))));
@@ -228,8 +228,9 @@ public class SentinelCommand implements CustomCommand {
if (p.getTargetEntity(10) instanceof CommandMinecart cm) {
CommandBlockHolder wb = Sentinel.getInstance().getDirector().whitelistManager
.generateHolder(p.getUniqueId(), cm);
if (wb.removeFromWhitelist()) {
.getFromList(cm.getUniqueId());
if (wb != null) {
wb.setWhitelisted(false);
String cleanedType = Text.cleanName(SerialLocation.translate(wb.loc()).getBlock().getType().toString());
sender.sendMessage(Text.prefix(Sentinel.getInstance().getDirector().io.lang.commandBlock.removeSuccess
.formatted(cleanedType, wb.command())));
@@ -242,8 +243,9 @@ public class SentinelCommand implements CustomCommand {
Block target = p.getTargetBlock(Set.of(Material.AIR), 10);
CommandBlockHolder wb = Sentinel.getInstance().getDirector().whitelistManager
.getFromWhitelist(target.getLocation());
if (wb != null && wb.removeFromWhitelist()) {
.getFromList(target.getLocation());
if (wb != null) {
wb.setWhitelisted(false);
String cleanedType = Text.cleanName(SerialLocation.translate(wb.loc()).getBlock().getType().toString());
sender.sendMessage(Text.prefix(Sentinel.getInstance().getDirector().io.lang.commandBlock.removeSuccess
.formatted(cleanedType, wb.command())));
@@ -261,10 +263,10 @@ public class SentinelCommand implements CustomCommand {
var whitelistManager = Sentinel.getInstance().getDirector().whitelistManager;
if (whitelistManager.autoWhitelist.contains(p.getUniqueId())) {
whitelistManager.autoWhitelist.remove(p.getUniqueId());
sender.sendMessage(Text.prefix(Sentinel.getInstance().getDirector().io.lang.commandBlock.autoWhitelistOn));
sender.sendMessage(Text.prefix(Sentinel.getInstance().getDirector().io.lang.commandBlock.autoWhitelistOff));
} else {
whitelistManager.autoWhitelist.add(p.getUniqueId());
sender.sendMessage(Text.prefix(Sentinel.getInstance().getDirector().io.lang.commandBlock.autoWhitelistOff));
sender.sendMessage(Text.prefix(Sentinel.getInstance().getDirector().io.lang.commandBlock.autoWhitelistOn));
}
}

View File

@@ -6,14 +6,11 @@ import io.github.itzispyder.pdk.utils.misc.SoundPlayer;
import me.trouper.sentinel.Sentinel;
import me.trouper.sentinel.data.types.CommandBlockHolder;
import me.trouper.sentinel.data.types.Selection;
import me.trouper.sentinel.utils.DisplayUtils;
import me.trouper.sentinel.utils.Text;
import me.trouper.sentinel.utils.PlayerUtils;
import me.trouper.sentinel.utils.ServerUtils;
import me.trouper.sentinel.utils.Text;
import me.trouper.sentinel.utils.display.BlockDisplayRaytracer;
import org.bukkit.*;
import org.bukkit.block.CommandBlock;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.entity.minecart.CommandMinecart;
import org.bukkit.event.EventHandler;
@@ -24,8 +21,6 @@ import org.bukkit.event.vehicle.VehicleDamageEvent;
import org.bukkit.inventory.ItemStack;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
public class WandEvents implements CustomListener {
public static final ItemStack SELECTION_WAND = ItemBuilder.create()
@@ -50,11 +45,7 @@ public class WandEvents implements CustomListener {
.build();
public static final Map<UUID, Selection> selections = new HashMap<>();
private static final ConcurrentLinkedQueue<BlockHighlight> blockHighlights = new ConcurrentLinkedQueue<>();
private static final Map<UUID, Set<BlockHighlight>> playerBlockHighlights = new ConcurrentHashMap<>();
private static final ConcurrentLinkedQueue<EntityHighlight> entityHighlights = new ConcurrentLinkedQueue<>();
private static final Map<UUID, Set<EntityHighlight>> playerEntityHighlights = new ConcurrentHashMap<>();
@EventHandler
public void onClickEntity(PlayerInteractEntityEvent e) {
Player p = e.getPlayer();
@@ -63,15 +54,15 @@ public class WandEvents implements CustomListener {
if (!i.isSimilar(SELECTION_WAND)) return;
if (!PlayerUtils.isTrusted(p)) return;
SoundPlayer add = new SoundPlayer(p.getLocation(),Sound.ENTITY_EXPERIENCE_ORB_PICKUP,100,1);
SoundPlayer add = new SoundPlayer(p.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 100, 1);
if (!(e.getRightClicked() instanceof CommandMinecart cm)) return;
e.setCancelled(true);
Sentinel.getInstance().getDirector().whitelistManager.generateHolder(p.getUniqueId(),cm).addToWhitelist();
Sentinel.getInstance().getDirector().whitelistManager.getFromList(cm.getUniqueId()).setWhitelisted(true);
add.play(p);
}
@EventHandler
public void onDamage(VehicleDamageEvent e) {
if (!(e.getAttacker() instanceof Player p)) return;
@@ -80,15 +71,15 @@ public class WandEvents implements CustomListener {
if (!i.isSimilar(SELECTION_WAND)) return;
if (!PlayerUtils.isTrusted(p)) return;
SoundPlayer remove = new SoundPlayer(p.getLocation(),Sound.BLOCK_GLASS_BREAK,100,1);
SoundPlayer remove = new SoundPlayer(p.getLocation(), Sound.BLOCK_GLASS_BREAK, 100, 1);
if (!(e.getVehicle() instanceof CommandMinecart cm)) return;
e.setCancelled(true);
Sentinel.getInstance().getDirector().whitelistManager.generateHolder(p.getUniqueId(),cm).removeFromWhitelist();
Sentinel.getInstance().getDirector().whitelistManager.getFromList(cm.getUniqueId()).setWhitelisted(false);
remove.play(p);
}
@EventHandler
public void onClick(PlayerInteractEvent e) {
Player p = e.getPlayer();
@@ -97,166 +88,97 @@ public class WandEvents implements CustomListener {
if (!i.isSimilar(SELECTION_WAND)) return;
if (!PlayerUtils.isTrusted(p)) return;
SoundPlayer add = new SoundPlayer(p.getLocation(),Sound.ENTITY_EXPERIENCE_ORB_PICKUP,100,1);
SoundPlayer remove = new SoundPlayer(p.getLocation(),Sound.BLOCK_GLASS_BREAK,100,1);
SoundPlayer set1 = new SoundPlayer(p.getLocation(),Sound.UI_BUTTON_CLICK,100,1);
SoundPlayer set2 = new SoundPlayer(p.getLocation(),Sound.UI_BUTTON_CLICK,100,0.8F);
SoundPlayer add = new SoundPlayer(p.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 100, 1);
SoundPlayer remove = new SoundPlayer(p.getLocation(), Sound.BLOCK_GLASS_BREAK, 100, 1);
SoundPlayer set1 = new SoundPlayer(p.getLocation(), Sound.UI_BUTTON_CLICK, 100, 1);
SoundPlayer set2 = new SoundPlayer(p.getLocation(), Sound.UI_BUTTON_CLICK, 100, 0.8F);
Selection selection = selections.computeIfAbsent(p.getUniqueId(), k -> new Selection());
if (p.getTargetBlockExact(10) == null) return;
Location loc = p.getTargetBlockExact(10).getLocation();
if (e.getAction() == Action.LEFT_CLICK_BLOCK) {
e.setCancelled(true);
if (p.isSneaking() && ServerUtils.isCommandBlock(loc.getBlock())) {
set1.play(p);
setPos1(p,selection,loc);
setPos1(p, selection, loc);
} else if (ServerUtils.isCommandBlock(loc.getBlock())) {
remove.play(p);
Sentinel.getInstance().getDirector().whitelistManager.generateHolder(p.getUniqueId(),(CommandBlock) loc.getBlock().getState()).removeFromWhitelist();
Sentinel.getInstance().getDirector().whitelistManager.getFromList(loc).setWhitelisted(false);
} else {
set1.play(p);
setPos1(p,selection,loc);
setPos1(p, selection, loc);
}
} else if (e.getAction() == Action.RIGHT_CLICK_BLOCK) {
e.setCancelled(true);
if (p.isSneaking() && ServerUtils.isCommandBlock(loc.getBlock())) {
e.setCancelled(true);
set2.play(p);
setPos2(p,selection,loc);
setPos2(p, selection, loc);
} else if (ServerUtils.isCommandBlock(loc.getBlock())) {
add.play(p);
Sentinel.getInstance().getDirector().whitelistManager.generateHolder(p.getUniqueId(),(CommandBlock) loc.getBlock().getState()).addToWhitelist();
Sentinel.getInstance().getDirector().whitelistManager.generateHolder(p.getUniqueId(),(CommandBlock) loc.getBlock().getState()).addAndWhitelist();
e.setCancelled(true);
} else {
e.setCancelled(true);
set2.play(p);
setPos2(p,selection,loc);
setPos2(p, selection, loc);
}
}
}
private record EntityHighlight(Player beholder, Entity ent, Color color) {
public void display() {
for (int i = 0; i < 5; i++) {
DisplayUtils.ring(ent.getLocation().clone().add(0, (double) i /5,0),0.6, (location) -> {
DisplayUtils.PLAYER_DUST_PARTICLE_FACTORY.apply(color,1F).accept(beholder,location);
},((location, integer) -> {
return integer % 36 == 0;
}));
}
}
}
private record BlockHighlight(Player beholder, Location loc, Material color) {
public void display() {
BlockDisplayRaytracer.outline(color, loc, 0.05, 2, List.of(beholder));
}
}
private static void sortNear(Player p) {
ItemStack i = p.getInventory().getItemInMainHand();
if (!i.isSimilar(SELECTION_WAND) || !PlayerUtils.isTrusted(p)) {
Set<BlockHighlight> existingBlocks = playerBlockHighlights.remove(p.getUniqueId());
Set<EntityHighlight> existingEntities = playerEntityHighlights.remove(p.getUniqueId());
if (existingBlocks != null) {
blockHighlights.removeAll(existingBlocks);
entityHighlights.removeAll(existingEntities);
}
return;
}
Set<BlockHighlight> currentBlocks = new HashSet<>();
Set<EntityHighlight> currentEntities = new HashSet<>();
// Highlight nearby command blocks
Selection around = new Selection();
around.setPos1(p.getLocation().add(-10, -10, -10));
around.setPos2(p.getLocation().add(10, 10, 10));
around.getBlocks().stream()
.filter(block -> ServerUtils.isCommandBlock(block) && block.getLocation().distance(p.getLocation()) <= 10)
.forEach(block -> {
CommandBlock cb = (CommandBlock) block.getState();
CommandBlockHolder holder = Sentinel.getInstance().getDirector().whitelistManager.generateHolder(p.getUniqueId(),cb);
Material color = holder.isWhitelisted()
? Material.LIME_CONCRETE_POWDER
: Material.RED_CONCRETE_POWDER;
if (holder.isUnknown()) {
color = Material.BLACK_CONCRETE_POWDER;
holder.addToExisting();
if (!(block.getState() instanceof CommandBlock cb)) return;
CommandBlockHolder holder = Sentinel.getInstance().getDirector().whitelistManager.getFromList(block.getLocation());
Material color = Material.BLACK_CONCRETE_POWDER;
if (holder == null) {
holder = Sentinel.getInstance().getDirector().whitelistManager.generateHolder(p.getUniqueId(), cb);
holder.add();
} else {
color = holder.isWhitelisted() ? Material.LIME_CONCRETE_POWDER : Material.RED_CONCRETE_POWDER;
}
currentBlocks.add(new BlockHighlight(p, block.getLocation(), color));
holder.highlight(p, color);
});
List<Entity> carts = p.getNearbyEntities(10,10,10).stream().filter(entity -> entity instanceof CommandMinecart).toList();
// Highlight nearby command minecarts
p.getNearbyEntities(10, 10, 10).stream()
.filter(entity -> entity instanceof CommandMinecart)
.forEach(entity -> {
CommandMinecart cm = (CommandMinecart) entity;
CommandBlockHolder holder = Sentinel.getInstance().getDirector().whitelistManager.getFromList(cm.getUniqueId());
Material color = Material.BLACK_CONCRETE_POWDER;
if (holder == null) {
holder = Sentinel.getInstance().getDirector().whitelistManager.generateHolder(p.getUniqueId(), cm);
holder.add();
} else {
color = holder.isWhitelisted() ? Material.LIME_CONCRETE_POWDER : Material.RED_CONCRETE_POWDER;
}
holder.highlight(p, color);
});
for (Entity cart : carts) {
if (!(cart instanceof CommandMinecart cm)) continue;
CommandBlockHolder holder = Sentinel.getInstance().getDirector().whitelistManager.generateHolder(p.getUniqueId(),cm);
Color color = holder.isWhitelisted()
? Color.fromRGB(0x00FF00)
: Color.fromRGB(0xFF0000);
if (holder.isUnknown()) {
color = Color.fromRGB(0);
holder.addToExisting();
}
currentEntities.add(new EntityHighlight(p, cart, color));
}
for (CommandBlockHolder wl : Sentinel.getInstance().getDirector().io.commandBlocks.whitelistedCMDBlocks) {
if (!wl.isPresent() && !wl.isCart()) {
currentBlocks.add(new BlockHighlight(p, wl.loc().translate(), Material.PURPLE_CONCRETE_POWDER));
}
}
Set<BlockHighlight> previousBlocks = playerBlockHighlights.getOrDefault(p.getUniqueId(), new HashSet<>());
Set<BlockHighlight> blocksToAdd = new HashSet<>(currentBlocks);
blocksToAdd.removeAll(previousBlocks);
Set<BlockHighlight> blocksToRemove = new HashSet<>(previousBlocks);
blocksToRemove.removeAll(currentBlocks);
Set<EntityHighlight> previousEntities = playerEntityHighlights.getOrDefault(p.getUniqueId(), new HashSet<>());
Set<EntityHighlight> entitiesToAdd = new HashSet<>(currentEntities);
entitiesToAdd.removeAll(previousEntities);
Set<EntityHighlight> entitiesToRemove = new HashSet<>(previousEntities);
entitiesToRemove.removeAll(currentEntities);
blockHighlights.addAll(blocksToAdd);
blockHighlights.removeAll(blocksToRemove);
playerBlockHighlights.put(p.getUniqueId(), currentBlocks);
entityHighlights.addAll(entitiesToAdd);
entityHighlights.removeAll(entitiesToRemove);
playerEntityHighlights.put(p.getUniqueId(), currentEntities);
// Highlight missing command blocks
List<CommandBlockHolder> holdersCopy = new ArrayList<>(Sentinel.getInstance().getDirector().io.commandBlocks.holders);
holdersCopy.forEach(holder -> {
if (!holder.present() && holder.isWhitelisted()) holder.highlight(p,Material.MAGENTA_CONCRETE_POWDER);
});
}
public static void handleDisplay() {
PlayerUtils.forEachTrusted(WandEvents::sortNear);
Iterator<BlockHighlight> blockIterator = blockHighlights.iterator();
while (blockIterator.hasNext()) {
BlockHighlight bh = blockIterator.next();
if (bh.beholder == null || !bh.beholder.isOnline() || bh.loc.distance(bh.beholder.getLocation()) > 10) {
blockIterator.remove();
playerBlockHighlights.computeIfPresent(bh.beholder.getUniqueId(), (uuid, set) -> {
set.remove(bh);
return set.isEmpty() ? null : set;
});
} else {
bh.display();
}
}
Iterator<EntityHighlight> entityIterator = entityHighlights.iterator();
while (entityIterator.hasNext()) {
EntityHighlight eh = entityIterator.next();
if (eh.beholder == null || !eh.beholder.isOnline() || eh.ent.getLocation().distance(eh.beholder.getLocation()) > 10) {
entityIterator.remove();
playerEntityHighlights.computeIfPresent(eh.beholder.getUniqueId(), (uuid,set) -> {
set.remove(eh);
return set.isEmpty() ? null : set;
});
} else {
eh.display();
}
}
// Display selections
selections.forEach((uuid, selection) -> {
Player p = Bukkit.getPlayer(uuid);
if (p == null || !p.isOnline() || !p.getInventory().getItemInMainHand().isSimilar(SELECTION_WAND)) return;
@@ -275,4 +197,4 @@ public class WandEvents implements CustomListener {
selection.setPos1(loc);
p.sendMessage(Text.prefix("Position 1 set to " + Text.formatLoc(loc)));
}
}
}

View File

@@ -1,6 +1,7 @@
package me.trouper.sentinel.server.events.extras;
import com.github.retrooper.packetevents.PacketEvents;
import com.github.retrooper.packetevents.event.PacketListener;
import com.github.retrooper.packetevents.event.PacketListenerAbstract;
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
import com.github.retrooper.packetevents.event.PacketSendEvent;
@@ -20,7 +21,7 @@ import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerJoinEvent;
public class ShadowRealmEvents extends PacketListenerAbstract implements CustomListener {
public class ShadowRealmEvents implements CustomListener, PacketListener {
@EventHandler
public void onJoin(PlayerJoinEvent e) {

View File

@@ -33,9 +33,10 @@ public class CommandBlockBreak extends AbstractViolation{
ServerUtils.verbose("CommandBlockBreak: Block is a command block");
Player p = e.getPlayer();
CommandBlock cb = (CommandBlock) b.getState();
CommandBlockHolder holder = Sentinel.getInstance().getDirector().whitelistManager.generateHolder(p.getUniqueId(),cb);
CommandBlockHolder holder = Sentinel.getInstance().getDirector().whitelistManager.getFromList(cb.getLocation());
if (PlayerUtils.isTrusted(e.getPlayer())) {
if (!Sentinel.getInstance().getDirector().whitelistManager.autoWhitelist.contains(p.getUniqueId())) {
if (Sentinel.getInstance().getDirector().whitelistManager.autoWhitelist.contains(p.getUniqueId())) {
ServerUtils.verbose("Auto Whitelist is on, un-whitelisting the command block.");
holder.setWhitelisted(false);
holder.delete();
}
@@ -43,6 +44,7 @@ public class CommandBlockBreak extends AbstractViolation{
}
if (!Sentinel.getInstance().getDirector().io.violationConfig.commandBlockBreak.enabled) {
ServerUtils.verbose("Not enabled, deletion allowed.");
holder.delete();
return;
}

View File

@@ -1,7 +1,16 @@
package me.trouper.sentinel.server.events.violations.blocks.command;
import com.github.retrooper.packetevents.event.PacketListener;
import com.github.retrooper.packetevents.event.PacketListenerAbstract;
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
import com.github.retrooper.packetevents.protocol.player.User;
import com.github.retrooper.packetevents.util.Vector3i;
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientTabComplete;
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientUpdateCommandBlock;
import io.github.itzispyder.pdk.plugin.gui.CustomGui;
import me.trouper.sentinel.Sentinel;
import me.trouper.sentinel.data.types.CommandBlockHolder;
import me.trouper.sentinel.server.events.violations.AbstractViolation;
import me.trouper.sentinel.server.functions.helpers.ActionConfiguration;
import me.trouper.sentinel.server.gui.Items;
@@ -10,6 +19,8 @@ import me.trouper.sentinel.server.gui.config.AntiNukeGUI;
import me.trouper.sentinel.utils.PlayerUtils;
import me.trouper.sentinel.utils.ServerUtils;
import me.trouper.sentinel.utils.Text;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.CommandBlock;
@@ -22,44 +33,54 @@ import org.bukkit.inventory.ItemStack;
import java.util.List;
public class CommandBlockEdit extends AbstractViolation {
public class CommandBlockEdit extends AbstractViolation implements PacketListener {
@EventHandler
private void onCMDBlockChange(EntityChangeBlockEvent e) {
//ServerUtils.verbose("CommandBlockChange: Detected the event");
if (!Sentinel.getInstance().getDirector().io.violationConfig.commandBlockEdit.enabled) return;
//ServerUtils.verbose("CommandBlockChange: Enabled");
if (!(e.getEntity() instanceof Player p)) return;
//ServerUtils.verbose("CommandBlockChange: Changer is a player");
Block b = e.getBlock();
if (!(ServerUtils.isCommandBlock(b)))
return;
ServerUtils.verbose("CommandBlockChange: Block is a command block");
CommandBlock cb = (CommandBlock) b.getState();
@Override
public void onPacketReceive(PacketReceiveEvent event) {
if (event.getPacketType() != PacketType.Play.Client.UPDATE_COMMAND_BLOCK) return;
ServerUtils.verbose("Packet is a command block update packet");
WrapperPlayClientUpdateCommandBlock wrapper = new WrapperPlayClientUpdateCommandBlock(event);
User user = event.getUser();
Player p = Bukkit.getPlayer(user.getUUID());
if (p == null) return;
Vector3i pos = wrapper.getPosition();
Location loc = new Location(p.getWorld(), pos.x, pos.y, pos.z);
CommandBlockHolder holder = Sentinel.getInstance().getDirector().whitelistManager.getFromList(loc);
if (PlayerUtils.isTrusted(p)) {
if (!Sentinel.getInstance().getDirector().whitelistManager.autoWhitelist.contains(p.getUniqueId())) return;
Sentinel.getInstance().getDirector().whitelistManager.generateHolder(p.getUniqueId(),cb).addToWhitelist();
if (Sentinel.getInstance().getDirector().whitelistManager.autoWhitelist.contains(p.getUniqueId())) holder.setWhitelisted(true);
holder.update(p,wrapper);
return;
}
ServerUtils.verbose("CommandBlockChange: Not trusted, performing action");
if (!Sentinel.getInstance().getDirector().io.violationConfig.commandBlockEdit.enabled) {
holder.update(p,wrapper);
return;
}
ServerUtils.verbose("Enabled, performing action");
event.setCancelled(true);
ActionConfiguration.Builder config = new ActionConfiguration.Builder()
.setEvent(e)
.setPlayer(p)
.deop(Sentinel.getInstance().getDirector().io.violationConfig.commandBlockEdit.deop)
.cancel(true)
.punish(Sentinel.getInstance().getDirector().io.violationConfig.commandBlockEdit.punish)
.setPunishmentCommands(Sentinel.getInstance().getDirector().io.violationConfig.commandBlockEdit.punishmentCommands)
.logToDiscord(Sentinel.getInstance().getDirector().io.violationConfig.commandBlockEdit.logToDiscord);
runActions(
Sentinel.getInstance().getDirector().io.lang.violations.protections.rootName.rootNameFormatPlayer.formatted(p.getName(), Sentinel.getInstance().getDirector().io.lang.violations.protections.rootName.edit, Sentinel.getInstance().getDirector().io.lang.violations.protections.rootName.commandBlock),
Sentinel.getInstance().getDirector().io.lang.violations.protections.rootName.rootNameFormatPlayer.formatted(p.getName(), Sentinel.getInstance().getDirector().io.lang.violations.protections.rootName.edit, Sentinel.getInstance().getDirector().io.lang.violations.protections.rootName.commandBlock),
generateCommandBlockInfo(cb),
generateCommandBlockInfo((CommandBlock) holder.loc().translate().getBlock().getState()),
config
);
}
@Override
public CustomGui getConfigGui() {
return CustomGui.create()

View File

@@ -2,6 +2,7 @@ package me.trouper.sentinel.server.events.violations.blocks.command;
import io.github.itzispyder.pdk.plugin.gui.CustomGui;
import me.trouper.sentinel.Sentinel;
import me.trouper.sentinel.data.types.CommandBlockHolder;
import me.trouper.sentinel.server.events.violations.AbstractViolation;
import me.trouper.sentinel.server.functions.helpers.ActionConfiguration;
import me.trouper.sentinel.server.gui.Items;
@@ -26,22 +27,24 @@ public class CommandBlockUse extends AbstractViolation {
@EventHandler
private void onCMDBlockUse(PlayerInteractEvent e) {
//ServerUtils.verbose("CommandBlockUse: Detected Interaction");
if (!Sentinel.getInstance().getDirector().io.violationConfig.commandBlockUse.enabled) return;
//ServerUtils.verbose("CommandBlockUse: Enabled");
Player p = e.getPlayer();
if (e.getClickedBlock() == null) return;
//ServerUtils.verbose("CommandBlockUse: Block isn't null");
Block b = e.getClickedBlock();
if (!(ServerUtils.isCommandBlock(b))) return;
CommandBlock cb = (CommandBlock) b.getState();
CommandBlockHolder holder = Sentinel.getInstance().getDirector().whitelistManager.getFromList(cb.getLocation());
if (PlayerUtils.isTrusted(p)) {
if (!Sentinel.getInstance().getDirector().whitelistManager.autoWhitelist.contains(p.getUniqueId())) return;
if (Sentinel.getInstance().getDirector().whitelistManager.isWhitelisted(cb)) return;
e.setCancelled(true);
Sentinel.getInstance().getDirector().whitelistManager.generateHolder(p.getUniqueId(), cb).addToWhitelist();
if (Sentinel.getInstance().getDirector().whitelistManager.autoWhitelist.contains(p.getUniqueId())) holder.setWhitelisted(true);
holder.update(p);
return;
}
if (!Sentinel.getInstance().getDirector().io.violationConfig.commandBlockUse.enabled) {
holder.update(p);
return;
}
ServerUtils.verbose("CommandBlockUse: Not trusted, performing action");
ActionConfiguration.Builder config = new ActionConfiguration.Builder()

View File

@@ -2,6 +2,7 @@ package me.trouper.sentinel.server.events.violations.entities;
import io.github.itzispyder.pdk.plugin.gui.CustomGui;
import me.trouper.sentinel.Sentinel;
import me.trouper.sentinel.data.types.CommandBlockHolder;
import me.trouper.sentinel.server.events.violations.AbstractViolation;
import me.trouper.sentinel.server.functions.helpers.ActionConfiguration;
import me.trouper.sentinel.server.gui.Items;
@@ -16,6 +17,7 @@ import org.bukkit.entity.minecart.CommandMinecart;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.vehicle.VehicleDamageEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
@@ -23,33 +25,39 @@ import java.util.List;
public class CommandMinecartBreak extends AbstractViolation {
@EventHandler
public void onBreak(EntityDamageEvent e) {
//ServerUtils.verbose("CommandBlockBreak: Detected the event");
if (!Sentinel.getInstance().getDirector().io.violationConfig.commandBlockMinecartBreak.enabled) return;
//ServerUtils.verbose("CommandBlockBreak: Changer is a player");
if (!(e.getEntity() instanceof CommandMinecart s)) return;
if (e.getDamageSource() == null) {
public void onBreak(VehicleDamageEvent e) {
if (!(e.getVehicle() instanceof CommandMinecart cm)) return;
if (e.getAttacker() == null) {
e.setCancelled(true);
return;
}
if (e.getDamageSource().getCausingEntity() == null) {
e.setCancelled(true);
return;
}
if (!(e.getDamageSource().getCausingEntity() instanceof Player p)) {
if (!(e.getAttacker() instanceof Player p)) {
e.setCancelled(true);
return;
}
CommandBlockHolder holder = Sentinel.getInstance().getDirector().whitelistManager.getFromList(cm.getUniqueId());
if (PlayerUtils.isTrusted(p)) {
if (Sentinel.getInstance().getDirector().whitelistManager.getFromExisting(s.getLocation()).isWhitelisted()) return;
Sentinel.getInstance().getDirector().whitelistManager.getFromExisting(s.getLocation()).removeFromExisting();
if (Sentinel.getInstance().getDirector().whitelistManager.autoWhitelist.contains(p.getUniqueId())) {
ServerUtils.verbose("Auto Whitelist is on, un-whitelisting the command minecart.");
holder.setWhitelisted(false);
holder.delete();
}
return;
}
if (!Sentinel.getInstance().getDirector().io.violationConfig.commandBlockMinecartBreak.enabled) {
ServerUtils.verbose("Not enabled, deletion allowed.");
holder.delete();
return;
}
ServerUtils.verbose("Not trusted, performing action");
ActionConfiguration.Builder config = new ActionConfiguration.Builder()
.setEvent(e)
.setEntity(s)
.setEntity(cm)
.setPlayer(p)
.deop(Sentinel.getInstance().getDirector().io.violationConfig.commandBlockBreak.deop)
.cancel(true)
@@ -60,7 +68,7 @@ public class CommandMinecartBreak extends AbstractViolation {
runActions(
Sentinel.getInstance().getDirector().io.lang.violations.protections.rootName.rootNameFormatPlayer.formatted(p.getName(), Sentinel.getInstance().getDirector().io.lang.violations.protections.rootName.brake, Sentinel.getInstance().getDirector().io.lang.violations.protections.rootName.commandMinecart),
Sentinel.getInstance().getDirector().io.lang.violations.protections.rootName.rootNameFormatPlayer.formatted(p.getName(), Sentinel.getInstance().getDirector().io.lang.violations.protections.rootName.brake, Sentinel.getInstance().getDirector().io.lang.violations.protections.rootName.commandMinecart),
generateMinecartInfo(s),
generateMinecartInfo(cm),
config
);
}

View File

@@ -0,0 +1,172 @@
package me.trouper.sentinel.server.events.violations.entities;
import com.github.retrooper.packetevents.event.PacketListener;
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
import com.github.retrooper.packetevents.protocol.player.User;
import com.github.retrooper.packetevents.util.Vector3i;
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientUpdateCommandBlock;
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientUpdateCommandBlockMinecart;
import io.github.itzispyder.pdk.plugin.gui.CustomGui;
import me.trouper.sentinel.Sentinel;
import me.trouper.sentinel.data.types.CommandBlockHolder;
import me.trouper.sentinel.server.events.violations.AbstractViolation;
import me.trouper.sentinel.server.functions.helpers.ActionConfiguration;
import me.trouper.sentinel.server.gui.Items;
import me.trouper.sentinel.server.gui.MainGUI;
import me.trouper.sentinel.server.gui.config.AntiNukeGUI;
import me.trouper.sentinel.utils.PlayerUtils;
import me.trouper.sentinel.utils.ServerUtils;
import me.trouper.sentinel.utils.Text;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.CommandBlock;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.entity.minecart.CommandMinecart;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import java.util.List;
import java.util.UUID;
public class CommandMinecartEdit extends AbstractViolation implements PacketListener {
@Override
public void onPacketReceive(PacketReceiveEvent event) {
if (event.getPacketType() != PacketType.Play.Client.UPDATE_COMMAND_BLOCK_MINECART) return;
ServerUtils.verbose("Packet is a command block update packet");
WrapperPlayClientUpdateCommandBlockMinecart wrapper = new WrapperPlayClientUpdateCommandBlockMinecart(event);
User user = event.getUser();
Player p = Bukkit.getPlayer(user.getUUID());
if (p == null) return;
if (!(getEntityById(p.getWorld(),wrapper.getEntityId()) instanceof CommandMinecart cart)) {
ServerUtils.verbose("Packet is a canceled due to bad entity UUID");
event.setCancelled(true);
return;
}
CommandBlockHolder holder = Sentinel.getInstance().getDirector().whitelistManager.getFromList(cart.getUniqueId());
if (PlayerUtils.isTrusted(p)) {
if (Sentinel.getInstance().getDirector().whitelistManager.autoWhitelist.contains(p.getUniqueId())) holder.setWhitelisted(true);
holder.update(p,wrapper);
return;
}
if (!Sentinel.getInstance().getDirector().io.violationConfig.commandBlockMinecartEdit.enabled) {
holder.update(p,wrapper);
return;
}
ServerUtils.verbose("Enabled, performing action");
event.setCancelled(true);
ActionConfiguration.Builder config = new ActionConfiguration.Builder()
.setPlayer(p)
.deop(Sentinel.getInstance().getDirector().io.violationConfig.commandBlockMinecartEdit.deop)
.punish(Sentinel.getInstance().getDirector().io.violationConfig.commandBlockMinecartEdit.punish)
.setPunishmentCommands(Sentinel.getInstance().getDirector().io.violationConfig.commandBlockMinecartEdit.punishmentCommands)
.logToDiscord(Sentinel.getInstance().getDirector().io.violationConfig.commandBlockMinecartEdit.logToDiscord);
runActions(
Sentinel.getInstance().getDirector().io.lang.violations.protections.rootName.rootNameFormatPlayer.formatted(p.getName(), Sentinel.getInstance().getDirector().io.lang.violations.protections.rootName.edit, Sentinel.getInstance().getDirector().io.lang.violations.protections.rootName.commandBlock),
Sentinel.getInstance().getDirector().io.lang.violations.protections.rootName.rootNameFormatPlayer.formatted(p.getName(), Sentinel.getInstance().getDirector().io.lang.violations.protections.rootName.edit, Sentinel.getInstance().getDirector().io.lang.violations.protections.rootName.commandBlock),
generateMinecartInfo(cart),
config
);
}
private Entity getEntityById(World world, int entityId) {
for (Entity entity : world.getEntities()) {
if (entity.getEntityId() == entityId) {
return entity;
}
}
return null; // Entity with the given ID not found
}
@Override
public CustomGui getConfigGui() {
return CustomGui.create()
.title(Text.color("&6&lSentinel &8»&0 Command Block Edit"))
.size(27)
.onDefine(this::getMainPage)
.defineMain(this::onClick)
.define(26, Items.BACK, e->{
e.getWhoClicked().openInventory(new AntiNukeGUI().home.getInventory());
})
.build();
}
@Override
public void getMainPage(Inventory inv) {
for (int i = 0; i < inv.getSize(); i++) {
inv.setItem(i,Items.BLANK);
}
ItemStack ring = Items.RED;
if (Sentinel.getInstance().getDirector().io.violationConfig.commandBlockMinecartEdit.enabled) {
ring = Items.GREEN;
}
List<Integer> ringList = List.of(3,4,5,12,14,21,22,23);
for (Integer i : ringList) {
inv.setItem(i,ring);
}
inv.setItem(26,Items.BACK);
inv.setItem(13,Items.booleanItem(Sentinel.getInstance().getDirector().io.violationConfig.commandBlockMinecartEdit.enabled,Items.configItem("Check Toggle", Material.CLOCK,"Enable/Disable this check entirely")));
inv.setItem(2,Items.booleanItem(Sentinel.getInstance().getDirector().io.violationConfig.commandBlockMinecartEdit.deop,Items.configItem("De-Op",Material.END_CRYSTAL,"Remove the user's operator privileges")));
inv.setItem(20,Items.booleanItem(Sentinel.getInstance().getDirector().io.violationConfig.commandBlockMinecartEdit.logToDiscord,Items.configItem("Log",Material.OAK_LOG,"If this check will produce a log to discord")));
inv.setItem(6,Items.booleanItem(Sentinel.getInstance().getDirector().io.violationConfig.commandBlockMinecartEdit.punish,Items.configItem("Punish",Material.REDSTONE_TORCH,"Run the punishment commands")));
inv.setItem(24,Items.stringListItem(Sentinel.getInstance().getDirector().io.violationConfig.commandBlockMinecartEdit.punishmentCommands,Material.DIAMOND_AXE,"Punishment Commands","Commands that will be ran \nif this check is flagged."));
}
@Override
public void onClick(InventoryClickEvent e) {
e.setCancelled(true);
if (!MainGUI.verify((Player) e.getWhoClicked())) return;
switch (e.getSlot()) {
case 13 -> {
Sentinel.getInstance().getDirector().io.violationConfig.commandBlockMinecartEdit.enabled = !Sentinel.getInstance().getDirector().io.violationConfig.commandBlockMinecartEdit.enabled;
getMainPage(e.getInventory());
Sentinel.getInstance().getDirector().io.violationConfig.save();
}
case 2 -> {
Sentinel.getInstance().getDirector().io.violationConfig.commandBlockMinecartEdit.deop = !Sentinel.getInstance().getDirector().io.violationConfig.commandBlockMinecartEdit.deop;
getMainPage(e.getInventory());
Sentinel.getInstance().getDirector().io.violationConfig.save();
}
case 20 -> {
Sentinel.getInstance().getDirector().io.violationConfig.commandBlockMinecartEdit.logToDiscord = !Sentinel.getInstance().getDirector().io.violationConfig.commandBlockMinecartEdit.logToDiscord;
getMainPage(e.getInventory());
Sentinel.getInstance().getDirector().io.violationConfig.save();
}
case 6 -> {
Sentinel.getInstance().getDirector().io.violationConfig.commandBlockMinecartEdit.punish = !Sentinel.getInstance().getDirector().io.violationConfig.commandBlockMinecartEdit.punish;
getMainPage(e.getInventory());
Sentinel.getInstance().getDirector().io.violationConfig.save();
}
case 24 -> {
if (e.isLeftClick()) {
queuePlayer((Player) e.getWhoClicked(), (cfg, args) -> {
cfg.commandBlockMinecartEdit.punishmentCommands.add(args.getAll().toString());
},"" + Sentinel.getInstance().getDirector().io.violationConfig.commandBlockMinecartEdit.punishmentCommands);
return;
}
Sentinel.getInstance().getDirector().io.violationConfig.commandBlockMinecartEdit.punishmentCommands.clear();
getMainPage(e.getInventory());
Sentinel.getInstance().getDirector().io.violationConfig.save();
}
}
}
}

View File

@@ -2,6 +2,7 @@ package me.trouper.sentinel.server.events.violations.entities;
import io.github.itzispyder.pdk.plugin.gui.CustomGui;
import me.trouper.sentinel.Sentinel;
import me.trouper.sentinel.data.types.CommandBlockHolder;
import me.trouper.sentinel.server.events.violations.AbstractViolation;
import me.trouper.sentinel.server.functions.helpers.ActionConfiguration;
import me.trouper.sentinel.server.gui.Items;
@@ -51,7 +52,7 @@ public class CommandMinecartPlace extends AbstractViolation {
@EventHandler
private void onVehicleCreate(VehicleCreateEvent e) {
//ServerUtils.verbose("Vehicle Creation Event");
if (!(e.getVehicle() instanceof CommandMinecart commandMinecart)) return;
if (!(e.getVehicle() instanceof CommandMinecart cm)) return;
if (queuedInteractions.isEmpty()) {
ServerUtils.verbose("Queue is empty, preventing");
e.setCancelled(true);
@@ -69,14 +70,17 @@ public class CommandMinecartPlace extends AbstractViolation {
e.setCancelled(true);
return;
}
CommandBlockHolder holder = Sentinel.getInstance().getDirector().whitelistManager.generateHolder(p.getUniqueId(),cm);
if (PlayerUtils.isTrusted(p)) {
ServerUtils.verbose("Player is trusted, allowing.");
Sentinel.getInstance().getDirector().whitelistManager.generateHolder(p.getUniqueId(),commandMinecart)
.addToExisting();
if (!Sentinel.getInstance().getDirector().whitelistManager.autoWhitelist.contains(p.getUniqueId())) holder.addAndWhitelist();
holder.add();
return;
}
if (!Sentinel.getInstance().getDirector().io.violationConfig.commandBlockMinecartPlace.enabled) {
holder.add();
return;
}
ActionConfiguration.Builder config = new ActionConfiguration.Builder()
.setEvent(e)
@@ -93,7 +97,7 @@ public class CommandMinecartPlace extends AbstractViolation {
runActions(
Sentinel.getInstance().getDirector().io.lang.violations.protections.rootName.rootNameFormatPlayer.formatted(p.getName(), Sentinel.getInstance().getDirector().io.lang.violations.protections.rootName.place, Sentinel.getInstance().getDirector().io.lang.violations.protections.rootName.commandMinecart),
Sentinel.getInstance().getDirector().io.lang.violations.protections.rootName.rootNameFormatPlayer.formatted(p.getName(), Sentinel.getInstance().getDirector().io.lang.violations.protections.rootName.place, Sentinel.getInstance().getDirector().io.lang.violations.protections.rootName.commandMinecart),
generateMinecartInfo(commandMinecart),
generateMinecartInfo(cm),
config
);
}
@@ -101,7 +105,6 @@ public class CommandMinecartPlace extends AbstractViolation {
@EventHandler
private void onIneteract(PlayerInteractEvent e) {
//ServerUtils.verbose("Player Interaction Event");
if (!Sentinel.getInstance().getDirector().io.violationConfig.commandBlockMinecartPlace.enabled) return;
//ServerUtils.verbose("MinecartCommandPlace: Check is enabled");
Player p = e.getPlayer();
if (e.getItem() == null) return;

View File

@@ -2,6 +2,7 @@ package me.trouper.sentinel.server.events.violations.entities;
import io.github.itzispyder.pdk.plugin.gui.CustomGui;
import me.trouper.sentinel.Sentinel;
import me.trouper.sentinel.data.types.CommandBlockHolder;
import me.trouper.sentinel.server.events.violations.AbstractViolation;
import me.trouper.sentinel.server.functions.helpers.ActionConfiguration;
import me.trouper.sentinel.server.gui.Items;
@@ -11,6 +12,7 @@ import me.trouper.sentinel.utils.PlayerUtils;
import me.trouper.sentinel.utils.ServerUtils;
import me.trouper.sentinel.utils.Text;
import org.bukkit.Material;
import org.bukkit.block.CommandBlock;
import org.bukkit.entity.Player;
import org.bukkit.entity.minecart.CommandMinecart;
import org.bukkit.event.EventHandler;
@@ -25,19 +27,27 @@ public class CommandMinecartUse extends AbstractViolation {
@EventHandler
private void onCMDBlockMinecartUse(PlayerInteractEntityEvent e) {
//ServerUtils.verbose("MinecartCommandUse: Detected Interaction with entity");
if (!Sentinel.getInstance().getDirector().io.violationConfig.commandBlockMinecartUse.enabled) return;
//ServerUtils.verbose("MinecartCommandUse: Enabled");
Player p = e.getPlayer();
if (!(e.getRightClicked() instanceof CommandMinecart s)) return;
if (!(e.getRightClicked() instanceof CommandMinecart cm)) return;
ServerUtils.verbose("MinecartCommandUse: Entity is minecart command");
if (PlayerUtils.isTrusted(p)) return;
ServerUtils.verbose("MinecartCommandUse: Not trusted, performing action");
CommandBlockHolder holder = Sentinel.getInstance().getDirector().whitelistManager.getFromList(cm.getUniqueId());
if (PlayerUtils.isTrusted(p)) {
if (Sentinel.getInstance().getDirector().whitelistManager.autoWhitelist.contains(p.getUniqueId())) holder.setWhitelisted(true);
holder.update(p);
e.setCancelled(true);
return;
}
if (!Sentinel.getInstance().getDirector().io.violationConfig.commandBlockUse.enabled) {
holder.update(p);
return;
}
ActionConfiguration.Builder config = new ActionConfiguration.Builder()
.setEvent(e)
.setPlayer(p)
.setEntity(s)
.setEntity(cm)
.cancel(true)
.punish(Sentinel.getInstance().getDirector().io.violationConfig.commandBlockMinecartUse.punish)
.deop(Sentinel.getInstance().getDirector().io.violationConfig.commandBlockMinecartUse.deop)
@@ -47,7 +57,7 @@ public class CommandMinecartUse extends AbstractViolation {
runActions(
Sentinel.getInstance().getDirector().io.lang.violations.protections.rootName.rootNameFormatPlayer.formatted(p.getName(), Sentinel.getInstance().getDirector().io.lang.violations.protections.rootName.use, Sentinel.getInstance().getDirector().io.lang.violations.protections.rootName.commandMinecart),
Sentinel.getInstance().getDirector().io.lang.violations.protections.rootName.rootNameFormatPlayer.formatted(p.getName(), Sentinel.getInstance().getDirector().io.lang.violations.protections.rootName.use, Sentinel.getInstance().getDirector().io.lang.violations.protections.rootName.commandMinecart),
generateMinecartInfo(s),
generateMinecartInfo(cm),
config
);
}

View File

@@ -1,9 +1,6 @@
package me.trouper.sentinel.server.events.violations.players;
import com.github.retrooper.packetevents.event.PacketListenerAbstract;
import com.github.retrooper.packetevents.event.PacketListenerPriority;
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
import com.github.retrooper.packetevents.event.PacketSendEvent;
import com.github.retrooper.packetevents.event.*;
import com.github.retrooper.packetevents.protocol.chat.Node;
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientTabComplete;
@@ -19,14 +16,10 @@ import java.util.List;
import java.util.Optional;
import java.util.UUID;
public class PluginCloakingPacket extends PacketListenerAbstract {
public class PluginCloakingPacket implements PacketListener {
public static final List<UUID> tabReplaceQueue = new ArrayList<>();
public PluginCloakingPacket() {
super(PacketListenerPriority.NORMAL);
}
@Override
public void onPacketReceive(PacketReceiveEvent event) {
if (!Sentinel.getInstance().getDirector().io.mainConfig.plugin.pluginHider) return;

View File

@@ -2,11 +2,13 @@ package me.trouper.sentinel.server.events.violations.whitelist;
import io.github.itzispyder.pdk.plugin.gui.CustomGui;
import me.trouper.sentinel.Sentinel;
import me.trouper.sentinel.data.types.CommandBlockHolder;
import me.trouper.sentinel.server.events.violations.AbstractViolation;
import me.trouper.sentinel.server.functions.helpers.ActionConfiguration;
import me.trouper.sentinel.server.gui.Items;
import me.trouper.sentinel.server.gui.MainGUI;
import me.trouper.sentinel.server.gui.config.AntiNukeGUI;
import me.trouper.sentinel.utils.PlayerUtils;
import me.trouper.sentinel.utils.ServerUtils;
import me.trouper.sentinel.utils.Text;
import org.bukkit.Material;
@@ -20,6 +22,8 @@ import org.bukkit.event.server.ServerCommandEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import java.util.UUID;
public class CommandBlockExecute extends AbstractViolation {
@EventHandler
@@ -32,6 +36,7 @@ public class CommandBlockExecute extends AbstractViolation {
Block block = s.getBlock();
CommandBlock cb = (CommandBlock) block.getState();
CommandBlockHolder holder = Sentinel.getInstance().getDirector().whitelistManager.getFromList(cb.getLocation());
String label = cb.getCommand();
ServerUtils.verbose("Command block is set to %s.".formatted(label));
@@ -39,9 +44,6 @@ public class CommandBlockExecute extends AbstractViolation {
if (label.startsWith("/")) label = label.substring(1);
ServerUtils.verbose("It's label is %s.".formatted(label));
boolean isRestricted = Sentinel.getInstance().getDirector().io.violationConfig.commandBlockWhitelist.disabledCommands.contains(label);
boolean canRun = Sentinel.getInstance().getDirector().whitelistManager.isWhitelisted(cb);
ActionConfiguration.Builder config = new ActionConfiguration.Builder()
.setEvent(e)
.setBlock(block)
@@ -50,7 +52,7 @@ public class CommandBlockExecute extends AbstractViolation {
.restoreBlock(Sentinel.getInstance().getDirector().io.violationConfig.commandBlockWhitelist.attemptRestore)
.logToDiscord(Sentinel.getInstance().getDirector().io.violationConfig.commandBlockWhitelist.logToDiscord);
if (isRestricted) {
if (Sentinel.getInstance().getDirector().io.violationConfig.commandBlockWhitelist.disabledCommands.contains(label)) {
ServerUtils.verbose("Command block is using a restricted command.");
runActions(
@@ -59,8 +61,8 @@ public class CommandBlockExecute extends AbstractViolation {
generateCommandBlockInfo(cb),
config
);
} else if (!canRun) {
ServerUtils.verbose("Command block can't run.");
} else if (holder == null || !holder.isWhitelisted() || !holder.present()|| !PlayerUtils.isTrusted(UUID.fromString(holder.owner()))) {
ServerUtils.verbose("Command block can't run. Not whitelisted and/or trusted.");
runActions(
Sentinel.getInstance().getDirector().io.lang.violations.protections.rootName.rootNameFormat.formatted(Sentinel.getInstance().getDirector().io.lang.violations.protections.rootName.commandBlockWhitelist),

View File

@@ -2,8 +2,10 @@ package me.trouper.sentinel.server.events.violations.whitelist;
import io.github.itzispyder.pdk.plugin.gui.CustomGui;
import me.trouper.sentinel.Sentinel;
import me.trouper.sentinel.data.types.CommandBlockHolder;
import me.trouper.sentinel.server.events.violations.AbstractViolation;
import me.trouper.sentinel.server.functions.helpers.ActionConfiguration;
import me.trouper.sentinel.utils.PlayerUtils;
import me.trouper.sentinel.utils.ServerUtils;
import org.bukkit.entity.minecart.CommandMinecart;
import org.bukkit.event.EventHandler;
@@ -11,6 +13,8 @@ import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.server.ServerCommandEvent;
import org.bukkit.inventory.Inventory;
import java.util.UUID;
public class CommandMinecartExecute extends AbstractViolation {
@EventHandler
@@ -19,8 +23,7 @@ public class CommandMinecartExecute extends AbstractViolation {
if (!Sentinel.getInstance().getDirector().io.violationConfig.commandBlockWhitelist.enabled) return;
//ServerUtils.verbose("Whitelist not disabled");
if (!(e.getSender() instanceof CommandMinecart s)) return;
//ServerUtils.verbose("Sender is command block");
CommandBlockHolder holder = Sentinel.getInstance().getDirector().whitelistManager.getFromList(s.getUniqueId());
String label = s.getCommand();
ServerUtils.verbose("Command block is set to %s.".formatted(label));
@@ -28,9 +31,6 @@ public class CommandMinecartExecute extends AbstractViolation {
if (label.startsWith("/")) label = label.substring(1);
ServerUtils.verbose("It's label is %s.".formatted(label));
boolean isRestricted = Sentinel.getInstance().getDirector().io.violationConfig.commandBlockWhitelist.disabledCommands.contains(label);
boolean canRun = Sentinel.getInstance().getDirector().whitelistManager.isWhitelisted(s);
ActionConfiguration.Builder config = new ActionConfiguration.Builder()
.setEvent(e)
.setEntity(s)
@@ -38,7 +38,7 @@ public class CommandMinecartExecute extends AbstractViolation {
.removeEntity(Sentinel.getInstance().getDirector().io.violationConfig.commandBlockWhitelist.destroyCart)
.logToDiscord(Sentinel.getInstance().getDirector().io.violationConfig.commandBlockWhitelist.logToDiscord);
if (isRestricted) {
if (Sentinel.getInstance().getDirector().io.violationConfig.commandBlockWhitelist.disabledCommands.contains(label)) {
ServerUtils.verbose("Command cart is using a restricted command.");
runActions(
@@ -47,11 +47,8 @@ public class CommandMinecartExecute extends AbstractViolation {
generateMinecartInfo(s),
config
);
return;
}
if (!canRun) {
ServerUtils.verbose("Command cart can't run.");
} else if (holder == null || !holder.isWhitelisted() || !holder.present() || !PlayerUtils.isTrusted(UUID.fromString(holder.owner()))) {
ServerUtils.verbose("Command cart can't run. Block is not whitelisted, and/or not trusted.");
runActions(
Sentinel.getInstance().getDirector().io.lang.violations.protections.rootName.rootNameFormat.formatted(Sentinel.getInstance().getDirector().io.lang.violations.protections.rootName.commandBlockWhitelist),

View File

@@ -1,6 +1,8 @@
package me.trouper.sentinel.server.functions.helpers;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import me.trouper.sentinel.Sentinel;
import me.trouper.sentinel.data.types.CommandBlockHolder;
import me.trouper.sentinel.data.types.SerialLocation;
import me.trouper.sentinel.utils.ServerUtils;
import me.trouper.sentinel.utils.trees.Node;
@@ -226,7 +228,8 @@ public class ActionConfiguration {
actions.add(config -> {
config.restoreBlock = restoreBlock;
if (config.block != null) {
if (Sentinel.getInstance().getDirector().whitelistManager.getFromWhitelist(config.block.getLocation()) != null && Sentinel.getInstance().getDirector().whitelistManager.getFromWhitelist(config.block.getLocation()).restore()) {
CommandBlockHolder holder = Sentinel.getInstance().getDirector().whitelistManager.getFromList(config.block.getLocation());
if (holder != null && holder.restore()) {
config.actionNode.addTextLine(Sentinel.getInstance().getDirector().io.lang.violations.protections.actionNode.restore);
} else {
config.actionNode.addTextLine(Sentinel.getInstance().getDirector().io.lang.violations.protections.actionNode.restoreFailed);

View File

@@ -5,7 +5,6 @@ import me.trouper.sentinel.data.types.SerialLocation;
import me.trouper.sentinel.data.types.CommandBlockHolder;
import me.trouper.sentinel.server.events.admin.WandEvents;
import me.trouper.sentinel.data.types.Selection;
import me.trouper.sentinel.utils.PlayerUtils;
import me.trouper.sentinel.utils.ServerUtils;
import me.trouper.sentinel.utils.Text;
import org.bukkit.Location;
@@ -57,7 +56,7 @@ public class CBWhitelistManager {
AtomicInteger number = new AtomicInteger();
selection.forEachBlock(block -> {
if (block.getType().equals(Material.COMMAND_BLOCK) || block.getType().equals(Material.REPEATING_COMMAND_BLOCK) || block.getType().equals(Material.CHAIN_COMMAND_BLOCK)) {
generateHolder(player.getUniqueId(),(CommandBlock) block.getState()).removeFromWhitelist();
getFromList(block.getLocation()).setWhitelisted(false);
number.getAndIncrement();
}
});
@@ -74,7 +73,7 @@ public class CBWhitelistManager {
AtomicInteger number = new AtomicInteger();
selection.forEachBlock(block -> {
if (block.getType().equals(Material.COMMAND_BLOCK) || block.getType().equals(Material.REPEATING_COMMAND_BLOCK) || block.getType().equals(Material.CHAIN_COMMAND_BLOCK)) {
generateHolder(player.getUniqueId(),(CommandBlock) block.getState()).destroy();
getFromList(block.getLocation()).delete();
number.getAndIncrement();
}
});
@@ -92,8 +91,7 @@ public class CBWhitelistManager {
AtomicInteger number = new AtomicInteger();
selection.forEachBlock(block -> {
if (ServerUtils.isCommandBlock(block)) {
CommandBlock cb = (CommandBlock) block.getState();
generateHolder(player.getUniqueId(),cb).addToWhitelist();
getFromList(block.getLocation()).addAndWhitelist();
number.getAndIncrement();
}
});
@@ -104,10 +102,11 @@ public class CBWhitelistManager {
public int clearAll() {
int total = 0;
for (CommandBlockHolder cb : Sentinel.getInstance().getDirector().io.commandBlocks.holders) {
cb.removeFromWhitelist();
cb.destroy();
cb.delete();
total++;
if (cb.loc().isUUID()) continue;
if (cb.isCart()) continue;
Location remove = SerialLocation.translate(cb.loc());
remove.getBlock().setType(Material.AIR);
}
@@ -118,10 +117,11 @@ public class CBWhitelistManager {
int total = 0;
for (CommandBlockHolder cb : Sentinel.getInstance().getDirector().io.commandBlocks.holders) {
if (!cb.owner().equals(who.toString())) continue;
cb.removeFromWhitelist();
cb.destroy();
cb.delete();
total++;
if (cb.loc().isUUID()) continue;
if (cb.isCart()) continue;
Location remove = SerialLocation.translate(cb.loc());
remove.getBlock().setType(Material.AIR);
}
@@ -163,4 +163,32 @@ public class CBWhitelistManager {
public boolean isConditional(CommandBlock cb) {
return cb.getBlock().getBlockData() instanceof org.bukkit.block.data.type.CommandBlock cbs && cbs.isConditional();
}
public CommandBlockHolder getFromList(UUID entityUUID) {
for (CommandBlockHolder existing : Sentinel.getInstance().getDirector().io.commandBlocks.holders) {
if (existing.loc().isUUID() && existing.loc().toUIID().equals(entityUUID)) {
return existing;
}
}
return null;
}
public CommandBlockHolder getFromList(Location loc) {
for (CommandBlockHolder existing : Sentinel.getInstance().getDirector().io.commandBlocks.holders) {
if (existing.loc().isSameLocation(loc)) {
return existing;
}
}
return null;
}
public CommandBlockHolder getFromList(SerialLocation loc) {
for (CommandBlockHolder existing : Sentinel.getInstance().getDirector().io.commandBlocks.holders) {
if (existing.loc().isSameLocation(loc)) {
return existing;
}
}
return null;
}
}

View File

@@ -104,7 +104,7 @@ public class WhitelistGUI {
//ServerUtils.verbose("Type material is %s", type.name());
String name = holder.loc().isUUID() ?
String name = holder.isCart() ?
"Minecart: " + holder.loc().toUIID() :
String.format("X: %d, Y: %d, Z: %d",
(int) holder.loc().x(),
@@ -122,7 +122,7 @@ public class WhitelistGUI {
//ServerUtils.verbose("Got type");
lore.add(Text.color("&7Whitelisted: " + (holder.isWhitelisted() ? "&aYes" : "&cNo")));
//ServerUtils.verbose("Got whitelist status");
lore.add(Text.color("&7Present: " + (holder.isPresent() ? "&aYes" : "&cNo")));
lore.add(Text.color("&7Present: " + (holder.present() ? "&aYes" : "&cNo")));
//ServerUtils.verbose("Got Present Status");
lore.add("");
lore.add(Text.color("&eClick to manage!"));
@@ -146,8 +146,7 @@ public class WhitelistGUI {
.defineMain(e -> e.setCancelled(true))
.define(0,createDisplayItem(holder))
.define(2, createActionItem(whitelisted ? "Un-Whitelist" : "Whitelist", whitelisted ? Material.BARRIER : Material.PAPER), e -> {
if (whitelisted) holder.removeFromWhitelist();
else holder.addToWhitelist();
holder.setWhitelisted(!whitelisted);
player.playSound(player.getLocation(),Sound.BLOCK_NOTE_BLOCK_PLING,1,1F);
openManagementMenu(player,holder);
})
@@ -183,18 +182,7 @@ public class WhitelistGUI {
player.openInventory(createGUI(player).getInventory());
})
.define(6,createActionItem("Take Ownership",Material.NAME_TAG), e -> {
CommandBlockHolder updated = new CommandBlockHolder(
player.getUniqueId().toString(),
holder.loc(),
holder.facing(),
holder.type(),
holder.auto(),
holder.conditional(),
holder.command()
);
holder.destroy();
if (whitelisted) updated.addToWhitelist();
updated.restore();
holder.setOwner(player.getUniqueId().toString());
player.playSound(player.getLocation(),Sound.ENTITY_VILLAGER_TRADE,1,1F);
openManagementMenu(player,holder);
})
@@ -241,7 +229,7 @@ public class WhitelistGUI {
private List<CommandBlockHolder> filterEntries(Player player, FilterOperator operator) {
Set<Filter> filters = activeFilters.computeIfAbsent(player.getUniqueId(), v -> new HashSet<>());
ServerUtils.verbose("Filtering entries for %s. Current: ", player,filters.toString());
return Sentinel.getInstance().getDirector().io.commandBlocks.existing.stream()
return Sentinel.getInstance().getDirector().io.commandBlocks.holders.stream()
.filter(holder -> {
if (filters.isEmpty()) return true;
@@ -258,7 +246,7 @@ public class WhitelistGUI {
case IMPULSE -> holder.getType().equals(Material.COMMAND_BLOCK);
case WHITELISTED -> holder.isWhitelisted();
case NOT_WHITELISTED -> !holder.isWhitelisted();
case NOT_PRESENT -> !holder.isPresent();
case NOT_PRESENT -> !holder.present();
};
result = operator.apply(result, conditionMet);

View File

@@ -19,9 +19,6 @@ import java.util.Map;
public final class Auth {
public String authorize(String license, String identifier) {
if (true) {
return "AUTHORIZED";
}
Map<String, List<String>> licenses = getLicenseList();
if (licenses == null) return "ERROR";

View File

@@ -1,5 +1,7 @@
package me.trouper.sentinel.startup.drm;
import com.github.retrooper.packetevents.PacketEvents;
import com.github.retrooper.packetevents.event.PacketListenerPriority;
import io.github.itzispyder.pdk.utils.SchedulerUtils;
import me.trouper.sentinel.Sentinel;
import me.trouper.sentinel.data.config.MainConfig;
@@ -38,7 +40,6 @@ public final class Loader {
&7Your License Key is &a%s&7.
&7Your server ID is &6%s&7.
&7You are &6%s&7.
&fIf you have just &apurchased&f the plugin:
&8- &7Join the &b&ndiscord&r&7 and open a ticket.
@@ -55,7 +56,7 @@ public final class Loader {
&fWoah! You read quite far!
&8- &7Want the plugin for cheaper, &nor even for free&r&7?
&8- &7DM &b@obvwolf&7 on discord and lets make a deal!
""".formatted(Sentinel.getInstance().license,Sentinel.getInstance().identifier, MainConfig.username));
""".formatted(Sentinel.getInstance().license,Sentinel.getInstance().identifier));
public boolean load(String license, String identifier, boolean coldStart) {
Sentinel.getInstance().getLogger().info("\n]====---- Requesting Authentication ----====[ \n- License Key: %s\n- Server ID: %s\n".formatted(license,identifier));
@@ -145,9 +146,13 @@ public final class Loader {
new CallbackCommand().register();
new ExtraCommand().register();
// Packets
PacketEvents.getAPI().getEventManager().registerListener(new PluginCloakingPacket(), PacketListenerPriority.NORMAL);
PacketEvents.getAPI().getEventManager().registerListener(new ShadowRealmEvents(), PacketListenerPriority.HIGHEST);
PacketEvents.getAPI().getEventManager().registerListener(new CommandBlockEdit(), PacketListenerPriority.NORMAL);
// Events
new AntiBanEvents().register();
new CommandBlockEdit().register();
new CommandBlockExecute().register();
new CommandMinecartPlace().register();
new CommandMinecartUse().register();

View File

@@ -37,6 +37,38 @@ public final class ServerUtils {
},1);
}
public static void verbose(int backtrace, String message, Object... args) {
if (!Sentinel.getInstance().getDirector().io.mainConfig.debugMode) return;
String callerInfo = "Unknown Caller";
// Capture the stack trace to determine the caller
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
if (stackTrace.length > 2 + backtrace) { // Ensure we have enough depth
StackTraceElement caller = stackTrace[2 + backtrace]; // The method that called `verbose()`
String className = caller.getClassName();
className = className.substring(className.lastIndexOf(".") + 1);
if (className.contains("-")) {
callerInfo = "Protected";
} else {
callerInfo = className + "." + caller.getMethodName();
}
}
String formattedMessage = message.formatted(args);
String log = "[Sentinel] [DEBUG ^ %s] [%s]: %s".formatted(backtrace, callerInfo, formattedMessage);
Sentinel.getInstance().getLogger().info(log);
for (Player trustedPlayer : Bukkit.getOnlinePlayers()) {
if (PlayerUtils.isTrusted(trustedPlayer)) {
trustedPlayer.sendMessage("§d§lSentinel §7[§bDEBUG§7] §7[§e%s§7] §8» §7%s"
.formatted(callerInfo, formattedMessage));
}
}
}
public static void verbose(String message, Object... args) {
if (!Sentinel.getInstance().getDirector().io.mainConfig.debugMode) return;
String callerInfo = "Unknown Caller";