use of org.spongepowered.api.world.Chunk in project SpongeCommon by SpongePowered.
the class MixinWorld method updateEntities.
/**
********************* TIMINGS **********************
*/
/**
* @author blood
* @author gabizou - Ported to 1.9.4 - replace direct field calls to overriden methods in MixinWorldServer
*
* @reason Add timing hooks in various areas. This method shouldn't be touched by mods/forge alike
*/
@Overwrite
public void updateEntities() {
// this.profiler.startSection("entities"); // Sponge - Don't use the profiler
// this.profiler.startSection("global"); // Sponge - Don't use the profiler
// Sponge
this.startEntityGlobalTimings();
for (int i = 0; i < this.weatherEffects.size(); ++i) {
net.minecraft.entity.Entity entity = this.weatherEffects.get(i);
try {
++entity.ticksExisted;
entity.onUpdate();
} catch (Throwable throwable2) {
// Sponge - end the entity timing
this.stopTimingForWeatherEntityTickCrash(entity);
CrashReport crashreport = CrashReport.makeCrashReport(throwable2, "Ticking entity");
CrashReportCategory crashreportcategory = crashreport.makeCategory("Entity being ticked");
if (entity == null) {
crashreportcategory.addCrashSection("Entity", "~~NULL~~");
} else {
entity.addEntityCrashInfo(crashreportcategory);
}
SpongeImplHooks.onEntityError(entity, crashreport);
}
if (entity.isDead) {
this.weatherEffects.remove(i--);
}
}
// Sponge
this.stopEntityTickTimingStartEntityRemovalTiming();
// this.profiler.endStartSection("remove"); // Sponge - Don't use the profiler
this.loadedEntityList.removeAll(this.unloadedEntityList);
for (int k = 0; k < this.unloadedEntityList.size(); ++k) {
net.minecraft.entity.Entity entity1 = this.unloadedEntityList.get(k);
// Sponge start - use cached chunk
// int j = entity1.chunkCoordX;
// int k1 = entity1.chunkCoordZ;
final net.minecraft.world.chunk.Chunk activeChunk = (net.minecraft.world.chunk.Chunk) ((IMixinEntity) entity1).getActiveChunk();
if (activeChunk != null) {
activeChunk.removeEntity(entity1);
}
// Sponge end
}
for (int l = 0; l < this.unloadedEntityList.size(); ++l) {
this.onEntityRemoved(this.unloadedEntityList.get(l));
}
this.unloadedEntityList.clear();
// Sponge
this.stopEntityRemovalTiming();
this.tickPlayers();
// this.profiler.endStartSection("regular"); // Sponge - Don't use the profiler
this.entityActivationCheck();
for (int i1 = 0; i1 < this.loadedEntityList.size(); ++i1) {
net.minecraft.entity.Entity entity2 = this.loadedEntityList.get(i1);
net.minecraft.entity.Entity entity3 = entity2.getRidingEntity();
if (entity3 != null) {
if (!entity3.isDead && entity3.isPassenger(entity2)) {
continue;
}
entity2.dismountRidingEntity();
}
// this.profiler.startSection("tick"); // Sponge - Don't use the profiler
// Sponge
this.startEntityTickTiming();
if (!entity2.isDead && !(entity2 instanceof EntityPlayerMP)) {
try {
this.updateEntity(entity2);
} catch (Throwable throwable1) {
// Sponge
this.stopTimingTickEntityCrash(entity2);
CrashReport crashreport1 = CrashReport.makeCrashReport(throwable1, "Ticking entity");
CrashReportCategory crashreportcategory1 = crashreport1.makeCategory("Entity being ticked");
entity2.addEntityCrashInfo(crashreportcategory1);
SpongeImplHooks.onEntityError(entity2, crashreport1);
}
}
// Sponge
this.stopEntityTickSectionBeforeRemove();
// this.profiler.endSection(); // Sponge - Don't use the profiler
// this.profiler.startSection("remove"); // Sponge - Don't use the profiler
// Sponge
this.startEntityRemovalTick();
if (entity2.isDead) {
// Sponge start - use cached chunk
// int l1 = entity2.chunkCoordX;
// int i2 = entity2.chunkCoordZ;
final net.minecraft.world.chunk.Chunk activeChunk = (net.minecraft.world.chunk.Chunk) ((IMixinEntity) entity2).getActiveChunk();
if (activeChunk != null) {
activeChunk.removeEntity(entity2);
}
// Sponge end
this.loadedEntityList.remove(i1--);
this.onEntityRemoved(entity2);
}
// Sponge
this.stopEntityRemovalTiming();
// this.profiler.endSection(); // Sponge - Don't use the profiler
}
// this.profiler.endStartSection("blockEntities"); // Sponge - Don't use the profiler
spongeTileEntityActivation();
this.processingLoadedTiles = true;
Iterator<net.minecraft.tileentity.TileEntity> iterator = this.tickableTileEntities.iterator();
while (iterator.hasNext()) {
// Sponge
this.startTileTickTimer();
net.minecraft.tileentity.TileEntity tileentity = iterator.next();
if (!tileentity.isInvalid() && tileentity.hasWorld()) {
BlockPos blockpos = tileentity.getPos();
if (((IMixinTileEntity) tileentity).shouldTick() && this.worldBorder.contains(blockpos)) {
// Sponge
try {
// this.profiler.startSection(tileentity.getClass().getSimpleName());
((ITickable) tileentity).update();
// this.profiler.endSection();
} catch (Throwable throwable) {
// Sponge
this.stopTimingTickTileEntityCrash(tileentity);
CrashReport crashreport2 = CrashReport.makeCrashReport(throwable, "Ticking block entity");
CrashReportCategory crashreportcategory2 = crashreport2.makeCategory("Block entity being ticked");
tileentity.addInfoToCrashReport(crashreportcategory2);
SpongeImplHooks.onTileEntityError(tileentity, crashreport2);
}
}
}
// Sponge
this.stopTileEntityAndStartRemoval();
if (tileentity.isInvalid()) {
iterator.remove();
this.loadedTileEntityList.remove(tileentity);
// Sponge start - use cached chunk
final net.minecraft.world.chunk.Chunk activeChunk = (net.minecraft.world.chunk.Chunk) ((IMixinTileEntity) tileentity).getActiveChunk();
if (activeChunk != null) {
// Forge: Bugfix: If we set the tile entity it immediately sets it in the chunk, so we could be desynced
if (activeChunk.getTileEntity(tileentity.getPos(), net.minecraft.world.chunk.Chunk.EnumCreateEntityType.CHECK) == tileentity) {
activeChunk.removeTileEntity(tileentity.getPos());
}
}
// Sponge end
}
// Sponge
this.stopTileEntityRemovelInWhile();
}
if (!this.tileEntitiesToBeRemoved.isEmpty()) {
// Sponge start - use forge hook
for (Object tile : this.tileEntitiesToBeRemoved) {
SpongeImplHooks.onTileChunkUnload(((net.minecraft.tileentity.TileEntity) tile));
}
// Sponge end
// forge: faster "contains" makes this removal much more efficient
java.util.Set<net.minecraft.tileentity.TileEntity> remove = java.util.Collections.newSetFromMap(new java.util.IdentityHashMap<>());
remove.addAll(this.tileEntitiesToBeRemoved);
this.tickableTileEntities.removeAll(remove);
this.loadedTileEntityList.removeAll(remove);
this.tileEntitiesToBeRemoved.clear();
}
if (!this.isRemote) {
try (final PhaseContext<?> context = BlockPhase.State.TILE_CHUNK_UNLOAD.createPhaseContext().source(this).buildAndSwitch()) {
// Sponge
this.startPendingTileEntityTimings();
}
}
// FML Move below remove to prevent CMEs
this.processingLoadedTiles = false;
if (!this.addedTileEntityList.isEmpty()) {
for (int j1 = 0; j1 < this.addedTileEntityList.size(); ++j1) {
net.minecraft.tileentity.TileEntity tileentity1 = this.addedTileEntityList.get(j1);
if (!tileentity1.isInvalid()) {
if (!this.loadedTileEntityList.contains(tileentity1)) {
this.addTileEntity(tileentity1);
}
if (this.isBlockLoaded(tileentity1.getPos())) {
net.minecraft.world.chunk.Chunk chunk = this.getChunkFromBlockCoords(tileentity1.getPos());
IBlockState iblockstate = chunk.getBlockState(tileentity1.getPos());
chunk.addTileEntity(tileentity1.getPos(), tileentity1);
this.notifyBlockUpdate(tileentity1.getPos(), iblockstate, iblockstate, 3);
}
}
}
this.addedTileEntityList.clear();
}
// Sponge
this.endPendingTileEntities();
// this.profiler.endSection(); // Sponge - Don't use the profiler
// this.profiler.endSection(); // Sponge - Don't use the profiler
}
use of org.spongepowered.api.world.Chunk in project LanternServer by LanternPowered.
the class LightningSpawnerAction method run.
@Override
public void run(ScriptContext scriptContext) {
final LanternWorld world = (LanternWorld) scriptContext.get(Parameters.WORLD).get();
final Random random = RANDOM.get();
final Iterable<Chunk> chunks = world.getLoadedChunks();
final int chance = (int) (1f / Math.max(this.chance, 0.000000000001f));
for (Chunk chunk : chunks) {
for (int i = 0; i < this.attemptsPerChunk; i++) {
final LanternChunk chunk1 = (LanternChunk) chunk;
if (random.nextInt(chance) != 0) {
continue;
}
final int value = random.nextInt(0x10000);
final int x = chunk1.getX() << 4 | value & 0xf;
final int z = chunk1.getZ() << 4 | (value >> 4) & 0xf;
final Entity entity = world.createEntity(EntityTypes.LIGHTNING, new Vector3d(x, world.getHighestYAt(x, z), z));
world.spawnEntity(entity);
}
}
}
use of org.spongepowered.api.world.Chunk in project LanternServer by LanternPowered.
the class LanternChunkManager method loadTickets.
public void loadTickets() throws IOException {
final Multimap<String, LanternLoadingTicket> tickets = LanternLoadingTicketIO.load(this.worldFolder, this, this.chunkLoadService);
final Iterator<Entry<String, LanternLoadingTicket>> it = tickets.entries().iterator();
final CauseStack causeStack = CauseStack.current();
while (it.hasNext()) {
final LanternLoadingTicket ticket = it.next().getValue();
if (ticket instanceof LanternEntityLoadingTicket) {
final LanternEntityLoadingTicket ticket0 = (LanternEntityLoadingTicket) ticket;
final EntityReference ref = ticket0.getEntityReference().orElse(null);
if (ref != null) {
causeStack.pushCause(ticket0);
final LanternChunk chunk = getOrCreateChunk(ref.getChunkCoords(), causeStack, true, true);
causeStack.popCause();
final Entity entity = chunk.getEntity(ref.getUniqueId()).orElse(null);
if (entity != null) {
ticket0.bindToEntity(entity);
} else {
// The entity is gone?
it.remove();
}
} else {
// The entity is gone?
it.remove();
}
}
}
for (Entry<String, Collection<LanternLoadingTicket>> entry : tickets.asMap().entrySet()) {
final Collection<ChunkTicketManager.Callback> callbacks = this.chunkLoadService.getCallbacks().get(entry.getKey());
// These maps will be loaded lazily
ImmutableListMultimap<UUID, LoadingTicket> playerLoadedTickets = null;
ImmutableList<LoadingTicket> nonPlayerLoadedTickets = null;
final Set<LoadingTicket> resultPlayerLoadedTickets = entry.getValue().stream().filter(ticket -> ticket instanceof PlayerLoadingTicket).collect(Collectors.toSet());
final Set<LoadingTicket> resultNonPlayerLoadedTickets = entry.getValue().stream().filter(ticket -> !(ticket instanceof PlayerLoadingTicket)).collect(Collectors.toSet());
final int maxTickets = this.chunkLoadService.getMaxTicketsById(entry.getKey());
for (ChunkTicketManager.Callback callback : callbacks) {
if (callback instanceof ChunkTicketManager.OrderedCallback) {
if (nonPlayerLoadedTickets == null) {
nonPlayerLoadedTickets = ImmutableList.copyOf(resultNonPlayerLoadedTickets);
resultNonPlayerLoadedTickets.clear();
}
final List<LoadingTicket> result = ((ChunkTicketManager.OrderedCallback) callback).onLoaded(nonPlayerLoadedTickets, this.world, maxTickets);
checkNotNull(result, "The OrderedCallback#onLoaded method may not return null, " + "error caused by (plugin=%s, clazz=%s)", entry.getKey(), callback.getClass().getName());
resultNonPlayerLoadedTickets.addAll(result);
}
if (callback instanceof ChunkTicketManager.PlayerOrderedCallback) {
if (playerLoadedTickets == null) {
final ImmutableListMultimap.Builder<UUID, LoadingTicket> mapBuilder = ImmutableListMultimap.builder();
resultPlayerLoadedTickets.forEach(ticket -> mapBuilder.put(((PlayerLoadingTicket) ticket).getPlayerUniqueId(), ticket));
resultPlayerLoadedTickets.clear();
playerLoadedTickets = mapBuilder.build();
}
final ListMultimap<UUID, LoadingTicket> result = ((ChunkTicketManager.PlayerOrderedCallback) callback).onPlayerLoaded(playerLoadedTickets, this.world);
checkNotNull(result, "The PlayerOrderedCallback#onPlayerLoaded method may not return null, " + "error caused by (plugin=%s, clazz=%s)", entry.getKey(), callback.getClass().getName());
resultPlayerLoadedTickets.addAll(result.values());
}
}
final List<LoadingTicket> resultLoadedTickets = new ArrayList<>();
resultLoadedTickets.addAll(resultPlayerLoadedTickets);
resultLoadedTickets.addAll(resultNonPlayerLoadedTickets);
// Lets see how many plugins attempted to add loading tickets
final int sizeA = resultLoadedTickets.size();
resultLoadedTickets.retainAll(entry.getValue());
final int sizeB = resultLoadedTickets.size();
if (sizeA != sizeB) {
Lantern.getLogger().warn("The plugin {} attempted to add LoadingTicket's that were previously not present.", entry.getKey());
}
// Remove all the tickets that are already released
resultLoadedTickets.removeIf(ticket -> ((ChunkLoadingTicket) ticket).isReleased());
if (resultLoadedTickets.size() > maxTickets) {
Lantern.getLogger().warn("The plugin {} has too many open chunk loading tickets {}. " + "Excess will be dropped", entry.getKey(), resultLoadedTickets.size());
resultLoadedTickets.subList(maxTickets, resultLoadedTickets.size()).clear();
}
// Release all the tickets that were no longer usable
final List<LoadingTicket> removedTickets = new ArrayList<>(entry.getValue());
removedTickets.removeAll(resultLoadedTickets);
removedTickets.forEach(LoadingTicket::release);
final ImmutableList<LoadingTicket> loadedTickets = ImmutableList.copyOf(resultLoadedTickets);
for (ChunkTicketManager.Callback callback : callbacks) {
callback.onLoaded(loadedTickets, this.world);
}
}
}
use of org.spongepowered.api.world.Chunk in project CatClearLag by Time6628.
the class EntitiesCommand method execute.
@Override
public CommandResult execute(CommandSource src, CommandContext args) throws CommandException {
List<Chunk> chunksToSort = (List<Chunk>) ((Player) src).getWorld().getLoadedChunks();
TreeMap<Chunk, Integer> sortedChunks = new TreeMap<>((o1, o2) -> Integer.compare(o2.getEntities().size(), o1.getEntities().size()));
for (Chunk chunk : chunksToSort) {
sortedChunks.put(chunk, chunk.getEntities().size());
}
List<Text> texts = new ArrayList<>();
sortedChunks.forEach(((chunk, integer) -> texts.add(Text.builder().append(Text.of(chunk.getPosition().getX() + "," + chunk.getPosition().getZ() + " contains " + integer + " entities.")).onClick(callback(chunk)).build())));
plugin.getPaginationService().builder().contents((texts)).title(Text.builder().color(TextColors.LIGHT_PURPLE).append(Text.of("Laggy Chunks")).build()).sendTo(src);
return CommandResult.success();
}
use of org.spongepowered.api.world.Chunk in project CatClearLag by Time6628.
the class TilesCommand method execute.
@Override
public CommandResult execute(CommandSource src, CommandContext args) throws CommandException {
List<Chunk> chunksToSort = (List<Chunk>) ((Player) src).getWorld().getLoadedChunks();
TreeMap<Chunk, Integer> sortedChunks = new TreeMap<>((o1, o2) -> Integer.compare(o2.getTileEntities().size(), o1.getTileEntities().size()));
for (Chunk chunk : chunksToSort) {
sortedChunks.put(chunk, chunk.getTileEntities().size());
}
List<Text> texts = new ArrayList<>();
sortedChunks.forEach(((chunk, integer) -> texts.add(Text.builder().append(Text.of(chunk.getPosition().getX() + "," + chunk.getPosition().getZ() + " contains " + integer + " tiles.")).onClick(callback(chunk)).build())));
plugin.getPaginationService().builder().contents((texts)).title(Text.builder().color(TextColors.LIGHT_PURPLE).append(Text.of("Laggy Chunks")).build()).sendTo(src);
return CommandResult.success();
}
Aggregations