mirror of
https://github.com/StarWishsama/Slimefun4.git
synced 2024-09-19 19:25:48 +00:00
Performance and memory improvements
This commit is contained in:
parent
d77fd498f8
commit
d0e7e21877
@ -48,6 +48,7 @@
|
||||
* Memory/GC improvements for the profiler
|
||||
* Performance improvements for the Fluid Pump
|
||||
* Removed EmeraldEnchants integration
|
||||
* Memory and performance improvements for ticking blocks
|
||||
|
||||
#### Fixes
|
||||
* Fixed #2448
|
||||
|
2
pom.xml
2
pom.xml
@ -337,7 +337,7 @@
|
||||
<dependency>
|
||||
<groupId>com.github.TheBusyBiscuit</groupId>
|
||||
<artifactId>CS-CoreLib2</artifactId>
|
||||
<version>0.27.3</version>
|
||||
<version>0.27.4</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@ -132,10 +132,15 @@ public abstract class Network {
|
||||
*
|
||||
* @param l
|
||||
* The {@link Location} to check for
|
||||
*
|
||||
* @return Whether the given {@link Location} is part of this {@link Network}
|
||||
*/
|
||||
public boolean connectsTo(@Nonnull Location l) {
|
||||
return connectedLocations.contains(l);
|
||||
if (regulator.equals(l)) {
|
||||
return true;
|
||||
} else {
|
||||
return connectedLocations.contains(l);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
@ -75,9 +75,11 @@ public class RainbowTickHandler extends BlockTicker {
|
||||
}
|
||||
|
||||
for (Material type : materials) {
|
||||
// This BlockData is purely virtual and only created on startup, it should have
|
||||
// no impact on performance, in fact it should save performance as it preloads
|
||||
// the data but also saves heavy calls for other Materials
|
||||
/**
|
||||
* This BlockData is purely virtual and only created on startup, it should have
|
||||
* no impact on performance, in fact it should save performance as it preloads
|
||||
* the data but also saves heavy calls for other Materials
|
||||
*/
|
||||
if (type.createBlockData() instanceof GlassPane) {
|
||||
return true;
|
||||
}
|
||||
@ -89,8 +91,10 @@ public class RainbowTickHandler extends BlockTicker {
|
||||
@Override
|
||||
public void tick(Block b, SlimefunItem item, Config data) {
|
||||
if (b.getType() == Material.AIR) {
|
||||
// The block was broken, setting the Material now would result in a
|
||||
// duplication glitch
|
||||
/**
|
||||
* The block was broken, setting the Material now would result in a
|
||||
* duplication glitch
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,6 @@ import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
import io.github.thebusybiscuit.cscorelib2.math.DoubleHandler;
|
||||
import io.github.thebusybiscuit.slimefun4.api.ErrorReport;
|
||||
import io.github.thebusybiscuit.slimefun4.api.network.Network;
|
||||
import io.github.thebusybiscuit.slimefun4.api.network.NetworkComponent;
|
||||
@ -23,6 +22,7 @@ import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent;
|
||||
import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetProvider;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.NumberUtils;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.holograms.SimpleHologram;
|
||||
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
|
||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
||||
@ -254,10 +254,10 @@ public class EnergyNet extends Network {
|
||||
|
||||
private void updateHologram(@Nonnull Block b, double supply, double demand) {
|
||||
if (demand > supply) {
|
||||
String netLoss = DoubleHandler.getFancyDouble(Math.abs(supply - demand));
|
||||
String netLoss = NumberUtils.getCompactDouble(demand - supply);
|
||||
SimpleHologram.update(b, "&4&l- &c" + netLoss + " &7J &e\u26A1");
|
||||
} else {
|
||||
String netGain = DoubleHandler.getFancyDouble(supply - demand);
|
||||
String netGain = NumberUtils.getCompactDouble(supply - demand);
|
||||
SimpleHologram.update(b, "&2&l+ &a" + netGain + " &7J &e\u26A1");
|
||||
}
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ public class SlimefunProfiler {
|
||||
*/
|
||||
private static final int MAX_TICK_DURATION = 100;
|
||||
|
||||
private final SlimefunThreadFactory threadFactory = new SlimefunThreadFactory(5);
|
||||
private final SlimefunThreadFactory threadFactory = new SlimefunThreadFactory(8);
|
||||
private final ExecutorService executor = Executors.newFixedThreadPool(threadFactory.getThreadCount(), threadFactory);
|
||||
|
||||
private final AtomicBoolean running = new AtomicBoolean(false);
|
||||
|
@ -8,12 +8,12 @@ import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import io.github.thebusybiscuit.cscorelib2.math.DoubleHandler;
|
||||
import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent;
|
||||
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler;
|
||||
import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNet;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.NumberUtils;
|
||||
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
||||
import me.mrCookieSlime.Slimefun.Objects.Category;
|
||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
||||
@ -50,8 +50,8 @@ public class Multimeter extends SimpleSlimefunItem<ItemUseHandler> {
|
||||
e.cancel();
|
||||
|
||||
Location l = e.getClickedBlock().get().getLocation();
|
||||
String stored = DoubleHandler.getFancyDouble(component.getCharge(l)) + " J";
|
||||
String capacity = DoubleHandler.getFancyDouble(component.getCapacity()) + " J";
|
||||
String stored = NumberUtils.getCompactDouble(component.getCharge(l)) + " J";
|
||||
String capacity = NumberUtils.getCompactDouble(component.getCapacity()) + " J";
|
||||
|
||||
Player p = e.getPlayer();
|
||||
p.sendMessage("");
|
||||
|
@ -11,6 +11,7 @@ import org.bukkit.block.Block;
|
||||
import io.github.thebusybiscuit.cscorelib2.skull.SkullBlock;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.Capacitor;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.HeadTexture;
|
||||
import io.papermc.lib.PaperLib;
|
||||
|
||||
/**
|
||||
* This task is run whenever a {@link Capacitor} needs to update their texture.
|
||||
@ -58,18 +59,23 @@ public class CapacitorTextureUpdateTask implements Runnable {
|
||||
if (type == Material.PLAYER_HEAD || type == Material.PLAYER_WALL_HEAD) {
|
||||
if (filledPercentage <= 0.25) {
|
||||
// 0-25% capacity
|
||||
SkullBlock.setFromHash(b, HeadTexture.CAPACITOR_25.getTexture());
|
||||
setTexture(b, HeadTexture.CAPACITOR_25);
|
||||
} else if (filledPercentage <= 0.5) {
|
||||
// 25-50% capacity
|
||||
SkullBlock.setFromHash(b, HeadTexture.CAPACITOR_50.getTexture());
|
||||
setTexture(b, HeadTexture.CAPACITOR_50);
|
||||
} else if (filledPercentage <= 0.75) {
|
||||
// 50-75% capacity
|
||||
SkullBlock.setFromHash(b, HeadTexture.CAPACITOR_75.getTexture());
|
||||
setTexture(b, HeadTexture.CAPACITOR_75);
|
||||
} else {
|
||||
// 75-100% capacity
|
||||
SkullBlock.setFromHash(b, HeadTexture.CAPACITOR_100.getTexture());
|
||||
setTexture(b, HeadTexture.CAPACITOR_100);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setTexture(@Nonnull Block b, @Nonnull HeadTexture texture) {
|
||||
SkullBlock.setFromHash(b, texture.getUniqueId(), texture.getTexture(), false);
|
||||
PaperLib.getBlockState(b, false).getState().update(true, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package io.github.thebusybiscuit.slimefun4.implementation.tasks;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
@ -10,17 +11,18 @@ import java.util.logging.Level;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
|
||||
import io.github.thebusybiscuit.cscorelib2.blocks.BlockPosition;
|
||||
import io.github.thebusybiscuit.cscorelib2.blocks.ChunkPosition;
|
||||
import io.github.thebusybiscuit.slimefun4.api.ErrorReport;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.PatternUtils;
|
||||
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
|
||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
||||
import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker;
|
||||
@ -39,17 +41,17 @@ import me.mrCookieSlime.Slimefun.api.Slimefun;
|
||||
public class TickerTask implements Runnable {
|
||||
|
||||
/**
|
||||
* This Map holds all currently actively ticking locations.
|
||||
* This Map holds all currently actively ticking locations.
|
||||
*/
|
||||
private final Map<String, Set<Location>> activeTickers = new ConcurrentHashMap<>();
|
||||
private final Map<ChunkPosition, Set<Location>> tickingLocations = new ConcurrentHashMap<>();
|
||||
|
||||
// These are "Queues" of blocks that need to be removed or moved
|
||||
private final Map<Location, Location> movingQueue = new ConcurrentHashMap<>();
|
||||
private final Map<Location, Boolean> deletionQueue = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* This Map tracks how many bugs have occurred in a given Location .
|
||||
* If too many bugs happen, we delete that Location.
|
||||
* This Map tracks how many bugs have occurred in a given Location .
|
||||
* If too many bugs happen, we delete that Location.
|
||||
*/
|
||||
private final Map<BlockPosition, Integer> bugs = new ConcurrentHashMap<>();
|
||||
|
||||
@ -97,8 +99,8 @@ public class TickerTask implements Runnable {
|
||||
}
|
||||
|
||||
if (!halted) {
|
||||
for (Map.Entry<String, Set<Location>> entry : activeTickers.entrySet()) {
|
||||
tickChunk(tickers, entry.getKey(), entry.getValue());
|
||||
for (Map.Entry<ChunkPosition, Set<Location>> entry : tickingLocations.entrySet()) {
|
||||
tickChunk(entry.getKey(), tickers, entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@ -123,21 +125,16 @@ public class TickerTask implements Runnable {
|
||||
}
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
private void tickChunk(Set<BlockTicker> tickers, String chunk, Set<Location> locations) {
|
||||
private void tickChunk(ChunkPosition chunk, Set<BlockTicker> tickers, Set<Location> locations) {
|
||||
try {
|
||||
String[] components = PatternUtils.SEMICOLON.split(chunk);
|
||||
|
||||
World world = Bukkit.getWorld(components[0]);
|
||||
int x = Integer.parseInt(components[components.length - 2]);
|
||||
int z = Integer.parseInt(components[components.length - 1]);
|
||||
|
||||
if (world != null && world.isChunkLoaded(x, z)) {
|
||||
// Only continue if the Chunk is actually loaded
|
||||
if (chunk.isLoaded()) {
|
||||
for (Location l : locations) {
|
||||
tickLocation(tickers, l);
|
||||
}
|
||||
}
|
||||
} catch (ArrayIndexOutOfBoundsException | NumberFormatException x) {
|
||||
Slimefun.getLogger().log(Level.SEVERE, x, () -> "An Exception has occurred while trying to parse Chunk: " + chunk);
|
||||
Slimefun.getLogger().log(Level.SEVERE, x, () -> "An Exception has occurred while trying to resolve Chunk: " + chunk);
|
||||
}
|
||||
}
|
||||
|
||||
@ -235,14 +232,82 @@ public class TickerTask implements Runnable {
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the {@link Map} of actively ticking locations according to
|
||||
* their chunk id.
|
||||
* This method returns a <strong>read-only</strong> {@link Map}
|
||||
* representation of every {@link ChunkPosition} and its corresponding
|
||||
* {@link Set} of ticking {@link Location Locations}.
|
||||
*
|
||||
* @return The {@link Map} of active tickers
|
||||
* This does include any {@link Location} from an unloaded {@link Chunk} too!
|
||||
*
|
||||
* @return A {@link Map} representation of all ticking {@link Location Locations}
|
||||
*/
|
||||
@Nonnull
|
||||
public Map<String, Set<Location>> getActiveTickers() {
|
||||
return activeTickers;
|
||||
public Map<ChunkPosition, Set<Location>> getLocations() {
|
||||
return Collections.unmodifiableMap(tickingLocations);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a <strong>read-only</strong> {@link Set}
|
||||
* of all ticking {@link Location Locations} in a given {@link Chunk}.
|
||||
* The {@link Chunk} does not have to be loaded.
|
||||
* If no {@link Location} is present, the returned {@link Set} will be empty.
|
||||
*
|
||||
* @param chunk
|
||||
* The {@link Chunk}
|
||||
*
|
||||
* @return A {@link Set} of all ticking {@link Location Locations}
|
||||
*/
|
||||
@Nonnull
|
||||
public Set<Location> getLocations(@Nonnull Chunk chunk) {
|
||||
Validate.notNull(chunk, "The Chunk cannot be null!");
|
||||
|
||||
Set<Location> locations = tickingLocations.getOrDefault(new ChunkPosition(chunk), new HashSet<>());
|
||||
return Collections.unmodifiableSet(locations);
|
||||
}
|
||||
|
||||
/**
|
||||
* This enables the ticker at the given {@link Location} and adds it to our "queue".
|
||||
*
|
||||
* @param l
|
||||
* The {@link Location} to activate
|
||||
*/
|
||||
public void enableTicker(@Nonnull Location l) {
|
||||
Validate.notNull(l, "Location cannot be null!");
|
||||
|
||||
ChunkPosition chunk = new ChunkPosition(l.getWorld(), l.getBlockX() >> 4, l.getBlockZ() >> 4);
|
||||
Set<Location> newValue = new HashSet<>();
|
||||
Set<Location> oldValue = tickingLocations.putIfAbsent(chunk, newValue);
|
||||
|
||||
/**
|
||||
* This is faster than doing computeIfAbsent(...)
|
||||
* on a ConcurrentHashMap because it won't block the Thread for too long
|
||||
*/
|
||||
if (oldValue != null) {
|
||||
oldValue.add(l);
|
||||
} else {
|
||||
newValue.add(l);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method disables the ticker at the given {@link Location} and removes it from our internal
|
||||
* "queue".
|
||||
*
|
||||
* @param l
|
||||
* The {@link Location} to remove
|
||||
*/
|
||||
public void disableTicker(@Nonnull Location l) {
|
||||
Validate.notNull(l, "Location cannot be null!");
|
||||
|
||||
ChunkPosition chunk = new ChunkPosition(l.getWorld(), l.getBlockX() >> 4, l.getBlockZ() >> 4);
|
||||
Set<Location> locations = tickingLocations.get(chunk);
|
||||
|
||||
if (locations != null) {
|
||||
locations.remove(l);
|
||||
|
||||
if (locations.isEmpty()) {
|
||||
tickingLocations.remove(chunk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package io.github.thebusybiscuit.slimefun4.utils;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
@ -114,11 +116,14 @@ public enum HeadTexture {
|
||||
public static final HeadTexture[] valuesCache = values();
|
||||
|
||||
private final String texture;
|
||||
private final UUID uuid;
|
||||
|
||||
HeadTexture(@Nonnull String texture) {
|
||||
Validate.notNull(texture, "Texture cannot be null");
|
||||
Validate.isTrue(PatternUtils.HEXADECIMAL.matcher(texture).matches(), "Textures must be in hexadecimal.");
|
||||
|
||||
this.texture = texture;
|
||||
this.uuid = UUID.nameUUIDFromBytes(texture.getBytes());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -131,6 +136,18 @@ public enum HeadTexture {
|
||||
return texture;
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns the {@link UUID} for this {@link HeadTexture}.
|
||||
* The {@link UUID} is generated from the texture and cached for
|
||||
* performance reasons.
|
||||
*
|
||||
* @return The {@link UUID} for this {@link HeadTexture}
|
||||
*/
|
||||
@Nonnull
|
||||
public UUID getUniqueId() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns an {@link ItemStack} with the given texture assigned to it.
|
||||
*
|
||||
|
@ -24,6 +24,7 @@ public final class NumberUtils {
|
||||
|
||||
/**
|
||||
* This is our {@link DecimalFormat} for decimal values.
|
||||
* This instance is not thread-safe!
|
||||
*/
|
||||
private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#.##", DecimalFormatSymbols.getInstance(Locale.ROOT));
|
||||
|
||||
@ -48,6 +49,34 @@ public final class NumberUtils {
|
||||
return NumberFormat.getNumberInstance(Locale.US).format(number);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public static String getCompactDouble(double value) {
|
||||
if (value < 0) {
|
||||
// Negative numbers are a special case
|
||||
return '-' + getCompactDouble(-value);
|
||||
}
|
||||
|
||||
if (value < 1000.0) {
|
||||
// Below 1K
|
||||
return DECIMAL_FORMAT.format(value);
|
||||
} else if (value < 1000000.0) {
|
||||
// Thousands
|
||||
return DECIMAL_FORMAT.format(value / 1000.0) + 'K';
|
||||
} else if (value < 1000000000.0) {
|
||||
// Million
|
||||
return DECIMAL_FORMAT.format(value / 1000000.0) + 'M';
|
||||
} else if (value < 1000000000000.0) {
|
||||
// Billion
|
||||
return DECIMAL_FORMAT.format(value / 1000000000.0) + 'B';
|
||||
} else if (value < 1000000000000000.0) {
|
||||
// Trillion
|
||||
return DECIMAL_FORMAT.format(value / 1000000000000.0) + 'T';
|
||||
} else {
|
||||
// Quadrillion
|
||||
return DECIMAL_FORMAT.format(value / 1000000000000000.0) + 'Q';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method transforms a String representation of a {@link LocalDateTime}
|
||||
* from GitHub's API back into a {@link LocalDateTime} object
|
||||
|
@ -1,5 +1,7 @@
|
||||
package io.github.thebusybiscuit.slimefun4.utils.holograms;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@ -17,9 +19,10 @@ public final class ReactorHologram {
|
||||
@Nullable
|
||||
public static ArmorStand getArmorStand(@Nonnull Location reactor, boolean createIfNoneExists) {
|
||||
Location l = new Location(reactor.getWorld(), reactor.getX() + 0.5, reactor.getY() + 0.7, reactor.getZ() + 0.5);
|
||||
Collection<Entity> holograms = l.getWorld().getNearbyEntities(l, 0.2, 0.2, 0.2, ReactorHologram::isPossibleHologram);
|
||||
|
||||
for (Entity n : l.getChunk().getEntities()) {
|
||||
if (n instanceof ArmorStand && l.distanceSquared(n.getLocation()) < 0.4D) {
|
||||
for (Entity n : holograms) {
|
||||
if (n instanceof ArmorStand) {
|
||||
return (ArmorStand) n;
|
||||
}
|
||||
}
|
||||
@ -34,14 +37,21 @@ public final class ReactorHologram {
|
||||
return hologram;
|
||||
}
|
||||
|
||||
private static boolean isPossibleHologram(@Nonnull Entity n) {
|
||||
if (n instanceof ArmorStand) {
|
||||
ArmorStand armorstand = (ArmorStand) n;
|
||||
return armorstand.isValid() && armorstand.isSilent() && armorstand.isMarker() && !armorstand.hasGravity();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void update(@Nonnull Location l, @Nonnull String name) {
|
||||
SlimefunPlugin.runSync(() -> {
|
||||
ArmorStand hologram = getArmorStand(l, true);
|
||||
|
||||
if (!hologram.isCustomNameVisible()) {
|
||||
hologram.setCustomNameVisible(true);
|
||||
}
|
||||
|
||||
hologram.setCustomNameVisible(true);
|
||||
hologram.setCustomName(ChatColors.color(name));
|
||||
});
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package io.github.thebusybiscuit.slimefun4.utils.holograms;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@ -42,9 +44,10 @@ public final class SimpleHologram {
|
||||
@Nullable
|
||||
private static ArmorStand getArmorStand(@Nonnull Block b, boolean createIfNoneExists) {
|
||||
Location l = new Location(b.getWorld(), b.getX() + 0.5, b.getY() + 0.7F, b.getZ() + 0.5);
|
||||
Collection<Entity> holograms = b.getWorld().getNearbyEntities(l, 0.2, 0.2, 0.2, SimpleHologram::isPossibleHologram);
|
||||
|
||||
for (Entity n : l.getChunk().getEntities()) {
|
||||
if (n instanceof ArmorStand && l.distanceSquared(n.getLocation()) < 0.4D && isPossibleHologram((ArmorStand) n)) {
|
||||
for (Entity n : holograms) {
|
||||
if (n instanceof ArmorStand) {
|
||||
return (ArmorStand) n;
|
||||
}
|
||||
}
|
||||
@ -56,8 +59,14 @@ public final class SimpleHologram {
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isPossibleHologram(@Nonnull ArmorStand armorstand) {
|
||||
return armorstand.isValid() && armorstand.isSilent() && armorstand.isMarker() && !armorstand.hasGravity() && armorstand.isCustomNameVisible();
|
||||
private static boolean isPossibleHologram(@Nonnull Entity n) {
|
||||
if (n instanceof ArmorStand) {
|
||||
ArmorStand armorstand = (ArmorStand) n;
|
||||
return armorstand.isValid() && armorstand.isSilent() && armorstand.isMarker() && !armorstand.hasGravity() && armorstand.isCustomNameVisible();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
|
@ -202,7 +202,7 @@ public abstract class AGenerator extends AbstractEnergyProvider {
|
||||
}
|
||||
|
||||
ItemStackWrapper wrapper = new ItemStackWrapper(item);
|
||||
return SlimefunUtils.isItemSimilar(wrapper, new ItemStack(Material.LAVA_BUCKET), true) || SlimefunUtils.isItemSimilar(wrapper, SlimefunItems.FUEL_BUCKET, true) || SlimefunUtils.isItemSimilar(wrapper, SlimefunItems.OIL_BUCKET, true);
|
||||
return item.getType() == Material.LAVA_BUCKET || SlimefunUtils.isItemSimilar(wrapper, SlimefunItems.FUEL_BUCKET, true) || SlimefunUtils.isItemSimilar(wrapper, SlimefunItems.OIL_BUCKET, true);
|
||||
}
|
||||
|
||||
private MachineFuel findRecipe(BlockMenu menu, Map<Integer, Integer> found) {
|
||||
|
@ -49,8 +49,6 @@ public class BlockInfoConfig extends Config {
|
||||
throw new UnsupportedOperationException("Can't set \"" + path + "\" to \"" + value + "\" (type: " + value.getClass().getSimpleName() + ") because BlockInfoConfig only supports Strings");
|
||||
}
|
||||
|
||||
checkPath(path);
|
||||
|
||||
if (value == null) {
|
||||
data.remove(path);
|
||||
} else {
|
||||
@ -58,15 +56,8 @@ public class BlockInfoConfig extends Config {
|
||||
}
|
||||
}
|
||||
|
||||
private void checkPath(String path) {
|
||||
if (path.indexOf('.') != -1) {
|
||||
throw new UnsupportedOperationException("BlockInfoConfig only supports Map<String,String> (path: " + path + ")");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(String path) {
|
||||
checkPath(path);
|
||||
return data.containsKey(path);
|
||||
}
|
||||
|
||||
@ -77,7 +68,6 @@ public class BlockInfoConfig extends Config {
|
||||
|
||||
@Override
|
||||
public String getString(String path) {
|
||||
checkPath(path);
|
||||
return data.get(path);
|
||||
}
|
||||
|
||||
|
@ -7,10 +7,8 @@ import java.nio.file.Files;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
@ -71,10 +69,6 @@ public class BlockStorage {
|
||||
return l.getWorld().getName() + ';' + l.getBlockX() + ';' + l.getBlockY() + ';' + l.getBlockZ();
|
||||
}
|
||||
|
||||
private static String locationToChunkString(Location l) {
|
||||
return l.getWorld().getName() + ";Chunk;" + (l.getBlockX() >> 4) + ';' + (l.getBlockZ() >> 4);
|
||||
}
|
||||
|
||||
private static String serializeChunk(World world, int x, int z) {
|
||||
return world.getName() + ";Chunk;" + x + ';' + z;
|
||||
}
|
||||
@ -177,7 +171,6 @@ public class BlockStorage {
|
||||
}
|
||||
|
||||
try {
|
||||
String chunkString = locationToChunkString(l);
|
||||
String json = cfg.getString(key);
|
||||
Config blockInfo = parseBlockInfo(l, json);
|
||||
|
||||
@ -195,9 +188,7 @@ public class BlockStorage {
|
||||
storage.put(l, blockInfo);
|
||||
|
||||
if (SlimefunPlugin.getRegistry().getTickerBlocks().contains(file.getName().replace(".sfb", ""))) {
|
||||
Map<String, Set<Location>> tickers = SlimefunPlugin.getTickerTask().getActiveTickers();
|
||||
Set<Location> locations = tickers.computeIfAbsent(chunkString, id -> new HashSet<>());
|
||||
locations.add(l);
|
||||
SlimefunPlugin.getTickerTask().enableTicker(l);
|
||||
}
|
||||
}
|
||||
} catch (Exception x) {
|
||||
@ -495,11 +486,7 @@ public class BlockStorage {
|
||||
}
|
||||
}
|
||||
|
||||
public static void setBlockInfo(Block block, Config cfg, boolean updateTicker) {
|
||||
setBlockInfo(block.getLocation(), cfg, updateTicker);
|
||||
}
|
||||
|
||||
public static void setBlockInfo(Location l, Config cfg, boolean updateTicker) {
|
||||
private static void setBlockInfo(Location l, Config cfg, boolean updateTicker) {
|
||||
BlockStorage storage = getStorage(l.getWorld());
|
||||
|
||||
if (storage == null) {
|
||||
@ -590,17 +577,7 @@ public class BlockStorage {
|
||||
universalInventory.save();
|
||||
}
|
||||
|
||||
String chunkString = locationToChunkString(l);
|
||||
Map<String, Set<Location>> tickers = SlimefunPlugin.getTickerTask().getActiveTickers();
|
||||
Set<Location> locations = tickers.get(chunkString);
|
||||
|
||||
if (locations != null) {
|
||||
locations.remove(l);
|
||||
|
||||
if (locations.isEmpty()) {
|
||||
tickers.remove(chunkString);
|
||||
}
|
||||
}
|
||||
SlimefunPlugin.getTickerTask().disableTicker(l);
|
||||
}
|
||||
}
|
||||
|
||||
@ -638,23 +615,15 @@ public class BlockStorage {
|
||||
refreshCache(storage, from, previousData.getString("id"), null, true);
|
||||
storage.storage.remove(from);
|
||||
|
||||
String chunkString = locationToChunkString(from);
|
||||
Map<String, Set<Location>> tickers = SlimefunPlugin.getTickerTask().getActiveTickers();
|
||||
Set<Location> locations = tickers.get(chunkString);
|
||||
|
||||
if (locations != null) {
|
||||
locations.remove(from);
|
||||
|
||||
if (locations.isEmpty()) {
|
||||
tickers.remove(chunkString);
|
||||
}
|
||||
}
|
||||
SlimefunPlugin.getTickerTask().disableTicker(from);
|
||||
}
|
||||
|
||||
private static void refreshCache(BlockStorage storage, Location l, String key, String value, boolean updateTicker) {
|
||||
if (key == null) {
|
||||
// This Block is no longer valid...
|
||||
// Fixes #1577
|
||||
/**
|
||||
* This Block is no longer valid...
|
||||
* Fixes #1577
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
@ -664,14 +633,8 @@ public class BlockStorage {
|
||||
if (updateTicker) {
|
||||
SlimefunItem item = SlimefunItem.getByID(key);
|
||||
|
||||
if (item != null && item.isTicking()) {
|
||||
String chunkString = locationToChunkString(l);
|
||||
|
||||
if (value != null) {
|
||||
Map<String, Set<Location>> tickers = SlimefunPlugin.getTickerTask().getActiveTickers();
|
||||
Set<Location> locations = tickers.computeIfAbsent(chunkString, id -> new HashSet<>());
|
||||
locations.add(l);
|
||||
}
|
||||
if (item != null && item.isTicking() && value != null) {
|
||||
SlimefunPlugin.getTickerTask().enableTicker(l);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -92,6 +92,13 @@ public class Metrics {
|
||||
this.plugin = plugin;
|
||||
this.pluginId = pluginId;
|
||||
|
||||
plugin.getLogger().log(Level.WARNING, "=================================================");
|
||||
plugin.getLogger().log(Level.WARNING, "{0} is using a deprecated version of", plugin.getName());
|
||||
plugin.getLogger().log(Level.WARNING, "bStats which is bundled with Slimefun.");
|
||||
plugin.getLogger().log(Level.WARNING, "Future versions will not include this file anymore.");
|
||||
plugin.getLogger().log(Level.WARNING, "{0} needs to be updated as soon as possible.", plugin.getName());
|
||||
plugin.getLogger().log(Level.WARNING, "=================================================");
|
||||
|
||||
// Get the config file
|
||||
File bStatsFolder = new File(plugin.getDataFolder().getParentFile(), "bStats");
|
||||
File configFile = new File(bStatsFolder, "config.yml");
|
||||
|
Loading…
Reference in New Issue
Block a user