mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-06-17 22:32:04 +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()));
|
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------------------");
|
v.add("&7&m------------------");
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
|
|||||||
@@ -68,6 +68,8 @@ import java.util.concurrent.atomic.AtomicLong;
|
|||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class IrisEngine implements Engine {
|
public class IrisEngine implements Engine {
|
||||||
|
private final AtomicInteger bud;
|
||||||
|
private final AtomicInteger buds;
|
||||||
private final AtomicInteger generated;
|
private final AtomicInteger generated;
|
||||||
private final AtomicInteger generatedLast;
|
private final AtomicInteger generatedLast;
|
||||||
private final AtomicDouble perSecond;
|
private final AtomicDouble perSecond;
|
||||||
@@ -77,6 +79,7 @@ public class IrisEngine implements Engine {
|
|||||||
private EngineEffects effects;
|
private EngineEffects effects;
|
||||||
private final EngineMantle mantle;
|
private final EngineMantle mantle;
|
||||||
private final ChronoLatch perSecondLatch;
|
private final ChronoLatch perSecondLatch;
|
||||||
|
private final ChronoLatch perSecondBudLatch;
|
||||||
private EngineExecutionEnvironment execution;
|
private EngineExecutionEnvironment execution;
|
||||||
private EngineWorldManager worldManager;
|
private EngineWorldManager worldManager;
|
||||||
private volatile int parallelism;
|
private volatile int parallelism;
|
||||||
@@ -105,12 +108,15 @@ public class IrisEngine implements Engine {
|
|||||||
public IrisEngine(EngineTarget target, boolean studio) {
|
public IrisEngine(EngineTarget target, boolean studio) {
|
||||||
this.studio = studio;
|
this.studio = studio;
|
||||||
this.target = target;
|
this.target = target;
|
||||||
|
bud = new AtomicInteger(0);
|
||||||
|
buds = new AtomicInteger(0);
|
||||||
metrics = new EngineMetrics(32);
|
metrics = new EngineMetrics(32);
|
||||||
cleanLatch = new ChronoLatch(Math.max(10000, Math.min(IrisSettings.get().getParallax()
|
cleanLatch = new ChronoLatch(Math.max(10000, Math.min(IrisSettings.get().getParallax()
|
||||||
.getParallaxChunkEvictionMS(), IrisSettings.get().getParallax().getParallaxRegionEvictionMS())));
|
.getParallaxChunkEvictionMS(), IrisSettings.get().getParallax().getParallaxRegionEvictionMS())));
|
||||||
generatedLast = new AtomicInteger(0);
|
generatedLast = new AtomicInteger(0);
|
||||||
perSecond = new AtomicDouble(0);
|
perSecond = new AtomicDouble(0);
|
||||||
perSecondLatch = new ChronoLatch(1000, false);
|
perSecondLatch = new ChronoLatch(1000, false);
|
||||||
|
perSecondBudLatch = new ChronoLatch(1000, false);
|
||||||
wallClock = new AtomicRollingSequence(32);
|
wallClock = new AtomicRollingSequence(32);
|
||||||
lastGPS = new AtomicLong(M.ms());
|
lastGPS = new AtomicLong(M.ms());
|
||||||
generated = new AtomicInteger(0);
|
generated = new AtomicInteger(0);
|
||||||
@@ -130,6 +136,12 @@ public class IrisEngine implements Engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void tickRandomPlayer() {
|
private void tickRandomPlayer() {
|
||||||
|
if(perSecondBudLatch.flip())
|
||||||
|
{
|
||||||
|
buds.set(bud.get());
|
||||||
|
bud.set(0);
|
||||||
|
}
|
||||||
|
|
||||||
if (effects != null) {
|
if (effects != null) {
|
||||||
effects.tickRandomPlayer();
|
effects.tickRandomPlayer();
|
||||||
}
|
}
|
||||||
@@ -272,6 +284,11 @@ public class IrisEngine implements Engine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBlockUpdatesPerSecond() {
|
||||||
|
return buds.get();
|
||||||
|
}
|
||||||
|
|
||||||
public void printMetrics(CommandSender sender) {
|
public void printMetrics(CommandSender sender) {
|
||||||
KMap<String, Double> totals = new KMap<>();
|
KMap<String, Double> totals = new KMap<>();
|
||||||
KMap<String, Double> weights = new KMap<>();
|
KMap<String, Double> weights = new KMap<>();
|
||||||
@@ -444,6 +461,11 @@ public class IrisEngine implements Engine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void blockUpdatedMetric() {
|
||||||
|
bud.incrementAndGet();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IrisBiome getFocus() {
|
public IrisBiome getFocus() {
|
||||||
if (getDimension().getFocus() == null || getDimension().getFocus().trim().isEmpty()) {
|
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.mantle.MantleFlag;
|
||||||
import com.volmit.iris.util.math.M;
|
import com.volmit.iris.util.math.M;
|
||||||
import com.volmit.iris.util.math.RNG;
|
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.ChronoLatch;
|
||||||
import com.volmit.iris.util.scheduling.J;
|
import com.volmit.iris.util.scheduling.J;
|
||||||
import com.volmit.iris.util.scheduling.Looper;
|
import com.volmit.iris.util.scheduling.Looper;
|
||||||
@@ -154,6 +155,7 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
|
|||||||
private void updateChunks() {
|
private void updateChunks() {
|
||||||
for (Player i : getEngine().getWorld().realWorld().getPlayers()) {
|
for (Player i : getEngine().getWorld().realWorld().getPlayers()) {
|
||||||
int r = 2;
|
int r = 2;
|
||||||
|
|
||||||
Chunk c = i.getLocation().getChunk();
|
Chunk c = i.getLocation().getChunk();
|
||||||
for (int x = -r; x <= r; x++) {
|
for (int x = -r; x <= r; x++) {
|
||||||
for (int z = -r; z <= r; z++) {
|
for (int z = -r; z <= r; z++) {
|
||||||
@@ -216,6 +218,12 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Chunk c = cc[RNG.r.nextInt(cc.length)];
|
Chunk c = cc[RNG.r.nextInt(cc.length)];
|
||||||
|
|
||||||
|
if(!c.isLoaded() || !Chunks.isSafe(c.getWorld(), c.getX(), c.getZ()))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
spawnIn(c, false);
|
spawnIn(c, false);
|
||||||
chunkCooldowns.put(Cache.key(c), M.ms());
|
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 {
|
public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdater, Renderer, Hotloadable {
|
||||||
IrisComplex getComplex();
|
IrisComplex getComplex();
|
||||||
|
|
||||||
|
int getBlockUpdatesPerSecond();
|
||||||
|
|
||||||
void printMetrics(CommandSender sender);
|
void printMetrics(CommandSender sender);
|
||||||
|
|
||||||
EngineMantle getMantle();
|
EngineMantle getMantle();
|
||||||
@@ -230,6 +232,8 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void blockUpdatedMetric();
|
||||||
|
|
||||||
@ChunkCoordinates
|
@ChunkCoordinates
|
||||||
@Override
|
@Override
|
||||||
default void updateChunk(Chunk c) {
|
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) {
|
default void update(int x, int y, int z, Chunk c, RNG rf) {
|
||||||
Block block = c.getBlock(x, y, z);
|
Block block = c.getBlock(x, y, z);
|
||||||
BlockData data = block.getBlockData();
|
BlockData data = block.getBlockData();
|
||||||
|
blockUpdatedMetric();
|
||||||
if (B.isStorage(data)) {
|
if (B.isStorage(data)) {
|
||||||
RNG rx = rf.nextParallelRNG(BlockPosition.toLong(x, y, z));
|
RNG rx = rf.nextParallelRNG(BlockPosition.toLong(x, y, z));
|
||||||
InventorySlotType slot = null;
|
InventorySlotType slot = null;
|
||||||
|
|||||||
@@ -125,6 +125,17 @@ public abstract class EngineAssignedWorldManager extends EngineAssignedComponent
|
|||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void on(ChunkLoadEvent e) {
|
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())) {
|
if (e.getChunk().getWorld().equals(getTarget().getWorld().realWorld())) {
|
||||||
onChunkLoad(e.getChunk(), e.isNewChunk());
|
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.json.JSONObject;
|
||||||
import com.volmit.iris.util.math.M;
|
import com.volmit.iris.util.math.M;
|
||||||
import com.volmit.iris.util.math.RNG;
|
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.plugin.VolmitSender;
|
||||||
import com.volmit.iris.util.scheduling.J;
|
import com.volmit.iris.util.scheduling.J;
|
||||||
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
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) {
|
public Entity spawn(Engine gen, Location at, RNG rng) {
|
||||||
|
if(!Chunks.isSafe(at))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
if (isSpawnEffectRiseOutOfGround()) {
|
if (isSpawnEffectRiseOutOfGround()) {
|
||||||
Location b = at.clone();
|
Location b = at.clone();
|
||||||
double sy = b.getY() - 5;
|
double sy = b.getY() - 5;
|
||||||
@@ -182,6 +188,11 @@ public class IrisEntity extends IrisRegistrant {
|
|||||||
|
|
||||||
Entity ee = doSpawn(at);
|
Entity ee = doSpawn(at);
|
||||||
|
|
||||||
|
if(ee == null && !Chunks.isSafe(at))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
if (!spawnerScript.isEmpty() && ee == null) {
|
if (!spawnerScript.isEmpty() && ee == null) {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
gen.getExecution().getAPI().setLocation(at);
|
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();
|
Location start = at.clone();
|
||||||
e.setInvulnerable(true);
|
e.setInvulnerable(true);
|
||||||
((LivingEntity) e).setAI(false);
|
((LivingEntity) e).setAI(false);
|
||||||
((LivingEntity) e).setCollidable(false);
|
((LivingEntity) e).setCollidable(false);
|
||||||
((LivingEntity) e).setNoDamageTicks(100000);
|
((LivingEntity) e).setNoDamageTicks(100000);
|
||||||
|
AtomicInteger t = new AtomicInteger(0);
|
||||||
AtomicInteger v = new AtomicInteger(0);
|
AtomicInteger v = new AtomicInteger(0);
|
||||||
v.set(J.sr(() -> {
|
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()) {
|
if (e.getLocation().getBlock().getType().isSolid() || ((LivingEntity) e).getEyeLocation().getBlock().getType().isSolid()) {
|
||||||
e.teleport(start.add(new Vector(0, 0.1, 0)));
|
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());
|
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) {
|
private Entity doSpawn(Location at) {
|
||||||
|
if(!Chunks.isSafe(at))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
if (type.equals(EntityType.UNKNOWN)) {
|
if (type.equals(EntityType.UNKNOWN)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,7 +70,6 @@ public interface DecreeSystem extends CommandExecutor, TabCompleter {
|
|||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
default boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
||||||
if (!sender.hasPermission("iris.all")) {
|
if (!sender.hasPermission("iris.all")) {
|
||||||
|
|||||||
@@ -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