expanded debug commands, added setting toggle for join and leave messages

This commit is contained in:
Elias Müller 2024-08-24 02:46:50 +02:00
parent 70058c552d
commit 35b40262a4
29 changed files with 182 additions and 58 deletions

View File

@ -21,9 +21,10 @@ import java.util.Optional;
*/ */
public abstract class Appliance { public abstract class Appliance {
private String localConfigPath; private String localConfigPath;
private List<Listener> listeners;
private List<ApplianceCommand<?>> commands;
public Appliance() { public Appliance() {}
}
/** /**
* Use this constructor to specify a config sub-path for use with the localConfig() method. * Use this constructor to specify a config sub-path for use with the localConfig() method.
@ -71,12 +72,15 @@ public abstract class Appliance {
public void onDisable() {} public void onDisable() {}
public void initialize(@NotNull JavaPlugin plugin) { public void initialize(@NotNull JavaPlugin plugin) {
eventHandlers().forEach(listener -> Bukkit.getPluginManager().registerEvents(listener, plugin)); this.listeners = eventHandlers();
commands().forEach(command -> setCommandExecutor(plugin, command.commandName, command)); this.commands = commands();
listeners.forEach(listener -> Bukkit.getPluginManager().registerEvents(listener, plugin));
commands.forEach(command -> setCommandExecutor(plugin, command.commandName, command));
} }
public void destruct(@NotNull JavaPlugin plugin) { public void destruct(@NotNull JavaPlugin plugin) {
eventHandlers().forEach(HandlerList::unregisterAll); listeners.forEach(HandlerList::unregisterAll);
} }
public <T extends Appliance> T queryAppliance(Class<T> clazz) { public <T extends Appliance> T queryAppliance(Class<T> clazz) {
@ -93,4 +97,12 @@ public abstract class Appliance {
throw new RuntimeException("All commands must be registered in plugin.yml. Missing command: " + name); throw new RuntimeException("All commands must be registered in plugin.yml. Missing command: " + name);
} }
} }
public List<Listener> getListeners() {
return listeners;
}
public List<ApplianceCommand<?>> getCommands() {
return commands;
}
} }

View File

@ -16,7 +16,8 @@ public class AdminMarker extends Appliance {
} }
@Override @Override
protected @NotNull List<Listener> eventHandlers() { @NotNull
protected List<Listener> eventHandlers() {
return List.of(new AdminMarkerListener()); return List.of(new AdminMarkerListener());
} }
} }

View File

@ -4,17 +4,8 @@ import eu.mhsl.craftattack.spawn.appliance.ApplianceListener;
import net.kyori.adventure.text.format.TextColor; import net.kyori.adventure.text.format.TextColor;
import org.bukkit.Color; import org.bukkit.Color;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerJoinEvent;
public class AdminMarkerListener extends ApplianceListener<AdminMarker> { public class AdminMarkerListener extends ApplianceListener<AdminMarker> {
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
Player p = event.getPlayer();
}
private TextColor getPlayerColor(Player player) { private TextColor getPlayerColor(Player player) {
if (player.hasPermission("chatcolor")) return TextColor.color(Color.AQUA.asRGB()); // TODO read permission from config if (player.hasPermission("chatcolor")) return TextColor.color(Color.AQUA.asRGB()); // TODO read permission from config
return TextColor.color(Color.WHITE.asRGB()); return TextColor.color(Color.WHITE.asRGB());

View File

@ -8,7 +8,8 @@ import java.util.List;
public class ChatMessages extends Appliance { public class ChatMessages extends Appliance {
@Override @Override
protected @NotNull List<Listener> eventHandlers() { @NotNull
protected List<Listener> eventHandlers() {
return List.of(new ChatMessagesListener()); return List.of(new ChatMessagesListener());
} }
} }

View File

@ -1,6 +1,8 @@
package eu.mhsl.craftattack.spawn.appliances.chatMessages; package eu.mhsl.craftattack.spawn.appliances.chatMessages;
import eu.mhsl.craftattack.spawn.appliance.ApplianceListener; import eu.mhsl.craftattack.spawn.appliance.ApplianceListener;
import eu.mhsl.craftattack.spawn.appliances.settings.Settings;
import eu.mhsl.craftattack.spawn.util.IteratorUtil;
import io.papermc.paper.event.player.AsyncChatEvent; import io.papermc.paper.event.player.AsyncChatEvent;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.event.ClickEvent; import net.kyori.adventure.text.event.ClickEvent;
@ -30,20 +32,28 @@ public class ChatMessagesListener extends ApplianceListener<ChatMessages> {
@EventHandler @EventHandler
public void onPlayerJoin(PlayerJoinEvent event) { public void onPlayerJoin(PlayerJoinEvent event) {
event.joinMessage( event.joinMessage(null);
IteratorUtil.onlinePlayers(player -> {
if(!Settings.instance().getSetting(player, Settings.Key.ShowJoinAndLeaveMessages, Boolean.class)) return;
player.sendMessage(
Component Component
.text(">>> ").color(NamedTextColor.GREEN) .text(">>> ").color(NamedTextColor.GREEN)
.append(getReportablePlayerName(event.getPlayer())) .append(getReportablePlayerName(event.getPlayer()))
); );
});
} }
@EventHandler @EventHandler
public void onPlayerLeave(PlayerQuitEvent event) { public void onPlayerLeave(PlayerQuitEvent event) {
event.quitMessage( event.quitMessage(null);
IteratorUtil.onlinePlayers(player -> {
if(!Settings.instance().getSetting(player, Settings.Key.ShowJoinAndLeaveMessages, Boolean.class)) return;
player.sendMessage(
Component Component
.text("<<< ").color(NamedTextColor.RED) .text("<<< ").color(NamedTextColor.RED)
.append(getReportablePlayerName(event.getPlayer())) .append(getReportablePlayerName(event.getPlayer()))
); );
});
} }
@EventHandler @EventHandler

View File

@ -16,7 +16,8 @@ public class CustomAdvancements extends Appliance {
} }
@Override @Override
protected @NotNull List<Listener> eventHandlers() { @NotNull
protected List<Listener> eventHandlers() {
return List.of(new CustomAdvancementsDamageEntityListener()); return List.of(new CustomAdvancementsDamageEntityListener());
} }
} }

View File

@ -9,7 +9,8 @@ import org.jetbrains.annotations.NotNull;
import java.util.List; import java.util.List;
public class Debug extends Appliance { public class Debug extends Appliance {
@Override @Override
protected @NotNull List<ApplianceCommand<?>> commands() { @NotNull
protected List<ApplianceCommand<?>> commands() {
return List.of( return List.of(
new UserInfoCommand(), new UserInfoCommand(),
new AppliancesCommand() new AppliancesCommand()

View File

@ -3,14 +3,18 @@ package eu.mhsl.craftattack.spawn.appliances.debug.command;
import eu.mhsl.craftattack.spawn.Main; import eu.mhsl.craftattack.spawn.Main;
import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand; import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand;
import eu.mhsl.craftattack.spawn.appliances.debug.Debug; import eu.mhsl.craftattack.spawn.appliances.debug.Debug;
import eu.mhsl.craftattack.spawn.util.text.ComponentUtil;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.ComponentBuilder; import net.kyori.adventure.text.ComponentBuilder;
import net.kyori.adventure.text.TextComponent; import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.event.HoverEvent;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.event.Listener;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.stream.Collectors; import java.util.List;
public class AppliancesCommand extends ApplianceCommand<Debug> { public class AppliancesCommand extends ApplianceCommand<Debug> {
public AppliancesCommand() { public AppliancesCommand() {
@ -21,9 +25,40 @@ public class AppliancesCommand extends ApplianceCommand<Debug> {
protected void execute(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { protected void execute(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
ComponentBuilder<TextComponent, TextComponent.Builder> componentBuilder = Component.text() ComponentBuilder<TextComponent, TextComponent.Builder> componentBuilder = Component.text()
.append(Component.text(Main.instance().getAppliances().size())) .append(Component.text(Main.instance().getAppliances().size()))
.append(Component.text(" appliances loaded:")) .append(Component.text(" appliances running:"))
.appendNewline() .appendNewline();
.append(Component.text(Main.instance().getAppliances().stream().map(appliance -> appliance.getClass().getSimpleName()).collect(Collectors.joining(", "))));
Main.instance().getAppliances().forEach(appliance -> {
List<ApplianceCommand<?>> commands = appliance.getCommands();
List<Listener> listener = appliance.getListeners();
componentBuilder
.append(Component.text(appliance.getClass().getSimpleName(), NamedTextColor.GREEN)
.hoverEvent(HoverEvent.showText(Component.text(appliance.getClass().getName()))))
.append(Component.text(": ", NamedTextColor.DARK_GRAY))
.append(Component.text(commands.size() + " Commands", NamedTextColor.GRAY)
.hoverEvent(HoverEvent.showText(commands.stream()
.map(applianceCommand -> Component.text()
.append(Component.text(applianceCommand.commandName, NamedTextColor.DARK_GREEN))
.append(Component.text(": "))
.append(Component.text(applianceCommand.getClass().getName()))
.build())
.reduce(ComponentUtil::appendWithNewline)
.orElse(Component.text("No commands available")))))
.append(Component.text(", ", NamedTextColor.GRAY))
.append(Component.text(listener.size() + " Listener", NamedTextColor.GRAY)
.hoverEvent(HoverEvent.showText(listener.stream()
.map(eventHandler -> Component.text()
.append(Component.text(eventHandler.getClass().getSimpleName(), NamedTextColor.DARK_GREEN))
.append(Component.text(": "))
.append(Component.text(eventHandler.getClass().getName()))
.build())
.reduce(ComponentUtil::appendWithNewline)
.orElse(Component.text("No listeners available")))))
.appendNewline();
});
componentBuilder.append(Component.text(Main.instance().getClass().getName(), NamedTextColor.GRAY));
sender.sendMessage(componentBuilder.build()); sender.sendMessage(componentBuilder.build());
} }

View File

@ -47,7 +47,8 @@ public class DisplayName extends Appliance {
@Override @Override
protected @NotNull List<Listener> eventHandlers() { @NotNull
protected List<Listener> eventHandlers() {
return List.of(new AdminMarkerListener()); return List.of(new AdminMarkerListener());
} }
} }

View File

@ -23,7 +23,6 @@ import org.bukkit.entity.Villager;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.eclipse.jetty.util.security.CertificateUtils;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.io.IOException; import java.io.IOException;
@ -216,7 +215,8 @@ public class Event extends Appliance {
} }
@Override @Override
protected @NotNull List<ApplianceCommand<?>> commands() { @NotNull
protected List<ApplianceCommand<?>> commands() {
return List.of( return List.of(
new EventCommand(), new EventCommand(),
new MoveEventVillagerCommand(), new MoveEventVillagerCommand(),
@ -227,7 +227,8 @@ public class Event extends Appliance {
} }
@Override @Override
protected @NotNull List<Listener> eventHandlers() { @NotNull
protected List<Listener> eventHandlers() {
return List.of( return List.of(
new ApplyPendingRewardsListener(), new ApplyPendingRewardsListener(),
new PlayerInteractAtEntityEventListener(this.villager.getUniqueId(), playerInteractAtEntityEvent -> joinEvent(playerInteractAtEntityEvent.getPlayer())), new PlayerInteractAtEntityEventListener(this.villager.getUniqueId(), playerInteractAtEntityEvent -> joinEvent(playerInteractAtEntityEvent.getPlayer())),

View File

@ -18,7 +18,8 @@ public class Fleischerchest extends Appliance {
} }
@Override @Override
protected @NotNull List<Listener> eventHandlers() { @NotNull
protected List<Listener> eventHandlers() {
return List.of(new FleischerchestCraftItemListener()); return List.of(new FleischerchestCraftItemListener());
} }
} }

View File

@ -16,7 +16,8 @@ public class Help extends Appliance {
} }
@Override @Override
protected @NotNull List<ApplianceCommand<?>> commands() { @NotNull
protected List<ApplianceCommand<?>> commands() {
return List.of( return List.of(
new HelpCommand(), new HelpCommand(),
new SpawnCommand(), new SpawnCommand(),

View File

@ -26,7 +26,8 @@ public class Kick extends Appliance {
} }
@Override @Override
protected @NotNull List<ApplianceCommand<?>> commands() { @NotNull
protected List<ApplianceCommand<?>> commands() {
return List.of(new KickCommand()); return List.of(new KickCommand());
} }
} }

View File

@ -118,12 +118,14 @@ public class Outlawed extends Appliance {
} }
@Override @Override
protected @NotNull List<ApplianceCommand<?>> commands() { @NotNull
protected List<ApplianceCommand<?>> commands() {
return List.of(new OutlawedCommand()); return List.of(new OutlawedCommand());
} }
@Override @Override
protected @NotNull List<Listener> eventHandlers() { @NotNull
protected List<Listener> eventHandlers() {
return List.of(new OutlawedReminderListener()); return List.of(new OutlawedReminderListener());
} }
} }

View File

@ -40,12 +40,14 @@ public class PanicBan extends Appliance {
} }
@Override @Override
protected @NotNull List<ApplianceCommand<?>> commands() { @NotNull
protected List<ApplianceCommand<?>> commands() {
return List.of(new PanicBanCommand()); return List.of(new PanicBanCommand());
} }
@Override @Override
protected @NotNull List<Listener> eventHandlers() { @NotNull
protected List<Listener> eventHandlers() {
return List.of(new PanicBanJoinListener()); return List.of(new PanicBanJoinListener());
} }
} }

View File

@ -29,14 +29,16 @@ public class PlayerLimit extends Appliance {
} }
@Override @Override
protected @NotNull List<Listener> eventHandlers() { @NotNull
protected List<Listener> eventHandlers() {
return List.of( return List.of(
new PlayerLimiterListener() new PlayerLimiterListener()
); );
} }
@Override @Override
protected @NotNull List<ApplianceCommand<?>> commands() { @NotNull
protected List<ApplianceCommand<?>> commands() {
return List.of( return List.of(
new SetPlayerLimitCommand() new SetPlayerLimitCommand()
); );

View File

@ -174,7 +174,8 @@ public class ProjectStart extends Appliance {
} }
@Override @Override
protected @NotNull List<Listener> eventHandlers() { @NotNull
protected List<Listener> eventHandlers() {
return List.of( return List.of(
new PlayerInvincibleListener(), new PlayerInvincibleListener(),
new NoAdvancementsListener() new NoAdvancementsListener()
@ -182,7 +183,8 @@ public class ProjectStart extends Appliance {
} }
@Override @Override
protected @NotNull List<ApplianceCommand<?>> commands() { @NotNull
protected List<ApplianceCommand<?>> commands() {
return List.of( return List.of(
new ProjectStartCommand(), new ProjectStartCommand(),
new ProjectStartCancelCommand(), new ProjectStartCancelCommand(),

View File

@ -136,7 +136,8 @@ public class Report extends Appliance {
} }
@Override @Override
protected @NotNull List<ApplianceCommand<?>> commands() { @NotNull
protected List<ApplianceCommand<?>> commands() {
return List.of(new ReportCommand()); return List.of(new ReportCommand());
} }
} }

View File

@ -62,7 +62,8 @@ public class Restart extends Appliance {
} }
@Override @Override
protected @NotNull List<ApplianceCommand<?>> commands() { @NotNull
protected List<ApplianceCommand<?>> commands() {
return List.of(new ScheduleRestartCommand(), new CancelRestartCommand()); return List.of(new ScheduleRestartCommand(), new CancelRestartCommand());
} }
} }

View File

@ -1,8 +1,10 @@
package eu.mhsl.craftattack.spawn.appliances.settings; package eu.mhsl.craftattack.spawn.appliances.settings;
import eu.mhsl.craftattack.spawn.Main;
import eu.mhsl.craftattack.spawn.appliance.Appliance; import eu.mhsl.craftattack.spawn.appliance.Appliance;
import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand; import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand;
import eu.mhsl.craftattack.spawn.appliances.settings.datatypes.Setting; import eu.mhsl.craftattack.spawn.appliances.settings.datatypes.Setting;
import eu.mhsl.craftattack.spawn.appliances.settings.settings.ShowJoinAndLeaveMessagesSetting;
import eu.mhsl.craftattack.spawn.appliances.settings.settings.TechnicalTablistSetting; import eu.mhsl.craftattack.spawn.appliances.settings.settings.TechnicalTablistSetting;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -17,6 +19,11 @@ import java.util.WeakHashMap;
public class Settings extends Appliance { public class Settings extends Appliance {
public enum Key { public enum Key {
TechnicalTab, TechnicalTab,
ShowJoinAndLeaveMessages,
}
public static Settings instance() {
return Main.instance().getAppliance(Settings.class);
} }
public record OpenSettingsInventory(Inventory inventory, List<Setting<?>> settings) {} public record OpenSettingsInventory(Inventory inventory, List<Setting<?>> settings) {}
@ -27,7 +34,8 @@ public class Settings extends Appliance {
if(settingsCache.containsKey(player)) return settingsCache.get(player); if(settingsCache.containsKey(player)) return settingsCache.get(player);
List<Setting<?>> settings = List.of( List<Setting<?>> settings = List.of(
new TechnicalTablistSetting() new TechnicalTablistSetting(),
new ShowJoinAndLeaveMessagesSetting()
); );
settings.forEach(setting -> setting.initializeFromPlayer(player)); settings.forEach(setting -> setting.initializeFromPlayer(player));
@ -70,12 +78,14 @@ public class Settings extends Appliance {
} }
@Override @Override
protected @NotNull List<Listener> eventHandlers() { @NotNull
protected List<Listener> eventHandlers() {
return List.of(new SettingsInventoryListener()); return List.of(new SettingsInventoryListener());
} }
@Override @Override
protected @NotNull List<ApplianceCommand<?>> commands() { @NotNull
protected List<ApplianceCommand<?>> commands() {
return List.of(new SettingsCommand()); return List.of(new SettingsCommand());
} }
} }

View File

@ -8,6 +8,7 @@ import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType; import org.bukkit.persistence.PersistentDataType;
import java.util.List; import java.util.List;
import java.util.Objects;
public abstract class BoolSetting extends Setting<Boolean> { public abstract class BoolSetting extends Setting<Boolean> {
private boolean state; private boolean state;
@ -21,7 +22,9 @@ public abstract class BoolSetting extends Setting<Boolean> {
@Override @Override
public void fromStorage(PersistentDataContainer container) { public void fromStorage(PersistentDataContainer container) {
this.state = Boolean.TRUE.equals(container.get(getNamespacedKey(), PersistentDataType.BOOLEAN)); this.state = container.has(getNamespacedKey())
? Objects.requireNonNull(container.get(getNamespacedKey(), PersistentDataType.BOOLEAN))
: defaultValue();
} }
@Override @Override

View File

@ -42,6 +42,7 @@ public abstract class Setting<TDataType> {
protected abstract Material icon(); protected abstract Material icon();
public abstract ItemMeta buildMeta(ItemMeta meta); public abstract ItemMeta buildMeta(ItemMeta meta);
protected abstract void change(); protected abstract void change();
protected abstract TDataType defaultValue();
protected abstract void fromStorage(PersistentDataContainer container); protected abstract void fromStorage(PersistentDataContainer container);
protected abstract void toStorage(PersistentDataContainer container, TDataType value); protected abstract void toStorage(PersistentDataContainer container, TDataType value);
public abstract Class<?> dataType(); public abstract Class<?> dataType();

View File

@ -0,0 +1,31 @@
package eu.mhsl.craftattack.spawn.appliances.settings.settings;
import eu.mhsl.craftattack.spawn.appliances.settings.Settings;
import eu.mhsl.craftattack.spawn.appliances.settings.datatypes.BoolSetting;
import org.bukkit.Material;
public class ShowJoinAndLeaveMessagesSetting extends BoolSetting {
public ShowJoinAndLeaveMessagesSetting() {
super(Settings.Key.ShowJoinAndLeaveMessages);
}
@Override
protected String title() {
return "Join & Leave Nachrichten anzeigen";
}
@Override
protected String description() {
return "Zeige allgemeine Beitritts und Verlassensmeldungen im Chat";
}
@Override
protected Material icon() {
return Material.PLAYER_HEAD;
}
@Override
protected Boolean defaultValue() {
return true;
}
}

View File

@ -23,4 +23,9 @@ public class TechnicalTablistSetting extends BoolSetting {
protected Material icon() { protected Material icon() {
return Material.COMMAND_BLOCK_MINECART; return Material.COMMAND_BLOCK_MINECART;
} }
@Override
protected Boolean defaultValue() {
return false;
}
} }

View File

@ -75,7 +75,8 @@ public class Tablist extends Appliance {
} }
@Override @Override
protected @NotNull List<Listener> eventHandlers() { @NotNull
protected List<Listener> eventHandlers() {
return List.of(new TablistListener()); return List.of(new TablistListener());
} }
} }

View File

@ -12,7 +12,8 @@ public class TitleClear extends Appliance {
player.clearTitle(); player.clearTitle();
} }
@Override @Override
protected @NotNull List<Listener> eventHandlers() { @NotNull
protected List<Listener> eventHandlers() {
return List.of( return List.of(
new TitleClearListener() new TitleClearListener()
); );

View File

@ -11,7 +11,6 @@ import org.apache.http.client.utils.URIBuilder;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.eclipse.jetty.websocket.server.WebSocketHandler;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.io.IOException; import java.io.IOException;
@ -139,7 +138,8 @@ public class Whitelist extends Appliance {
} }
@Override @Override
protected @NotNull List<Listener> eventHandlers() { @NotNull
protected List<Listener> eventHandlers() {
return List.of( return List.of(
new PlayerJoinListener() new PlayerJoinListener()
); );

View File

@ -14,7 +14,6 @@ import org.bukkit.Location;
import org.bukkit.entity.*; import org.bukkit.entity.*;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.geysermc.cumulus.form.SimpleForm; import org.geysermc.cumulus.form.SimpleForm;
import org.geysermc.cumulus.form.util.FormBuilder;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.List; import java.util.List;
@ -60,12 +59,14 @@ public class WorldMuseum extends Appliance {
} }
@Override @Override
protected @NotNull List<ApplianceCommand<?>> commands() { @NotNull
protected List<ApplianceCommand<?>> commands() {
return List.of(new MoveWorldMuseumVillagerCommand()); return List.of(new MoveWorldMuseumVillagerCommand());
} }
@Override @Override
protected @NotNull List<Listener> eventHandlers() { @NotNull
protected List<Listener> eventHandlers() {
return List.of( return List.of(
new PlayerInteractAtEntityEventListener(this.villager.getUniqueId(), playerInteractAtEntityEvent -> handleVillagerInteraction(playerInteractAtEntityEvent.getPlayer())), new PlayerInteractAtEntityEventListener(this.villager.getUniqueId(), playerInteractAtEntityEvent -> handleVillagerInteraction(playerInteractAtEntityEvent.getPlayer())),
new DismissInventoryOpenFromHolder(this.villager.getUniqueId()) new DismissInventoryOpenFromHolder(this.villager.getUniqueId())

View File

@ -13,6 +13,10 @@ import java.awt.*;
import java.util.Arrays; import java.util.Arrays;
public class ComponentUtil { public class ComponentUtil {
public static TextComponent appendWithNewline(Component a, Component b) {
return Component.text().append(a.appendNewline().append(b)).build();
}
public static Component getFormattedTPS() { public static Component getFormattedTPS() {
double[] tpsValues = Bukkit.getTPS(); double[] tpsValues = Bukkit.getTPS();