use of org.valkyrienskies.core.game.IPlayer in project Valkyrien-Skies-2 by ValkyrienSkies.
the class MixinServerWorld method postTick.
@Inject(method = "tick", at = @At("TAIL"))
private void postTick(final BooleanSupplier shouldKeepTicking, final CallbackInfo ci) {
// First update the IPlayer wrapper list
updateVSPlayerWrappers();
// Find newly loaded chunks
final List<ChunkHolder> loadedChunksList = Lists.newArrayList(((ThreadedAnvilChunkStorageAccessor) serverChunkManager.threadedAnvilChunkStorage).callEntryIterator());
// Create DenseVoxelShapeUpdate for new loaded chunks
final List<IVoxelShapeUpdate> newLoadedChunks = new ArrayList<>();
for (final ChunkHolder chunkHolder : loadedChunksList) {
final Optional<WorldChunk> worldChunkOptional = chunkHolder.getTickingFuture().getNow(ChunkHolder.UNLOADED_WORLD_CHUNK).left();
if (worldChunkOptional.isPresent()) {
final WorldChunk worldChunk = worldChunkOptional.get();
final int chunkX = worldChunk.getPos().x;
final int chunkZ = worldChunk.getPos().z;
final ChunkSection[] chunkSections = worldChunk.getSectionArray();
// For now just assume chunkY goes from 0 to 16
for (int chunkY = 0; chunkY < 16; chunkY++) {
final ChunkSection chunkSection = chunkSections[chunkY];
final Vector3ic chunkPos = new Vector3i(chunkX, chunkY, chunkZ);
if (!knownChunkRegions.contains(chunkPos)) {
if (chunkSection != null) {
// Add this chunk to the ground rigid body
final DenseVoxelShapeUpdate voxelShapeUpdate = VSGameUtilsKt.toDenseVoxelUpdate(chunkSection, chunkPos);
newLoadedChunks.add(voxelShapeUpdate);
} else {
final EmptyVoxelShapeUpdate emptyVoxelShapeUpdate = new EmptyVoxelShapeUpdate(chunkPos.x(), chunkPos.y(), chunkPos.z(), false, false);
newLoadedChunks.add(emptyVoxelShapeUpdate);
}
knownChunkRegions.add(chunkPos);
}
}
}
}
// Then tick the ship world
shipObjectWorld.tickShips(newLoadedChunks);
// Send ships to clients
final IVSPacket shipDataPacket = VSPacketShipDataList.Companion.create(shipObjectWorld.getQueryableShipData().iterator());
for (final ServerPlayerEntity playerEntity : players) {
VSNetworking.shipDataPacketToClientSender.sendToClient(shipDataPacket, playerEntity);
}
// Then determine the chunk watch/unwatch tasks, and then execute them
final ImmutableList<IPlayer> playersToTick = ImmutableList.copyOf(vsPlayerWrappers.values());
final Pair<Spliterator<ChunkWatchTask>, Spliterator<ChunkUnwatchTask>> chunkWatchAndUnwatchTasksPair = shipObjectWorld.tickShipChunkLoading(playersToTick);
// Use Spliterator instead of iterators so that we can multi thread the execution of these tasks
final Spliterator<ChunkWatchTask> chunkWatchTasks = chunkWatchAndUnwatchTasksPair.getFirst();
final Spliterator<ChunkUnwatchTask> chunkUnwatchTasks = chunkWatchAndUnwatchTasksPair.getSecond();
// But for now just do it single threaded
chunkWatchTasks.forEachRemaining(chunkWatchTask -> {
System.out.println("Watch task for " + chunkWatchTask.getChunkX() + " : " + chunkWatchTask.getChunkZ());
final Packet<?>[] chunkPacketBuffer = new Packet[2];
final ChunkPos chunkPos = new ChunkPos(chunkWatchTask.getChunkX(), chunkWatchTask.getChunkZ());
// TODO: Move this somewhere else
serverChunkManager.setChunkForced(chunkPos, true);
for (final IPlayer player : chunkWatchTask.getPlayersNeedWatching()) {
final MinecraftPlayer minecraftPlayer = (MinecraftPlayer) player;
final ServerPlayerEntity serverPlayerEntity = (ServerPlayerEntity) minecraftPlayer.getPlayerEntityReference().get();
if (serverPlayerEntity != null) {
((ThreadedAnvilChunkStorageAccessor) serverChunkManager.threadedAnvilChunkStorage).callSendWatchPackets(serverPlayerEntity, chunkPos, chunkPacketBuffer, false, true);
}
}
chunkWatchTask.onExecuteChunkWatchTask();
});
chunkUnwatchTasks.forEachRemaining(chunkUnwatchTask -> {
System.out.println("Unwatch task for " + chunkUnwatchTask.getChunkX() + " : " + chunkUnwatchTask.getChunkZ());
chunkUnwatchTask.onExecuteChunkUnwatchTask();
});
}
use of org.valkyrienskies.core.game.IPlayer in project Valkyrien-Skies-2 by ValkyrienSkies.
the class MixinThreadedAnvilChunkStorage method postGetPlayersWatchingChunk.
/**
* Force the game send chunk update packets to players watching ship chunks.
*
* @author Tri0de
*/
@Inject(method = "getPlayersWatchingChunk", at = @At("TAIL"), cancellable = true)
private void postGetPlayersWatchingChunk(final ChunkPos chunkPos, final boolean onlyOnWatchDistanceEdge, final CallbackInfoReturnable<Stream<ServerPlayerEntity>> cir) {
final Iterator<IPlayer> playersWatchingShipChunk = VSGameUtilsKt.getShipObjectWorld(world).getIPlayersWatchingShipChunk(chunkPos.x, chunkPos.z);
if (!playersWatchingShipChunk.hasNext()) {
// No players watching this ship chunk, so we don't need to modify anything
return;
}
final Stream<ServerPlayerEntity> oldReturnValue = cir.getReturnValue();
final Set<ServerPlayerEntity> watchingPlayers = new HashSet<>();
oldReturnValue.forEach(watchingPlayers::add);
playersWatchingShipChunk.forEachRemaining(iPlayer -> {
final MinecraftPlayer minecraftPlayer = (MinecraftPlayer) iPlayer;
final ServerPlayerEntity playerEntity = (ServerPlayerEntity) minecraftPlayer.getPlayerEntityReference().get();
if (playerEntity != null) {
watchingPlayers.add(playerEntity);
}
});
final Stream<ServerPlayerEntity> newReturnValue = watchingPlayers.stream();
cir.setReturnValue(newReturnValue);
}
Aggregations