1
mirror of https://github.com/StarWishsama/Slimefun4.git synced 2024-09-19 19:25:48 +00:00

Reduced technical debt / Refactoring

This commit is contained in:
TheBusyBiscuit 2020-06-21 10:26:54 +02:00
parent d18cb3a898
commit 8e07ada321
15 changed files with 430 additions and 308 deletions

View File

@ -29,6 +29,7 @@
#### Changes
* Coolant Cells now last twice as long
* Ticking blocks will now catch more errors caused by addons
* Massive performance improvements
#### Fixes

View File

@ -18,6 +18,7 @@ import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.config.Config;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.api.events.GEOResourceGenerationEvent;
import io.github.thebusybiscuit.slimefun4.implementation.items.geo.GEOMiner;
import io.github.thebusybiscuit.slimefun4.implementation.items.geo.GEOScanner;
@ -71,8 +72,10 @@ public class ResourceManager {
SlimefunPlugin.getRegistry().getGEOResources().add(resource);
}
if (SlimefunPlugin.getMinecraftVersion() != MinecraftVersion.UNIT_TEST) {
config.save();
}
}
public OptionalInt getSupplies(GEOResource resource, World world, int x, int z) {
String key = resource.getKey().toString().replace(':', '-');

View File

@ -64,15 +64,16 @@ public final class SlimefunItems {
public static final SlimefunItemStack FILLED_FLASK_OF_KNOWLEDGE = new SlimefunItemStack("FILLED_FLASK_OF_KNOWLEDGE", Material.EXPERIENCE_BOTTLE, "&aFlask of Knowledge");
/* Backpacks */
public static final SlimefunItemStack BACKPACK_SMALL = new SlimefunItemStack("SMALL_BACKPACK", HeadTexture.BACKPACK, "&eSmall Backpack", "", "&7Size: &e9", "&7ID: <ID>", "", LoreBuilder.RIGHT_CLICK_TO_OPEN);
public static final SlimefunItemStack BACKPACK_MEDIUM = new SlimefunItemStack("MEDIUM_BACKPACK", HeadTexture.BACKPACK, "&eBackpack", "", "&7Size: &e18", "&7ID: <ID>", "", LoreBuilder.RIGHT_CLICK_TO_OPEN);
public static final SlimefunItemStack BACKPACK_LARGE = new SlimefunItemStack("LARGE_BACKPACK", HeadTexture.BACKPACK, "&eLarge Backpack", "", "&7Size: &e27", "&7ID: <ID>", "", LoreBuilder.RIGHT_CLICK_TO_OPEN);
public static final SlimefunItemStack WOVEN_BACKPACK = new SlimefunItemStack("WOVEN_BACKPACK", HeadTexture.BACKPACK, "&eWoven Backpack", "", "&7Size: &e36", "&7ID: <ID>", "", LoreBuilder.RIGHT_CLICK_TO_OPEN);
public static final SlimefunItemStack GILDED_BACKPACK = new SlimefunItemStack("GILDED_BACKPACK", HeadTexture.BACKPACK, "&eGilded Backpack", "", "&7Size: &e45", "&7ID: <ID>", "", LoreBuilder.RIGHT_CLICK_TO_OPEN);
public static final SlimefunItemStack RADIANT_BACKPACK = new SlimefunItemStack("RADIANT_BACKPACK", HeadTexture.BACKPACK, "&eRadiant Backpack", "", "&7Size: &e54 (Double chest)", "&7ID: <ID>", "", LoreBuilder.RIGHT_CLICK_TO_OPEN);
public static final SlimefunItemStack BOUND_BACKPACK = new SlimefunItemStack("BOUND_BACKPACK", HeadTexture.ENDER_BACKPACK, "&cSoulbound Backpack", "", "&7Size: &e36", "&7ID: <ID>", "", LoreBuilder.RIGHT_CLICK_TO_OPEN);
public static final SlimefunItemStack COOLER = new SlimefunItemStack("COOLER", HeadTexture.COOLER, "&bCooler", "&rAllows you to store Juices/Smoothies", "&rand automatically consumes them when you are hungry", "&rand you have this in your Inventory", "", "&7Size: &e27", "&7ID: <ID>", "", LoreBuilder.RIGHT_CLICK_TO_OPEN);
public static final SlimefunItemStack RESTORED_BACKPACK = new SlimefunItemStack("RESTORED_BACKPACK", HeadTexture.RESTORED_BACKPACK, "&eRestored Backpack", "", "&7Retrieve your lost items", "&7ID: <ID>", "", LoreBuilder.RIGHT_CLICK_TO_OPEN);
private static final String BACKPACK_ID = "&7ID: <ID>";
public static final SlimefunItemStack BACKPACK_SMALL = new SlimefunItemStack("SMALL_BACKPACK", HeadTexture.BACKPACK, "&eSmall Backpack", "", "&7Size: &e9", BACKPACK_ID, "", LoreBuilder.RIGHT_CLICK_TO_OPEN);
public static final SlimefunItemStack BACKPACK_MEDIUM = new SlimefunItemStack("MEDIUM_BACKPACK", HeadTexture.BACKPACK, "&eBackpack", "", "&7Size: &e18", BACKPACK_ID, "", LoreBuilder.RIGHT_CLICK_TO_OPEN);
public static final SlimefunItemStack BACKPACK_LARGE = new SlimefunItemStack("LARGE_BACKPACK", HeadTexture.BACKPACK, "&eLarge Backpack", "", "&7Size: &e27", BACKPACK_ID, "", LoreBuilder.RIGHT_CLICK_TO_OPEN);
public static final SlimefunItemStack WOVEN_BACKPACK = new SlimefunItemStack("WOVEN_BACKPACK", HeadTexture.BACKPACK, "&eWoven Backpack", "", "&7Size: &e36", BACKPACK_ID, "", LoreBuilder.RIGHT_CLICK_TO_OPEN);
public static final SlimefunItemStack GILDED_BACKPACK = new SlimefunItemStack("GILDED_BACKPACK", HeadTexture.BACKPACK, "&eGilded Backpack", "", "&7Size: &e45", BACKPACK_ID, "", LoreBuilder.RIGHT_CLICK_TO_OPEN);
public static final SlimefunItemStack RADIANT_BACKPACK = new SlimefunItemStack("RADIANT_BACKPACK", HeadTexture.BACKPACK, "&eRadiant Backpack", "", "&7Size: &e54 (Double chest)", BACKPACK_ID, "", LoreBuilder.RIGHT_CLICK_TO_OPEN);
public static final SlimefunItemStack BOUND_BACKPACK = new SlimefunItemStack("BOUND_BACKPACK", HeadTexture.ENDER_BACKPACK, "&cSoulbound Backpack", "", "&7Size: &e36", BACKPACK_ID, "", LoreBuilder.RIGHT_CLICK_TO_OPEN);
public static final SlimefunItemStack COOLER = new SlimefunItemStack("COOLER", HeadTexture.COOLER, "&bCooler", "&rAllows you to store Juices/Smoothies", "&rand automatically consumes them when you are hungry", "&rand you have this in your Inventory", "", "&7Size: &e27", BACKPACK_ID, "", LoreBuilder.RIGHT_CLICK_TO_OPEN);
public static final SlimefunItemStack RESTORED_BACKPACK = new SlimefunItemStack("RESTORED_BACKPACK", HeadTexture.RESTORED_BACKPACK, "&eRestored Backpack", "", "&7Retrieve your lost items", BACKPACK_ID, "", LoreBuilder.RIGHT_CLICK_TO_OPEN);
/* Jetpacks */
public static final SlimefunItemStack DURALUMIN_JETPACK = new SlimefunItemStack("DURALUMIN_JETPACK", Material.LEATHER_CHESTPLATE, Color.SILVER, "&9Electric Jetpack &7- &eI", "", LoreBuilder.material("Duralumin"), LoreBuilder.powerCharged(0, 20), "&8\u21E8 &7Thrust: &c0.35", "", LoreBuilder.CROUCH_TO_USE);

View File

@ -156,18 +156,44 @@ public class AncientAltarListener implements Listener {
}
}
private void useAltar(Block b, Player p) {
private void useAltar(Block altar, Player p) {
ItemStack catalyst = new CustomItem(p.getInventory().getItemInMainHand(), 1);
List<Block> pedestals = getPedestals(b);
List<Block> pedestals = getPedestals(altar);
if (!altars.contains(b)) {
altars.add(b);
if (!altars.contains(altar)) {
altars.add(altar);
if (pedestals.size() == 8) {
pedestals.forEach(block -> altarsInUse.add(block.getLocation()));
if (catalyst.getType() != Material.AIR) {
startRitual(p, altar, pedestals, catalyst);
}
else {
altars.remove(altar);
SlimefunPlugin.getLocal().sendMessage(p, "machines.ANCIENT_ALTAR.unknown-catalyst", true);
for (Block block : pedestals) {
altarsInUse.remove(block.getLocation());
}
// Unknown catalyst, no longer in use
altarsInUse.remove(altar.getLocation());
}
}
else {
altars.remove(altar);
SlimefunPlugin.getLocal().sendMessage(p, "machines.ANCIENT_ALTAR.not-enough-pedestals", true, msg -> msg.replace("%pedestals%", String.valueOf(pedestals.size())));
// Not a valid altar so remove from inuse
altarsInUse.remove(altar.getLocation());
}
}
}
private void startRitual(Player p, Block b, List<Block> pedestals, ItemStack catalyst) {
List<ItemStack> input = new ArrayList<>();
for (Block pedestal : pedestals) {
Item stack = findItem(pedestal);
@ -212,27 +238,6 @@ public class AncientAltarListener implements Listener {
altarsInUse.remove(b.getLocation());
}
}
else {
altars.remove(b);
SlimefunPlugin.getLocal().sendMessage(p, "machines.ANCIENT_ALTAR.unknown-catalyst", true);
for (Block block : pedestals) {
altarsInUse.remove(block.getLocation());
}
// Unknown catalyst, no longer in use
altarsInUse.remove(b.getLocation());
}
}
else {
altars.remove(b);
SlimefunPlugin.getLocal().sendMessage(p, "machines.ANCIENT_ALTAR.not-enough-pedestals", true, msg -> msg.replace("%pedestals%", String.valueOf(pedestals.size())));
// Not a valid altar so remove from inuse
altarsInUse.remove(b.getLocation());
}
}
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onBlockPlace(BlockPlaceEvent e) {
@ -353,6 +358,18 @@ public class AncientAltarListener implements Listener {
private Optional<ItemStack> checkRecipe(ItemStack catalyst, List<ItemStackWrapper> items) {
for (AltarRecipe recipe : altarRecipes) {
if (SlimefunUtils.isItemSimilar(catalyst, recipe.getCatalyst(), true)) {
Optional<ItemStack> optional = checkPedestals(items, recipe);
if (optional.isPresent()) {
return optional;
}
}
}
return Optional.empty();
}
private Optional<ItemStack> checkPedestals(List<ItemStackWrapper> items, AltarRecipe recipe) {
for (int i = 0; i < 8; i++) {
if (SlimefunUtils.isItemSimilar(items.get(i), recipe.getInput().get(0), true)) {
for (int j = 1; j < 8; j++) {
@ -365,8 +382,6 @@ public class AncientAltarListener implements Listener {
}
}
}
}
}
return Optional.empty();
}

View File

@ -13,6 +13,7 @@ import org.bukkit.Tag;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
@ -88,26 +89,10 @@ public class BlockListener implements Listener {
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onBlockUnregister(BlockBreakEvent e) {
Block blockAbove = e.getBlock().getRelative(BlockFace.UP);
if (sensitiveMaterials.contains(blockAbove.getType())) {
SlimefunItem sfItem = BlockStorage.check(blockAbove);
if (sfItem != null && !sfItem.useVanillaBlockBreaking()) {
SlimefunBlockHandler blockHandler = SlimefunPlugin.getRegistry().getBlockHandlers().get(sfItem.getID());
if (blockHandler != null) {
if (blockHandler.onBreak(e.getPlayer(), blockAbove, sfItem, UnregisterReason.PLAYER_BREAK)) {
blockAbove.getWorld().dropItemNaturally(blockAbove.getLocation(), BlockStorage.retrieve(blockAbove));
blockAbove.setType(Material.AIR);
}
else {
if (hasSensitiveBlockAbove(e.getPlayer(), e.getBlock())) {
e.setCancelled(true);
return;
}
}
}
}
SlimefunItem sfItem = BlockStorage.check(e.getBlock());
ItemStack item = e.getPlayer().getInventory().getItemInMainHand();
@ -147,6 +132,10 @@ public class BlockListener implements Listener {
}
}
dropItems(e, drops);
}
private void dropItems(BlockBreakEvent e, List<ItemStack> drops) {
if (!drops.isEmpty()) {
e.getBlock().setType(Material.AIR);
@ -160,6 +149,30 @@ public class BlockListener implements Listener {
}
}
private boolean hasSensitiveBlockAbove(Player p, Block b) {
Block blockAbove = b.getRelative(BlockFace.UP);
if (sensitiveMaterials.contains(blockAbove.getType())) {
SlimefunItem sfItem = BlockStorage.check(blockAbove);
if (sfItem != null && !sfItem.useVanillaBlockBreaking()) {
SlimefunBlockHandler blockHandler = SlimefunPlugin.getRegistry().getBlockHandlers().get(sfItem.getID());
if (blockHandler != null) {
if (blockHandler.onBreak(p, blockAbove, sfItem, UnregisterReason.PLAYER_BREAK)) {
blockAbove.getWorld().dropItemNaturally(blockAbove.getLocation(), BlockStorage.retrieve(blockAbove));
blockAbove.setType(Material.AIR);
}
else {
return true;
}
}
}
}
return false;
}
private int getBonusDropsWithFortune(ItemStack item, Block b) {
int fortune = 1;

View File

@ -19,6 +19,7 @@ import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNet;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.implementation.tasks.TickerTask;
import io.github.thebusybiscuit.slimefun4.utils.HeadTexture;
import io.github.thebusybiscuit.slimefun4.utils.NumberUtils;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
@ -103,14 +104,14 @@ public class DebugFishListener implements Listener {
if (item.isTicking()) {
p.sendMessage(ChatColors.color("&dTicker: " + enabledTooltip));
p.sendMessage(ChatColors.color(" &dAsync: &e" + (BlockStorage.check(b).getBlockTicker().isSynchronized() ? disabledTooltip : enabledTooltip)));
p.sendMessage(ChatColors.color(" &dTimings: &e" + ticker.toMillis(ticker.getTimings(b), true)));
p.sendMessage(ChatColors.color(" &dTotal Timings: &e" + ticker.toMillis(ticker.getTimings(BlockStorage.checkID(b)), true)));
p.sendMessage(ChatColors.color(" &dChunk Timings: &e" + ticker.toMillis(ticker.getTimings(b.getChunk()), true)));
p.sendMessage(ChatColors.color(" &dTimings: &e" + NumberUtils.getAsMillis(ticker.getTimings(b))));
p.sendMessage(ChatColors.color(" &dTotal Timings: &e" + NumberUtils.getAsMillis(ticker.getTimings(BlockStorage.checkID(b)))));
p.sendMessage(ChatColors.color(" &dChunk Timings: &e" + NumberUtils.getAsMillis(ticker.getTimings(b.getChunk()))));
}
else if (item.getEnergyTicker() != null) {
p.sendMessage(ChatColors.color("&dTicking: " + "&3Indirect"));
p.sendMessage(ChatColors.color(" &dTimings: &e" + ticker.toMillis(ticker.getTimings(b), true)));
p.sendMessage(ChatColors.color(" &dChunk Timings: &e" + ticker.toMillis(ticker.getTimings(b.getChunk()), true)));
p.sendMessage(ChatColors.color(" &dTimings: &e" + NumberUtils.getAsMillis(ticker.getTimings(b))));
p.sendMessage(ChatColors.color(" &dChunk Timings: &e" + NumberUtils.getAsMillis(ticker.getTimings(b.getChunk()))));
}
else {
p.sendMessage(ChatColors.color("&dTicker: " + disabledTooltip));

View File

@ -9,6 +9,7 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityExplodeEvent;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Objects.SlimefunBlockHandler;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
@ -33,7 +34,7 @@ public class ExplosionsListener implements Listener {
blocks.remove();
// Hardened Glass and WitherProof blocks cannot be destroyed by explosions
if (!id.equalsIgnoreCase("HARDENED_GLASS") && !SlimefunPlugin.getRegistry().getWitherProofBlocks().containsKey(id)) {
if (!id.equals(SlimefunItems.HARDENED_GLASS.getItemId()) && !SlimefunPlugin.getRegistry().getWitherProofBlocks().containsKey(id)) {
boolean success = true;
SlimefunItem sfItem = SlimefunItem.getByID(id);

View File

@ -80,7 +80,7 @@ public class GrapplingHookListener implements Listener {
Player p = (Player) arrow.getShooter();
if (p.getGameMode() != GameMode.CREATIVE && (boolean) grappleState.get(p.getUniqueId())) {
arrow.getWorld().dropItem(arrow.getLocation(), SlimefunItems.GRAPPLING_HOOK);
arrow.getWorld().dropItem(arrow.getLocation(), SlimefunItems.GRAPPLING_HOOK.clone());
}
Vector velocity = new Vector(0.0, 0.2, 0.0);
@ -135,7 +135,7 @@ public class GrapplingHookListener implements Listener {
// To fix issue #253
Slimefun.runSync(() -> {
if (grappleState.containsKey(uuid)) {
SlimefunPlugin.getBowListener().getBows().remove(uuid);
SlimefunPlugin.getBowListener().getProjectileData().remove(uuid);
for (Entity n : temporaryEntities.get(uuid)) {
if (n.isValid()) {

View File

@ -1,5 +1,6 @@
package io.github.thebusybiscuit.slimefun4.implementation.listeners;
import java.util.List;
import java.util.Set;
import org.bukkit.Material;
@ -9,9 +10,7 @@ import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.BasicCircuitBoard;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.Objects.handlers.EntityKillHandler;
@ -19,8 +18,12 @@ import me.mrCookieSlime.Slimefun.api.Slimefun;
public class MobDropListener implements Listener {
public MobDropListener(SlimefunPlugin plugin) {
private final BasicCircuitBoard circuitBoard;
public MobDropListener(SlimefunPlugin plugin, BasicCircuitBoard circuitBoard) {
plugin.getServer().getPluginManager().registerEvents(this, plugin);
this.circuitBoard = circuitBoard;
}
@EventHandler
@ -31,15 +34,7 @@ public class MobDropListener implements Listener {
Set<ItemStack> customDrops = SlimefunPlugin.getRegistry().getMobDrops(e.getEntityType());
if (customDrops != null && !customDrops.isEmpty()) {
for (ItemStack drop : customDrops) {
if (Slimefun.hasUnlocked(p, drop, true)) {
if (SlimefunUtils.isItemSimilar(drop, SlimefunItems.BASIC_CIRCUIT_BOARD, true) && !((BasicCircuitBoard) SlimefunItems.BASIC_CIRCUIT_BOARD.getItem()).isDroppedFromGolems()) {
continue;
}
e.getDrops().add(drop.clone());
}
}
addDrops(p, customDrops, e.getDrops());
}
if (item.getType() != Material.AIR) {
@ -51,4 +46,16 @@ public class MobDropListener implements Listener {
}
}
}
private void addDrops(Player p, Set<ItemStack> customDrops, List<ItemStack> drops) {
for (ItemStack drop : customDrops) {
if (Slimefun.hasUnlocked(p, drop, true)) {
if (circuitBoard != null && circuitBoard.isItem(drop) && !circuitBoard.isDroppedFromGolems()) {
continue;
}
drops.add(drop.clone());
}
}
}
}

View File

@ -19,16 +19,31 @@ import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.Objects.handlers.BowShootHandler;
import me.mrCookieSlime.Slimefun.api.Slimefun;
/**
* This {@link Listener} is responsible for tracking {@link Arrow Arrows} fired from a
* {@link SlimefunBow}.
*
* @author TheBusyBiscuit
*
* @see SlimefunBow
*
*/
public class SlimefunBowListener implements Listener {
private final Map<UUID, SlimefunBow> bows = new HashMap<>();
private final Map<UUID, SlimefunBow> projectiles = new HashMap<>();
public void register(SlimefunPlugin plugin) {
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
public Map<UUID, SlimefunBow> getBows() {
return bows;
/**
* This returns a {@link HashMap} holding the {@link UUID} of a {@link Arrow} and the
* associated {@link SlimefunBow} with which this {@link Arrow} was fired from.
*
* @return A {@link HashMap} with all actively tracked {@link Arrow Arrows}
*/
public Map<UUID, SlimefunBow> getProjectileData() {
return projectiles;
}
@EventHandler
@ -37,7 +52,7 @@ public class SlimefunBowListener implements Listener {
SlimefunItem bow = SlimefunItem.getByItem(e.getBow());
if (bow instanceof SlimefunBow) {
bows.put(e.getProjectile().getUniqueId(), (SlimefunBow) bow);
projectiles.put(e.getProjectile().getUniqueId(), (SlimefunBow) bow);
}
}
}
@ -46,7 +61,7 @@ public class SlimefunBowListener implements Listener {
public void onArrowHit(ProjectileHitEvent e) {
Slimefun.runSync(() -> {
if (e.getEntity().isValid() && e.getEntity() instanceof Arrow) {
bows.remove(e.getEntity().getUniqueId());
projectiles.remove(e.getEntity().getUniqueId());
}
}, 4L);
}
@ -54,13 +69,13 @@ public class SlimefunBowListener implements Listener {
@EventHandler
public void onArrowSuccessfulHit(EntityDamageByEntityEvent e) {
if (e.getDamager() instanceof Arrow && e.getEntity() instanceof LivingEntity) {
SlimefunBow bow = bows.get(e.getDamager().getUniqueId());
SlimefunBow bow = projectiles.get(e.getDamager().getUniqueId());
if (bow != null) {
bow.callItemHandler(BowShootHandler.class, handler -> handler.onHit(e, (LivingEntity) e.getEntity()));
}
bows.remove(e.getDamager().getUniqueId());
projectiles.remove(e.getDamager().getUniqueId());
}
}

View File

@ -10,6 +10,7 @@ import java.util.concurrent.ThreadLocalRandom;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.AbstractArrow;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.ChestedHorse;
import org.bukkit.entity.LivingEntity;
@ -78,17 +79,40 @@ public class TalismanListener implements Listener {
Projectile projectile = (Projectile) ((EntityDamageByEntityEvent) e).getDamager();
if (Talisman.checkFor(e, SlimefunItems.TALISMAN_WHIRLWIND)) {
Player p = (Player) e.getEntity();
returnProjectile((Player) e.getEntity(), projectile);
}
}
}
}
/**
* This method is used for the {@link Talisman} of the whirlwind, it returns a copy
* of a {@link Projectile} that was fired at a {@link Player}.
*
* @param p
* The {@link Player} who was hit
* @param projectile
* The {@link Projectile} that hit this {@link Player}
*/
private void returnProjectile(Player p, Projectile projectile) {
Vector direction = p.getEyeLocation().getDirection().multiply(2.0);
Location loc = p.getEyeLocation().add(direction.getX(), direction.getY(), direction.getZ());
Projectile clone = (Projectile) e.getEntity().getWorld().spawnEntity(loc, projectile.getType());
clone.setShooter(projectile.getShooter());
clone.setVelocity(direction);
Projectile returnedProjectile = (Projectile) p.getWorld().spawnEntity(loc, projectile.getType());
returnedProjectile.setShooter(projectile.getShooter());
returnedProjectile.setVelocity(direction);
if (projectile instanceof AbstractArrow) {
AbstractArrow firedArrow = (AbstractArrow) projectile;
AbstractArrow returnedArrow = (AbstractArrow) returnedProjectile;
returnedArrow.setDamage(firedArrow.getDamage());
returnedArrow.setPickupStatus(firedArrow.getPickupStatus());
returnedArrow.setPierceLevel(firedArrow.getPierceLevel());
}
projectile.remove();
}
}
}
}
@EventHandler(ignoreCancelled = true)
public void onKill(EntityDeathEvent e) {

View File

@ -1,6 +1,5 @@
package io.github.thebusybiscuit.slimefun4.implementation.tasks;
import java.text.DecimalFormat;
import java.util.AbstractMap;
import java.util.Comparator;
import java.util.HashMap;
@ -9,11 +8,14 @@ import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.function.Function;
import java.util.logging.Level;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
@ -28,6 +30,7 @@ import io.github.thebusybiscuit.cscorelib2.chat.ChatColors;
import io.github.thebusybiscuit.cscorelib2.chat.json.ChatComponent;
import io.github.thebusybiscuit.cscorelib2.chat.json.HoverEvent;
import io.github.thebusybiscuit.slimefun4.api.ErrorReport;
import io.github.thebusybiscuit.slimefun4.utils.NumberUtils;
import io.github.thebusybiscuit.slimefun4.utils.PatternUtils;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
@ -37,24 +40,29 @@ import me.mrCookieSlime.Slimefun.api.Slimefun;
public class TickerTask implements Runnable {
private final DecimalFormat decimalFormat = new DecimalFormat("#.##");
private final ConcurrentMap<Location, Location> move = new ConcurrentHashMap<>();
private final ConcurrentMap<Location, Boolean> delete = new ConcurrentHashMap<>();
private final ConcurrentMap<Location, Long> blockTimings = new ConcurrentHashMap<>();
private final ConcurrentMap<String, Integer> chunkItemCount = new ConcurrentHashMap<>();
private final ConcurrentMap<String, Integer> machineCount = new ConcurrentHashMap<>();
private final ConcurrentMap<String, Long> machineTimings = new ConcurrentHashMap<>();
private final ConcurrentMap<String, Long> chunkTimings = new ConcurrentHashMap<>();
private final ConcurrentMap<Location, Integer> buggedBlocks = new ConcurrentHashMap<>();
private final Set<String> chunksSkipped = new HashSet<>();
private static final int VISIBILITY_THRESHOLD = 200_000;
private final Set<BlockTicker> tickers = new HashSet<>();
// These are "Queues" of blocks that need to be removed or moved
private final ConcurrentMap<Location, Location> movingQueue = new ConcurrentHashMap<>();
private final ConcurrentMap<Location, Boolean> deletionQueue = new ConcurrentHashMap<>();
private final ConcurrentMap<Location, Integer> buggedBlocks = new ConcurrentHashMap<>();
private final ConcurrentMap<Location, Long> blockTimings = new ConcurrentHashMap<>();
private final ConcurrentMap<String, Integer> machineCount = new ConcurrentHashMap<>();
private final ConcurrentMap<String, Long> machineTimings = new ConcurrentHashMap<>();
private final ConcurrentMap<String, Long> chunkTimings = new ConcurrentHashMap<>();
private final ConcurrentMap<String, Integer> chunkItemCount = new ConcurrentHashMap<>();
private final Set<String> skippedChunks = new HashSet<>();
private boolean halted = false;
private int skipped = 0;
private int skippedBlocks = 0;
private int chunks = 0;
private int machines = 0;
private int blocks = 0;
private long time = 0;
private boolean running = false;
@ -65,104 +73,60 @@ public class TickerTask implements Runnable {
@Override
public void run() {
if (running) return;
if (running) {
return;
}
running = true;
long timestamp = System.nanoTime();
skipped = 0;
skippedBlocks = 0;
chunks = 0;
machines = 0;
blocks = 0;
chunkItemCount.clear();
machineCount.clear();
time = 0;
chunkTimings.clear();
chunksSkipped.clear();
skippedChunks.clear();
machineTimings.clear();
blockTimings.clear();
Map<Location, Integer> bugged = new HashMap<>(buggedBlocks);
Map<Location, Integer> bugs = new HashMap<>(buggedBlocks);
buggedBlocks.clear();
Map<Location, Boolean> remove = new HashMap<>(delete);
Map<Location, Boolean> removals = new HashMap<>(deletionQueue);
for (Map.Entry<Location, Boolean> entry : remove.entrySet()) {
for (Map.Entry<Location, Boolean> entry : removals.entrySet()) {
BlockStorage._integrated_removeBlockInfo(entry.getKey(), entry.getValue());
delete.remove(entry.getKey());
deletionQueue.remove(entry.getKey());
}
if (!halted) {
for (String tickedChunk : BlockStorage.getTickingChunks()) {
long timestamp2 = System.nanoTime();
for (String chunk : BlockStorage.getTickingChunks()) {
long chunkTimestamp = System.nanoTime();
chunks++;
for (Location l : BlockStorage.getTickingLocations(tickedChunk)) {
for (Location l : BlockStorage.getTickingLocations(chunk)) {
if (l.getWorld().isChunkLoaded(l.getBlockX() >> 4, l.getBlockZ() >> 4)) {
Block b = l.getBlock();
SlimefunItem item = BlockStorage.check(l);
if (item != null && item.getBlockTicker() != null) {
machines++;
try {
item.getBlockTicker().update();
if (item.getBlockTicker().isSynchronized()) {
Slimefun.runSync(() -> {
try {
long timestamp3 = System.nanoTime();
item.getBlockTicker().tick(b, item, BlockStorage.getLocationInfo(l));
Long machinetime = machineTimings.get(item.getID());
Integer chunk = chunkItemCount.get(tickedChunk);
Integer machine = machineCount.get(item.getID());
machineTimings.put(item.getID(), (machinetime != null ? machinetime : 0) + (System.nanoTime() - timestamp3));
chunkItemCount.put(tickedChunk, (chunk != null ? chunk : 0) + 1);
machineCount.put(item.getID(), (machine != null ? machine : 0) + 1);
blockTimings.put(l, System.nanoTime() - timestamp3);
}
catch (Exception x) {
int errors = bugged.getOrDefault(l, 0);
reportErrors(l, item, x, errors);
}
});
tick(l, chunk, bugs);
}
else {
long timestamp3 = System.nanoTime();
item.getBlockTicker().tick(b, item, BlockStorage.getLocationInfo(l));
machineTimings.merge(item.getID(), (System.nanoTime() - timestamp3), Long::sum);
chunkItemCount.merge(tickedChunk, 1, Integer::sum);
machineCount.merge(item.getID(), 1, Integer::sum);
blockTimings.put(l, System.nanoTime() - timestamp3);
}
tickers.add(item.getBlockTicker());
}
catch (Exception x) {
int errors = bugged.getOrDefault(l, 0);
reportErrors(l, item, x, errors);
}
}
else skipped++;
}
else {
skipped += BlockStorage.getTickingLocations(tickedChunk).size();
chunksSkipped.add(tickedChunk);
skippedBlocks += BlockStorage.getTickingLocations(chunk).size();
skippedChunks.add(chunk);
chunks--;
break;
}
}
chunkTimings.put(tickedChunk, System.nanoTime() - timestamp2);
chunkTimings.put(chunk, System.nanoTime() - chunkTimestamp);
}
}
for (Map.Entry<Location, Location> entry : move.entrySet()) {
for (Map.Entry<Location, Location> entry : movingQueue.entrySet()) {
BlockStorage._integrated_moveLocationInfo(entry.getKey(), entry.getValue());
}
move.clear();
movingQueue.clear();
Iterator<BlockTicker> iterator = tickers.iterator();
while (iterator.hasNext()) {
@ -174,23 +138,74 @@ public class TickerTask implements Runnable {
running = false;
}
private void reportErrors(Location l, SlimefunItem item, Exception x, int errors) {
private void tick(Location l, String tickedChunk, Map<Location, Integer> bugs) {
Block b = l.getBlock();
SlimefunItem item = BlockStorage.check(l);
if (item != null && item.getBlockTicker() != null) {
blocks++;
try {
item.getBlockTicker().update();
if (item.getBlockTicker().isSynchronized()) {
Slimefun.runSync(() -> {
try {
long timestamp = System.nanoTime();
item.getBlockTicker().tick(b, item, BlockStorage.getLocationInfo(l));
long machinetime = NumberUtils.getLong(machineTimings.get(item.getID()), 0);
int chunk = NumberUtils.getInt(chunkItemCount.get(tickedChunk), 0);
int machine = NumberUtils.getInt(machineCount.get(item.getID()), 0);
machineTimings.put(item.getID(), machinetime + (System.nanoTime() - timestamp));
chunkItemCount.put(tickedChunk, chunk + 1);
machineCount.put(item.getID(), machine + 1);
blockTimings.put(l, System.nanoTime() - timestamp);
}
catch (Exception | LinkageError x) {
int errors = bugs.getOrDefault(l, 0);
reportErrors(l, item, x, errors);
}
});
}
else {
long timestamp = System.nanoTime();
item.getBlockTicker().tick(b, item, BlockStorage.getLocationInfo(l));
machineTimings.merge(item.getID(), (System.nanoTime() - timestamp), Long::sum);
chunkItemCount.merge(tickedChunk, 1, Integer::sum);
machineCount.merge(item.getID(), 1, Integer::sum);
blockTimings.put(l, System.nanoTime() - timestamp);
}
tickers.add(item.getBlockTicker());
}
catch (Exception x) {
int errors = bugs.getOrDefault(l, 0);
reportErrors(l, item, x, errors);
}
}
else {
skippedBlocks++;
}
}
private void reportErrors(Location l, SlimefunItem item, Throwable x, int errors) {
errors++;
if (errors == 1) {
// Generate a new Error-Report
new ErrorReport(x, l, item);
buggedBlocks.put(l, errors);
}
else if (errors == 4) {
Slimefun.getLogger().log(Level.SEVERE, "X: {0} Y: {1} Z: {2} ({3})", new Object[] { l.getBlockX(), l.getBlockY(), l.getBlockZ(), item.getID() });
Slimefun.getLogger().log(Level.SEVERE, "has thrown 4 Exceptions in the last 4 Ticks, the Block has been terminated.");
Slimefun.getLogger().log(Level.SEVERE, "has thrown 4 error messages in the last 4 Ticks, the Block has been terminated.");
Slimefun.getLogger().log(Level.SEVERE, "Check your /plugins/Slimefun/error-reports/ folder for details.");
Slimefun.getLogger().log(Level.SEVERE, " ");
BlockStorage._integrated_removeBlockInfo(l, true);
Bukkit.getScheduler().scheduleSyncDelayedTask(SlimefunPlugin.instance, () -> l.getBlock().setType(Material.AIR));
}
else {
@ -199,59 +214,41 @@ public class TickerTask implements Runnable {
}
public String getTime() {
return toMillis(time, false);
return NumberUtils.getAsMillis(time);
}
public void info(CommandSender sender) {
sender.sendMessage(ChatColors.color("&2== &aSlimefun Diagnostic Tool &2=="));
sender.sendMessage(ChatColors.color("&6Halted: &e&l" + String.valueOf(halted).toUpperCase(Locale.ROOT)));
sender.sendMessage("");
sender.sendMessage(ChatColors.color("&6Impact: &e" + toMillis(time, true)));
sender.sendMessage(ChatColors.color("&6Impact: &e" + NumberUtils.getAsMillis(time)));
sender.sendMessage(ChatColors.color("&6Ticked Chunks: &e" + chunks));
sender.sendMessage(ChatColors.color("&6Ticked Machines: &e" + machines));
sender.sendMessage(ChatColors.color("&6Skipped Machines: &e" + skipped));
sender.sendMessage(ChatColors.color("&6Ticked Machines: &e" + blocks));
sender.sendMessage(ChatColors.color("&6Skipped Machines: &e" + skippedBlocks));
sender.sendMessage("");
sender.sendMessage(ChatColors.color("&6Ticking Machines:"));
List<Map.Entry<String, Long>> timings = machineCount.keySet().stream().map(key -> new AbstractMap.SimpleEntry<>(key, machineTimings.getOrDefault(key, 0L))).sorted((o1, o2) -> o2.getValue().compareTo(o1.getValue())).collect(Collectors.toList());
if (sender instanceof Player) {
ChatComponent component = new ChatComponent(ChatColors.color(" &7&oHover for more Info"));
StringBuilder builder = new StringBuilder();
int hidden = 0;
for (Map.Entry<String, Long> entry : timings) {
summarizeTimings(sender, entry -> {
int count = machineCount.get(entry.getKey());
String timings = NumberUtils.getAsMillis(entry.getValue());
String average = NumberUtils.getAsMillis(entry.getValue() / count);
if (entry.getValue() > 300_000) {
builder.append("\n&c").append(entry.getKey()).append(" - ").append(count).append("x &7(").append(toMillis(entry.getValue(), true)).append(", ").append(toMillis(entry.getValue() / count, true)).append(" avg/machine)");
}
else hidden++;
}
builder.append("\n\n&c+ &4").append(hidden).append(" Hidden");
component.setHoverEvent(new HoverEvent(ChatColors.color(builder.toString())));
component.sendMessage((Player) sender);
}
else {
int hidden = 0;
for (Map.Entry<String, Long> entry : timings) {
int count = machineCount.get(entry.getKey());
if (entry.getValue() > 300_000) {
sender.sendMessage(" " + entry.getKey() + " - " + count + "x (" + toMillis(entry.getValue(), false) + ", " + toMillis(entry.getValue() / count, false) + " avg/machine)");
}
else hidden++;
}
sender.sendMessage("+ " + hidden + " Hidden");
}
return entry.getKey() + " - " + count + "x (" + timings + ", " + average + " avg/machine)";
}, machineCount.keySet().stream().map(key -> new AbstractMap.SimpleEntry<>(key, machineTimings.getOrDefault(key, 0L))));
sender.sendMessage("");
sender.sendMessage(ChatColors.color("&6Ticking Chunks:"));
timings = chunkTimings.entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).collect(Collectors.toList());
summarizeTimings(sender, entry -> {
int count = chunkItemCount.getOrDefault(entry.getKey(), 0);
String timings = NumberUtils.getAsMillis(entry.getValue());
return formatChunk(entry.getKey()) + " - " + count + "x (" + timings + ")";
}, chunkTimings.entrySet().stream().filter(entry -> !skippedChunks.contains(entry.getKey())));
}
private void summarizeTimings(CommandSender sender, Function<Map.Entry<String, Long>, String> formatter, Stream<Map.Entry<String, Long>> stream) {
List<Entry<String, Long>> timings = stream.sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).collect(Collectors.toList());
if (sender instanceof Player) {
ChatComponent component = new ChatComponent(ChatColors.color(" &7&oHover for more Info"));
@ -259,11 +256,11 @@ public class TickerTask implements Runnable {
int hidden = 0;
for (Map.Entry<String, Long> entry : timings) {
if (!chunksSkipped.contains(entry.getKey())) {
if (entry.getValue() > 0) {
builder.append("\n&c").append(formatChunk(entry.getKey())).append(" - ").append(chunkItemCount.getOrDefault(entry.getKey(), 0)).append("x &7(").append(toMillis(entry.getValue(), true)).append(')');
if (entry.getValue() > VISIBILITY_THRESHOLD) {
builder.append("\n&c").append(formatter.apply(entry));
}
else hidden++;
else {
hidden++;
}
}
@ -276,15 +273,15 @@ public class TickerTask implements Runnable {
int hidden = 0;
for (Map.Entry<String, Long> entry : timings) {
if (!chunksSkipped.contains(entry.getKey())) {
if (entry.getValue() > 0) {
sender.sendMessage(" " + formatChunk(entry.getKey()) + " - " + (chunkItemCount.getOrDefault(entry.getKey(), 0)) + "x (" + toMillis(entry.getValue(), false) + ")");
if (entry.getValue() > VISIBILITY_THRESHOLD) {
sender.sendMessage(" " + ChatColor.stripColor(formatter.apply(entry)));
}
else hidden++;
else {
hidden++;
}
}
sender.sendMessage(ChatColors.color("&c+ &4" + hidden + " Hidden"));
sender.sendMessage("+ " + hidden + " Hidden");
}
}
@ -318,35 +315,17 @@ public class TickerTask implements Runnable {
halted = true;
}
public String toMillis(long nanoseconds, boolean colors) {
String number = decimalFormat.format(nanoseconds / 1000000.0);
if (!colors) {
return number;
}
else {
String[] parts = PatternUtils.NUMBER_SEPERATOR.split(number);
if (parts.length == 1) {
return parts[0];
}
else {
return parts[0] + ',' + ChatColor.GRAY + parts[1] + "ms";
}
}
}
@Override
public String toString() {
return "TickerTask {\n" + " HALTED = " + halted + "\n" + " tickers = " + tickers + "\n" + " move = " + move + "\n" + " delete = " + delete + "\n" + " chunks = " + chunkItemCount + "\n" + " machines = " + machineCount + "\n" + " machinetime = " + machineTimings + "\n" + " chunktime = " + chunkTimings + "\n" + " skipped = " + chunksSkipped + "\n" + "}";
return "TickerTask {\n" + " HALTED = " + halted + "\n" + " tickers = " + tickers + "\n" + " move = " + movingQueue + "\n" + " delete = " + deletionQueue + "\n" + " chunks = " + chunkItemCount + "\n" + " machines = " + machineCount + "\n" + " machinetime = " + machineTimings + "\n" + " chunktime = " + chunkTimings + "\n" + " skipped = " + skippedChunks + "\n" + "}";
}
public void queueMove(Location from, Location to) {
move.put(from, to);
movingQueue.put(from, to);
}
public void queueDelete(Location l, boolean destroy) {
delete.put(l, destroy);
deletionQueue.put(l, destroy);
}
public void start(SlimefunPlugin plugin) {

View File

@ -1,5 +1,6 @@
package io.github.thebusybiscuit.slimefun4.utils;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.time.Duration;
import java.time.LocalDateTime;
@ -9,6 +10,8 @@ import org.bukkit.ChatColor;
public final class NumberUtils {
private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#.##");
private NumberUtils() {}
public static String formatBigNumber(int i) {
@ -57,11 +60,31 @@ public final class NumberUtils {
return timeleft + seconds + "s";
}
public static int getInt(String str, int defaultVal) {
public static int getInt(String str, int defaultValue) {
if (PatternUtils.NUMERIC.matcher(str).matches()) {
return Integer.parseInt(str);
}
return defaultVal;
return defaultValue;
}
public static String getAsMillis(long nanoseconds) {
String number = DECIMAL_FORMAT.format(nanoseconds / 1000000.0);
String[] parts = PatternUtils.NUMBER_SEPERATOR.split(number);
if (parts.length == 1) {
return parts[0];
}
else {
return parts[0] + ',' + ChatColor.GRAY + parts[1] + "ms";
}
}
public static long getLong(Long value, long defaultValue) {
return value == null ? defaultValue : value;
}
public static int getInt(Integer value, int defaultValue) {
return value == null ? defaultValue : value;
}
}

View File

@ -46,6 +46,7 @@ import io.github.thebusybiscuit.slimefun4.core.services.plugins.ThirdPartyPlugin
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.implementation.items.altar.AncientAltar;
import io.github.thebusybiscuit.slimefun4.implementation.items.backpacks.Cooler;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.BasicCircuitBoard;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.reactors.Reactor;
import io.github.thebusybiscuit.slimefun4.implementation.items.tools.GrapplingHook;
import io.github.thebusybiscuit.slimefun4.implementation.items.weapons.SeismicAxe;
@ -225,7 +226,6 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
new MultiBlockListener(this);
new GadgetsListener(this);
new DispenserListener(this);
new MobDropListener(this);
new BlockListener(this);
new EnhancedFurnaceListener(this);
new ItemPickupListener(this);
@ -237,6 +237,8 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
new WitherListener(this);
new IronGolemListener(this);
new MobDropListener(this, (BasicCircuitBoard) SlimefunItems.BASIC_CIRCUIT_BOARD.getItem());
// Item-specific Listeners
new VampireBladeListener(this, (VampireBlade) SlimefunItems.BLADE_OF_VAMPIRES.getItem());
new CoolerListener(this, (Cooler) SlimefunItems.COOLER.getItem());
@ -436,12 +438,18 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
for (String folder : storageFolders) {
File file = new File("data-storage/Slimefun", folder);
if (!file.exists()) file.mkdirs();
if (!file.exists()) {
file.mkdirs();
}
}
for (String folder : pluginFolders) {
File file = new File("plugins/Slimefun", folder);
if (!file.exists()) file.mkdirs();
if (!file.exists()) {
file.mkdirs();
}
}
}

View File

@ -75,10 +75,15 @@ public class BlockStorage {
private static Location deserializeLocation(String l) {
try {
String[] components = PatternUtils.SEMICOLON.split(l);
if (components.length != 4) return null;
if (components.length != 4) {
return null;
}
World w = Bukkit.getWorld(components[0]);
if (w != null) return new Location(w, Integer.parseInt(components[1]), Integer.parseInt(components[2]), Integer.parseInt(components[3]));
if (w != null) {
return new Location(w, Integer.parseInt(components[1]), Integer.parseInt(components[2]), Integer.parseInt(components[3]));
}
}
catch (NumberFormatException x) {
Slimefun.getLogger().log(Level.WARNING, "Could not parse Number", x);
@ -160,6 +165,7 @@ public class BlockStorage {
Slimefun.getLogger().log(Level.WARNING, x, () -> "Failed to load " + file.getName() + '(' + key + ") for Slimefun " + SlimefunPlugin.getVersion());
}
}
done++;
}
}
@ -253,7 +259,7 @@ public class BlockStorage {
}
public void save(boolean remove) {
this.save(true, remove);
save(true, remove);
}
public void save(boolean computeChanges, boolean remove) {
@ -311,6 +317,14 @@ public class BlockStorage {
}
if (chunkChanges > 0) {
saveChunks(remove);
}
changes = 0;
chunkChanges = 0;
}
private void saveChunks(boolean remove) {
File chunks = new File(PATH_CHUNKS + "chunks.sfc");
Config cfg = new Config(PATH_CHUNKS + "chunks.temp");
@ -328,10 +342,6 @@ public class BlockStorage {
}
}
changes = 0;
chunkChanges = 0;
}
public static void store(Block block, ItemStack item) {
SlimefunItem sfitem = SlimefunItem.getByItem(item);
if (sfitem != null) addBlockInfo(block, "id", sfitem.getID(), true);
@ -511,15 +521,19 @@ public class BlockStorage {
}
if (destroy) {
if (storage.hasInventory(l)) storage.clearInventory(l);
if (storage.hasInventory(l)) {
storage.clearInventory(l);
}
UniversalBlockMenu universalInventory = getUniversalInventory(l);
if (universalInventory != null) {
universalInventory.close();
universalInventory.save();
}
String chunkString = locationToChunkString(l);
if (SlimefunPlugin.getRegistry().getActiveTickers().containsKey(chunkString)) {
Set<Location> locations = SlimefunPlugin.getRegistry().getActiveTickers().get(chunkString);
locations.remove(l);
@ -528,7 +542,9 @@ public class BlockStorage {
SlimefunPlugin.getRegistry().getActiveTickers().remove(chunkString);
SlimefunPlugin.getRegistry().getActiveChunks().remove(chunkString);
}
else SlimefunPlugin.getRegistry().getActiveTickers().put(chunkString, locations);
else {
SlimefunPlugin.getRegistry().getActiveTickers().put(chunkString, locations);
}
}
}
}
@ -538,7 +554,10 @@ public class BlockStorage {
}
public static void _integrated_moveLocationInfo(Location from, Location to) {
if (!hasBlockInfo(from)) return;
if (!hasBlockInfo(from)) {
return;
}
BlockStorage storage = getStorage(from.getWorld());
setBlockInfo(to, getLocationInfo(from), true);
@ -563,7 +582,9 @@ public class BlockStorage {
SlimefunPlugin.getRegistry().getActiveTickers().remove(chunkString);
SlimefunPlugin.getRegistry().getActiveChunks().remove(chunkString);
}
else SlimefunPlugin.getRegistry().getActiveTickers().put(chunkString, locations);
else {
SlimefunPlugin.getRegistry().getActiveTickers().put(chunkString, locations);
}
}
}
@ -600,7 +621,10 @@ public class BlockStorage {
}
public static SlimefunItem check(Location l) {
if (!hasBlockInfo(l)) return null;
if (!hasBlockInfo(l)) {
return null;
}
return SlimefunItem.getByID(getLocationInfo(l, "id"));
}
@ -608,7 +632,9 @@ public class BlockStorage {
if (SlimefunPlugin.getBlockDataService().isTileEntity(b.getType())) {
Optional<String> blockData = SlimefunPlugin.getBlockDataService().getBlockData(b);
if (blockData.isPresent()) return blockData.get();
if (blockData.isPresent()) {
return blockData.get();
}
}
return checkID(b.getLocation());
@ -692,8 +718,8 @@ public class BlockStorage {
if (menu != null) {
for (HumanEntity human : new ArrayList<>(menu.toInventory().getViewers())) {
// Prevents "java.lang.IllegalStateException: Asynchronous entity add!" when closing inventory while
// holding an item
// Prevents "java.lang.IllegalStateException: Asynchronous entity add!"
// when closing the inventory while holding an item
Slimefun.runSync(human::closeInventory);
}
@ -729,8 +755,13 @@ public class BlockStorage {
public static boolean hasInventory(Block b) {
BlockStorage storage = getStorage(b.getWorld());
if (storage == null) return false;
else return storage.hasInventory(b.getLocation());
if (storage == null) {
return false;
}
else {
return storage.hasInventory(b.getLocation());
}
}
public static BlockMenu getInventory(Location l) {