Minor performance improvement for custom mining

This commit is contained in:
Jules 2024-07-26 15:32:48 -07:00
parent b80cda490c
commit 61efa519c2
6 changed files with 146 additions and 118 deletions

View File

@ -43,7 +43,7 @@ public class BlockInfo {
options.put(option, config.getBoolean("options." + key));
} catch (IllegalArgumentException exception) {
MMOCore.plugin.getLogger().log(Level.WARNING,
"Could not load option '" + key + "' from block info '" + block.generateKey() + "': " + exception.getMessage());
"Could not load option '" + key + "' from block info '" + block.display() + "': " + exception.getMessage());
}
if (config.contains("triggers")) {
@ -55,7 +55,7 @@ public class BlockInfo {
triggers.add(MMOCore.plugin.loadManager.loadTrigger(new MMOLineConfig(key)));
} catch (IllegalArgumentException exception) {
MMOCore.plugin.getLogger().log(Level.WARNING,
"Could not load trigger '" + key + "' from block info '" + block.generateKey() + "': " + exception.getMessage());
"Could not load trigger '" + key + "' from block info '" + block.display() + "': " + exception.getMessage());
}
}
@ -71,6 +71,7 @@ public class BlockInfo {
return options.getOrDefault(option, option.getDefault());
}
@NotNull
public BlockType getBlock() {
return block;
}

View File

@ -1,29 +1,31 @@
package net.Indyuce.mmocore.api.block;
import org.bukkit.block.Block;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public interface BlockType {
/**
* Called when placing temporary blocks
*/
void place(BlockInfo.RegeneratingBlock placed);
/**
* Called when placing temporary blocks
*/
void place(@NotNull BlockInfo.RegeneratingBlock placed);
/**
* Called when regenerating an older block with block regen
*/
void regenerate(BlockInfo.RegeneratingBlock regenerating);
/**
* Called when regenerating an older block with block regen
*/
void regenerate(@NotNull BlockInfo.RegeneratingBlock regenerating);
/**
* Generates a key used to store the BlockInfo instance in the manager map,
* the key depends on the block type to make sure there is no interference
*/
String generateKey();
@NotNull String display();
/**
* Applies some extra break restrictions; returns TRUE if the block can be
* broken. This method is used to prevent non mature crops from being broken
* for example
*/
boolean breakRestrictions(Block block);
/**
* Applies some extra break restrictions; returns TRUE if the block can be
* broken. This method is used to prevent non mature crops from being broken
* for example
*/
boolean breakRestrictions(@NotNull Block block);
int hashCode();
boolean equals(@Nullable Object obj);
}

View File

@ -8,51 +8,66 @@ import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import java.util.Objects;
public class SkullBlockType implements BlockType {
private final String value;
private final String value;
public SkullBlockType(MMOLineConfig config) {
config.validate("value");
public SkullBlockType(MMOLineConfig config) {
config.validate("value");
value = config.getString("value");
}
value = config.getString("value");
}
public SkullBlockType(Block block) {
value = MythicLib.plugin.getVersion().getWrapper().getSkullValue(block);
}
public SkullBlockType(Block block) {
value = MythicLib.plugin.getVersion().getWrapper().getSkullValue(block);
}
public String getValue() {
return value;
}
public String getValue() {
return value;
}
@Override
public void place(RegeneratingBlock block) {
Location loc = block.getLocation();
loc.getBlock().setType(Material.PLAYER_HEAD);
@Override
public void place(RegeneratingBlock block) {
Location loc = block.getLocation();
loc.getBlock().setType(Material.PLAYER_HEAD);
// save skull orientation if replaced block is a player head
if (MMOCoreUtils.isPlayerHead(block.getBlockData().getMaterial()))
loc.getBlock().setBlockData(block.getBlockData());
// save skull orientation if replaced block is a player head
if (MMOCoreUtils.isPlayerHead(block.getBlockData().getMaterial()))
loc.getBlock().setBlockData(block.getBlockData());
MythicLib.plugin.getVersion().getWrapper().setSkullValue(loc.getBlock(), value);
}
MythicLib.plugin.getVersion().getWrapper().setSkullValue(loc.getBlock(), value);
}
@Override
public void regenerate(RegeneratingBlock block) {
Location loc = block.getLocation();
// This makes sure that if a skull loses its original rotation
// it can revert back to it when the base block is regenerated
loc.getBlock().setBlockData(block.getBlockData());
MythicLib.plugin.getVersion().getWrapper().setSkullValue(loc.getBlock(), value);
}
@Override
public void regenerate(RegeneratingBlock block) {
Location loc = block.getLocation();
// This makes sure that if a skull loses its original rotation
// it can revert back to it when the base block is regenerated
loc.getBlock().setBlockData(block.getBlockData());
MythicLib.plugin.getVersion().getWrapper().setSkullValue(loc.getBlock(), value);
}
@Override
public String generateKey() {
return "vanilla-skull-" + value;
}
@Override
public String display() {
return "Skull{" + value + "}";
}
@Override
public boolean breakRestrictions(Block block) {
return true;
}
@Override
public boolean breakRestrictions(Block block) {
return true;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
SkullBlockType that = (SkullBlockType) o;
return Objects.equals(value, that.value);
}
@Override
public int hashCode() {
return Objects.hash(value);
}
}

View File

@ -1,5 +1,7 @@
package net.Indyuce.mmocore.api.block;
import io.lumine.mythic.lib.api.MMOLineConfig;
import net.Indyuce.mmocore.api.block.BlockInfo.RegeneratingBlock;
import org.apache.commons.lang.Validate;
import org.bukkit.Location;
import org.bukkit.Material;
@ -7,63 +9,75 @@ import org.bukkit.block.Block;
import org.bukkit.block.data.Ageable;
import org.bukkit.block.data.BlockData;
import net.Indyuce.mmocore.api.block.BlockInfo.RegeneratingBlock;
import io.lumine.mythic.lib.api.MMOLineConfig;
import java.util.Objects;
public class VanillaBlockType implements BlockType {
private final Material type;
private final Material type;
/*
* allows to plant back crops with a custom age so that it does not always
* have to full grow again-
*/
private final int age;
/*
* allows to plant back crops with a custom age so that it does not always
* have to full grow again-
*/
private final int age;
public VanillaBlockType(MMOLineConfig config) {
config.validate("type");
public VanillaBlockType(MMOLineConfig config) {
config.validate("type");
type = Material.valueOf(config.getString("type").toUpperCase().replace("-", "_").replace(" ", "_"));
age = config.getInt("age", 0);
type = Material.valueOf(config.getString("type").toUpperCase().replace("-", "_").replace(" ", "_"));
age = config.getInt("age", 0);
Validate.isTrue(age >= 0 && age < 8, "Age must be between 0 and 7");
}
Validate.isTrue(age >= 0 && age < 8, "Age must be between 0 and 7");
}
public VanillaBlockType(Block block) {
type = block.getType();
age = 0;
}
public VanillaBlockType(Block block) {
type = block.getType();
age = 0;
}
public Material getType() {
return type;
}
public Material getType() {
return type;
}
@Override
public void place(RegeneratingBlock block) {
Location loc = block.getLocation();
block.getLocation().getBlock().setType(type);
@Override
public void place(RegeneratingBlock block) {
Location loc = block.getLocation();
block.getLocation().getBlock().setType(type);
BlockData state = block.getLocation().getBlock().getBlockData();
if (age > 0 && state instanceof Ageable) {
((Ageable) state).setAge(age);
loc.getBlock().setBlockData(state);
}
}
BlockData state = block.getLocation().getBlock().getBlockData();
if (age > 0 && state instanceof Ageable) {
((Ageable) state).setAge(age);
loc.getBlock().setBlockData(state);
}
}
@Override
public void regenerate(RegeneratingBlock block) {
Location loc = block.getLocation();
loc.getBlock().setType(type);
// Sets the original blocks old data (only when regenerating)
loc.getBlock().setBlockData(block.getBlockData());
}
@Override
public void regenerate(RegeneratingBlock block) {
Location loc = block.getLocation();
loc.getBlock().setType(type);
// Sets the original blocks old data (only when regenerating)
loc.getBlock().setBlockData(block.getBlockData());
}
@Override
public String generateKey() {
return "vanilla-block-" + type.name();
}
@Override
public String display() {
return "Vanilla{" + type.name() + "}";
}
@Override
public boolean breakRestrictions(Block block) {
return age == 0 || (block.getBlockData() instanceof Ageable && ((Ageable) block.getBlockData()).getAge() >= age);
}
@Override
public boolean breakRestrictions(Block block) {
return age == 0 || (block.getBlockData() instanceof Ageable && ((Ageable) block.getBlockData()).getAge() >= age);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
VanillaBlockType that = (VanillaBlockType) o;
return type == that.type;
}
@Override
public int hashCode() {
return Objects.hash(type);
}
}

View File

@ -91,13 +91,7 @@ public class RestrictionManager implements MMOCoreManager {
}
public class ToolPermissions implements PreloadedObject {
/**
* Now saving string keys using {@link BlockType#generateKey()} instead
* of iterating through the set to take advantage of the O(1) time
* complexity of hash sets.
*/
private final Set<String> mineable = new HashSet<>();
private final Set<BlockType> mineable = new HashSet<>();
private final ItemType tool;
private final boolean defaultSet;
@ -112,7 +106,7 @@ public class RestrictionManager implements MMOCoreManager {
}
if (config.contains("can-mine"))
for (String key : config.getStringList("can-mine"))
mineable.add(MMOCore.plugin.loadManager.loadBlockType(new MMOLineConfig(key)).generateKey());
mineable.add(MMOCore.plugin.loadManager.loadBlockType(new MMOLineConfig(key)));
});
public ToolPermissions(ConfigurationSection config) {
@ -138,9 +132,9 @@ public class RestrictionManager implements MMOCoreManager {
* @param type Block being broken
* @return If the given block can be broken
*/
public boolean canMine(BlockType type) {
public boolean canMine(@NotNull BlockType type) {
ToolPermissions parent;
return mineable.contains(type.generateKey()) || ((parent = getParent()) != null && parent.canMine(type));
return mineable.contains(type) || ((parent = getParent()) != null && parent.canMine(type));
}
/**

View File

@ -15,6 +15,7 @@ import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Entity;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable;
import java.util.*;
@ -26,7 +27,7 @@ public class CustomBlockManager extends SpecificProfessionManager {
/**
* Registered block infos
*/
private final Map<String, BlockInfo> map = new HashMap<>();
private final Map<BlockType, BlockInfo> map = new HashMap<>();
/**
* Blocks that are regenerating and that must be refreshed whenever the
@ -57,8 +58,8 @@ public class CustomBlockManager extends SpecificProfessionManager {
blockTypes.add(function);
}
public void register(BlockInfo regen) {
map.put(regen.getBlock().generateKey(), regen);
public void register(@NotNull BlockInfo regen) {
map.put(regen.getBlock(), regen);
}
/**
@ -68,10 +69,11 @@ public class CustomBlockManager extends SpecificProfessionManager {
* @param block Block to check
* @return The new block behaviour or null if no new behaviour
*/
public @Nullable BlockInfo getInfo(Block block) {
return map.get(findBlockType(block).generateKey());
public @Nullable BlockInfo getInfo(@NotNull Block block) {
return map.get(findBlockType(block));
}
@NotNull
public BlockType findBlockType(Block block) {
for (Function<Block, Optional<BlockType>> blockType : blockTypes) {
Optional<BlockType> type = blockType.apply(block);