Intercepting message "Respawn point set" with packets
devspexx opened this issue ยท 3 comments
Make sure you're doing the following
- You're using the latest build for your server version
- This isn't an issue caused by another plugin
- You've checked for duplicate issues
- You didn't use
/reload
Describe the question
Question regarding "Respawn point set" message in the game chat when a player interacts with bed - when their bed spawn location updates. Can you modify or remove that message in the chat along with the action bar message? Can either of those be customized or removed or cancelled via packets?
API method(s) used
I've used an override method onPacketSending with a PacketEvent parameter.
In there I am checking for packet type like so: PacketType.Play.Server.
The part is where the enum goes and I've tried even some deprecated ones such as BED, USE_BED, ANIMATION, GAME_STATE_CHANGE, CHAT - for which I figured that is for players who send a message to the game chat.
This is the only thing I've tried so far because I can't think of another.
I've tried messing around with the PlayerInteractEvent but that didn't give me an expected result.
I'm looking for a little help and tips in which direction I should be going instead, with the code.
I'm using Minecraft Spigot 1.19.2.
Expected behavior
I'm expecting to be able to modify/remove the message in the game chat and action bar.
Code
This is an example code of how I'm handling packet intercepting
public class PacketInterceptor extends PacketAdapter {
public PacketInterceptor(Main main) {
super(main, ListenerPriority.NORMAL, PacketType.Play.Server.BED);
}
@Override
public void onPacketSending(PacketEvent event) {
event.setCancelled(true);
}
}
I've managed to "hide" the default action bar messages like so:
@EventHandler
public void onPlayerInteract(org.bukkit.event.player.PlayerInteractEvent event) {
// check for action type
Player player = event.getPlayer();
if (event.getAction() != Action.RIGHT_CLICK_BLOCK)
return;
// check for block type
Block block = event.getClickedBlock();
Material blockMaterial = block.getType();
if (!blockMaterial.name().contains("_BED"))
return;
// check for time
if (player.getWorld().getTime() < 13000 || player.getWorld().getTime() > 23000) {
event.setCancelled(true);
return;
}
// enter the player in bed
player.setSleepingIgnored(true);
player.teleport(block.getLocation());
player.setBedSpawnLocation(block.getLocation()); // removing this function doesn't remove the message either
}
Additional context
I'd really appreciate any help here! Thank you.
I've found out that the message "Respawn point set" only sends to the chat if player interacts with the FOOT part of the bed block (1x2, foot and head).
So, that's one way of doing it, without the packets, for anyone who's looking for a quick solution..
@EventHandler
public void onPlayerInteract(org.bukkit.event.player.PlayerInteractEvent event) {
// check for action type
Player player = event.getPlayer();
if (event.getAction() != Action.RIGHT_CLICK_BLOCK)
return;
// check for block type
Block block = event.getClickedBlock();
Material blockMaterial = block.getType();
if (!blockMaterial.name().endsWith("_BED"))
return;
// check for block face
BlockData blockData = event.getClickedBlock().getBlockData();
Part bedPart = ((org.bukkit.block.data.type.Bed) blockData).getPart();
if (bedPart == Part.FOOT) {
event.setCancelled(true);
player.setBedSpawnLocation(block.getLocation()); // update the bed spawn location
return;
}
// check for time
if (player.getWorld().getTime() < 12800 || player.getWorld().getTime() > 23000) {
event.setCancelled(true);
return;
}
// enter the player in bed
player.setSleepingIgnored(true);
player.teleport(block.getLocation());
player.setBedSpawnLocation(block.getLocation());
}
Final code, looks like this (sharing this for anyone looking for an answer):
@EventHandler
public void onPlayerInteract(org.bukkit.event.player.PlayerInteractEvent event) {
// check for action type
Player player = event.getPlayer();
if (event.getAction() != Action.RIGHT_CLICK_BLOCK)
return;
// check for block type
Block block = event.getClickedBlock();
Material blockMaterial = block.getType();
if (!blockMaterial.name().endsWith("_BED"))
return;
// check for block face
BlockData blockData = event.getClickedBlock().getBlockData();
Part bedPart = ((org.bukkit.block.data.type.Bed) blockData).getPart();
if (bedPart == Part.FOOT) {
event.setCancelled(true);
return;
}
// check for world type, players can only sleep in the overworld world type
Environment environment = player.getWorld().getEnvironment();
if (environment != Environment.NORMAL) {
String message = main.config.getString("settings.bed-sleep-messages.not-possible-world");
player.spigot().sendMessage(ChatMessageType.ACTION_BAR,
TextComponent.fromLegacyText(main.helpers.colorize(message)));
event.setCancelled(true);
return;
}
// can't sleep during the day
long worldTime = player.getWorld().getTime();
if (worldTime < 13000 || worldTime > 23000) {
String message = main.config.getString("settings.bed-sleep-messages.not-possible-night");
if (message != "")
player.spigot().sendMessage(ChatMessageType.ACTION_BAR,
TextComponent.fromLegacyText(main.helpers.colorize(message)));
event.setCancelled(true);
return;
}
// distance too high between the player and the bed
double bedDistance = player.getLocation().distance(block.getLocation());
if (bedDistance > 2.5D) {
String message = main.config.getString("settings.bed-sleep-messages.not-possible-distance");
message = message.replace("{blocks}", new DecimalFormat("#.##").format(bedDistance).replace(",", "."));
if (message != "")
player.spigot().sendMessage(ChatMessageType.ACTION_BAR,
TextComponent.fromLegacyText(main.helpers.colorize(message)));
event.setCancelled(true);
return;
}
// check for nearby mobs
List<Entity> nearbyMobs = player.getWorld().getEntities().stream()
.filter(entity -> entity instanceof Mob && !(entity instanceof Player))
.filter(entity -> entity.getLocation().distance(block.getLocation()) <= 8)
.collect(Collectors.toList());
if (nearbyMobs.size() > 0) {
String message = main.config.getString("settings.bed-sleep-messages.not-safe");
message = message
.replace("{amount}", String.valueOf(nearbyMobs.size()))
.replace("{monster-s}", nearbyMobs.size() == 1 ? "monster" : "monsters");
if (message != "")
player.spigot().sendMessage(ChatMessageType.ACTION_BAR,
TextComponent.fromLegacyText(main.helpers.colorize(message)));
event.setCancelled(true);
return;
}
// enter the player in bed
String message = main.config.getString("settings.bed-sleep-messages.ok");
if (message != "")
player.spigot().sendMessage(ChatMessageType.ACTION_BAR,
TextComponent.fromLegacyText(main.helpers.colorize(message)));
player.setSleepingIgnored(true);
player.teleport(block.getLocation());
player.setBedSpawnLocation(block.getLocation());
}
@EventHandler
public void onPlayerBedEnter(org.bukkit.event.player.PlayerBedEnterEvent event) {
Player player = event.getPlayer();
// prevent the player from sliding down from bed
// spawning under/next to it due to Vector not being 0
player.setVelocity(new Vector(0, 0 , 0));
BedEnterResult result = event.getBedEnterResult();
// invalid world..
Environment environment = player.getWorld().getEnvironment();
if (environment != Environment.NORMAL) {
event.setUseBed(Result.DENY);
event.setCancelled(true);
return;
}
// player tried to sleep during the day
long worldTime = player.getWorld().getTime();
if (worldTime < 13000 || worldTime > 23000) {
event.setUseBed(Result.DENY);
event.setCancelled(true);
return;
}
// distance too high between the player and the bed
double bedDistance = player.getLocation().distance(event.getBed().getLocation());
if (bedDistance > 2.5D) {
event.setUseBed(Result.DENY);
event.setCancelled(true);
return;
}
// check for nearby mobs
List<Entity> nearbyMobs = player.getWorld().getEntities().stream()
.filter(entity -> entity instanceof Mob && !(entity instanceof Player))
.filter(entity -> entity.getLocation().distance(event.getBed().getLocation()) <= 8)
.collect(Collectors.toList());
if (nearbyMobs.size() > 0) {
event.setUseBed(Result.DENY);
event.setCancelled(true);
return;
}
}