Search in sources :

Example 1 with IPlayer

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();
    });
}
Also used : IPlayer(org.valkyrienskies.core.game.IPlayer) ChunkWatchTask(org.valkyrienskies.core.chunk_tracking.ChunkWatchTask) ChunkHolder(net.minecraft.server.world.ChunkHolder) EmptyVoxelShapeUpdate(org.valkyrienskies.physics_api.voxel_updates.EmptyVoxelShapeUpdate) ArrayList(java.util.ArrayList) ChunkUnwatchTask(org.valkyrienskies.core.chunk_tracking.ChunkUnwatchTask) WorldChunk(net.minecraft.world.chunk.WorldChunk) Vector3ic(org.joml.Vector3ic) MinecraftPlayer(org.valkyrienskies.mod.common.util.MinecraftPlayer) IVoxelShapeUpdate(org.valkyrienskies.physics_api.voxel_updates.IVoxelShapeUpdate) ChunkPos(net.minecraft.util.math.ChunkPos) ThreadedAnvilChunkStorageAccessor(org.valkyrienskies.mod.mixin.accessors.server.world.ThreadedAnvilChunkStorageAccessor) Spliterator(java.util.Spliterator) DenseVoxelShapeUpdate(org.valkyrienskies.physics_api.voxel_updates.DenseVoxelShapeUpdate) Packet(net.minecraft.network.Packet) IVSPacket(org.valkyrienskies.core.networking.IVSPacket) ServerPlayerEntity(net.minecraft.server.network.ServerPlayerEntity) Vector3i(org.joml.Vector3i) IVSPacket(org.valkyrienskies.core.networking.IVSPacket) ChunkSection(net.minecraft.world.chunk.ChunkSection) Inject(org.spongepowered.asm.mixin.injection.Inject)

Example 2 with IPlayer

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);
}
Also used : IPlayer(org.valkyrienskies.core.game.IPlayer) MinecraftPlayer(org.valkyrienskies.mod.common.util.MinecraftPlayer) ServerPlayerEntity(net.minecraft.server.network.ServerPlayerEntity) HashSet(java.util.HashSet) Inject(org.spongepowered.asm.mixin.injection.Inject)

Aggregations

ServerPlayerEntity (net.minecraft.server.network.ServerPlayerEntity)2 Inject (org.spongepowered.asm.mixin.injection.Inject)2 IPlayer (org.valkyrienskies.core.game.IPlayer)2 MinecraftPlayer (org.valkyrienskies.mod.common.util.MinecraftPlayer)2 ArrayList (java.util.ArrayList)1 HashSet (java.util.HashSet)1 Spliterator (java.util.Spliterator)1 Packet (net.minecraft.network.Packet)1 ChunkHolder (net.minecraft.server.world.ChunkHolder)1 ChunkPos (net.minecraft.util.math.ChunkPos)1 ChunkSection (net.minecraft.world.chunk.ChunkSection)1 WorldChunk (net.minecraft.world.chunk.WorldChunk)1 Vector3i (org.joml.Vector3i)1 Vector3ic (org.joml.Vector3ic)1 ChunkUnwatchTask (org.valkyrienskies.core.chunk_tracking.ChunkUnwatchTask)1 ChunkWatchTask (org.valkyrienskies.core.chunk_tracking.ChunkWatchTask)1 IVSPacket (org.valkyrienskies.core.networking.IVSPacket)1 ThreadedAnvilChunkStorageAccessor (org.valkyrienskies.mod.mixin.accessors.server.world.ThreadedAnvilChunkStorageAccessor)1 DenseVoxelShapeUpdate (org.valkyrienskies.physics_api.voxel_updates.DenseVoxelShapeUpdate)1 EmptyVoxelShapeUpdate (org.valkyrienskies.physics_api.voxel_updates.EmptyVoxelShapeUpdate)1