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.Collections;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
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;
@ -68,6 +69,10 @@ public class ClientManager {
getServer().getPlayerManager().getPlayers().add(player); getServer().getPlayerManager().getPlayers().add(player);
for (ChunkData chunk : server.getWorld().getData().getChunks()) { for (ChunkData chunk : server.getWorld().getData().getChunks()) {
if (!client.canSeeChunk(chunk.getPosition())) {
continue;
}
PacketLoadChunk packet = new PacketLoadChunk("Core:LoadChunk"); PacketLoadChunk packet = new PacketLoadChunk("Core:LoadChunk");
packet.getPosition().set( packet.getPosition().set(
chunk.getPosition().x, chunk.getPosition().x,
@ -91,7 +96,11 @@ public class ClientManager {
clientsById.remove(client.getId()); 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 -> { getClients().forEach(c -> {
if (c.getState() != State.CONNECTED) return; if (c.getState() != State.CONNECTED) return;
if (!(c instanceof ClientPlayer)) 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() { public Collection<Client> getClients() {
return clients; return clients;
} }

View File

@ -1,5 +1,8 @@
package ru.windcorp.progressia.server.comms; 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 abstract class ClientPlayer extends Client {
public ClientPlayer(int id) { public ClientPlayer(int id) {
@ -8,4 +11,12 @@ public abstract class ClientPlayer extends Client {
public abstract String getLogin(); 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); Coordinates.convertInWorldToChunk(blockInWorld, output);
} }
@Override
protected Vec3i getAffectedChunk(Vec3i output) {
getRelevantChunk(output);
return output;
}
@Override @Override
public void dispose() { public void dispose() {
super.dispose(); super.dispose();

View File

@ -2,7 +2,9 @@ package ru.windcorp.progressia.server.world.tasks;
import java.util.function.Consumer; import java.util.function.Consumer;
import glm.vec._3.i.Vec3i;
import ru.windcorp.progressia.common.comms.packets.PacketWorldChange; 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.common.world.WorldData;
import ru.windcorp.progressia.server.Server; import ru.windcorp.progressia.server.Server;
@ -24,7 +26,21 @@ public abstract class CachedWorldChange extends CachedChange {
@Override @Override
public void affect(Server server) { public void affect(Server server) {
affectCommon(server.getWorld().getData()); 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); CrashReports.report(e, "Could not write entity %s", entity);
} }
server.getClientManager().broadcastGamePacket(packet); server.getClientManager().broadcastLocal(packet, entity.getChunkCoords(null));
} }
@Override @Override

View File

@ -41,4 +41,10 @@ class RemoveTile extends CachedWorldChange {
Coordinates.convertInWorldToChunk(blockInWorld, output); 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); Coordinates.convertInWorldToChunk(blockInWorld, output);
} }
@Override
protected Vec3i getAffectedChunk(Vec3i output) {
getRelevantChunk(output);
return output;
}
@Override @Override
public void dispose() { public void dispose() {
super.dispose(); super.dispose();

View File

@ -37,7 +37,7 @@ public class TestChunkSender implements WorldDataListener {
CrashReports.report(e, "TestChunkSender fjcked up. javahorse stupid"); CrashReports.report(e, "TestChunkSender fjcked up. javahorse stupid");
} }
server.getClientManager().broadcastGamePacket(packet); server.getClientManager().broadcastLocal(packet, chunk.getPosition());
tmp_sendPlayerIfPossible(world, chunk); tmp_sendPlayerIfPossible(world, chunk);
} }
@ -48,7 +48,7 @@ public class TestChunkSender implements WorldDataListener {
if (Glm.equals(e.getChunkCoords(null), chunk.getPosition())) { 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); 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()));
} }
} }