This commit is contained in:
xGinko 2024-07-30 01:25:57 +02:00
parent 849d6fbaf5
commit 7969f75a3a
4 changed files with 43 additions and 23 deletions

View File

@ -20,20 +20,24 @@ import space.arim.morepaperlib.scheduling.ScheduledTask;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class VillagerChunkLimit extends VillagerOptimizerModule implements Runnable, Listener {
private ScheduledTask periodic_chunk_check;
private final List<Villager.Profession> non_optimized_removal_priority, optimized_removal_priority, profession_whitelist;
private final List<Villager.Profession> non_optimized_removal_priority, optimized_removal_priority;
private final Set<Villager.Profession> profession_whitelist;
private final ExpiringSet<Chunk> checked_chunks;
private final long check_period;
private final int non_optimized_max_per_chunk, optimized_max_per_chunk;
private final boolean log_enabled, skip_unloaded_chunks;
private final boolean log_enabled, skip_unloaded_chunks, use_whitelist;
@SuppressWarnings("deprecation")
protected VillagerChunkLimit() {
super("villager-chunk-limit");
config.master().addComment(configPath + ".enable",
@ -57,6 +61,8 @@ public class VillagerChunkLimit extends VillagerOptimizerModule implements Runna
return false;
}
}).collect(Collectors.toList());
this.use_whitelist = config.getBoolean(configPath + ".whitelist-certain-professions", false,
"Enable if you only want to manage villager counts for certain profession types.");
this.profession_whitelist = config.getList(configPath + ".removal-whitelist", defaults,
"Only professions in this list will count for the cap.")
.stream()
@ -64,14 +70,14 @@ public class VillagerChunkLimit extends VillagerOptimizerModule implements Runna
try {
return Villager.Profession.valueOf(configuredProfession);
} catch (IllegalArgumentException e) {
warn("(unoptimized) Villager profession '" + configuredProfession +
warn("(whitelist) Villager profession '" + configuredProfession +
"' not recognized. Make sure you're using the correct profession enums from " +
"https://jd.papermc.io/paper/1.20/org/bukkit/entity/Villager.Profession.html.");
return null;
}
})
.filter(Objects::nonNull)
.collect(Collectors.toList());
.collect(Collectors.toCollection(HashSet::new));
this.non_optimized_max_per_chunk = config.getInt(configPath + ".unoptimized.max-per-chunk", 20,
"The maximum amount of unoptimized villagers per chunk.");
this.checked_chunks = new ExpiringSet<>(Duration.ofSeconds(
@ -175,7 +181,7 @@ public class VillagerChunkLimit extends VillagerOptimizerModule implements Runna
Villager villager = (Villager) entity;
// Ignore villager if profession is not in the whitelist
if (!profession_whitelist.contains(villager.getProfession())) continue;
if (use_whitelist && !profession_whitelist.contains(villager.getProfession())) continue;
if (wrapperCache.get(villager).isOptimized()) {
optimized_villagers.add(villager);
@ -198,7 +204,7 @@ public class VillagerChunkLimit extends VillagerOptimizerModule implements Runna
scheduling.entitySpecificScheduler(villager).run(kill -> {
villager.remove();
if (log_enabled) info("Removed unoptimized villager with profession '" +
Util.formatEnum(villager.getProfession()) + "' at " + LocationUtil.toString(villager.getLocation()));
Util.toNiceString(villager.getProfession()) + "' at " + LocationUtil.toString(villager.getLocation()));
}, null);
}
}
@ -217,7 +223,7 @@ public class VillagerChunkLimit extends VillagerOptimizerModule implements Runna
scheduling.entitySpecificScheduler(villager).run(kill -> {
villager.remove();
if (log_enabled) info("Removed unoptimized villager with profession '" +
Util.formatEnum(villager.getProfession()) + "' at " + LocationUtil.toString(villager.getLocation()));
Util.toNiceString(villager.getProfession()) + "' at " + LocationUtil.toString(villager.getLocation()));
}, null);
}
}

View File

@ -135,11 +135,11 @@ public class OptimizeByBlock extends VillagerOptimizerModule implements Listener
if (notify_player) {
final TextReplacementConfig vilProfession = TextReplacementConfig.builder()
.matchLiteral("%vil_profession%")
.replacement(Util.formatEnum(closestOptimizableVillager.villager().getProfession()))
.replacement(Util.toNiceString(closestOptimizableVillager.villager().getProfession()))
.build();
final TextReplacementConfig placedMaterial = TextReplacementConfig.builder()
.matchLiteral("%blocktype%")
.replacement(Util.formatEnum(placed.getType()))
.replacement(Util.toNiceString(placed.getType()))
.build();
VillagerOptimizer.getLang(player.locale()).block_optimize_success
.forEach(line -> KyoriUtil.sendMessage(player, line.replaceText(vilProfession).replaceText(placedMaterial)));
@ -200,18 +200,18 @@ public class OptimizeByBlock extends VillagerOptimizerModule implements Listener
if (notify_player) {
final TextReplacementConfig vilProfession = TextReplacementConfig.builder()
.matchLiteral("%vil_profession%")
.replacement(Util.formatEnum(closestOptimizedVillager.villager().getProfession()))
.replacement(Util.toNiceString(closestOptimizedVillager.villager().getProfession()))
.build();
final TextReplacementConfig brokenMaterial = TextReplacementConfig.builder()
.matchLiteral("%blocktype%")
.replacement(Util.formatEnum(broken.getType()))
.replacement(Util.toNiceString(broken.getType()))
.build();
VillagerOptimizer.getLang(player.locale()).block_unoptimize_success
.forEach(line -> KyoriUtil.sendMessage(player, line.replaceText(vilProfession).replaceText(brokenMaterial)));
}
if (log_enabled) {
info(player.getName() + " unoptimized villager using " + Util.formatEnum(broken.getType()) +
info(player.getName() + " unoptimized villager using " + Util.toNiceString(broken.getType()) +
LocationUtil.toString(closestOptimizedVillager.villager().getLocation()));
}
}

View File

@ -127,18 +127,18 @@ public class OptimizeByWorkstation extends VillagerOptimizerModule implements Li
if (notify_player) {
final TextReplacementConfig vilProfession = TextReplacementConfig.builder()
.matchLiteral("%vil_profession%")
.replacement(Util.formatEnum(wrapped.villager().getProfession()))
.replacement(Util.toNiceString(wrapped.villager().getProfession()))
.build();
final TextReplacementConfig placedWorkstation = TextReplacementConfig.builder()
.matchLiteral("%blocktype%")
.replacement(Util.formatEnum(placed.getType()))
.replacement(Util.toNiceString(placed.getType()))
.build();
VillagerOptimizer.getLang(player.locale()).workstation_optimize_success
.forEach(line -> KyoriUtil.sendMessage(player, line.replaceText(vilProfession).replaceText(placedWorkstation)));
}
if (log_enabled) {
info(player.getName() + " optimized villager using workstation " + Util.formatEnum(placed.getType()) + " at " +
info(player.getName() + " optimized villager using workstation " + Util.toNiceString(placed.getType()) + " at " +
LocationUtil.toString(wrapped.villager().getLocation()));
}
@ -191,18 +191,18 @@ public class OptimizeByWorkstation extends VillagerOptimizerModule implements Li
if (notify_player) {
final TextReplacementConfig vilProfession = TextReplacementConfig.builder()
.matchLiteral("%vil_profession%")
.replacement(Util.formatEnum(closestOptimized.villager().getProfession()))
.replacement(Util.toNiceString(closestOptimized.villager().getProfession()))
.build();
final TextReplacementConfig brokenWorkstation = TextReplacementConfig.builder()
.matchLiteral("%blocktype%")
.replacement(Util.formatEnum(broken.getType()))
.replacement(Util.toNiceString(broken.getType()))
.build();
VillagerOptimizer.getLang(player.locale()).workstation_unoptimize_success
.forEach(line -> KyoriUtil.sendMessage(player, line.replaceText(vilProfession).replaceText(brokenWorkstation)));
}
if (log_enabled) {
info(player.getName() + " unoptimized villager using workstation " + Util.formatEnum(broken.getType()) + " at " +
info(player.getName() + " unoptimized villager using workstation " + Util.toNiceString(broken.getType()) + " at " +
LocationUtil.toString(closestOptimized.villager().getLocation()));
}
}

View File

@ -7,11 +7,12 @@ import net.kyori.adventure.text.format.TextDecoration;
import org.bukkit.Chunk;
import org.bukkit.Material;
import org.bukkit.entity.Villager;
import org.bukkit.util.OldEnum;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.time.Duration;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
@ -25,7 +26,7 @@ public class Util {
static {
PL_COLOR = TextColor.color(102,255,230);
PL_STYLE = Style.style(PL_COLOR, TextDecoration.BOLD);
PROFESSION_MAP = new EnumMap<>(Material.class);
PROFESSION_MAP = new HashMap<>();
PROFESSION_MAP.put(XMaterial.LOOM.parseMaterial(), Villager.Profession.SHEPHERD);
PROFESSION_MAP.put(XMaterial.BARREL.parseMaterial(), Villager.Profession.FISHERMAN);
PROFESSION_MAP.put(XMaterial.SMOKER.parseMaterial(), Villager.Profession.BUTCHER);
@ -71,14 +72,27 @@ public class Util {
}
}
public static @NotNull String formatEnum(@NotNull Enum<?> input) {
@SuppressWarnings({"deprecation", "UnstableApiUsage"})
public static @NotNull String toNiceString(@NotNull Object input) {
// Get name
String name;
if (input instanceof Enum<?>) {
name = ((Enum<?>) input).name();
} else if (input instanceof OldEnum<?>) {
name = ((OldEnum<?>) input).name();
} else {
name = input.toString();
}
// Turn something like "REDSTONE_TORCH" into "redstone torch"
String[] lowercaseWords = input.name().toLowerCase(Locale.ROOT).split("_");
String[] lowercaseWords = name.toLowerCase(Locale.ROOT).split("_");
// Capitalize first letter for each word
for (int i = 0; i < lowercaseWords.length; i++) {
String word = lowercaseWords[i];
// Capitalize first letter for each word
lowercaseWords[i] = word.substring(0, 1).toUpperCase() + word.substring(1);
}
// return as nice string
return String.join(" ", lowercaseWords);
}