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