mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-12-26 10:39:07 +00:00
Fix infinite spawning bug
This commit is contained in:
@@ -152,6 +152,12 @@ public class BoardSVC implements IrisService, BoardProvider {
|
||||
v.add(C.LIGHT_PURPLE + "Tasks" + C.GRAY + ": " + Form.f(Iris.jobCount()));
|
||||
}
|
||||
|
||||
if(engine.getBlockUpdatesPerSecond() > 0)
|
||||
{
|
||||
v.add("&7&m------------------");
|
||||
v.add(C.LIGHT_PURPLE + "BUD/s" + C.GRAY + ": " + Form.f(engine.getBlockUpdatesPerSecond()));
|
||||
}
|
||||
|
||||
v.add("&7&m------------------");
|
||||
|
||||
return v;
|
||||
|
||||
@@ -68,6 +68,8 @@ import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
@Data
|
||||
public class IrisEngine implements Engine {
|
||||
private final AtomicInteger bud;
|
||||
private final AtomicInteger buds;
|
||||
private final AtomicInteger generated;
|
||||
private final AtomicInteger generatedLast;
|
||||
private final AtomicDouble perSecond;
|
||||
@@ -77,6 +79,7 @@ public class IrisEngine implements Engine {
|
||||
private EngineEffects effects;
|
||||
private final EngineMantle mantle;
|
||||
private final ChronoLatch perSecondLatch;
|
||||
private final ChronoLatch perSecondBudLatch;
|
||||
private EngineExecutionEnvironment execution;
|
||||
private EngineWorldManager worldManager;
|
||||
private volatile int parallelism;
|
||||
@@ -105,12 +108,15 @@ public class IrisEngine implements Engine {
|
||||
public IrisEngine(EngineTarget target, boolean studio) {
|
||||
this.studio = studio;
|
||||
this.target = target;
|
||||
bud = new AtomicInteger(0);
|
||||
buds = new AtomicInteger(0);
|
||||
metrics = new EngineMetrics(32);
|
||||
cleanLatch = new ChronoLatch(Math.max(10000, Math.min(IrisSettings.get().getParallax()
|
||||
.getParallaxChunkEvictionMS(), IrisSettings.get().getParallax().getParallaxRegionEvictionMS())));
|
||||
generatedLast = new AtomicInteger(0);
|
||||
perSecond = new AtomicDouble(0);
|
||||
perSecondLatch = new ChronoLatch(1000, false);
|
||||
perSecondBudLatch = new ChronoLatch(1000, false);
|
||||
wallClock = new AtomicRollingSequence(32);
|
||||
lastGPS = new AtomicLong(M.ms());
|
||||
generated = new AtomicInteger(0);
|
||||
@@ -130,6 +136,12 @@ public class IrisEngine implements Engine {
|
||||
}
|
||||
|
||||
private void tickRandomPlayer() {
|
||||
if(perSecondBudLatch.flip())
|
||||
{
|
||||
buds.set(bud.get());
|
||||
bud.set(0);
|
||||
}
|
||||
|
||||
if (effects != null) {
|
||||
effects.tickRandomPlayer();
|
||||
}
|
||||
@@ -272,6 +284,11 @@ public class IrisEngine implements Engine {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBlockUpdatesPerSecond() {
|
||||
return buds.get();
|
||||
}
|
||||
|
||||
public void printMetrics(CommandSender sender) {
|
||||
KMap<String, Double> totals = new KMap<>();
|
||||
KMap<String, Double> weights = new KMap<>();
|
||||
@@ -444,6 +461,11 @@ public class IrisEngine implements Engine {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void blockUpdatedMetric() {
|
||||
bud.incrementAndGet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IrisBiome getFocus() {
|
||||
if (getDimension().getFocus() == null || getDimension().getFocus().trim().isEmpty()) {
|
||||
|
||||
@@ -38,6 +38,7 @@ import com.volmit.iris.util.mantle.Mantle;
|
||||
import com.volmit.iris.util.mantle.MantleFlag;
|
||||
import com.volmit.iris.util.math.M;
|
||||
import com.volmit.iris.util.math.RNG;
|
||||
import com.volmit.iris.util.plugin.Chunks;
|
||||
import com.volmit.iris.util.scheduling.ChronoLatch;
|
||||
import com.volmit.iris.util.scheduling.J;
|
||||
import com.volmit.iris.util.scheduling.Looper;
|
||||
@@ -154,6 +155,7 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
|
||||
private void updateChunks() {
|
||||
for (Player i : getEngine().getWorld().realWorld().getPlayers()) {
|
||||
int r = 2;
|
||||
|
||||
Chunk c = i.getLocation().getChunk();
|
||||
for (int x = -r; x <= r; x++) {
|
||||
for (int z = -r; z <= r; z++) {
|
||||
@@ -216,6 +218,12 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
|
||||
}
|
||||
|
||||
Chunk c = cc[RNG.r.nextInt(cc.length)];
|
||||
|
||||
if(!c.isLoaded() || !Chunks.isSafe(c.getWorld(), c.getX(), c.getZ()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
spawnIn(c, false);
|
||||
chunkCooldowns.put(Cache.key(c), M.ms());
|
||||
}
|
||||
|
||||
@@ -86,6 +86,8 @@ import java.util.function.Consumer;
|
||||
public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdater, Renderer, Hotloadable {
|
||||
IrisComplex getComplex();
|
||||
|
||||
int getBlockUpdatesPerSecond();
|
||||
|
||||
void printMetrics(CommandSender sender);
|
||||
|
||||
EngineMantle getMantle();
|
||||
@@ -230,6 +232,8 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
|
||||
|
||||
}
|
||||
|
||||
void blockUpdatedMetric();
|
||||
|
||||
@ChunkCoordinates
|
||||
@Override
|
||||
default void updateChunk(Chunk c) {
|
||||
@@ -298,7 +302,7 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
|
||||
default void update(int x, int y, int z, Chunk c, RNG rf) {
|
||||
Block block = c.getBlock(x, y, z);
|
||||
BlockData data = block.getBlockData();
|
||||
|
||||
blockUpdatedMetric();
|
||||
if (B.isStorage(data)) {
|
||||
RNG rx = rf.nextParallelRNG(BlockPosition.toLong(x, y, z));
|
||||
InventorySlotType slot = null;
|
||||
|
||||
@@ -125,6 +125,17 @@ public abstract class EngineAssignedWorldManager extends EngineAssignedComponent
|
||||
|
||||
@EventHandler
|
||||
public void on(ChunkLoadEvent e) {
|
||||
|
||||
try
|
||||
{
|
||||
throw new RuntimeException("WHO FUCKIN DUN IT?");
|
||||
}
|
||||
|
||||
catch(Throwable ee)
|
||||
{
|
||||
ee.printStackTrace();
|
||||
}
|
||||
|
||||
if (e.getChunk().getWorld().equals(getTarget().getWorld().realWorld())) {
|
||||
onChunkLoad(e.getChunk(), e.isNewChunk());
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ import com.volmit.iris.util.format.C;
|
||||
import com.volmit.iris.util.json.JSONObject;
|
||||
import com.volmit.iris.util.math.M;
|
||||
import com.volmit.iris.util.math.RNG;
|
||||
import com.volmit.iris.util.plugin.Chunks;
|
||||
import com.volmit.iris.util.plugin.VolmitSender;
|
||||
import com.volmit.iris.util.scheduling.J;
|
||||
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
||||
@@ -173,6 +174,11 @@ public class IrisEntity extends IrisRegistrant {
|
||||
}
|
||||
|
||||
public Entity spawn(Engine gen, Location at, RNG rng) {
|
||||
if(!Chunks.isSafe(at))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (isSpawnEffectRiseOutOfGround()) {
|
||||
Location b = at.clone();
|
||||
double sy = b.getY() - 5;
|
||||
@@ -182,6 +188,11 @@ public class IrisEntity extends IrisRegistrant {
|
||||
|
||||
Entity ee = doSpawn(at);
|
||||
|
||||
if(ee == null && !Chunks.isSafe(at))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!spawnerScript.isEmpty() && ee == null) {
|
||||
synchronized (this) {
|
||||
gen.getExecution().getAPI().setLocation(at);
|
||||
@@ -331,15 +342,22 @@ public class IrisEntity extends IrisRegistrant {
|
||||
}
|
||||
}
|
||||
|
||||
if (isSpawnEffectRiseOutOfGround() && e instanceof LivingEntity) {
|
||||
if (Chunks.hasPlayersNearby(at) && isSpawnEffectRiseOutOfGround() && e instanceof LivingEntity) {
|
||||
Location start = at.clone();
|
||||
e.setInvulnerable(true);
|
||||
((LivingEntity) e).setAI(false);
|
||||
((LivingEntity) e).setCollidable(false);
|
||||
((LivingEntity) e).setNoDamageTicks(100000);
|
||||
|
||||
AtomicInteger t = new AtomicInteger(0);
|
||||
AtomicInteger v = new AtomicInteger(0);
|
||||
v.set(J.sr(() -> {
|
||||
if(t.get() > 100)
|
||||
{
|
||||
J.csr(v.get());
|
||||
return;
|
||||
}
|
||||
|
||||
t.incrementAndGet();
|
||||
if (e.getLocation().getBlock().getType().isSolid() || ((LivingEntity) e).getEyeLocation().getBlock().getType().isSolid()) {
|
||||
e.teleport(start.add(new Vector(0, 0.1, 0)));
|
||||
ItemStack itemCrackData = new ItemStack(((LivingEntity) e).getEyeLocation().clone().subtract(0, 2, 0).getBlock().getBlockData().getMaterial());
|
||||
@@ -376,6 +394,11 @@ public class IrisEntity extends IrisRegistrant {
|
||||
}
|
||||
|
||||
private Entity doSpawn(Location at) {
|
||||
if(!Chunks.isSafe(at))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (type.equals(EntityType.UNKNOWN)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -70,7 +70,6 @@ public interface DecreeSystem extends CommandExecutor, TabCompleter {
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
default boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
||||
if (!sender.hasPermission("iris.all")) {
|
||||
|
||||
54
src/main/java/com/volmit/iris/util/plugin/Chunks.java
Normal file
54
src/main/java/com/volmit/iris/util/plugin/Chunks.java
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.plugin;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class Chunks {
|
||||
public static boolean isSafe(World w, int x, int z)
|
||||
{
|
||||
return w.isChunkLoaded(x, z)
|
||||
&& w.isChunkLoaded(x+1, z)
|
||||
&& w.isChunkLoaded(x, z+1)
|
||||
&& w.isChunkLoaded(x-1, z)
|
||||
&& w.isChunkLoaded(x, z-1)
|
||||
&& w.isChunkLoaded(x-1, z-1)
|
||||
&& w.isChunkLoaded(x+1, z+1)
|
||||
&& w.isChunkLoaded(x+1, z-1)
|
||||
&& w.isChunkLoaded(x-1, z+1);
|
||||
}
|
||||
|
||||
public static boolean isSafe(Location l)
|
||||
{
|
||||
return isSafe(l.getWorld(), l.getBlockX() >> 4, l.getBlockZ() >> 4);
|
||||
}
|
||||
|
||||
public static boolean hasPlayersNearby(Location at) {
|
||||
try{
|
||||
return !at.getWorld().getNearbyEntities(at, 32, 32, 32, (i) -> i instanceof Player).isEmpty();
|
||||
}
|
||||
|
||||
catch(Throwable ignored)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user