mirror of
https://github.com/Minestom/Minestom.git
synced 2025-02-05 15:01:46 +01:00
Revamp of the packet sending code, added possibility to have listeners for outgoing packets
This commit is contained in:
parent
3c2c7acb0b
commit
c60f625c55
@ -31,7 +31,6 @@ import net.minestom.server.item.Material;
|
||||
import net.minestom.server.listener.manager.PacketListenerManager;
|
||||
import net.minestom.server.network.ConnectionManager;
|
||||
import net.minestom.server.network.PacketProcessor;
|
||||
import net.minestom.server.network.PacketWriterUtils;
|
||||
import net.minestom.server.network.netty.NettyServer;
|
||||
import net.minestom.server.network.packet.server.play.PluginMessagePacket;
|
||||
import net.minestom.server.network.packet.server.play.ServerDifficultyPacket;
|
||||
@ -49,6 +48,7 @@ import net.minestom.server.storage.StorageLocation;
|
||||
import net.minestom.server.storage.StorageManager;
|
||||
import net.minestom.server.timer.SchedulerManager;
|
||||
import net.minestom.server.utils.MathUtils;
|
||||
import net.minestom.server.utils.PacketUtils;
|
||||
import net.minestom.server.utils.thread.MinestomThread;
|
||||
import net.minestom.server.utils.validate.Check;
|
||||
import net.minestom.server.world.Difficulty;
|
||||
@ -242,8 +242,7 @@ public final class MinecraftServer {
|
||||
Check.notNull(brandName, "The brand name cannot be null");
|
||||
MinecraftServer.brandName = brandName;
|
||||
|
||||
PluginMessagePacket brandMessage = PluginMessagePacket.getBrandPacket();
|
||||
PacketWriterUtils.writeAndSend(connectionManager.getOnlinePlayers(), brandMessage);
|
||||
PacketUtils.sendGroupedPacket(connectionManager.getOnlinePlayers(), PluginMessagePacket.getBrandPacket());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -301,12 +300,11 @@ public final class MinecraftServer {
|
||||
Check.notNull(difficulty, "The server difficulty cannot be null.");
|
||||
MinecraftServer.difficulty = difficulty;
|
||||
|
||||
// The difficulty packet
|
||||
// Send the packet to all online players
|
||||
ServerDifficultyPacket serverDifficultyPacket = new ServerDifficultyPacket();
|
||||
serverDifficultyPacket.difficulty = difficulty;
|
||||
serverDifficultyPacket.locked = true; // Can only be modified on single-player
|
||||
// Send the packet to all online players
|
||||
PacketWriterUtils.writeAndSend(connectionManager.getOnlinePlayers(), serverDifficultyPacket);
|
||||
PacketUtils.sendGroupedPacket(connectionManager.getOnlinePlayers(), serverDifficultyPacket);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -468,14 +466,16 @@ public final class MinecraftServer {
|
||||
"The chunk view distance must be between 2 and 32");
|
||||
MinecraftServer.chunkViewDistance = chunkViewDistance;
|
||||
if (started) {
|
||||
UpdateViewDistancePacket updateViewDistancePacket = new UpdateViewDistancePacket();
|
||||
updateViewDistancePacket.viewDistance = chunkViewDistance;
|
||||
|
||||
final Collection<Player> players = connectionManager.getOnlinePlayers();
|
||||
|
||||
PacketWriterUtils.writeAndSend(players, updateViewDistancePacket);
|
||||
UpdateViewDistancePacket updateViewDistancePacket = new UpdateViewDistancePacket();
|
||||
updateViewDistancePacket.viewDistance = chunkViewDistance;
|
||||
|
||||
connectionManager.getOnlinePlayers().forEach(player -> {
|
||||
// Send packet to all online players
|
||||
PacketUtils.sendGroupedPacket(players, updateViewDistancePacket);
|
||||
|
||||
players.forEach(player -> {
|
||||
final Chunk playerChunk = player.getChunk();
|
||||
if (playerChunk != null) {
|
||||
player.refreshVisibleChunks(playerChunk);
|
||||
|
@ -71,10 +71,10 @@ public final class UpdateManager {
|
||||
final long tickTime = System.nanoTime() - currentTime;
|
||||
|
||||
// Tick end callbacks
|
||||
doTickCallback(tickEndCallbacks, tickTime / 1000000);
|
||||
doTickCallback(tickEndCallbacks, tickTime / 1000000L);
|
||||
|
||||
// Sleep until next tick
|
||||
final long sleepTime = Math.max(1, (tickDistance - tickTime) / 1000000);
|
||||
final long sleepTime = Math.max(1, (tickDistance - tickTime) / 1000000L);
|
||||
|
||||
try {
|
||||
Thread.sleep(sleepTime);
|
||||
|
@ -1,11 +1,10 @@
|
||||
package net.minestom.server;
|
||||
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.network.PacketWriterUtils;
|
||||
import net.minestom.server.network.packet.server.ServerPacket;
|
||||
import net.minestom.server.utils.PacketUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
@ -56,7 +55,7 @@ public interface Viewable {
|
||||
* @param packet the packet to send to all viewers
|
||||
*/
|
||||
default void sendPacketToViewers(@NotNull ServerPacket packet) {
|
||||
PacketWriterUtils.writeAndSend(getViewers(), packet);
|
||||
PacketUtils.sendGroupedPacket(getViewers(), packet);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -69,40 +68,22 @@ public interface Viewable {
|
||||
*/
|
||||
default void sendPacketsToViewers(@NotNull ServerPacket... packets) {
|
||||
for (ServerPacket packet : packets) {
|
||||
PacketWriterUtils.writeAndSend(getViewers(), packet);
|
||||
PacketUtils.sendGroupedPacket(getViewers(), packet);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a packet to all viewers and the viewable element if it is a player.
|
||||
* <p>
|
||||
* If 'this' isn't a player, then {@link #sendPacketToViewers(ServerPacket)} is called instead.
|
||||
* If 'this' isn't a player, then {only @link #sendPacketToViewers(ServerPacket)} is called.
|
||||
*
|
||||
* @param packet the packet to send
|
||||
*/
|
||||
default void sendPacketToViewersAndSelf(@NotNull ServerPacket packet) {
|
||||
if (this instanceof Player) {
|
||||
if (getViewers().isEmpty()) {
|
||||
PacketWriterUtils.writeAndSend((Player) this, packet);
|
||||
} else {
|
||||
UNSAFE_sendPacketToViewersAndSelf(packet);
|
||||
}
|
||||
} else {
|
||||
sendPacketToViewers(packet);
|
||||
((Player) this).getPlayerConnection().sendPacket(packet);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a packet to all the viewers and 'this'.
|
||||
* <p>
|
||||
* Unsafe because of a cast to {@link Player} without any check beforehand.
|
||||
*
|
||||
* @param packet the packet to send
|
||||
*/
|
||||
private void UNSAFE_sendPacketToViewersAndSelf(@NotNull ServerPacket packet) {
|
||||
Set<Player> recipients = new HashSet<>(getViewers());
|
||||
recipients.add((Player) this);
|
||||
PacketWriterUtils.writeAndSend(recipients, packet);
|
||||
sendPacketToViewers(packet);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,15 +1,16 @@
|
||||
package net.minestom.server.advancements;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minestom.server.chat.ColoredText;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.item.ItemStack;
|
||||
import net.minestom.server.item.Material;
|
||||
import net.minestom.server.network.packet.server.play.AdvancementsPacket;
|
||||
import net.minestom.server.network.player.PlayerConnection;
|
||||
import net.minestom.server.utils.PacketUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Represents an advancement located in an {@link AdvancementTab}.
|
||||
@ -373,17 +374,11 @@ public class Advancement {
|
||||
updateCriteria();
|
||||
|
||||
if (tab != null) {
|
||||
// Update the tab cached packet
|
||||
tab.updatePacket();
|
||||
final Set<Player> viewers = tab.getViewers();
|
||||
AdvancementsPacket createPacket = tab.createPacket();
|
||||
|
||||
final ByteBuf createBuffer = tab.createBuffer;
|
||||
final ByteBuf removeBuffer = tab.removeBuffer;
|
||||
tab.getViewers().forEach(player -> {
|
||||
final PlayerConnection playerConnection = player.getPlayerConnection();
|
||||
// Receive order is important
|
||||
playerConnection.sendPacket(removeBuffer, true);
|
||||
playerConnection.sendPacket(createBuffer, true);
|
||||
});
|
||||
PacketUtils.sendGroupedPacket(viewers, tab.removePacket);
|
||||
PacketUtils.sendGroupedPacket(viewers, createPacket);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,9 @@
|
||||
package net.minestom.server.advancements;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minestom.server.Viewable;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.network.packet.server.play.AdvancementsPacket;
|
||||
import net.minestom.server.network.player.PlayerConnection;
|
||||
import net.minestom.server.utils.PacketUtils;
|
||||
import net.minestom.server.utils.advancement.AdvancementUtils;
|
||||
import net.minestom.server.utils.validate.Check;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@ -33,19 +31,16 @@ public class AdvancementTab implements Viewable {
|
||||
// Advancement -> its parent
|
||||
private final Map<Advancement, Advancement> advancementMap = new HashMap<>();
|
||||
|
||||
// Packet cache, updated every time the tab changes
|
||||
protected ByteBuf createBuffer;
|
||||
// the packet used to clear the tab (used to remove it and to update an advancement)
|
||||
// will never change (since the root identifier is always the same)
|
||||
protected final ByteBuf removeBuffer;
|
||||
protected final AdvancementsPacket removePacket;
|
||||
|
||||
protected AdvancementTab(@NotNull String rootIdentifier, @NotNull AdvancementRoot root) {
|
||||
this.root = root;
|
||||
|
||||
cacheAdvancement(rootIdentifier, root, null);
|
||||
|
||||
final AdvancementsPacket removePacket = AdvancementUtils.getRemovePacket(new String[]{rootIdentifier});
|
||||
this.removeBuffer = PacketUtils.writePacket(removePacket);
|
||||
this.removePacket = AdvancementUtils.getRemovePacket(new String[]{rootIdentifier});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -88,13 +83,6 @@ public class AdvancementTab implements Viewable {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the packet buffer.
|
||||
*/
|
||||
protected void updatePacket() {
|
||||
this.createBuffer = PacketUtils.writePacket(createPacket());
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the packet which build the whole advancement tab.
|
||||
*
|
||||
@ -135,8 +123,6 @@ public class AdvancementTab implements Viewable {
|
||||
advancement.setParent(parent);
|
||||
advancement.updateCriteria();
|
||||
this.advancementMap.put(advancement, parent);
|
||||
|
||||
updatePacket();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -149,7 +135,7 @@ public class AdvancementTab implements Viewable {
|
||||
final PlayerConnection playerConnection = player.getPlayerConnection();
|
||||
|
||||
// Send the tab to the player
|
||||
playerConnection.sendPacket(createBuffer, true);
|
||||
playerConnection.sendPacket(createPacket());
|
||||
|
||||
addPlayer(player);
|
||||
|
||||
@ -166,7 +152,7 @@ public class AdvancementTab implements Viewable {
|
||||
|
||||
// Remove the tab
|
||||
if (!player.isRemoved()) {
|
||||
playerConnection.sendPacket(removeBuffer, true);
|
||||
playerConnection.sendPacket(removePacket);
|
||||
}
|
||||
|
||||
removePlayer(player);
|
||||
|
@ -291,9 +291,6 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
|
||||
@Override
|
||||
public void update(long time) {
|
||||
// Flush all pending packets
|
||||
playerConnection.flush();
|
||||
|
||||
playerConnection.updateStats();
|
||||
|
||||
// Process received packets
|
||||
@ -1687,7 +1684,7 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
public void setTeam(Team team) {
|
||||
super.setTeam(team);
|
||||
if (team != null)
|
||||
getPlayerConnection().sendPacket(team.getTeamsCreationPacket());
|
||||
getPlayerConnection().sendPacket(team.createTeamsCreationPacket());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2338,7 +2335,7 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
|
||||
// Team
|
||||
if (this.getTeam() != null)
|
||||
connection.sendPacket(this.getTeam().getTeamsCreationPacket());
|
||||
connection.sendPacket(this.getTeam().createTeamsCreationPacket());
|
||||
|
||||
EntityHeadLookPacket entityHeadLookPacket = new EntityHeadLookPacket();
|
||||
entityHeadLookPacket.entityId = getEntityId();
|
||||
|
@ -13,7 +13,6 @@ import net.minestom.server.instance.batch.ChunkBatch;
|
||||
import net.minestom.server.instance.block.Block;
|
||||
import net.minestom.server.instance.block.BlockManager;
|
||||
import net.minestom.server.instance.block.CustomBlock;
|
||||
import net.minestom.server.network.PacketWriterUtils;
|
||||
import net.minestom.server.network.packet.server.play.ChunkDataPacket;
|
||||
import net.minestom.server.network.packet.server.play.UpdateLightPacket;
|
||||
import net.minestom.server.network.player.PlayerConnection;
|
||||
@ -464,7 +463,8 @@ public abstract class Chunk implements Viewable, DataContainer {
|
||||
}
|
||||
updateLightPacket.skyLight = temp;
|
||||
updateLightPacket.blockLight = temp2;
|
||||
PacketWriterUtils.writeAndSend(player, updateLightPacket);
|
||||
|
||||
playerConnection.sendPacket(updateLightPacket);
|
||||
}
|
||||
}
|
||||
|
||||
@ -496,6 +496,7 @@ public abstract class Chunk implements Viewable, DataContainer {
|
||||
*
|
||||
* @param section the section to update
|
||||
* @param player the player to send the packet to
|
||||
* @throws IllegalArgumentException if {@code section} is not a valid section
|
||||
*/
|
||||
public void sendChunkSectionUpdate(int section, @NotNull Player player) {
|
||||
if (!PlayerUtils.isNettyClient(player))
|
||||
@ -503,7 +504,7 @@ public abstract class Chunk implements Viewable, DataContainer {
|
||||
Check.argCondition(!MathUtils.isBetween(section, 0, CHUNK_SECTION_COUNT),
|
||||
"The chunk section " + section + " does not exist");
|
||||
|
||||
PacketWriterUtils.writeAndSend(player, getChunkSectionUpdatePacket(section));
|
||||
player.getPlayerConnection().sendPacket(createChunkSectionUpdatePacket(section));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -513,7 +514,7 @@ public abstract class Chunk implements Viewable, DataContainer {
|
||||
* @return the {@link ChunkDataPacket} to update a single chunk section
|
||||
*/
|
||||
@NotNull
|
||||
protected ChunkDataPacket getChunkSectionUpdatePacket(int section) {
|
||||
protected ChunkDataPacket createChunkSectionUpdatePacket(int section) {
|
||||
ChunkDataPacket chunkDataPacket = getFreshPartialDataPacket();
|
||||
chunkDataPacket.fullChunk = false;
|
||||
int[] sections = new int[CHUNK_SECTION_COUNT];
|
||||
|
@ -1,9 +1,10 @@
|
||||
package net.minestom.server.instance;
|
||||
|
||||
import net.minestom.server.instance.block.Block;
|
||||
import net.minestom.server.network.PacketWriterUtils;
|
||||
import net.minestom.server.network.packet.server.play.ExplosionPacket;
|
||||
import net.minestom.server.utils.BlockPosition;
|
||||
import net.minestom.server.utils.PacketUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -54,7 +55,7 @@ public abstract class Explosion {
|
||||
*
|
||||
* @param instance instance to perform this explosion in
|
||||
*/
|
||||
public void apply(Instance instance) {
|
||||
public void apply(@NotNull Instance instance) {
|
||||
List<BlockPosition> blocks = prepare(instance);
|
||||
ExplosionPacket packet = new ExplosionPacket();
|
||||
packet.x = getCenterX();
|
||||
@ -80,7 +81,7 @@ public abstract class Explosion {
|
||||
postExplosion(instance, blocks, packet);
|
||||
|
||||
// TODO send only to close players
|
||||
PacketWriterUtils.writeAndSend(instance.getPlayers(), packet);
|
||||
PacketUtils.sendGroupedPacket(instance.getPlayers(), packet);
|
||||
|
||||
postSend(instance, blocks);
|
||||
}
|
||||
|
@ -16,12 +16,12 @@ import net.minestom.server.instance.batch.ChunkBatch;
|
||||
import net.minestom.server.instance.block.Block;
|
||||
import net.minestom.server.instance.block.BlockManager;
|
||||
import net.minestom.server.instance.block.CustomBlock;
|
||||
import net.minestom.server.network.PacketWriterUtils;
|
||||
import net.minestom.server.network.packet.server.play.BlockActionPacket;
|
||||
import net.minestom.server.network.packet.server.play.TimeUpdatePacket;
|
||||
import net.minestom.server.storage.StorageLocation;
|
||||
import net.minestom.server.thread.ThreadProvider;
|
||||
import net.minestom.server.utils.BlockPosition;
|
||||
import net.minestom.server.utils.PacketUtils;
|
||||
import net.minestom.server.utils.Position;
|
||||
import net.minestom.server.utils.chunk.ChunkCallback;
|
||||
import net.minestom.server.utils.chunk.ChunkUtils;
|
||||
@ -369,7 +369,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
|
||||
*/
|
||||
public void setTime(long time) {
|
||||
this.time = time;
|
||||
PacketWriterUtils.writeAndSend(getPlayers(), getTimePacket());
|
||||
PacketUtils.sendGroupedPacket(getPlayers(), createTimePacket());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -417,12 +417,12 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a {@link TimeUpdatePacket} with the current age and time of this instance
|
||||
* Creates a {@link TimeUpdatePacket} with the current age and time of this instance
|
||||
*
|
||||
* @return the {@link TimeUpdatePacket} with this instance data
|
||||
*/
|
||||
@NotNull
|
||||
private TimeUpdatePacket getTimePacket() {
|
||||
private TimeUpdatePacket createTimePacket() {
|
||||
TimeUpdatePacket timeUpdatePacket = new TimeUpdatePacket();
|
||||
timeUpdatePacket.worldAge = worldAge;
|
||||
timeUpdatePacket.timeOfDay = time;
|
||||
@ -996,7 +996,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
|
||||
|
||||
// time needs to be send to players
|
||||
if (timeUpdate != null && !CooldownUtils.hasCooldown(time, lastTimeUpdate, timeUpdate)) {
|
||||
PacketWriterUtils.writeAndSend(getPlayers(), getTimePacket());
|
||||
PacketUtils.sendGroupedPacket(getPlayers(), createTimePacket());
|
||||
this.lastTimeUpdate = time;
|
||||
}
|
||||
|
||||
|
@ -2,8 +2,8 @@ package net.minestom.server.instance;
|
||||
|
||||
import net.minestom.server.entity.Entity;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.network.PacketWriterUtils;
|
||||
import net.minestom.server.network.packet.server.play.WorldBorderPacket;
|
||||
import net.minestom.server.utils.PacketUtils;
|
||||
import net.minestom.server.utils.Position;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@ -100,6 +100,7 @@ public class WorldBorder {
|
||||
*/
|
||||
public void setWarningTime(int warningTime) {
|
||||
this.warningTime = warningTime;
|
||||
|
||||
WorldBorderPacket worldBorderPacket = new WorldBorderPacket();
|
||||
worldBorderPacket.action = WorldBorderPacket.Action.SET_WARNING_TIME;
|
||||
worldBorderPacket.wbAction = new WorldBorderPacket.WBSetWarningTime(warningTime);
|
||||
@ -115,6 +116,7 @@ public class WorldBorder {
|
||||
*/
|
||||
public void setWarningBlocks(int warningBlocks) {
|
||||
this.warningBlocks = warningBlocks;
|
||||
|
||||
WorldBorderPacket worldBorderPacket = new WorldBorderPacket();
|
||||
worldBorderPacket.action = WorldBorderPacket.Action.SET_WARNING_BLOCKS;
|
||||
worldBorderPacket.wbAction = new WorldBorderPacket.WBSetWarningBlocks(warningBlocks);
|
||||
@ -137,6 +139,7 @@ public class WorldBorder {
|
||||
this.speed = speed;
|
||||
this.lerpStartTime = System.currentTimeMillis();
|
||||
|
||||
|
||||
WorldBorderPacket worldBorderPacket = new WorldBorderPacket();
|
||||
worldBorderPacket.action = WorldBorderPacket.Action.LERP_SIZE;
|
||||
worldBorderPacket.wbAction = new WorldBorderPacket.WBLerpSize(oldDiameter, newDiameter, speed);
|
||||
@ -270,10 +273,10 @@ public class WorldBorder {
|
||||
/**
|
||||
* Sends a {@link WorldBorderPacket} to all the instance players.
|
||||
*
|
||||
* @param worldBorderPacket the packet to send
|
||||
* @param packet the packet to send
|
||||
*/
|
||||
private void sendPacket(@NotNull WorldBorderPacket worldBorderPacket) {
|
||||
PacketWriterUtils.writeAndSend(instance.getPlayers(), worldBorderPacket);
|
||||
private void sendPacket(@NotNull WorldBorderPacket packet) {
|
||||
PacketUtils.sendGroupedPacket(instance.getPlayers(), packet);
|
||||
}
|
||||
|
||||
public enum CollisionAxis {
|
||||
|
@ -13,7 +13,6 @@ import net.minestom.server.inventory.click.InventoryClickResult;
|
||||
import net.minestom.server.inventory.condition.InventoryCondition;
|
||||
import net.minestom.server.item.ItemStack;
|
||||
import net.minestom.server.item.StackingRule;
|
||||
import net.minestom.server.network.PacketWriterUtils;
|
||||
import net.minestom.server.network.packet.server.play.EntityEquipmentPacket;
|
||||
import net.minestom.server.network.packet.server.play.SetSlotPacket;
|
||||
import net.minestom.server.network.packet.server.play.WindowItemsPacket;
|
||||
@ -214,7 +213,7 @@ public class PlayerInventory implements InventoryModifier, InventoryClickHandler
|
||||
* the inventory items
|
||||
*/
|
||||
public void update() {
|
||||
PacketWriterUtils.writeAndSend(player, createWindowItemsPacket());
|
||||
player.getPlayerConnection().sendPacket(createWindowItemsPacket());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -9,9 +9,9 @@ import net.minestom.server.command.CommandManager;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.event.player.PlayerChatEvent;
|
||||
import net.minestom.server.network.ConnectionManager;
|
||||
import net.minestom.server.network.PacketWriterUtils;
|
||||
import net.minestom.server.network.packet.client.play.ClientChatMessagePacket;
|
||||
import net.minestom.server.network.packet.server.play.ChatMessagePacket;
|
||||
import net.minestom.server.utils.PacketUtils;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.function.Function;
|
||||
@ -62,7 +62,7 @@ public class ChatMessageListener {
|
||||
ChatMessagePacket chatMessagePacket =
|
||||
new ChatMessagePacket(jsonMessage, ChatMessagePacket.Position.CHAT, player.getUuid());
|
||||
|
||||
PacketWriterUtils.writeAndSend(recipients, chatMessagePacket);
|
||||
PacketUtils.sendGroupedPacket(recipients, chatMessagePacket);
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -1,21 +1,24 @@
|
||||
package net.minestom.server.listener.manager;
|
||||
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.network.packet.client.ClientPlayPacket;
|
||||
import net.minestom.server.network.ConnectionManager;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Interface used to add a listener for incoming packets with {@link net.minestom.server.network.ConnectionManager#onPacketReceive(PacketConsumer)}.
|
||||
* Interface used to add a listener for incoming/outgoing packets with
|
||||
* {@link ConnectionManager#onPacketReceive(PacketConsumer)} and {@link ConnectionManager#onPacketSend(PacketConsumer)}.
|
||||
*
|
||||
* @param <T> the packet type
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface PacketConsumer {
|
||||
public interface PacketConsumer<T> {
|
||||
|
||||
/**
|
||||
* Called when a packet is received from the client.
|
||||
* Called when a packet is received/sent from/to a client.
|
||||
*
|
||||
* @param player the player who sent the packet
|
||||
* @param packetController the packet controller, used to cancel or control which listener will be called
|
||||
* @param packet the received packet
|
||||
* @param player the player concerned by the packet
|
||||
* @param packetController the packet controller, can be used to cancel the packet
|
||||
* @param packet the packet
|
||||
*/
|
||||
void accept(@NotNull Player player, @NotNull PacketController packetController, @NotNull ClientPlayPacket packet);
|
||||
void accept(@NotNull Player player, @NotNull PacketController packetController, @NotNull T packet);
|
||||
}
|
||||
|
@ -1,19 +1,15 @@
|
||||
package net.minestom.server.listener.manager;
|
||||
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.network.packet.client.ClientPlayPacket;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Used to control the output of a packet in {@link PacketConsumer#accept(Player, PacketController, ClientPlayPacket)}.
|
||||
* Used to control the output of a packet in {@link PacketConsumer#accept(Player, PacketController, Object)}.
|
||||
*/
|
||||
public class PacketController {
|
||||
|
||||
private boolean cancel;
|
||||
private PacketListenerConsumer packetListenerConsumer;
|
||||
|
||||
protected PacketController(@Nullable PacketListenerConsumer packetListenerConsumer) {
|
||||
this.packetListenerConsumer = packetListenerConsumer;
|
||||
protected PacketController() {
|
||||
}
|
||||
|
||||
/**
|
||||
@ -33,25 +29,4 @@ public class PacketController {
|
||||
public void setCancel(boolean cancel) {
|
||||
this.cancel = cancel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the listener associated with the packet.
|
||||
*
|
||||
* @return the packet's listener, null if not present
|
||||
*/
|
||||
@Nullable
|
||||
public PacketListenerConsumer getPacketListenerConsumer() {
|
||||
return packetListenerConsumer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the packet listener, setting it to null cancel the listener.
|
||||
* <p>
|
||||
* WARNING: this will overwrite the default minestom listener, be sure to know what you are doing.
|
||||
*
|
||||
* @param packetListenerConsumer the new packet listener, can be null
|
||||
*/
|
||||
public void setPacketListenerConsumer(@Nullable PacketListenerConsumer packetListenerConsumer) {
|
||||
this.packetListenerConsumer = packetListenerConsumer;
|
||||
}
|
||||
}
|
||||
|
@ -6,13 +6,17 @@ import net.minestom.server.listener.*;
|
||||
import net.minestom.server.network.ConnectionManager;
|
||||
import net.minestom.server.network.packet.client.ClientPlayPacket;
|
||||
import net.minestom.server.network.packet.client.play.*;
|
||||
import net.minestom.server.network.packet.server.ServerPacket;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public final class PacketListenerManager {
|
||||
|
||||
public final static Logger LOGGER = LoggerFactory.getLogger(PacketListenerManager.class);
|
||||
private static final ConnectionManager CONNECTION_MANAGER = MinecraftServer.getConnectionManager();
|
||||
|
||||
private final Map<Class<? extends ClientPlayPacket>, PacketListenerConsumer> listeners = new ConcurrentHashMap<>();
|
||||
@ -56,7 +60,7 @@ public final class PacketListenerManager {
|
||||
* @param player the player who sent the packet
|
||||
* @param <T> the packet type
|
||||
*/
|
||||
public <T extends ClientPlayPacket> void process(@NotNull T packet, @NotNull Player player) {
|
||||
public <T extends ClientPlayPacket> void processClientPacket(@NotNull T packet, @NotNull Player player) {
|
||||
|
||||
final Class clazz = packet.getClass();
|
||||
|
||||
@ -64,26 +68,29 @@ public final class PacketListenerManager {
|
||||
|
||||
// Listener can be null if none has been set before, call PacketConsumer anyway
|
||||
if (packetListenerConsumer == null) {
|
||||
System.err.println("Packet " + clazz + " does not have any default listener! (The issue comes from Minestom)");
|
||||
LOGGER.error("Packet " + clazz + " does not have any default listener! (The issue comes from Minestom)");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
final PacketController packetController = new PacketController(packetListenerConsumer);
|
||||
for (PacketConsumer packetConsumer : CONNECTION_MANAGER.getReceivePacketConsumers()) {
|
||||
final PacketController packetController = new PacketController();
|
||||
for (PacketConsumer<ClientPlayPacket> packetConsumer : CONNECTION_MANAGER.getReceivePacketConsumers()) {
|
||||
packetConsumer.accept(player, packetController, packet);
|
||||
}
|
||||
|
||||
if (packetController.isCancel())
|
||||
return;
|
||||
|
||||
// Get the new listener (or the same) from the packet controller
|
||||
packetListenerConsumer = packetController.getPacketListenerConsumer();
|
||||
// Finally execute the listener
|
||||
packetListenerConsumer.accept(packet, player);
|
||||
}
|
||||
|
||||
// Call the listener if not null
|
||||
// (can be null because no listener is set, or because it has been changed by the controller)
|
||||
if (packetListenerConsumer != null) {
|
||||
packetListenerConsumer.accept(packet, player);
|
||||
public <T extends ServerPacket> boolean processServerPacket(@NotNull T packet, @NotNull Player player) {
|
||||
final PacketController packetController = new PacketController();
|
||||
for (PacketConsumer<ServerPacket> packetConsumer : CONNECTION_MANAGER.getSendPacketConsumers()) {
|
||||
packetConsumer.accept(player, packetController, packet);
|
||||
}
|
||||
|
||||
return !packetController.isCancel();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -4,10 +4,13 @@ import net.minestom.server.chat.JsonMessage;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.entity.fakeplayer.FakePlayer;
|
||||
import net.minestom.server.listener.manager.PacketConsumer;
|
||||
import net.minestom.server.network.packet.client.ClientPlayPacket;
|
||||
import net.minestom.server.network.packet.client.login.LoginStartPacket;
|
||||
import net.minestom.server.network.packet.server.ServerPacket;
|
||||
import net.minestom.server.network.packet.server.login.LoginSuccessPacket;
|
||||
import net.minestom.server.network.packet.server.play.ChatMessagePacket;
|
||||
import net.minestom.server.network.player.PlayerConnection;
|
||||
import net.minestom.server.utils.PacketUtils;
|
||||
import net.minestom.server.utils.callback.validator.PlayerValidator;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@ -26,7 +29,9 @@ public final class ConnectionManager {
|
||||
private final Map<PlayerConnection, Player> connectionPlayerMap = Collections.synchronizedMap(new HashMap<>());
|
||||
|
||||
// All the consumers to call once a packet is received
|
||||
private final List<PacketConsumer> receivePacketConsumers = new CopyOnWriteArrayList<>();
|
||||
private final List<PacketConsumer<ClientPlayPacket>> receivePacketConsumers = new CopyOnWriteArrayList<>();
|
||||
// All the consumers to call once a packet is sent
|
||||
private final List<PacketConsumer<ServerPacket>> sendPacketConsumers = new CopyOnWriteArrayList<>();
|
||||
// The uuid provider once a player login
|
||||
private UuidProvider uuidProvider;
|
||||
// The player provider to have your own Player implementation
|
||||
@ -115,7 +120,8 @@ public final class ConnectionManager {
|
||||
private void broadcastJson(@NotNull String json, @NotNull Collection<Player> recipients) {
|
||||
ChatMessagePacket chatMessagePacket =
|
||||
new ChatMessagePacket(json, ChatMessagePacket.Position.SYSTEM_MESSAGE);
|
||||
PacketWriterUtils.writeAndSend(recipients, chatMessagePacket);
|
||||
|
||||
PacketUtils.sendGroupedPacket(recipients, chatMessagePacket);
|
||||
}
|
||||
|
||||
private Collection<Player> getRecipients(@Nullable PlayerValidator condition) {
|
||||
@ -142,7 +148,7 @@ public final class ConnectionManager {
|
||||
* @return an unmodifiable list of packet's consumers
|
||||
*/
|
||||
@NotNull
|
||||
public List<PacketConsumer> getReceivePacketConsumers() {
|
||||
public List<PacketConsumer<ClientPlayPacket>> getReceivePacketConsumers() {
|
||||
return Collections.unmodifiableList(receivePacketConsumers);
|
||||
}
|
||||
|
||||
@ -151,10 +157,29 @@ public final class ConnectionManager {
|
||||
*
|
||||
* @param packetConsumer the packet consumer
|
||||
*/
|
||||
public void onPacketReceive(@NotNull PacketConsumer packetConsumer) {
|
||||
public void onPacketReceive(@NotNull PacketConsumer<ClientPlayPacket> packetConsumer) {
|
||||
this.receivePacketConsumers.add(packetConsumer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all the listeners which are called for each packet sent.
|
||||
*
|
||||
* @return an unmodifiable list of packet's consumers
|
||||
*/
|
||||
@NotNull
|
||||
public List<PacketConsumer<ServerPacket>> getSendPacketConsumers() {
|
||||
return Collections.unmodifiableList(sendPacketConsumers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a consumer to call once a packet is sent.
|
||||
*
|
||||
* @param packetConsumer the packet consumer
|
||||
*/
|
||||
public void onPacketSend(@NotNull PacketConsumer<ServerPacket> packetConsumer) {
|
||||
this.sendPacketConsumers.add(packetConsumer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes how {@link UUID} are attributed to players.
|
||||
* <p>
|
||||
|
@ -1,101 +0,0 @@
|
||||
package net.minestom.server.network;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.network.packet.server.ServerPacket;
|
||||
import net.minestom.server.network.player.PlayerConnection;
|
||||
import net.minestom.server.utils.PacketUtils;
|
||||
import net.minestom.server.utils.player.PlayerUtils;
|
||||
import net.minestom.server.utils.thread.MinestomThread;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Utils class used to write {@link ServerPacket} in the appropriate thread pool.
|
||||
* <p>
|
||||
* WARNING: those methods do not guarantee a receive order.
|
||||
*/
|
||||
public final class PacketWriterUtils {
|
||||
|
||||
private static final ExecutorService PACKET_WRITER_POOL = new MinestomThread(MinecraftServer.THREAD_COUNT_PACKET_WRITER, MinecraftServer.THREAD_NAME_PACKET_WRITER);
|
||||
|
||||
/**
|
||||
* Writes the {@link ServerPacket} in the writer thread pool.
|
||||
* <p>
|
||||
* WARNING: should not be used if the packet receive order is important
|
||||
*
|
||||
* @param serverPacket the packet to write
|
||||
* @param consumer the consumer called once the packet has been written
|
||||
*/
|
||||
public static void writeCallbackPacket(@NotNull ServerPacket serverPacket, @NotNull Consumer<ByteBuf> consumer) {
|
||||
PACKET_WRITER_POOL.execute(() -> {
|
||||
final ByteBuf buffer = PacketUtils.writePacket(serverPacket);
|
||||
consumer.accept(buffer);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a {@link ServerPacket} in the writer thread pool and send it to every players in {@code players}.
|
||||
* <p>
|
||||
* WARNING: should not be used if the packet receive order is important
|
||||
*
|
||||
* @param players the players list to send the packet to
|
||||
* @param serverPacket the packet to write and send
|
||||
*/
|
||||
public static void writeAndSend(@NotNull Collection<Player> players, @NotNull ServerPacket serverPacket) {
|
||||
PACKET_WRITER_POOL.execute(() -> {
|
||||
if (players.isEmpty())
|
||||
return;
|
||||
|
||||
final ByteBuf buffer = PacketUtils.writePacket(serverPacket);
|
||||
for (Player player : players) {
|
||||
final PlayerConnection playerConnection = player.getPlayerConnection();
|
||||
if (PlayerUtils.isNettyClient(player)) {
|
||||
playerConnection.writePacket(buffer, true);
|
||||
} else {
|
||||
playerConnection.sendPacket(serverPacket);
|
||||
}
|
||||
}
|
||||
buffer.release();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a {@link ServerPacket} and send it to a {@link PlayerConnection}.
|
||||
* <p>
|
||||
* WARNING: should not be used if the packet receive order is important
|
||||
*
|
||||
* @param playerConnection the connection to send the packet to
|
||||
* @param serverPacket the packet to write and send
|
||||
*/
|
||||
public static void writeAndSend(@NotNull PlayerConnection playerConnection, @NotNull ServerPacket serverPacket) {
|
||||
PACKET_WRITER_POOL.execute(() -> {
|
||||
if (PlayerUtils.isNettyClient(playerConnection)) {
|
||||
final ByteBuf buffer = PacketUtils.writePacket(serverPacket);
|
||||
buffer.retain();
|
||||
playerConnection.writePacket(buffer, false);
|
||||
buffer.release();
|
||||
} else {
|
||||
playerConnection.sendPacket(serverPacket);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a {@link ServerPacket} and send it to a {@link Player}.
|
||||
* <p>
|
||||
* WARNING: should not be used if the packet receive order is important
|
||||
*
|
||||
* @param player the player to send the packet to
|
||||
* @param serverPacket the packet to write and send
|
||||
*/
|
||||
public static void writeAndSend(@NotNull Player player, @NotNull ServerPacket serverPacket) {
|
||||
final PlayerConnection playerConnection = player.getPlayerConnection();
|
||||
writeAndSend(playerConnection, serverPacket);
|
||||
}
|
||||
|
||||
}
|
@ -17,7 +17,7 @@ public abstract class ClientPlayPacket implements ClientPacket {
|
||||
* @param player the player who sent the packet
|
||||
*/
|
||||
public void process(@NotNull Player player) {
|
||||
PACKET_LISTENER_MANAGER.process(this, player);
|
||||
PACKET_LISTENER_MANAGER.processClientPacket(this, player);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -34,8 +34,9 @@ public class PluginMessagePacket implements ServerPacket {
|
||||
PluginMessagePacket brandMessage = new PluginMessagePacket();
|
||||
brandMessage.channel = "minecraft:brand";
|
||||
|
||||
BinaryWriter writer = new BinaryWriter();
|
||||
writer.writeSizedString(MinecraftServer.getBrandName());
|
||||
final String brandName = MinecraftServer.getBrandName();
|
||||
BinaryWriter writer = new BinaryWriter(4 + brandName.length());
|
||||
writer.writeSizedString(brandName);
|
||||
|
||||
brandMessage.data = writer.toByteArray();
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.minestom.server.network.packet.server.play;
|
||||
|
||||
import net.minestom.server.chat.JsonMessage;
|
||||
import net.minestom.server.network.packet.server.ServerPacket;
|
||||
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
|
||||
import net.minestom.server.utils.binary.BinaryWriter;
|
||||
@ -22,7 +23,7 @@ public class TeamsPacket implements ServerPacket {
|
||||
/**
|
||||
* The display name for the team
|
||||
*/
|
||||
public String teamDisplayName;
|
||||
public JsonMessage teamDisplayName;
|
||||
/**
|
||||
* The friendly flags to
|
||||
*/
|
||||
@ -42,11 +43,11 @@ public class TeamsPacket implements ServerPacket {
|
||||
/**
|
||||
* The prefix of the team
|
||||
*/
|
||||
public String teamPrefix;
|
||||
public JsonMessage teamPrefix;
|
||||
/**
|
||||
* The suffix of the team
|
||||
*/
|
||||
public String teamSuffix;
|
||||
public JsonMessage teamSuffix;
|
||||
/**
|
||||
* An array with all entities in the team
|
||||
*/
|
||||
@ -65,13 +66,13 @@ public class TeamsPacket implements ServerPacket {
|
||||
switch (action) {
|
||||
case CREATE_TEAM:
|
||||
case UPDATE_TEAM_INFO:
|
||||
writer.writeSizedString(this.teamDisplayName);
|
||||
writer.writeSizedString(this.teamDisplayName.toString());
|
||||
writer.writeByte(this.friendlyFlags);
|
||||
writer.writeSizedString(this.nameTagVisibility.getIdentifier());
|
||||
writer.writeSizedString(this.collisionRule.getIdentifier());
|
||||
writer.writeVarInt(this.teamColor);
|
||||
writer.writeSizedString(this.teamPrefix);
|
||||
writer.writeSizedString(this.teamSuffix);
|
||||
writer.writeSizedString(this.teamPrefix.toString());
|
||||
writer.writeSizedString(this.teamSuffix.toString());
|
||||
break;
|
||||
case REMOVE_TEAM:
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
package net.minestom.server.network.player;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.entity.fakeplayer.FakePlayer;
|
||||
@ -13,24 +12,11 @@ import java.net.SocketAddress;
|
||||
|
||||
public class FakePlayerConnection extends PlayerConnection {
|
||||
|
||||
@Override
|
||||
public void sendPacket(@NotNull ByteBuf buffer, boolean copy) {
|
||||
throw new UnsupportedOperationException("FakePlayer cannot read Bytebuf");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writePacket(@NotNull ByteBuf buffer, boolean copy) {
|
||||
throw new UnsupportedOperationException("FakePlayer cannot write to Bytebuf");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendPacket(@NotNull ServerPacket serverPacket) {
|
||||
getFakePlayer().getController().consumePacket(serverPacket);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() {
|
||||
// Does nothing
|
||||
if (shouldSendPacket(serverPacket)) {
|
||||
getFakePlayer().getController().consumePacket(serverPacket);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
@ -1,6 +1,5 @@
|
||||
package net.minestom.server.network.player;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import lombok.Getter;
|
||||
@ -81,38 +80,11 @@ public class NettyPlayerConnection extends PlayerConnection {
|
||||
channel.pipeline().addAfter("framer", "compressor", new PacketCompressor(threshold));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendPacket(@NotNull ByteBuf buffer, boolean copy) {
|
||||
if (copy) {
|
||||
buffer = buffer.copy();
|
||||
buffer.retain();
|
||||
channel.writeAndFlush(buffer);
|
||||
buffer.release();
|
||||
} else {
|
||||
channel.writeAndFlush(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writePacket(@NotNull ByteBuf buffer, boolean copy) {
|
||||
if (copy) {
|
||||
buffer = buffer.copy();
|
||||
buffer.retain();
|
||||
channel.write(buffer);
|
||||
buffer.release();
|
||||
} else {
|
||||
channel.write(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendPacket(@NotNull ServerPacket serverPacket) {
|
||||
channel.writeAndFlush(serverPacket);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() {
|
||||
getChannel().flush();
|
||||
if (shouldSendPacket(serverPacket)) {
|
||||
channel.writeAndFlush(serverPacket);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
@ -1,16 +1,18 @@
|
||||
package net.minestom.server.network.player;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import lombok.Getter;
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.chat.ChatColor;
|
||||
import net.minestom.server.chat.ColoredText;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.listener.manager.PacketListenerManager;
|
||||
import net.minestom.server.network.ConnectionManager;
|
||||
import net.minestom.server.network.ConnectionState;
|
||||
import net.minestom.server.network.packet.server.ServerPacket;
|
||||
import net.minestom.server.network.packet.server.login.LoginDisconnectPacket;
|
||||
import net.minestom.server.network.packet.server.play.DisconnectPacket;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.net.SocketAddress;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
@ -21,6 +23,8 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
*/
|
||||
public abstract class PlayerConnection {
|
||||
|
||||
protected static final PacketListenerManager PACKET_LISTENER_MANAGER = MinecraftServer.getPacketListenerManager();
|
||||
|
||||
private Player player;
|
||||
private ConnectionState connectionState;
|
||||
private boolean online;
|
||||
@ -68,33 +72,19 @@ public abstract class PlayerConnection {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a raw {@link ByteBuf} to the client.
|
||||
*
|
||||
* @param buffer The buffer to send.
|
||||
* @param copy Should be true unless your only using the ByteBuf once.
|
||||
*/
|
||||
public abstract void sendPacket(@NotNull ByteBuf buffer, boolean copy);
|
||||
|
||||
/**
|
||||
* Writes a raw {@link ByteBuf} to the client.
|
||||
*
|
||||
* @param buffer The buffer to send.
|
||||
* @param copy Should be true unless your only using the ByteBuf once.
|
||||
*/
|
||||
public abstract void writePacket(@NotNull ByteBuf buffer, boolean copy);
|
||||
|
||||
/**
|
||||
* Serializes the packet and send it to the client.
|
||||
* <p>
|
||||
* Also responsible for executing {@link ConnectionManager#getSendPacketConsumers()} consumers.
|
||||
*
|
||||
* @param serverPacket the packet to send
|
||||
* @see #shouldSendPacket(ServerPacket)
|
||||
*/
|
||||
public abstract void sendPacket(@NotNull ServerPacket serverPacket);
|
||||
|
||||
/**
|
||||
* Flush all waiting packets.
|
||||
*/
|
||||
public abstract void flush();
|
||||
protected boolean shouldSendPacket(@NotNull ServerPacket serverPacket) {
|
||||
return player == null || PACKET_LISTENER_MANAGER.processServerPacket(serverPacket, player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the remote address of the client.
|
||||
@ -112,8 +102,9 @@ public abstract class PlayerConnection {
|
||||
/**
|
||||
* Gets the player linked to this connection.
|
||||
*
|
||||
* @return the player
|
||||
* @return the player, can be null if not initialized yet
|
||||
*/
|
||||
@Nullable
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
@ -401,13 +401,13 @@ public class Sidebar implements Scoreboard {
|
||||
TeamsPacket teamsPacket = new TeamsPacket();
|
||||
teamsPacket.teamName = teamName;
|
||||
teamsPacket.action = TeamsPacket.Action.CREATE_TEAM;
|
||||
teamsPacket.teamDisplayName = teamDisplayName.toString();
|
||||
teamsPacket.teamDisplayName = teamDisplayName;
|
||||
teamsPacket.friendlyFlags = friendlyFlags;
|
||||
teamsPacket.nameTagVisibility = nameTagVisibility;
|
||||
teamsPacket.collisionRule = collisionRule;
|
||||
teamsPacket.teamColor = teamColor;
|
||||
teamsPacket.teamPrefix = prefix.toString();
|
||||
teamsPacket.teamSuffix = suffix.toString();
|
||||
teamsPacket.teamPrefix = prefix;
|
||||
teamsPacket.teamSuffix = suffix;
|
||||
teamsPacket.entities = new String[]{entityName};
|
||||
return teamsPacket;
|
||||
}
|
||||
@ -434,13 +434,13 @@ public class Sidebar implements Scoreboard {
|
||||
TeamsPacket teamsPacket = new TeamsPacket();
|
||||
teamsPacket.teamName = teamName;
|
||||
teamsPacket.action = TeamsPacket.Action.UPDATE_TEAM_INFO;
|
||||
teamsPacket.teamDisplayName = teamDisplayName.toString();
|
||||
teamsPacket.teamDisplayName = teamDisplayName;
|
||||
teamsPacket.friendlyFlags = friendlyFlags;
|
||||
teamsPacket.nameTagVisibility = nameTagVisibility;
|
||||
teamsPacket.collisionRule = collisionRule;
|
||||
teamsPacket.teamColor = teamColor;
|
||||
teamsPacket.teamPrefix = prefix.toString();
|
||||
teamsPacket.teamSuffix = suffix.toString();
|
||||
teamsPacket.teamPrefix = prefix;
|
||||
teamsPacket.teamSuffix = suffix;
|
||||
return teamsPacket;
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,11 @@
|
||||
package net.minestom.server.scoreboard;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.chat.ChatColor;
|
||||
import net.minestom.server.chat.ColoredText;
|
||||
import net.minestom.server.entity.LivingEntity;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.network.PacketWriterUtils;
|
||||
import net.minestom.server.network.ConnectionManager;
|
||||
import net.minestom.server.network.packet.server.play.TeamsPacket;
|
||||
import net.minestom.server.network.packet.server.play.TeamsPacket.CollisionRule;
|
||||
import net.minestom.server.network.packet.server.play.TeamsPacket.NameTagVisibility;
|
||||
@ -21,18 +20,12 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
*/
|
||||
public class Team {
|
||||
|
||||
private static final ConnectionManager CONNECTION_MANAGER = MinecraftServer.getConnectionManager();
|
||||
|
||||
/**
|
||||
* A collection of all registered entities who are on the team
|
||||
*/
|
||||
private final Set<String> members;
|
||||
/**
|
||||
* Creation packet for the team to create
|
||||
*/
|
||||
private final TeamsPacket teamsCreationPacket;
|
||||
/**
|
||||
* A byte buf to destroy the team
|
||||
*/
|
||||
private final ByteBuf teamsDestroyPacket;
|
||||
|
||||
/**
|
||||
* The registry name of the team
|
||||
@ -94,22 +87,6 @@ public class Team {
|
||||
|
||||
this.entities = new String[0];
|
||||
this.members = new CopyOnWriteArraySet<>();
|
||||
|
||||
// Initializes creation packet
|
||||
this.teamsCreationPacket = new TeamsPacket();
|
||||
this.teamsCreationPacket.teamName = teamName;
|
||||
this.teamsCreationPacket.action = TeamsPacket.Action.CREATE_TEAM;
|
||||
this.teamsCreationPacket.teamDisplayName = this.teamDisplayName.toString();
|
||||
this.teamsCreationPacket.friendlyFlags = this.friendlyFlags;
|
||||
this.teamsCreationPacket.nameTagVisibility = this.nameTagVisibility;
|
||||
this.teamsCreationPacket.collisionRule = this.collisionRule;
|
||||
this.teamsCreationPacket.teamColor = this.teamColor.getId();
|
||||
this.teamsCreationPacket.teamPrefix = this.prefix.toString();
|
||||
this.teamsCreationPacket.teamSuffix = this.suffix.toString();
|
||||
this.teamsCreationPacket.entities = this.entities;
|
||||
|
||||
// Directly write packet since it will not change
|
||||
this.teamsDestroyPacket = PacketUtils.writePacket(this.createTeamDestructionPacket());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -124,7 +101,6 @@ public class Team {
|
||||
System.arraycopy(this.entities, 0, entitiesCache, 0, this.entities.length);
|
||||
entitiesCache[this.entities.length] = member;
|
||||
this.entities = entitiesCache;
|
||||
this.teamsCreationPacket.entities = this.entities;
|
||||
|
||||
// Adds a new member to the team
|
||||
this.members.add(member);
|
||||
@ -134,8 +110,9 @@ public class Team {
|
||||
addPlayerPacket.teamName = this.teamName;
|
||||
addPlayerPacket.action = TeamsPacket.Action.ADD_PLAYERS_TEAM;
|
||||
addPlayerPacket.entities = new String[]{member};
|
||||
|
||||
// Sends to all online players the add player packet
|
||||
PacketWriterUtils.writeAndSend(MinecraftServer.getConnectionManager().getOnlinePlayers(), addPlayerPacket);
|
||||
PacketUtils.sendGroupedPacket(CONNECTION_MANAGER.getOnlinePlayers(), addPlayerPacket);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -150,7 +127,7 @@ public class Team {
|
||||
removePlayerPacket.action = TeamsPacket.Action.REMOVE_PLAYERS_TEAM;
|
||||
removePlayerPacket.entities = new String[]{member};
|
||||
// Sends to all online player teh remove player packet
|
||||
PacketWriterUtils.writeAndSend(MinecraftServer.getConnectionManager().getOnlinePlayers(), removePlayerPacket);
|
||||
PacketUtils.sendGroupedPacket(CONNECTION_MANAGER.getOnlinePlayers(), removePlayerPacket);
|
||||
|
||||
// Removes the player from the
|
||||
this.members.remove(member);
|
||||
@ -161,7 +138,6 @@ public class Team {
|
||||
entitiesCache[count++] = teamMember;
|
||||
}
|
||||
this.entities = entitiesCache;
|
||||
this.teamsCreationPacket.entities = this.entities;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -173,7 +149,6 @@ public class Team {
|
||||
*/
|
||||
public void setTeamDisplayName(ColoredText teamDisplayName) {
|
||||
this.teamDisplayName = teamDisplayName;
|
||||
this.teamsCreationPacket.teamDisplayName = teamDisplayName.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -195,7 +170,6 @@ public class Team {
|
||||
*/
|
||||
public void setNameTagVisibility(NameTagVisibility visibility) {
|
||||
this.nameTagVisibility = visibility;
|
||||
this.teamsCreationPacket.nameTagVisibility = visibility;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -217,7 +191,6 @@ public class Team {
|
||||
*/
|
||||
public void setCollisionRule(CollisionRule rule) {
|
||||
this.collisionRule = rule;
|
||||
this.teamsCreationPacket.collisionRule = rule;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -239,7 +212,6 @@ public class Team {
|
||||
*/
|
||||
public void setTeamColor(ChatColor color) {
|
||||
this.teamColor = color;
|
||||
this.teamsCreationPacket.teamColor = color.getId();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -261,7 +233,6 @@ public class Team {
|
||||
*/
|
||||
public void setPrefix(ColoredText prefix) {
|
||||
this.prefix = prefix;
|
||||
this.teamsCreationPacket.teamPrefix = prefix.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -283,7 +254,6 @@ public class Team {
|
||||
*/
|
||||
public void setSuffix(ColoredText suffix) {
|
||||
this.suffix = suffix;
|
||||
this.teamsCreationPacket.teamSuffix = suffix.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -305,7 +275,6 @@ public class Team {
|
||||
*/
|
||||
public void setFriendlyFlags(byte flag) {
|
||||
this.friendlyFlags = flag;
|
||||
this.teamsCreationPacket.friendlyFlags = flag;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -328,16 +297,24 @@ public class Team {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the creation packet to add a team.
|
||||
* Creates the creation packet to add a team.
|
||||
*
|
||||
* @return the packet to add the team
|
||||
*/
|
||||
public TeamsPacket getTeamsCreationPacket() {
|
||||
return teamsCreationPacket;
|
||||
}
|
||||
public TeamsPacket createTeamsCreationPacket() {
|
||||
TeamsPacket teamsCreationPacket = new TeamsPacket();
|
||||
teamsCreationPacket.teamName = teamName;
|
||||
teamsCreationPacket.action = TeamsPacket.Action.CREATE_TEAM;
|
||||
teamsCreationPacket.teamDisplayName = this.teamDisplayName;
|
||||
teamsCreationPacket.friendlyFlags = this.friendlyFlags;
|
||||
teamsCreationPacket.nameTagVisibility = this.nameTagVisibility;
|
||||
teamsCreationPacket.collisionRule = this.collisionRule;
|
||||
teamsCreationPacket.teamColor = this.teamColor.getId();
|
||||
teamsCreationPacket.teamPrefix = this.prefix;
|
||||
teamsCreationPacket.teamSuffix = this.suffix;
|
||||
teamsCreationPacket.entities = this.entities;
|
||||
|
||||
public ByteBuf getTeamsDestroyPacket() {
|
||||
return teamsDestroyPacket;
|
||||
return teamsCreationPacket;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -435,16 +412,14 @@ public class Team {
|
||||
final TeamsPacket updatePacket = new TeamsPacket();
|
||||
updatePacket.teamName = this.teamName;
|
||||
updatePacket.action = TeamsPacket.Action.UPDATE_TEAM_INFO;
|
||||
updatePacket.teamDisplayName = this.teamDisplayName.toString();
|
||||
updatePacket.teamDisplayName = this.teamDisplayName;
|
||||
updatePacket.friendlyFlags = this.friendlyFlags;
|
||||
updatePacket.nameTagVisibility = this.nameTagVisibility;
|
||||
updatePacket.collisionRule = this.collisionRule;
|
||||
updatePacket.teamColor = this.teamColor.getId();
|
||||
updatePacket.teamPrefix = this.prefix.toString();
|
||||
updatePacket.teamSuffix = this.suffix.toString();
|
||||
ByteBuf buffer = PacketUtils.writePacket(updatePacket);
|
||||
for (Player onlinePlayer : MinecraftServer.getConnectionManager().getOnlinePlayers()) {
|
||||
onlinePlayer.getPlayerConnection().sendPacket(buffer, true);
|
||||
}
|
||||
updatePacket.teamPrefix = this.prefix;
|
||||
updatePacket.teamSuffix = this.suffix;
|
||||
|
||||
PacketUtils.sendGroupedPacket(MinecraftServer.getConnectionManager().getOnlinePlayers(), updatePacket);
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,14 @@
|
||||
package net.minestom.server.scoreboard;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.chat.ChatColor;
|
||||
import net.minestom.server.chat.ColoredText;
|
||||
import net.minestom.server.entity.LivingEntity;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.network.PacketWriterUtils;
|
||||
import net.minestom.server.network.packet.server.ServerPacket;
|
||||
import net.minestom.server.network.ConnectionManager;
|
||||
import net.minestom.server.utils.PacketUtils;
|
||||
import net.minestom.server.utils.UniqueIdUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -20,6 +20,8 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
*/
|
||||
public final class TeamManager {
|
||||
|
||||
private static final ConnectionManager CONNECTION_MANAGER = MinecraftServer.getConnectionManager();
|
||||
|
||||
/**
|
||||
* Represents all registered teams
|
||||
*/
|
||||
@ -37,9 +39,10 @@ public final class TeamManager {
|
||||
*
|
||||
* @param team The team to be registered
|
||||
*/
|
||||
protected void registerNewTeam(Team team) {
|
||||
protected void registerNewTeam(@NotNull Team team) {
|
||||
this.teams.add(team);
|
||||
this.broadcastPacket(team.getTeamsCreationPacket());
|
||||
|
||||
PacketUtils.sendGroupedPacket(MinecraftServer.getConnectionManager().getOnlinePlayers(), team.createTeamsCreationPacket());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -48,7 +51,7 @@ public final class TeamManager {
|
||||
* @param registryName The registry name of team
|
||||
* @return {@code true} if the team was deleted, otherwise {@code false}
|
||||
*/
|
||||
public boolean deleteTeam(String registryName) {
|
||||
public boolean deleteTeam(@NotNull String registryName) {
|
||||
Team team = this.getTeam(registryName);
|
||||
if (team == null) return false;
|
||||
return this.deleteTeam(team);
|
||||
@ -60,9 +63,9 @@ public final class TeamManager {
|
||||
* @param team The team to be deleted
|
||||
* @return {@code true} if the team was deleted, otherwise {@code false}
|
||||
*/
|
||||
public boolean deleteTeam(Team team) {
|
||||
public boolean deleteTeam(@NotNull Team team) {
|
||||
// Sends to all online players a team destroy packet
|
||||
this.broadcastBuffer(team.getTeamsDestroyPacket());
|
||||
PacketUtils.sendGroupedPacket(CONNECTION_MANAGER.getOnlinePlayers(), team.createTeamDestructionPacket());
|
||||
return this.teams.remove(team);
|
||||
}
|
||||
|
||||
@ -72,7 +75,7 @@ public final class TeamManager {
|
||||
* @param name The registry name of the team
|
||||
* @return the team builder
|
||||
*/
|
||||
public TeamBuilder createBuilder(String name) {
|
||||
public TeamBuilder createBuilder(@NotNull String name) {
|
||||
return new TeamBuilder(name, this);
|
||||
}
|
||||
|
||||
@ -82,7 +85,7 @@ public final class TeamManager {
|
||||
* @param name The registry name
|
||||
* @return the created {@link Team}
|
||||
*/
|
||||
public Team createTeam(String name) {
|
||||
public Team createTeam(@NotNull String name) {
|
||||
return this.createBuilder(name).build();
|
||||
}
|
||||
|
||||
@ -193,24 +196,4 @@ public final class TeamManager {
|
||||
public Set<Team> getTeams() {
|
||||
return this.teams;
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcasts to all online {@link Player}'s a {@link ServerPacket}
|
||||
*
|
||||
* @param packet The packet to broadcast
|
||||
*/
|
||||
private void broadcastPacket(ServerPacket packet) {
|
||||
PacketWriterUtils.writeAndSend(MinecraftServer.getConnectionManager().getOnlinePlayers(), packet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcasts to all online {@link Player}'s a buffer
|
||||
*
|
||||
* @param buffer The buffer to broadcast
|
||||
*/
|
||||
private void broadcastBuffer(ByteBuf buffer) {
|
||||
for (Player onlinePlayer : MinecraftServer.getConnectionManager().getOnlinePlayers()) {
|
||||
onlinePlayer.getPlayerConnection().sendPacket(buffer, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,10 +2,13 @@ package net.minestom.server.utils;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.network.packet.server.ServerPacket;
|
||||
import net.minestom.server.utils.binary.BinaryWriter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Class used to write packets.
|
||||
*/
|
||||
@ -15,6 +18,12 @@ public final class PacketUtils {
|
||||
|
||||
}
|
||||
|
||||
public static void sendGroupedPacket(Collection<Player> players, ServerPacket packet) {
|
||||
for (Player player : players) {
|
||||
player.getPlayerConnection().sendPacket(packet);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a {@link ServerPacket} into a {@link ByteBuf}.
|
||||
*
|
||||
|
@ -83,6 +83,12 @@ public class PlayerInit {
|
||||
packetController.setCancel(false);
|
||||
});
|
||||
|
||||
connectionManager.onPacketSend((player, packetController, packet) -> {
|
||||
// Listen to all sent packet
|
||||
System.out.println("PACKET: " + packet.getClass().getSimpleName());
|
||||
packetController.setCancel(false);
|
||||
});
|
||||
|
||||
connectionManager.addPlayerInitialization(player -> {
|
||||
|
||||
player.addEventCallback(EntityAttackEvent.class, event -> {
|
||||
|
Loading…
Reference in New Issue
Block a user