553 lines
22 KiB
Java
553 lines
22 KiB
Java
package de.nexuslobby;
|
||
|
||
import de.nexuslobby.api.ModuleManager;
|
||
import de.nexuslobby.commands.*;
|
||
import de.nexuslobby.modules.ProtectionModule;
|
||
import de.nexuslobby.modules.ScoreboardModule;
|
||
import de.nexuslobby.modules.ItemsModule;
|
||
import de.nexuslobby.modules.security.SecurityModule;
|
||
import de.nexuslobby.modules.tablist.TablistModule;
|
||
import de.nexuslobby.modules.bossbar.BossBarModule;
|
||
import de.nexuslobby.modules.actionbar.ActionBarModule;
|
||
import de.nexuslobby.modules.settings.LobbySettingsModule;
|
||
import de.nexuslobby.modules.portal.PortalManager;
|
||
import de.nexuslobby.modules.portal.PortalCommand;
|
||
import de.nexuslobby.modules.servers.ServerSwitcherListener;
|
||
import de.nexuslobby.modules.servers.ServerChecker;
|
||
import de.nexuslobby.modules.armorstandtools.*;
|
||
import de.nexuslobby.modules.gadgets.GadgetModule;
|
||
import de.nexuslobby.modules.hologram.HologramModule;
|
||
import de.nexuslobby.modules.mapart.MapArtModule;
|
||
import de.nexuslobby.modules.intro.IntroModule;
|
||
import de.nexuslobby.modules.border.BorderModule;
|
||
import de.nexuslobby.modules.parkour.ParkourManager;
|
||
import de.nexuslobby.modules.parkour.ParkourListener;
|
||
import de.nexuslobby.modules.player.PlayerInspectModule;
|
||
import de.nexuslobby.modules.ball.SoccerModule;
|
||
import de.nexuslobby.utils.*;
|
||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||
import net.md_5.bungee.api.chat.ClickEvent;
|
||
import net.md_5.bungee.api.chat.ComponentBuilder;
|
||
import net.md_5.bungee.api.chat.HoverEvent;
|
||
import net.md_5.bungee.api.chat.TextComponent;
|
||
import org.bukkit.Bukkit;
|
||
import org.bukkit.GameMode;
|
||
import org.bukkit.Location;
|
||
import org.bukkit.World;
|
||
import org.bukkit.configuration.file.FileConfiguration;
|
||
import org.bukkit.configuration.file.YamlConfiguration;
|
||
import org.bukkit.entity.ArmorStand;
|
||
import org.bukkit.entity.Entity;
|
||
import org.bukkit.entity.Player;
|
||
import org.bukkit.event.EventHandler;
|
||
import org.bukkit.event.EventPriority;
|
||
import org.bukkit.event.Listener;
|
||
import org.bukkit.event.player.PlayerInteractAtEntityEvent;
|
||
import org.bukkit.event.player.PlayerJoinEvent;
|
||
import org.bukkit.plugin.java.JavaPlugin;
|
||
import org.bukkit.scheduler.BukkitRunnable;
|
||
import org.jetbrains.annotations.NotNull;
|
||
|
||
import java.io.File;
|
||
import java.util.HashSet;
|
||
import java.util.Set;
|
||
import java.util.UUID;
|
||
|
||
public class NexusLobby extends JavaPlugin implements Listener {
|
||
|
||
private static NexusLobby instance;
|
||
private ModuleManager moduleManager;
|
||
private PortalManager portalManager;
|
||
private TablistModule tablistModule;
|
||
private LobbySettingsModule lobbySettingsModule;
|
||
private ItemsModule itemsModule;
|
||
private GadgetModule gadgetModule;
|
||
private HologramModule hologramModule;
|
||
private DynamicArmorStandModule dynamicArmorStandModule;
|
||
private MapArtModule mapArtModule;
|
||
private IntroModule introModule;
|
||
private BorderModule borderModule;
|
||
private ParkourManager parkourManager;
|
||
private SoccerModule soccerModule;
|
||
private ArmorStandLookAtModule armorStandLookAtModule;
|
||
|
||
private ConversationManager conversationManager;
|
||
|
||
private File visualsFile;
|
||
private FileConfiguration visualsConfig;
|
||
|
||
private boolean updateAvailable = false;
|
||
private String latestVersion = "";
|
||
|
||
private final Set<UUID> silentPlayers = new HashSet<>();
|
||
|
||
public static NexusLobby getInstance() {
|
||
return instance;
|
||
}
|
||
|
||
public Set<UUID> getSilentPlayers() {
|
||
return silentPlayers;
|
||
}
|
||
|
||
public ConversationManager getConversationManager() {
|
||
return conversationManager;
|
||
}
|
||
|
||
public ParkourManager getParkourManager() {
|
||
return parkourManager;
|
||
}
|
||
|
||
public SoccerModule getSoccerModule() {
|
||
return soccerModule;
|
||
}
|
||
|
||
@Override
|
||
public void onEnable() {
|
||
getLogger().info("");
|
||
getLogger().info("[NexusLobby] _ __ __ __ __ ");
|
||
getLogger().info("[NexusLobby] / | / /__ _ ____ _______/ / ____ / /_ / /_ __ __");
|
||
getLogger().info("[NexusLobby] / |/ / _ \\| |/_/ / / / ___/ / / __ \\ / __ \\/ __ \\/ / / /");
|
||
getLogger().info("[NexusLobby] / /| / __/> </ /_/ (__ ) /___/ /_/ / /_/ / /_/ / /_/ / ");
|
||
getLogger().info("[NexusLobby] /_/ |_/\\___/_/|_|\\__,_/____/_____/\\____/_.___/_.___/\\__, / ");
|
||
getLogger().info("[NexusLobby] /____/ ");
|
||
getLogger().info("[NexusLobby] ");
|
||
getLogger().info("[NexusLobby] NexusLobby Plugin aktiviert! Version: " + getDescription().getVersion());
|
||
|
||
instance = this;
|
||
initCustomConfigs();
|
||
validateConfig();
|
||
|
||
// Lade die Sprachdatei
|
||
LangManager.load(this);
|
||
|
||
getServer().getMessenger().registerOutgoingPluginChannel(this, "BungeeCord");
|
||
moduleManager = new ModuleManager(this);
|
||
|
||
// --- Parkour & Conversation Initialisierung ---
|
||
this.parkourManager = new ParkourManager(this);
|
||
this.conversationManager = new ConversationManager(this);
|
||
|
||
ArmorStandGUI.init();
|
||
|
||
registerModules();
|
||
moduleManager.enableAll();
|
||
|
||
registerListeners();
|
||
|
||
ServerChecker.startGlobalChecker();
|
||
|
||
armorStandLookAtModule = new ArmorStandLookAtModule();
|
||
|
||
startAutoConversationTimer();
|
||
|
||
if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) {
|
||
new NexusLobbyExpansion().register();
|
||
getLogger().info("NexusLobby PAPI Expansion registriert.");
|
||
}
|
||
|
||
registerCommands();
|
||
checkUpdates();
|
||
}
|
||
|
||
private void startAutoConversationTimer() {
|
||
new BukkitRunnable() {
|
||
@Override
|
||
public void run() {
|
||
if (conversationManager != null) {
|
||
conversationManager.startAllAutomatedConversations();
|
||
}
|
||
}
|
||
}.runTaskTimer(this, 100L, 300L);
|
||
}
|
||
|
||
public void reloadPlugin() {
|
||
getLogger().info("Plugin Reload wird gestartet...");
|
||
|
||
Bukkit.getScheduler().cancelTasks(this);
|
||
|
||
if (moduleManager != null) {
|
||
moduleManager.disableAll();
|
||
}
|
||
|
||
reloadConfig();
|
||
visualsConfig = null;
|
||
reloadVisualsConfig();
|
||
Config.load();
|
||
|
||
if (conversationManager != null) {
|
||
conversationManager.setupFile();
|
||
}
|
||
|
||
if (borderModule != null) {
|
||
borderModule.reloadConfig();
|
||
}
|
||
|
||
if (portalManager != null) {
|
||
portalManager.loadPortals();
|
||
}
|
||
|
||
ArmorStandGUI.init();
|
||
|
||
if (moduleManager != null) {
|
||
moduleManager.enableAll();
|
||
}
|
||
|
||
ServerChecker.startGlobalChecker();
|
||
// FIX: ArmorStandLookAtModule als Feld tracken. Bukkit.getScheduler().cancelTasks()
|
||
// am Anfang von reloadPlugin() cancelt den alten Task bereits – hier nur
|
||
// neu starten und Referenz aktualisieren, damit kein doppelter Task läuft.
|
||
armorStandLookAtModule = new ArmorStandLookAtModule();
|
||
startAutoConversationTimer();
|
||
|
||
getLogger().info("Plugin Reload abgeschlossen. Änderungen wurden übernommen.");
|
||
}
|
||
|
||
private void checkUpdates() {
|
||
new UpdateChecker(this).getVersion(version -> {
|
||
String currentVersion = this.getDescription().getVersion();
|
||
if (isRemoteVersionNewer(currentVersion, version)) {
|
||
this.updateAvailable = true;
|
||
this.latestVersion = version;
|
||
getLogger().warning("====================================================");
|
||
getLogger().warning("Update gefunden! v" + currentVersion + " -> v" + version);
|
||
getLogger().warning("====================================================");
|
||
} else {
|
||
this.updateAvailable = false;
|
||
this.latestVersion = "";
|
||
getLogger().info("NexusLobby ist aktuell/neu genug (lokal v" + currentVersion + ", remote v" + version + ").");
|
||
}
|
||
});
|
||
}
|
||
|
||
private boolean isRemoteVersionNewer(String localVersion, String remoteVersion) {
|
||
int[] local = extractVersionNumbers(localVersion);
|
||
int[] remote = extractVersionNumbers(remoteVersion);
|
||
|
||
int max = Math.max(local.length, remote.length);
|
||
for (int i = 0; i < max; i++) {
|
||
int l = i < local.length ? local[i] : 0;
|
||
int r = i < remote.length ? remote[i] : 0;
|
||
if (r > l) return true;
|
||
if (r < l) return false;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
private int[] extractVersionNumbers(String version) {
|
||
if (version == null || version.isBlank()) return new int[0];
|
||
|
||
java.util.regex.Matcher matcher = java.util.regex.Pattern.compile("\\\\d+").matcher(version);
|
||
java.util.List<Integer> parts = new java.util.ArrayList<>();
|
||
while (matcher.find()) {
|
||
try {
|
||
parts.add(Integer.parseInt(matcher.group()));
|
||
} catch (NumberFormatException ignored) {
|
||
parts.add(0);
|
||
}
|
||
}
|
||
|
||
int[] result = new int[parts.size()];
|
||
for (int i = 0; i < parts.size(); i++) {
|
||
result[i] = parts.get(i);
|
||
}
|
||
return result;
|
||
}
|
||
|
||
private void registerModules() {
|
||
moduleManager.registerModule(new ProtectionModule());
|
||
moduleManager.registerModule(new ScoreboardModule());
|
||
|
||
this.itemsModule = new ItemsModule();
|
||
moduleManager.registerModule(this.itemsModule);
|
||
|
||
this.gadgetModule = new GadgetModule();
|
||
moduleManager.registerModule(this.gadgetModule);
|
||
|
||
this.hologramModule = new HologramModule();
|
||
moduleManager.registerModule(this.hologramModule);
|
||
|
||
this.dynamicArmorStandModule = new DynamicArmorStandModule();
|
||
moduleManager.registerModule(this.dynamicArmorStandModule);
|
||
|
||
moduleManager.registerModule(new ArmorStandStatusModule());
|
||
|
||
this.mapArtModule = new MapArtModule();
|
||
moduleManager.registerModule(this.mapArtModule);
|
||
|
||
this.introModule = new IntroModule();
|
||
moduleManager.registerModule(this.introModule);
|
||
|
||
this.borderModule = new BorderModule();
|
||
moduleManager.registerModule(this.borderModule);
|
||
|
||
moduleManager.registerModule(new SecurityModule());
|
||
moduleManager.registerModule(new BossBarModule());
|
||
moduleManager.registerModule(new ActionBarModule());
|
||
|
||
this.lobbySettingsModule = new LobbySettingsModule();
|
||
moduleManager.registerModule(lobbySettingsModule);
|
||
|
||
this.tablistModule = new TablistModule();
|
||
moduleManager.registerModule(tablistModule);
|
||
|
||
// Player Inspect Modul registrieren
|
||
moduleManager.registerModule(new PlayerInspectModule());
|
||
|
||
// Soccer Modul registrieren
|
||
this.soccerModule = new SoccerModule();
|
||
moduleManager.registerModule(this.soccerModule);
|
||
|
||
this.portalManager = new PortalManager(this);
|
||
moduleManager.registerModule(portalManager);
|
||
}
|
||
|
||
private void registerListeners() {
|
||
getServer().getPluginManager().registerEvents(this, this);
|
||
getServer().getPluginManager().registerEvents(new ServerSwitcherListener(), this);
|
||
getServer().getPluginManager().registerEvents(new VoidProtection(), this);
|
||
getServer().getPluginManager().registerEvents(new DoubleJump(), this);
|
||
getServer().getPluginManager().registerEvents(new PlayerHider(), this);
|
||
getServer().getPluginManager().registerEvents(new MaintenanceListener(), this);
|
||
getServer().getPluginManager().registerEvents(new ASTListener(), this);
|
||
getServer().getPluginManager().registerEvents(new ParkourListener(this.parkourManager), this);
|
||
|
||
getServer().getPluginManager().registerEvents(new NPCClickListener(), this);
|
||
}
|
||
|
||
private void validateConfig() {
|
||
ConfigValidator validator = new ConfigValidator(this, getConfig());
|
||
validator.validate();
|
||
}
|
||
|
||
public class NPCClickListener implements Listener {
|
||
@EventHandler
|
||
public void onNPCClick(PlayerInteractAtEntityEvent event) {
|
||
Entity entity = event.getRightClicked();
|
||
Player player = event.getPlayer();
|
||
|
||
if (entity instanceof ArmorStand as) {
|
||
if (as.getScoreboardTags().contains("parkour_trainer")) {
|
||
player.performCommand("warp parkour");
|
||
player.sendMessage("§6§lTrainer §8» §aViel Erfolg beim Parkour! Gib dein Bestes!");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
@EventHandler(priority = EventPriority.LOWEST)
|
||
public void onJoin(PlayerJoinEvent event) {
|
||
Player player = event.getPlayer();
|
||
if (silentPlayers.contains(player.getUniqueId())) {
|
||
event.setJoinMessage(null);
|
||
}
|
||
|
||
teleportToSpawn(player);
|
||
|
||
player.getInventory().clear();
|
||
player.getInventory().setArmorContents(null);
|
||
|
||
BuildCommand.removePlayerFromBuildMode(player);
|
||
|
||
String defaultGmName = getConfig().getString("lobby.default-gamemode", "Adventure");
|
||
try {
|
||
player.setGameMode(GameMode.valueOf(defaultGmName.toUpperCase()));
|
||
} catch (IllegalArgumentException e) {
|
||
player.setGameMode(GameMode.ADVENTURE);
|
||
}
|
||
|
||
if (player.hasPermission("nexuslobby.admin") && updateAvailable) {
|
||
player.sendMessage("");
|
||
player.sendMessage(de.nexuslobby.utils.LangManager.get("update_available"));
|
||
player.sendMessage(de.nexuslobby.utils.LangManager.get("update_version").replace("{old}", getDescription().getVersion()).replace("{new}", latestVersion));
|
||
TextComponent link = new TextComponent(de.nexuslobby.utils.LangManager.get("update_download_link"));
|
||
link.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://www.spigotmc.org/resources/132388/"));
|
||
link.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT,
|
||
new ComponentBuilder(de.nexuslobby.utils.LangManager.get("update_download_hover")).create()));
|
||
player.spigot().sendMessage(link);
|
||
player.sendMessage("");
|
||
}
|
||
}
|
||
|
||
private void teleportToSpawn(Player player) {
|
||
FileConfiguration config = getConfig();
|
||
if (config.contains("spawn.world")) {
|
||
String worldName = config.getString("spawn.world");
|
||
World world = Bukkit.getWorld(worldName);
|
||
if (world != null) {
|
||
Location spawnLoc = new Location(
|
||
world,
|
||
config.getDouble("spawn.x"),
|
||
config.getDouble("spawn.y"),
|
||
config.getDouble("spawn.z"),
|
||
(float) config.getDouble("spawn.yaw"),
|
||
(float) config.getDouble("spawn.pitch")
|
||
);
|
||
player.teleport(spawnLoc);
|
||
}
|
||
}
|
||
}
|
||
|
||
private void initCustomConfigs() {
|
||
if (!getDataFolder().exists()) getDataFolder().mkdirs();
|
||
|
||
File configFile = new File(getDataFolder(), "config.yml");
|
||
if (!configFile.exists()) saveResource("config.yml", false);
|
||
|
||
reloadConfig();
|
||
|
||
File settingsFile = new File(getDataFolder(), "settings.yml");
|
||
if (!settingsFile.exists()) saveResource("settings.yml", false);
|
||
|
||
visualsFile = new File(getDataFolder(), "visuals.yml");
|
||
if (!visualsFile.exists()) saveResource("visuals.yml", false);
|
||
|
||
// lang.yml automatisch erstellen, falls nicht vorhanden
|
||
File langFile = new File(getDataFolder(), "lang.yml");
|
||
if (!langFile.exists()) saveResource("lang.yml", false);
|
||
|
||
reloadVisualsConfig();
|
||
Config.load();
|
||
}
|
||
|
||
public void reloadVisualsConfig() {
|
||
if (visualsFile == null) visualsFile = new File(getDataFolder(), "visuals.yml");
|
||
visualsConfig = YamlConfiguration.loadConfiguration(visualsFile);
|
||
}
|
||
|
||
public FileConfiguration getVisualsConfig() {
|
||
if (visualsConfig == null) reloadVisualsConfig();
|
||
return visualsConfig;
|
||
}
|
||
|
||
@Override
|
||
public void onDisable() {
|
||
// Cancle alle Scheduler-Tasks
|
||
Bukkit.getScheduler().cancelTasks(this);
|
||
|
||
// Stoppe spezifische Tasks
|
||
ServerChecker.stopGlobalChecker();
|
||
|
||
// Unregister alle Event-Listener
|
||
org.bukkit.event.HandlerList.unregisterAll((org.bukkit.plugin.Plugin) this);
|
||
|
||
// Schließe BungeeCord Channel
|
||
getServer().getMessenger().unregisterOutgoingPluginChannel(this, "BungeeCord");
|
||
|
||
// Disable alle Module (inkl. eigenes Cleanup)
|
||
if (moduleManager != null) {
|
||
moduleManager.disableAll();
|
||
}
|
||
|
||
getLogger().info("NexusLobby deaktiviert.");
|
||
}
|
||
|
||
private void registerCommands() {
|
||
LobbyTabCompleter tabCompleter = new LobbyTabCompleter(portalManager, hologramModule);
|
||
NexusLobbyCommand nexusCommand = new NexusLobbyCommand();
|
||
|
||
if (getCommand("portal") != null) {
|
||
getCommand("portal").setExecutor(new PortalCommand(portalManager));
|
||
getCommand("portal").setTabCompleter(tabCompleter);
|
||
}
|
||
|
||
if (getCommand("holo") != null) {
|
||
getCommand("holo").setExecutor(new HoloCommand(hologramModule));
|
||
getCommand("holo").setTabCompleter(tabCompleter);
|
||
}
|
||
|
||
if (getCommand("maintenance") != null) {
|
||
getCommand("maintenance").setExecutor(new MaintenanceCommand());
|
||
getCommand("maintenance").setTabCompleter(tabCompleter);
|
||
}
|
||
|
||
if (getCommand("giveportalwand") != null) getCommand("giveportalwand").setExecutor(new GivePortalToolCommand(this));
|
||
if (getCommand("settings") != null) getCommand("settings").setExecutor(new LobbySettingsCommand(lobbySettingsModule));
|
||
if (getCommand("build") != null) getCommand("build").setExecutor(new BuildCommand());
|
||
|
||
if (getCommand("nexustools") != null) {
|
||
getCommand("nexustools").setExecutor(new ArmorStandCommand());
|
||
getCommand("nexustools").setTabCompleter(tabCompleter);
|
||
}
|
||
|
||
if (getCommand("nexuscmd") != null) {
|
||
getCommand("nexuscmd").setExecutor(new ArmorStandCmdExecutor());
|
||
getCommand("nexuscmd").setTabCompleter(tabCompleter);
|
||
}
|
||
|
||
if (getCommand("nexuslobby") != null) {
|
||
getCommand("nexuslobby").setExecutor(nexusCommand);
|
||
getCommand("nexuslobby").setTabCompleter(tabCompleter);
|
||
}
|
||
|
||
if (getCommand("spawn") != null) {
|
||
getCommand("spawn").setExecutor(nexusCommand);
|
||
getCommand("spawn").setTabCompleter(tabCompleter);
|
||
}
|
||
|
||
if (getCommand("setstart") != null) {
|
||
getCommand("setstart").setExecutor(nexusCommand);
|
||
getCommand("setstart").setTabCompleter(tabCompleter);
|
||
}
|
||
|
||
if (getCommand("setcheckpoint") != null) {
|
||
getCommand("setcheckpoint").setExecutor(nexusCommand);
|
||
getCommand("setcheckpoint").setTabCompleter(tabCompleter);
|
||
}
|
||
|
||
if (getCommand("setfinish") != null) {
|
||
getCommand("setfinish").setExecutor(nexusCommand);
|
||
getCommand("setfinish").setTabCompleter(tabCompleter);
|
||
}
|
||
|
||
if (getCommand("mapart") != null) getCommand("mapart").setTabCompleter(tabCompleter);
|
||
if (getCommand("intro") != null) getCommand("intro").setTabCompleter(tabCompleter);
|
||
|
||
if (getCommand("border") != null) {
|
||
getCommand("border").setExecutor(new BorderCommand());
|
||
getCommand("border").setTabCompleter(tabCompleter);
|
||
}
|
||
|
||
if (getCommand("serverswitcher") != null) {
|
||
ServerSwitcherListener serverSwitcher = new ServerSwitcherListener();
|
||
getCommand("serverswitcher").setExecutor(serverSwitcher);
|
||
}
|
||
}
|
||
|
||
public class NexusLobbyExpansion extends PlaceholderExpansion {
|
||
@Override public @NotNull String getIdentifier() { return "nexuslobby"; }
|
||
@Override public @NotNull String getAuthor() { return "M_Viper"; }
|
||
@Override public @NotNull String getVersion() { return NexusLobby.this.getDescription().getVersion(); }
|
||
@Override public boolean persist() { return true; }
|
||
|
||
@Override
|
||
public String onPlaceholderRequest(Player player, @NotNull String params) {
|
||
if (player == null) return "";
|
||
if (params.equalsIgnoreCase("maintenance_status")) return MaintenanceListener.isMaintenance() ? "§cAktiv" : "§aDeaktiviert";
|
||
if (params.equalsIgnoreCase("version")) return NexusLobby.this.getDescription().getVersion();
|
||
if (params.equalsIgnoreCase("build_mode")) return BuildCommand.isInBuildMode(player) ? "§aAktiv" : "§cInaktiv";
|
||
if (params.equalsIgnoreCase("silent_join")) return silentPlayers.contains(player.getUniqueId()) ? "§aEin" : "§cAus";
|
||
if (params.equalsIgnoreCase("parkour_top")) {
|
||
return parkourManager != null ? parkourManager.getTopTen() : "N/A";
|
||
}
|
||
if (params.equalsIgnoreCase("parkour_top_1")) {
|
||
return parkourManager != null ? parkourManager.getTopTen(1) : "N/A";
|
||
}
|
||
if (params.equalsIgnoreCase("parkour_top_2")) {
|
||
return parkourManager != null ? parkourManager.getTopTen(2) : "N/A";
|
||
}
|
||
return null;
|
||
}
|
||
}
|
||
|
||
public ModuleManager getModuleManager() { return moduleManager; }
|
||
public PortalManager getPortalManager() { return portalManager; }
|
||
public TablistModule getTablistModule() { return tablistModule; }
|
||
public LobbySettingsModule getLobbySettingsModule() { return lobbySettingsModule; }
|
||
public ItemsModule getItemsModule() { return itemsModule; }
|
||
public GadgetModule getGadgetModule() { return gadgetModule; }
|
||
public HologramModule getHologramModule() { return hologramModule; }
|
||
public DynamicArmorStandModule getDynamicArmorStandModule() { return dynamicArmorStandModule; }
|
||
public MapArtModule getMapArtModule() { return mapArtModule; }
|
||
public IntroModule getIntroModule() { return introModule; }
|
||
public BorderModule getBorderModule() { return borderModule; }
|
||
} |