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
protected void doRender() {
client.getComms().processPackets();
Camera camera = client.getCamera();
if (camera.hasAnchor()) {
renderWorld();

View File

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

View File

@ -91,6 +91,7 @@ public class Server {
this.playerManager = new PlayerManager(this);
this.loadManager = new LoadManager(this);
schedule(getClientManager()::processPackets);
schedule(new ChunkRequestDaemon(loadManager.getChunkManager())::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.map.TIntObjectMap;
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.packets.Packet;
import ru.windcorp.progressia.common.world.PacketSetGravityModel;
@ -92,6 +93,10 @@ public class ClientManager {
client.disconnect();
clientsById.remove(client.getId());
}
public void processPackets() {
getClients().forEach(CommsChannel::processPackets);
}
/**
* 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.comms.controls.*;
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.generation.planet.PlanetGravityModel;
import ru.windcorp.progressia.server.world.tile.*;
@ -486,11 +489,22 @@ public class TestContent {
Vec3i blockInWorld = controlData.getBlockInWorld();
AbsFace face = controlData.getFace();
if (server.getWorld().getData().getChunkByBlock(blockInWorld) == null)
if (server.getWorld().getData().getChunkByBlock(blockInWorld) == null) {
return;
if (server.getWorld().getData().getTiles(blockInWorld, face).isFull())
}
if (server.getWorld().getData().getTiles(blockInWorld, face).isFull()) {
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() {