9
0
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:
cyberpwn
2021-08-29 10:25:52 -04:00
parent 7997d52df5
commit 04c44de145
8 changed files with 131 additions and 4 deletions

View File

@@ -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;

View File

@@ -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()) {

View File

@@ -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());
}

View File

@@ -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;

View File

@@ -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());
}

View File

@@ -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;
}

View File

@@ -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")) {

View 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;
}
}
}