Added the concept of visible chunks and entities

This commit is contained in:
OLEGSHA 2020-12-26 15:25:28 +03:00
parent c6677ec8fd
commit fd0269f913
8 changed files with 87 additions and 5 deletions

View File

@ -5,6 +5,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.concurrent.atomic.AtomicInteger;
import glm.vec._3.i.Vec3i;
import gnu.trove.TCollections;
import gnu.trove.map.TIntObjectMap;
import gnu.trove.map.hash.TIntObjectHashMap;
@ -68,6 +69,10 @@ public class ClientManager {
getServer().getPlayerManager().getPlayers().add(player);
for (ChunkData chunk : server.getWorld().getData().getChunks()) {
if (!client.canSeeChunk(chunk.getPosition())) {
continue;
}
PacketLoadChunk packet = new PacketLoadChunk("Core:LoadChunk");
packet.getPosition().set(
chunk.getPosition().x,
@ -91,7 +96,11 @@ public class ClientManager {
clientsById.remove(client.getId());
}
public void broadcastGamePacket(Packet packet) {
/**
* Sends the provided packet to all connected player clients.
* @param packet the packet to broadcast
*/
public void broadcastToAllPlayers(Packet packet) {
getClients().forEach(c -> {
if (c.getState() != State.CONNECTED) return;
if (!(c instanceof ClientPlayer)) return;
@ -99,6 +108,34 @@ public class ClientManager {
});
}
/**
* Sends the provided packet to all connected player clients that can see the chunk identified by {@code chunkPos}.
* @param packet the packet to broadcast
* @param chunkPos the chunk coordinates of the chunk that must be visible
*/
public void broadcastLocal(Packet packet, Vec3i chunkPos) {
getClients().forEach(c -> {
if (c.getState() != State.CONNECTED) return;
if (!(c instanceof ClientPlayer)) return;
if (!((ClientPlayer) c).canSeeChunk(chunkPos)) return;
c.sendPacket(packet);
});
}
/**
* Sends the provided packet to all connected player clients that can see the entity identified by {@code entityId}.
* @param packet the packet to broadcast
* @param entityId the ID of the entity that must be visible
*/
public void broadcastLocal(Packet packet, long entityId) {
getClients().forEach(c -> {
if (c.getState() != State.CONNECTED) return;
if (!(c instanceof ClientPlayer)) return;
if (!((ClientPlayer) c).canSeeEntity(entityId)) return;
c.sendPacket(packet);
});
}
public Collection<Client> getClients() {
return clients;
}

View File

@ -1,5 +1,8 @@
package ru.windcorp.progressia.server.comms;
import glm.vec._3.i.Vec3i;
import ru.windcorp.progressia.test.TestContent;
public abstract class ClientPlayer extends Client {
public ClientPlayer(int id) {
@ -8,4 +11,12 @@ public abstract class ClientPlayer extends Client {
public abstract String getLogin();
public boolean canSeeChunk(Vec3i chunkPos) {
return true;
}
public boolean canSeeEntity(long entityId) {
return entityId == TestContent.PLAYER_ENTITY_ID;
}
}

View File

@ -45,6 +45,12 @@ class AddTile extends CachedWorldChange {
Coordinates.convertInWorldToChunk(blockInWorld, output);
}
@Override
protected Vec3i getAffectedChunk(Vec3i output) {
getRelevantChunk(output);
return output;
}
@Override
public void dispose() {
super.dispose();

View File

@ -2,7 +2,9 @@ package ru.windcorp.progressia.server.world.tasks;
import java.util.function.Consumer;
import glm.vec._3.i.Vec3i;
import ru.windcorp.progressia.common.comms.packets.PacketWorldChange;
import ru.windcorp.progressia.common.util.Vectors;
import ru.windcorp.progressia.common.world.WorldData;
import ru.windcorp.progressia.server.Server;
@ -24,7 +26,21 @@ public abstract class CachedWorldChange extends CachedChange {
@Override
public void affect(Server server) {
affectCommon(server.getWorld().getData());
server.getClientManager().broadcastGamePacket(packet);
Vec3i v = Vectors.grab3i();
Vec3i chunkPos = getAffectedChunk(v);
if (chunkPos == null) {
server.getClientManager().broadcastToAllPlayers(packet);
} else {
server.getClientManager().broadcastLocal(packet, chunkPos);
}
Vectors.release(chunkPos);
}
protected Vec3i getAffectedChunk(Vec3i output) {
return null;
}
/**

View File

@ -50,7 +50,7 @@ class ChangeEntity extends CachedChange {
CrashReports.report(e, "Could not write entity %s", entity);
}
server.getClientManager().broadcastGamePacket(packet);
server.getClientManager().broadcastLocal(packet, entity.getChunkCoords(null));
}
@Override

View File

@ -41,4 +41,10 @@ class RemoveTile extends CachedWorldChange {
Coordinates.convertInWorldToChunk(blockInWorld, output);
}
@Override
protected Vec3i getAffectedChunk(Vec3i output) {
getRelevantChunk(output);
return output;
}
}

View File

@ -36,6 +36,12 @@ class SetBlock extends CachedWorldChange {
Coordinates.convertInWorldToChunk(blockInWorld, output);
}
@Override
protected Vec3i getAffectedChunk(Vec3i output) {
getRelevantChunk(output);
return output;
}
@Override
public void dispose() {
super.dispose();

View File

@ -37,7 +37,7 @@ public class TestChunkSender implements WorldDataListener {
CrashReports.report(e, "TestChunkSender fjcked up. javahorse stupid");
}
server.getClientManager().broadcastGamePacket(packet);
server.getClientManager().broadcastLocal(packet, chunk.getPosition());
tmp_sendPlayerIfPossible(world, chunk);
}
@ -48,7 +48,7 @@ public class TestChunkSender implements WorldDataListener {
if (Glm.equals(e.getChunkCoords(null), chunk.getPosition())) {
System.out.printf("TestChunkSender: player found in (%d; %d; %d)\n", e.getChunkCoords(null).x, e.getChunkCoords(null).y, e.getChunkCoords(null).z);
server.getClientManager().broadcastGamePacket(new PacketSetLocalPlayer(e.getEntityId()));
server.getClientManager().broadcastToAllPlayers(new PacketSetLocalPlayer(e.getEntityId()));
}
}