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

[CI skip] Refactoring and optimizations

This commit is contained in:
TheBusyBiscuit 2020-06-11 13:50:22 +02:00
parent 79e8ca46ff
commit c5cc2a86ff
8 changed files with 169 additions and 119 deletions

View File

@ -39,6 +39,7 @@
* Crafting Organic Food/Fertilizer yields more output now * Crafting Organic Food/Fertilizer yields more output now
* Organic Food (Melon) now uses Melon Slices instead of Melon blocks * Organic Food (Melon) now uses Melon Slices instead of Melon blocks
* The Seismic Axe now skips the first two blocks to clear your field of view * The Seismic Axe now skips the first two blocks to clear your field of view
* Auto Disenchanting is now a tiny bit faster
* Small performance improvements * Small performance improvements
#### Fixes #### Fixes

View File

@ -252,14 +252,14 @@ public final class PlayerProfile {
* The profile can then be removed from RAM. * The profile can then be removed from RAM.
*/ */
public void markForDeletion() { public void markForDeletion() {
this.markedForDeletion = true; markedForDeletion = true;
} }
/** /**
* Call this method if this Profile has unsaved changes. * Call this method if this Profile has unsaved changes.
*/ */
public void markDirty() { public void markDirty() {
this.dirty = true; dirty = true;
} }
public PlayerBackpack createBackpack(int size) { public PlayerBackpack createBackpack(int size) {

View File

@ -1,5 +1,6 @@
package io.github.thebusybiscuit.slimefun4.core.networks.cargo; package io.github.thebusybiscuit.slimefun4.core.networks.cargo;
import java.util.Deque;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedList; import java.util.LinkedList;
@ -236,25 +237,7 @@ public class CargoNet extends ChestTerminalNetwork {
List<Location> outputs = outputNodes.get(frequency); List<Location> outputs = outputNodes.get(frequency);
if (outputs != null) { if (outputs != null) {
List<Location> outputList = new LinkedList<>(outputs); stack = distributeItem(stack, inputNode, outputs);
Config cfg = BlockStorage.getLocationInfo(inputNode);
boolean roundrobin = "true".equals(cfg.getString("round-robin"));
if (roundrobin) {
roundRobinSort(inputNode, outputList);
}
for (Location output : outputList) {
Optional<Block> target = getAttachedBlock(output.getBlock());
if (target.isPresent()) {
stack = CargoUtils.insert(output.getBlock(), target.get(), stack);
if (stack == null) {
break;
}
}
}
} }
DirtyChestMenu menu = CargoUtils.getChestMenu(inputTarget); DirtyChestMenu menu = CargoUtils.getChestMenu(inputTarget);
@ -272,14 +255,49 @@ public class CargoNet extends ChestTerminalNetwork {
} }
} }
private void roundRobinSort(Location input, List<Location> outputs) { private ItemStack distributeItem(ItemStack stack, Location inputNode, List<Location> outputNodes) {
int index = roundRobin.getOrDefault(input, 0); ItemStack item = stack;
if (index < outputs.size()) { Deque<Location> destinations = new LinkedList<>(outputNodes);
Config cfg = BlockStorage.getLocationInfo(inputNode);
boolean roundrobin = "true".equals(cfg.getString("round-robin"));
if (roundrobin) {
roundRobinSort(inputNode, destinations);
}
for (Location output : destinations) {
Optional<Block> target = getAttachedBlock(output.getBlock());
if (target.isPresent()) {
item = CargoUtils.insert(output.getBlock(), target.get(), item);
if (item == null) {
break;
}
}
}
return item;
}
/**
* This method sorts a given {@link Deque} of output node locations using a semi-accurate
* round-robin method.
*
* @param inputNode
* The {@link Location} of the input node
* @param outputNodes
* A {@link Deque} of {@link Location Locations} of the output nodes
*/
private void roundRobinSort(Location inputNode, Deque<Location> outputNodes) {
int index = roundRobin.getOrDefault(inputNode, 0);
if (index < outputNodes.size()) {
// Not ideal but actually not bad performance-wise over more elegant alternatives // Not ideal but actually not bad performance-wise over more elegant alternatives
for (int i = 0; i < index; i++) { for (int i = 0; i < index; i++) {
Location temp = outputs.remove(0); Location temp = outputNodes.removeFirst();
outputs.add(temp); outputNodes.add(temp);
} }
index++; index++;
@ -288,16 +306,26 @@ public class CargoNet extends ChestTerminalNetwork {
index = 1; index = 1;
} }
roundRobin.put(input, index); roundRobin.put(inputNode, index);
} }
private static int getFrequency(Location l) { /**
* This method returns the frequency a given node is set to.
* Should there be an {@link Exception} to this method it will fall back to zero in
* order to protect the integrity of the {@link CargoNet}.
*
* @param node
* The {@link Location} of our cargo node
*
* @return The frequency of the given node
*/
private static int getFrequency(Location node) {
try { try {
String str = BlockStorage.getLocationInfo(l).getString("frequency"); String str = BlockStorage.getLocationInfo(node).getString("frequency");
return Integer.parseInt(str); return Integer.parseInt(str);
} }
catch (Exception x) { catch (Exception x) {
Slimefun.getLogger().log(Level.SEVERE, x, () -> "An Error occurred while parsing a Cargo Node Frequency (" + l.getWorld().getName() + " - " + l.getBlockX() + "," + l.getBlockY() + "," + +l.getBlockZ() + ")"); Slimefun.getLogger().log(Level.SEVERE, x, () -> "An Error occurred while parsing a Cargo Node Frequency (" + node.getWorld().getName() + " - " + node.getBlockX() + "," + node.getBlockY() + "," + +node.getBlockZ() + ")");
return 0; return 0;
} }
} }

View File

@ -229,24 +229,7 @@ public class PerWorldSettingsService {
config.setDefaultValue("enabled", true); config.setDefaultValue("enabled", true);
if (config.getBoolean("enabled")) { if (config.getBoolean("enabled")) {
for (SlimefunItem item : SlimefunPlugin.getRegistry().getEnabledSlimefunItems()) { loadItemsFromWorldConfig(name, config, items);
if (item != null && item.getID() != null) {
String addon = item.getAddon().getName().toLowerCase(Locale.ROOT);
config.setDefaultValue(addon + ".enabled", true);
config.setDefaultValue(addon + '.' + item.getID(), true);
boolean isAddonDisabled = config.getBoolean(addon + ".enabled");
if (isAddonDisabled) {
Set<String> blacklist = disabledAddons.computeIfAbsent(plugin, key -> new HashSet<>());
blacklist.add(name);
}
if (!isAddonDisabled || !config.getBoolean(addon + '.' + item.getID())) {
items.add(item.getID());
}
}
}
if (SlimefunPlugin.getMinecraftVersion() != MinecraftVersion.UNIT_TEST) { if (SlimefunPlugin.getMinecraftVersion() != MinecraftVersion.UNIT_TEST) {
config.save(); config.save();
@ -260,6 +243,27 @@ public class PerWorldSettingsService {
} }
} }
private void loadItemsFromWorldConfig(String worldName, Config config, Set<String> items) {
for (SlimefunItem item : SlimefunPlugin.getRegistry().getEnabledSlimefunItems()) {
if (item != null && item.getID() != null) {
String addon = item.getAddon().getName().toLowerCase(Locale.ROOT);
config.setDefaultValue(addon + ".enabled", true);
config.setDefaultValue(addon + '.' + item.getID(), true);
boolean isAddonDisabled = config.getBoolean(addon + ".enabled");
if (isAddonDisabled) {
Set<String> blacklist = disabledAddons.computeIfAbsent(plugin, key -> new HashSet<>());
blacklist.add(worldName);
}
if (!isAddonDisabled || !config.getBoolean(addon + '.' + item.getID())) {
items.add(item.getID());
}
}
}
}
private Config getConfig(World world) { private Config getConfig(World world) {
return new Config(plugin, "world-settings/" + world.getName() + ".yml"); return new Config(plugin, "world-settings/" + world.getName() + ".yml");
} }

View File

@ -37,10 +37,13 @@ public class PermissionsService {
public void register(Iterable<SlimefunItem> items, boolean save) { public void register(Iterable<SlimefunItem> items, boolean save) {
for (SlimefunItem item : items) { for (SlimefunItem item : items) {
if (item != null && item.getID() != null && !migrate(item)) { if (item != null && item.getID() != null) {
config.setDefaultValue(item.getID() + ".permission", "none"); String path = item.getID() + ".permission";
config.setDefaultValue(path, "none");
config.setDefaultValue(item.getID() + ".lore", new String[] { "&rYou do not have the permission", "&rto access this item." }); config.setDefaultValue(item.getID() + ".lore", new String[] { "&rYou do not have the permission", "&rto access this item." });
permissions.put(item.getID(), config.getString(item.getID() + ".permission"));
permissions.put(item.getID(), config.getString(path));
} }
} }
@ -49,23 +52,6 @@ public class PermissionsService {
} }
} }
// Temporary migration method for the old system
private boolean migrate(SlimefunItem item) {
String permission = SlimefunPlugin.getItemCfg().getString(item.getID() + ".required-permission");
if (permission != null) {
config.setDefaultValue(item.getID() + ".permission", permission.length() == 0 ? "none" : permission);
config.setDefaultValue(item.getID() + ".lore", SlimefunPlugin.getItemCfg().getString(item.getID() + ".no-permission-tooltip"));
permissions.put(item.getID(), config.getString(item.getID() + ".permission"));
SlimefunPlugin.getItemCfg().setValue(item.getID() + ".required-permission", null);
SlimefunPlugin.getItemCfg().setValue(item.getID() + ".no-permission-tooltip", null);
return true;
}
return false;
}
/** /**
* This method checks whether the given {@link Permissible} has the {@link Permission} * This method checks whether the given {@link Permissible} has the {@link Permission}
* to access the given {@link SlimefunItem}. * to access the given {@link SlimefunItem}.

View File

@ -18,6 +18,7 @@ import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.inventory.InvUtils; import io.github.thebusybiscuit.cscorelib2.inventory.InvUtils;
import io.github.thebusybiscuit.cscorelib2.materials.MaterialCollections; import io.github.thebusybiscuit.cscorelib2.materials.MaterialCollections;
import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction; import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
import io.github.thebusybiscuit.cscorelib2.scheduling.TaskQueue;
import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem; import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import me.mrCookieSlime.Slimefun.SlimefunPlugin; import me.mrCookieSlime.Slimefun.SlimefunPlugin;
@ -26,7 +27,6 @@ import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SimpleSlimefunItem; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SimpleSlimefunItem;
import me.mrCookieSlime.Slimefun.Objects.handlers.BlockUseHandler; import me.mrCookieSlime.Slimefun.Objects.handlers.BlockUseHandler;
import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.BlockStorage;
import me.mrCookieSlime.Slimefun.api.Slimefun;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
public class Composter extends SimpleSlimefunItem<BlockUseHandler> implements RecipeDisplayItem { public class Composter extends SimpleSlimefunItem<BlockUseHandler> implements RecipeDisplayItem {
@ -86,19 +86,19 @@ public class Composter extends SimpleSlimefunItem<BlockUseHandler> implements Re
ItemStack output = getOutput(p, input); ItemStack output = getOutput(p, input);
if (output != null) { if (output != null) {
for (int j = 1; j < 12; j++) { TaskQueue tasks = new TaskQueue();
int index = j;
Slimefun.runSync(() -> { tasks.thenRepeatEvery(30, 10, () -> {
if (index < 11) { Material material = input.getType().isBlock() ? input.getType() : Material.HAY_BLOCK;
b.getWorld().playEffect(b.getLocation(), Effect.STEP_SOUND, input.getType().isBlock() ? input.getType() : Material.HAY_BLOCK); b.getWorld().playEffect(b.getLocation(), Effect.STEP_SOUND, material);
} });
else {
p.getWorld().playSound(p.getLocation(), Sound.ENTITY_ARROW_HIT_PLAYER, 1F, 1F); tasks.thenRun(20, () -> {
pushItem(b, output.clone()); p.getWorld().playSound(p.getLocation(), Sound.ENTITY_ARROW_HIT_PLAYER, 1F, 1F);
} pushItem(b, output.clone());
}, j * 30L); });
}
tasks.execute(SlimefunPlugin.instance);
} }
else { else {
SlimefunPlugin.getLocal().sendMessage(p, "machines.wrong-item", true); SlimefunPlugin.getLocal().sendMessage(p, "machines.wrong-item", true);

View File

@ -81,14 +81,10 @@ public abstract class AutoAnvil extends AContainer {
if (item != null && item.getType().getMaxDurability() > 0 && ((Damageable) item.getItemMeta()).getDamage() > 0) { if (item != null && item.getType().getMaxDurability() > 0 && ((Damageable) item.getItemMeta()).getDamage() > 0) {
if (SlimefunUtils.isItemSimilar(target, SlimefunItems.DUCT_TAPE, true)) { if (SlimefunUtils.isItemSimilar(target, SlimefunItems.DUCT_TAPE, true)) {
ItemStack newItem = item.clone(); ItemStack repaired = repair(item);
short durability = (short) (((Damageable) newItem.getItemMeta()).getDamage() - (item.getType().getMaxDurability() / getRepairFactor())); recipe = new MachineRecipe(30, new ItemStack[] { target, item }, new ItemStack[] { repaired });
if (durability < 0) durability = 0;
ItemMeta meta = newItem.getItemMeta();
((Damageable) meta).setDamage(durability);
newItem.setItemMeta(meta);
recipe = new MachineRecipe(30, new ItemStack[] { target, item }, new ItemStack[] { newItem });
} }
break; break;
} }
} }
@ -106,4 +102,20 @@ public abstract class AutoAnvil extends AContainer {
} }
} }
private ItemStack repair(ItemStack item) {
ItemStack repaired = item.clone();
ItemMeta meta = repaired.getItemMeta();
short maxDurability = item.getType().getMaxDurability();
short durability = (short) (((Damageable) meta).getDamage() - (maxDurability / getRepairFactor()));
if (durability < 0) {
durability = 0;
}
((Damageable) meta).setDamage(durability);
repaired.setItemMeta(meta);
return repaired;
}
} }

View File

@ -31,6 +31,18 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
import me.mrCookieSlime.Slimefun.api.energy.ChargableBlock; import me.mrCookieSlime.Slimefun.api.energy.ChargableBlock;
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
/**
* The {@link AutoDisenchanter}, in contrast to the {@link AutoEnchanter}, removes
* {@link Enchantment Enchantments} from a given {@link ItemStack} and transfers them
* to a book.
*
* @author TheBusyBiscuit
* @author Walshy
* @author poma123
*
* @see AutoEnchanter
*
*/
public class AutoDisenchanter extends AContainer { public class AutoDisenchanter extends AContainer {
public AutoDisenchanter(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { public AutoDisenchanter(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
@ -74,7 +86,7 @@ public class AutoDisenchanter extends AContainer {
else progress.put(b, timeleft - 1); else progress.put(b, timeleft - 1);
} }
else { else {
menu.replaceExistingItem(22, new CustomItem(new ItemStack(Material.BLACK_STAINED_GLASS_PANE), " ")); menu.replaceExistingItem(22, new CustomItem(Material.BLACK_STAINED_GLASS_PANE, " "));
for (ItemStack item : processing.get(b).getOutput()) { for (ItemStack item : processing.get(b).getOutput()) {
menu.pushItem(item, getOutputSlots()); menu.pushItem(item, getOutputSlots());
@ -92,19 +104,13 @@ public class AutoDisenchanter extends AContainer {
for (int slot : getInputSlots()) { for (int slot : getInputSlots()) {
ItemStack item = menu.getItemInSlot(slot); ItemStack item = menu.getItemInSlot(slot);
// Check if disenchantable if (!isDisenchantable(item)) {
SlimefunItem sfItem = null;
// stops endless checks of getByItem for empty book stacks.
if ((item != null) && (item.getType() != Material.BOOK)) {
sfItem = SlimefunItem.getByItem(item);
}
if (sfItem != null && !sfItem.isDisenchantable()) {
return; return;
} }
AutoDisenchantEvent event = new AutoDisenchantEvent(item); AutoDisenchantEvent event = new AutoDisenchantEvent(item);
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) { if (event.isCancelled()) {
return; return;
} }
@ -128,34 +134,18 @@ public class AutoDisenchanter extends AContainer {
} }
if (amount > 0) { if (amount > 0) {
ItemStack newItem = item.clone(); ItemStack disenchantedItem = item.clone();
newItem.setAmount(1); disenchantedItem.setAmount(1);
ItemStack book = target.clone();
book.setAmount(1);
book.setType(Material.ENCHANTED_BOOK);
ItemMeta itemMeta = newItem.getItemMeta(); ItemStack book = new ItemStack(Material.ENCHANTED_BOOK);
ItemMeta bookMeta = book.getItemMeta(); transferEnchantments(disenchantedItem, book, enchantments);
((Repairable) bookMeta).setRepairCost(((Repairable) itemMeta).getRepairCost());
((Repairable) itemMeta).setRepairCost(0);
newItem.setItemMeta(itemMeta);
book.setItemMeta(bookMeta);
EnchantmentStorageMeta meta = (EnchantmentStorageMeta) book.getItemMeta();
for (Map.Entry<Enchantment, Integer> entry : enchantments.entrySet()) {
newItem.removeEnchantment(entry.getKey());
meta.addStoredEnchant(entry.getKey(), entry.getValue(), true);
}
book.setItemMeta(meta);
for (ItemEnchantment ench : emeraldEnchantments) { for (ItemEnchantment ench : emeraldEnchantments) {
EmeraldEnchants.getInstance().getRegistry().applyEnchantment(book, ench.getEnchantment(), ench.getLevel()); EmeraldEnchants.getInstance().getRegistry().applyEnchantment(book, ench.getEnchantment(), ench.getLevel());
EmeraldEnchants.getInstance().getRegistry().applyEnchantment(newItem, ench.getEnchantment(), 0); EmeraldEnchants.getInstance().getRegistry().applyEnchantment(disenchantedItem, ench.getEnchantment(), 0);
} }
recipe = new MachineRecipe(100 * amount, new ItemStack[] { target, item }, new ItemStack[] { newItem, book }); recipe = new MachineRecipe(90 * amount, new ItemStack[] { target, item }, new ItemStack[] { disenchantedItem, book });
break; break;
} }
} }
@ -176,6 +166,35 @@ public class AutoDisenchanter extends AContainer {
} }
} }
private void transferEnchantments(ItemStack item, ItemStack book, Map<Enchantment, Integer> enchantments) {
ItemMeta itemMeta = item.getItemMeta();
ItemMeta bookMeta = book.getItemMeta();
((Repairable) bookMeta).setRepairCost(((Repairable) itemMeta).getRepairCost());
((Repairable) itemMeta).setRepairCost(0);
item.setItemMeta(itemMeta);
book.setItemMeta(bookMeta);
EnchantmentStorageMeta meta = (EnchantmentStorageMeta) book.getItemMeta();
for (Map.Entry<Enchantment, Integer> entry : enchantments.entrySet()) {
item.removeEnchantment(entry.getKey());
meta.addStoredEnchant(entry.getKey(), entry.getValue(), true);
}
book.setItemMeta(meta);
}
private boolean isDisenchantable(ItemStack item) {
SlimefunItem sfItem = null;
// stops endless checks of getByItem for empty book stacks.
if (item != null && item.getType() != Material.BOOK) {
sfItem = SlimefunItem.getByItem(item);
}
return sfItem == null || sfItem.isDisenchantable();
}
@Override @Override
public int getSpeed() { public int getSpeed() {
return 1; return 1;