mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-06 00:17:58 +01:00
Optimize bandwidth + fix keep alive
This commit is contained in:
parent
b00627f778
commit
eb5659c235
@ -1,5 +1,7 @@
|
|||||||
package net.minestom.server;
|
package net.minestom.server;
|
||||||
|
|
||||||
|
import net.kyori.text.TextComponent;
|
||||||
|
import net.kyori.text.format.TextColor;
|
||||||
import net.minestom.server.entity.EntityManager;
|
import net.minestom.server.entity.EntityManager;
|
||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
||||||
import net.minestom.server.instance.InstanceManager;
|
import net.minestom.server.instance.InstanceManager;
|
||||||
@ -12,6 +14,9 @@ import java.util.concurrent.ExecutorService;
|
|||||||
|
|
||||||
public class UpdateManager {
|
public class UpdateManager {
|
||||||
|
|
||||||
|
private static final long KEEP_ALIVE_DELAY = 10_000;
|
||||||
|
private static final long KEEP_ALIVE_KICK = 30_000;
|
||||||
|
|
||||||
private ExecutorService mainUpdate = new MinestomThread(MinecraftServer.THREAD_COUNT_MAIN_UPDATE, MinecraftServer.THREAD_NAME_MAIN_UPDATE);
|
private ExecutorService mainUpdate = new MinestomThread(MinecraftServer.THREAD_COUNT_MAIN_UPDATE, MinecraftServer.THREAD_NAME_MAIN_UPDATE);
|
||||||
private boolean stopRequested;
|
private boolean stopRequested;
|
||||||
|
|
||||||
@ -33,9 +38,14 @@ public class UpdateManager {
|
|||||||
final long time = System.currentTimeMillis();
|
final long time = System.currentTimeMillis();
|
||||||
final KeepAlivePacket keepAlivePacket = new KeepAlivePacket(time);
|
final KeepAlivePacket keepAlivePacket = new KeepAlivePacket(time);
|
||||||
for (Player player : connectionManager.getOnlinePlayers()) {
|
for (Player player : connectionManager.getOnlinePlayers()) {
|
||||||
if (time - player.getLastKeepAlive() > 10000) {
|
final long lastKeepAlive = time - player.getLastKeepAlive();
|
||||||
|
if (lastKeepAlive > KEEP_ALIVE_DELAY && player.didAnswerKeepAlive()) {
|
||||||
player.refreshKeepAlive(time);
|
player.refreshKeepAlive(time);
|
||||||
player.getPlayerConnection().sendPacket(keepAlivePacket);
|
player.getPlayerConnection().sendPacket(keepAlivePacket);
|
||||||
|
} else if (lastKeepAlive >= KEEP_ALIVE_KICK) {
|
||||||
|
TextComponent textComponent = TextComponent.of("No Keep Alive answer")
|
||||||
|
.color(TextColor.RED);
|
||||||
|
player.kick(textComponent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,6 +266,8 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
|||||||
public boolean addViewer(Player player) {
|
public boolean addViewer(Player player) {
|
||||||
Check.notNull(player, "Viewer cannot be null");
|
Check.notNull(player, "Viewer cannot be null");
|
||||||
boolean result = this.viewers.add(player);
|
boolean result = this.viewers.add(player);
|
||||||
|
if (!result)
|
||||||
|
return false;
|
||||||
player.viewableEntities.add(this);
|
player.viewableEntities.add(this);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -142,6 +142,9 @@ public abstract class EntityCreature extends LivingEntity {
|
|||||||
@Override
|
@Override
|
||||||
public boolean addViewer(Player player) {
|
public boolean addViewer(Player player) {
|
||||||
boolean result = super.addViewer(player);
|
boolean result = super.addViewer(player);
|
||||||
|
if (!result)
|
||||||
|
return false;
|
||||||
|
|
||||||
PlayerConnection playerConnection = player.getPlayerConnection();
|
PlayerConnection playerConnection = player.getPlayerConnection();
|
||||||
|
|
||||||
EntityPacket entityPacket = new EntityPacket();
|
EntityPacket entityPacket = new EntityPacket();
|
||||||
|
@ -30,6 +30,10 @@ public abstract class ObjectEntity extends Entity {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean addViewer(Player player) {
|
public boolean addViewer(Player player) {
|
||||||
|
boolean result = super.addViewer(player);
|
||||||
|
if (!result)
|
||||||
|
return false;
|
||||||
|
|
||||||
PlayerConnection playerConnection = player.getPlayerConnection();
|
PlayerConnection playerConnection = player.getPlayerConnection();
|
||||||
|
|
||||||
SpawnEntityPacket spawnEntityPacket = new SpawnEntityPacket();
|
SpawnEntityPacket spawnEntityPacket = new SpawnEntityPacket();
|
||||||
@ -46,7 +50,7 @@ public abstract class ObjectEntity extends Entity {
|
|||||||
playerConnection.sendPacket(getPassengersPacket());
|
playerConnection.sendPacket(getPassengersPacket());
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.addViewer(player); // Add player to viewers list
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -54,6 +54,7 @@ import java.util.function.Consumer;
|
|||||||
public class Player extends LivingEntity {
|
public class Player extends LivingEntity {
|
||||||
|
|
||||||
private long lastKeepAlive;
|
private long lastKeepAlive;
|
||||||
|
private boolean answerKeepAlive;
|
||||||
|
|
||||||
private String username;
|
private String username;
|
||||||
protected PlayerConnection playerConnection;
|
protected PlayerConnection playerConnection;
|
||||||
@ -144,6 +145,9 @@ public class Player extends LivingEntity {
|
|||||||
|
|
||||||
setCanPickupItem(true); // By default
|
setCanPickupItem(true); // By default
|
||||||
|
|
||||||
|
// Allow the server to send the next keep alive packet
|
||||||
|
refreshAnswerKeepAlive(true);
|
||||||
|
|
||||||
this.gameMode = GameMode.SURVIVAL;
|
this.gameMode = GameMode.SURVIVAL;
|
||||||
this.dimension = Dimension.OVERWORLD;
|
this.dimension = Dimension.OVERWORLD;
|
||||||
this.levelType = LevelType.DEFAULT;
|
this.levelType = LevelType.DEFAULT;
|
||||||
@ -337,11 +341,10 @@ public class Player extends LivingEntity {
|
|||||||
// Tick event
|
// Tick event
|
||||||
callEvent(PlayerTickEvent.class, playerTickEvent);
|
callEvent(PlayerTickEvent.class, playerTickEvent);
|
||||||
|
|
||||||
|
|
||||||
// Multiplayer sync
|
// Multiplayer sync
|
||||||
if (!getViewers().isEmpty()) {
|
final boolean positionChanged = position.getX() != lastX || position.getY() != lastY || position.getZ() != lastZ;
|
||||||
final boolean positionChanged = position.getX() != lastX || position.getZ() != lastZ || position.getY() != lastY;
|
|
||||||
final boolean viewChanged = position.getYaw() != lastYaw || position.getPitch() != lastPitch;
|
final boolean viewChanged = position.getYaw() != lastYaw || position.getPitch() != lastPitch;
|
||||||
|
if (!getViewers().isEmpty() && (positionChanged || viewChanged)) {
|
||||||
ServerPacket updatePacket = null;
|
ServerPacket updatePacket = null;
|
||||||
ServerPacket optionalUpdatePacket = null;
|
ServerPacket optionalUpdatePacket = null;
|
||||||
if (positionChanged && viewChanged) {
|
if (positionChanged && viewChanged) {
|
||||||
@ -483,6 +486,9 @@ public class Player extends LivingEntity {
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
boolean result = super.addViewer(player);
|
boolean result = super.addViewer(player);
|
||||||
|
if (!result)
|
||||||
|
return false;
|
||||||
|
|
||||||
PlayerConnection viewerConnection = player.getPlayerConnection();
|
PlayerConnection viewerConnection = player.getPlayerConnection();
|
||||||
String property = "eyJ0aW1lc3RhbXAiOjE1NjU0ODMwODQwOTYsInByb2ZpbGVJZCI6ImFiNzBlY2I0MjM0NjRjMTRhNTJkN2EwOTE1MDdjMjRlIiwicHJvZmlsZU5hbWUiOiJUaGVNb2RlOTExIiwidGV4dHVyZXMiOnsiU0tJTiI6eyJ1cmwiOiJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlL2RkOTE2NzJiNTE0MmJhN2Y3MjA2ZTRjN2IwOTBkNzhlM2Y1ZDc2NDdiNWFmZDIyNjFhZDk4OGM0MWI2ZjcwYTEifX19";
|
String property = "eyJ0aW1lc3RhbXAiOjE1NjU0ODMwODQwOTYsInByb2ZpbGVJZCI6ImFiNzBlY2I0MjM0NjRjMTRhNTJkN2EwOTE1MDdjMjRlIiwicHJvZmlsZU5hbWUiOiJUaGVNb2RlOTExIiwidGV4dHVyZXMiOnsiU0tJTiI6eyJ1cmwiOiJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlL2RkOTE2NzJiNTE0MmJhN2Y3MjA2ZTRjN2IwOTBkNzhlM2Y1ZDc2NDdiNWFmZDIyNjFhZDk4OGM0MWI2ZjcwYTEifX19";
|
||||||
SpawnPlayerPacket spawnPlayerPacket = new SpawnPlayerPacket();
|
SpawnPlayerPacket spawnPlayerPacket = new SpawnPlayerPacket();
|
||||||
@ -1566,6 +1572,15 @@ public class Player extends LivingEntity {
|
|||||||
*/
|
*/
|
||||||
public void refreshKeepAlive(long lastKeepAlive) {
|
public void refreshKeepAlive(long lastKeepAlive) {
|
||||||
this.lastKeepAlive = lastKeepAlive;
|
this.lastKeepAlive = lastKeepAlive;
|
||||||
|
this.answerKeepAlive = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean didAnswerKeepAlive() {
|
||||||
|
return answerKeepAlive;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void refreshAnswerKeepAlive(boolean answerKeepAlive) {
|
||||||
|
this.answerKeepAlive = answerKeepAlive;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -121,7 +121,7 @@ public class Inventory implements InventoryModifier, InventoryClickHandler, View
|
|||||||
* Refresh the inventory for all viewers
|
* Refresh the inventory for all viewers
|
||||||
*/
|
*/
|
||||||
public void update() {
|
public void update() {
|
||||||
PacketWriterUtils.writeAndSend(getViewers(), getWindowItemsPacket());
|
PacketWriterUtils.writeAndSend(getViewers(), createWindowItemsPacket());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -134,7 +134,7 @@ public class Inventory implements InventoryModifier, InventoryClickHandler, View
|
|||||||
if (!getViewers().contains(player))
|
if (!getViewers().contains(player))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
PacketWriterUtils.writeAndSend(player, getWindowItemsPacket());
|
PacketWriterUtils.writeAndSend(player, createWindowItemsPacket());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -145,8 +145,7 @@ public class Inventory implements InventoryModifier, InventoryClickHandler, View
|
|||||||
@Override
|
@Override
|
||||||
public boolean addViewer(Player player) {
|
public boolean addViewer(Player player) {
|
||||||
boolean result = this.viewers.add(player);
|
boolean result = this.viewers.add(player);
|
||||||
WindowItemsPacket windowItemsPacket = getWindowItemsPacket();
|
PacketWriterUtils.writeAndSend(player, createWindowItemsPacket());
|
||||||
player.getPlayerConnection().sendPacket(windowItemsPacket);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,7 +173,7 @@ public class Inventory implements InventoryModifier, InventoryClickHandler, View
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private WindowItemsPacket getWindowItemsPacket() {
|
private WindowItemsPacket createWindowItemsPacket() {
|
||||||
WindowItemsPacket windowItemsPacket = new WindowItemsPacket();
|
WindowItemsPacket windowItemsPacket = new WindowItemsPacket();
|
||||||
windowItemsPacket.windowId = getWindowId();
|
windowItemsPacket.windowId = getWindowId();
|
||||||
windowItemsPacket.count = (short) itemStacks.length;
|
windowItemsPacket.count = (short) itemStacks.length;
|
||||||
|
@ -18,6 +18,8 @@ public class KeepAliveListener {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
player.refreshAnswerKeepAlive(true);
|
||||||
|
|
||||||
// Update latency
|
// Update latency
|
||||||
int latency = (int) (System.currentTimeMillis() - packet.id);
|
int latency = (int) (System.currentTimeMillis() - packet.id);
|
||||||
player.refreshLatency(latency);
|
player.refreshLatency(latency);
|
||||||
|
@ -26,8 +26,7 @@ public class PacketWriterUtils {
|
|||||||
|
|
||||||
public static void writeAndSend(Collection<Player> players, ServerPacket serverPacket) {
|
public static void writeAndSend(Collection<Player> players, ServerPacket serverPacket) {
|
||||||
batchesPool.execute(() -> {
|
batchesPool.execute(() -> {
|
||||||
int size = players.size();
|
if (players.isEmpty())
|
||||||
if (size == 0)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ByteBuf buffer = PacketUtils.writePacket(serverPacket);
|
ByteBuf buffer = PacketUtils.writePacket(serverPacket);
|
||||||
|
Loading…
Reference in New Issue
Block a user