Added packet buffering and fix crash when placing flowers on leaves

- Packets are now buffered before processing to reduce stack depth
- Attempts to place tiles on invalid locations get rejected earlier
This commit is contained in:
OLEGSHA 2021-08-23 17:37:25 +03:00
parent 84864f8947
commit 62729f5873
Signed by: OLEGSHA
GPG Key ID: E57A4B08D64AFF7A
5 changed files with 39 additions and 3 deletions

View File

@ -76,6 +76,8 @@ public class LayerWorld extends Layer {
@Override @Override
protected void doRender() { protected void doRender() {
client.getComms().processPackets();
Camera camera = client.getCamera(); Camera camera = client.getCamera();
if (camera.hasAnchor()) { if (camera.hasAnchor()) {
renderWorld(); renderWorld();

View File

@ -22,6 +22,7 @@ import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List;
import ru.windcorp.progressia.common.comms.packets.Packet; import ru.windcorp.progressia.common.comms.packets.Packet;
@ -53,6 +54,8 @@ public abstract class CommsChannel {
private State state = State.CONNECTING; private State state = State.CONNECTING;
private final Collection<CommsListener> listeners = Collections.synchronizedCollection(new ArrayList<>()); private final Collection<CommsListener> listeners = Collections.synchronizedCollection(new ArrayList<>());
private final List<Packet> pendingPackets = Collections.synchronizedList(new ArrayList<>());
protected abstract void doSendPacket(Packet packet) throws IOException; protected abstract void doSendPacket(Packet packet) throws IOException;
@ -101,8 +104,19 @@ public abstract class CommsChannel {
public abstract void disconnect(); public abstract void disconnect();
protected void onPacketReceived(Packet packet) { protected void onPacketReceived(Packet packet) {
pendingPackets.add(packet);
}
protected void forwardPacketToListeners(Packet packet) {
listeners.forEach(l -> l.onPacketReceived(packet)); listeners.forEach(l -> l.onPacketReceived(packet));
} }
public void processPackets() {
synchronized (pendingPackets) {
pendingPackets.forEach(this::forwardPacketToListeners);
pendingPackets.clear();
}
}
public void addListener(CommsListener listener) { public void addListener(CommsListener listener) {
listeners.add(listener); listeners.add(listener);

View File

@ -91,6 +91,7 @@ public class Server {
this.playerManager = new PlayerManager(this); this.playerManager = new PlayerManager(this);
this.loadManager = new LoadManager(this); this.loadManager = new LoadManager(this);
schedule(getClientManager()::processPackets);
schedule(new ChunkRequestDaemon(loadManager.getChunkManager())::tick); schedule(new ChunkRequestDaemon(loadManager.getChunkManager())::tick);
schedule(new EntityRequestDaemon(loadManager.getEntityManager())::tick); schedule(new EntityRequestDaemon(loadManager.getEntityManager())::tick);

View File

@ -26,6 +26,7 @@ import glm.vec._3.i.Vec3i;
import gnu.trove.TCollections; import gnu.trove.TCollections;
import gnu.trove.map.TIntObjectMap; import gnu.trove.map.TIntObjectMap;
import gnu.trove.map.hash.TIntObjectHashMap; import gnu.trove.map.hash.TIntObjectHashMap;
import ru.windcorp.progressia.common.comms.CommsChannel;
import ru.windcorp.progressia.common.comms.CommsChannel.State; import ru.windcorp.progressia.common.comms.CommsChannel.State;
import ru.windcorp.progressia.common.comms.packets.Packet; import ru.windcorp.progressia.common.comms.packets.Packet;
import ru.windcorp.progressia.common.world.PacketSetGravityModel; import ru.windcorp.progressia.common.world.PacketSetGravityModel;
@ -92,6 +93,10 @@ public class ClientManager {
client.disconnect(); client.disconnect();
clientsById.remove(client.getId()); clientsById.remove(client.getId());
} }
public void processPackets() {
getClients().forEach(CommsChannel::processPackets);
}
/** /**
* Sends the provided packet to all connected player clients. * Sends the provided packet to all connected player clients.

View File

@ -55,6 +55,9 @@ import ru.windcorp.progressia.common.world.tile.*;
import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.server.Server;
import ru.windcorp.progressia.server.comms.controls.*; import ru.windcorp.progressia.server.comms.controls.*;
import ru.windcorp.progressia.server.world.block.*; import ru.windcorp.progressia.server.world.block.*;
import ru.windcorp.progressia.server.world.context.ServerBlockContext;
import ru.windcorp.progressia.server.world.context.ServerTileContext;
import ru.windcorp.progressia.server.world.context.ServerTileStackContext;
import ru.windcorp.progressia.server.world.entity.*; import ru.windcorp.progressia.server.world.entity.*;
import ru.windcorp.progressia.server.world.generation.planet.PlanetGravityModel; import ru.windcorp.progressia.server.world.generation.planet.PlanetGravityModel;
import ru.windcorp.progressia.server.world.tile.*; import ru.windcorp.progressia.server.world.tile.*;
@ -486,11 +489,22 @@ public class TestContent {
Vec3i blockInWorld = controlData.getBlockInWorld(); Vec3i blockInWorld = controlData.getBlockInWorld();
AbsFace face = controlData.getFace(); AbsFace face = controlData.getFace();
if (server.getWorld().getData().getChunkByBlock(blockInWorld) == null) if (server.getWorld().getData().getChunkByBlock(blockInWorld) == null) {
return; return;
if (server.getWorld().getData().getTiles(blockInWorld, face).isFull()) }
if (server.getWorld().getData().getTiles(blockInWorld, face).isFull()) {
return; return;
server.createAbsoluteContext().addTile(blockInWorld, face.relativize(AbsFace.POS_Z), tile); }
ServerBlockContext context = server.createContext(blockInWorld);
ServerTileStackContext tsContext = context.push(context.toContext(face));
ServerTileContext tileContext = tsContext.push(tsContext.getTileCount());
TileLogic logic = TileLogicRegistry.getInstance().get(tile.getId());
if (!logic.canOccupyFace(tileContext)) {
return;
}
tileContext.addTile(tile);
} }
private static void registerMisc() { private static void registerMisc() {