GUI is working

This commit is contained in:
Mika 2025-05-18 18:52:56 +02:00
parent 3ab16e6303
commit be5f91df88
19 changed files with 418 additions and 135 deletions

View File

@ -8,6 +8,10 @@ version = '1.0-SNAPSHOT'
repositories {
mavenCentral()
maven {
name = "codemc-snapshots"
url = "https://repo.codemc.io/repository/maven-snapshots/"
}
maven {
name = "spigotmc-repo"
url = "https://hub.spigotmc.org/nexus/content/repositories/snapshots/"
@ -16,12 +20,17 @@ repositories {
name = "sonatype"
url = "https://oss.sonatype.org/content/groups/public/"
}
flatDir {
dirs("lib")
}
}
dependencies {
implementation(platform("org.hibernate.orm:hibernate-platform:6.6.7.Final"))
compileOnly("org.spigotmc:spigot-api:1.21.3-R0.1-SNAPSHOT")
implementation("net.wesjd:anvilgui:1.10.4-SNAPSHOT")
implementation(files("../SpiGUI/build/libs/SpiGUI-1.4.1.jar"))
compileOnly('org.projectlombok:lombok:1.18.36')
annotationProcessor 'org.projectlombok:lombok:1.18.36'
@ -30,9 +39,10 @@ dependencies {
testAnnotationProcessor 'org.projectlombok:lombok:1.18.36'
implementation("org.xerial:sqlite-jdbc:3.48.0.0")
implementation("org.hibernate.orm:hibernate-core:6.6.7.Final")
implementation("jakarta.transaction:jakarta.transaction-api")
implementation("org.hibernate.orm:hibernate-core:6.6.7.Final")
implementation("org.hibernate.orm:hibernate-community-dialects:6.6.7.Final")
implementation("org.apache.commons:commons-vfs2:2.10.0")
}
def targetJavaVersion = 21

View File

@ -4,6 +4,7 @@ import com.google.common.reflect.ClassPath;
import de.polyfish0.survivalGames.annotations.Command;
import de.polyfish0.survivalGames.annotations.EventClass;
import de.polyfish0.survivalGames.annotations.Permission;
import de.polyfish0.survivalGames.config.ConfigManager;
import de.polyfish0.survivalGames.database.HibernateUtil;
import de.polyfish0.survivalGames.database.player.PlayerEntity;
import de.polyfish0.survivalGames.database.player.PlayerRepository;
@ -21,6 +22,7 @@ import java.util.logging.Level;
import java.util.logging.Logger;
public final class SurvivalGames extends JavaPlugin {
public static final String prefix = "§c[SG]§r ";
public static final Logger logger = Logger.getLogger("Survival Games");
public static JavaPlugin plugin;
private final Set<String> usedCommands = new HashSet<>();
@ -28,23 +30,25 @@ public final class SurvivalGames extends JavaPlugin {
@Override
public void onEnable() {
plugin = this;
new ConfigManager(this);
File folder = new File(String.format("plugins/%s", getDescription().getName()));
if(!folder.isDirectory())
folder.delete();
if(!folder.exists())
folder.mkdirs();
/*PlayerEntity player = new PlayerEntity(0L, "Mika");
PlayerRepository playerRepository = new PlayerRepository();
PlayerEntity player = new PlayerEntity(0L, "Mika", 1, 2, 3, 4, 5);
playerRepository.save(player).thenRun(() -> {
Bukkit.getScheduler().runTask(plugin, () -> {
Bukkit.broadcastMessage("Spieler Gepseichert!");
});
});*/
});
register();
}
@Override
public void onDisable() {
HibernateUtil.shutdown();
}
private void register() {
try {
ClassPath cp = ClassPath.from(getClass().getClassLoader());
@ -62,11 +66,6 @@ public final class SurvivalGames extends JavaPlugin {
}
}
@Override
public void onDisable() {
HibernateUtil.shutdown();
}
private void registerCommand(Class<?> klass) {
if(!CommandExecutor.class.isAssignableFrom(klass)) {
logger.log(Level.SEVERE, "Class \"" + klass.getName() + "\" is annotated with @Command but does not implements CommandExecutor");

View File

@ -1,5 +1,6 @@
package de.polyfish0.survivalGames.commands;
import com.samjakob.spigui.menu.SGMenu;
import de.polyfish0.survivalGames.annotations.Command;
import de.polyfish0.survivalGames.annotations.Permission;
import de.polyfish0.survivalGames.gui.GuiManager;
@ -18,7 +19,7 @@ public class SurvivalGamesCommand implements CommandExecutor {
return true;
}
GuiManager.getInstance().openNewInventory((Player) sender, MainMenu.class);
GuiManager.getInstance().openInventory((Player) sender, MainMenu.class);
return true;
}

View File

@ -0,0 +1,108 @@
package de.polyfish0.survivalGames.config;
import lombok.Getter;
import org.apache.commons.vfs2.*;
import org.apache.commons.vfs2.FileSystemException;
import org.apache.commons.vfs2.impl.DefaultFileMonitor;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class ConfigManager {
@Getter
private static ConfigManager instance;
private JavaPlugin plugin;
private FileConfiguration config;
private final static Map<String, Object> defaults = new HashMap<>() {{
put(ConfigValues.Game.MINPLAYERS.getPath(), 2);
put(ConfigValues.Game.MAXPLAYERS.getPath(), 16);
put(ConfigValues.Game.PLAYERSPERTEAM.getPath(), 2);
put(ConfigValues.Game.MINWORLDRADIUS.getPath(), 32);
put(ConfigValues.Game.MAXWORLDRADIUS.getPath(), 256);
put(ConfigValues.Game.SHRINKDURATION.getPath(), 60 * 60 * 4);
put(ConfigValues.Game.COUNTDOWN.getPath(), 30);
put(ConfigValues.Game.GRACEPERIOD.getPath(), 0);
put(ConfigValues.Game.ENABLENETHER.getPath(), false);
put(ConfigValues.Game.ENABLEEND.getPath(), false);
put(ConfigValues.Game.FRIENDLYFIRE.getPath(), true);
put(ConfigValues.Spectator.ALLOWSPECTATORS.getPath(), true);
put(ConfigValues.Spectator.TELEPORTTOPLAYERS.getPath(), true);
}};
public ConfigManager(JavaPlugin plugin) {
if(instance != null)
return;
instance = this;
this.plugin = plugin;
this.config = this.plugin.getConfig();
createConfig();
setupFileSystemWatcher();
}
public void setValue(ConfigPath path, Object value) {
config.set(path.getPath(), value);
plugin.saveConfig();
}
public Object getValue(ConfigPath path) {
return config.get(path.getPath());
}
public Class<?> getClassForConfigPath(ConfigPath path) {
return defaults.get(path.getPath()).getClass();
}
private void createConfig() {
config.addDefaults(defaults);
config.options().copyDefaults(true);
plugin.saveConfig();
}
private void setupFileSystemWatcher() {
try {
File config = new File(String.format("plugins/%s/config.yml", plugin.getDescription().getName()));
FileSystemManager fsManager = VFS.getManager();
FileObject fileObject = fsManager.toFileObject(config);
try(DefaultFileMonitor monitor = new DefaultFileMonitor(new FileListener() {
@Override
public void fileChanged(FileChangeEvent fileChangeEvent) {
try {
new YamlConfiguration().load(config);
} catch (IOException e) {
throw new RuntimeException(e);
} catch (InvalidConfigurationException e) {
plugin.getLogger().severe("The config file is invalid.");
return;
}
plugin.getLogger().info("The config was reloaded.");
plugin.reloadConfig();
}
@Override
public void fileCreated(FileChangeEvent fileChangeEvent) {}
@Override
public void fileDeleted(FileChangeEvent fileChangeEvent) {
plugin.getLogger().info("The config was deleted. Create a new one.");
createConfig();
}
})) {
monitor.setRecursive(false);
monitor.addFile(fileObject);
monitor.start();
}
} catch (FileSystemException e) {
throw new RuntimeException(e);
}
}
}

View File

@ -0,0 +1,5 @@
package de.polyfish0.survivalGames.config;
public interface ConfigPath {
String getPath();
}

View File

@ -0,0 +1,38 @@
package de.polyfish0.survivalGames.config;
import lombok.Getter;
public class ConfigValues {
@Getter
public enum Game implements ConfigPath {
MINPLAYERS("minPlayers"),
MAXPLAYERS("maxPlayers"),
PLAYERSPERTEAM("playersPerTeam"),
MINWORLDRADIUS("border.minWorldRadius"),
MAXWORLDRADIUS("border.maxWorldRadius"),
SHRINKDURATION("border.shrinkDuration"),
COUNTDOWN("countdown"),
GRACEPERIOD("gracePeriod"),
ENABLENETHER("enableNether"),
ENABLEEND("enableEnd"),
FRIENDLYFIRE("friendlyFire");
private final String path;
Game(String path) {
this.path = String.format("game.%s", path);
}
}
@Getter
public enum Spectator implements ConfigPath {
ALLOWSPECTATORS("allowSpectators"),
TELEPORTTOPLAYERS("teleportToPlayers");
private final String path;
Spectator(String path) {
this.path = String.format("spectator.%s", path);
}
}
}

View File

@ -2,7 +2,6 @@ package de.polyfish0.survivalGames.database;
import org.hibernate.Session;
import org.hibernate.Transaction;
import java.io.Serializable;
import java.util.concurrent.CompletableFuture;
public abstract class BaseRepository<T> {

View File

@ -11,7 +11,7 @@ public class HibernateUtil {
.setProperty("hibernate.connection.driver_class", "org.sqlite.JDBC")
.setProperty("hibernate.connection.url", String.format("jdbc:sqlite:plugins/%s/database.db", SurvivalGames.plugin.getDescription().getName()))
.setProperty("hibernate.dialect", "org.hibernate.community.dialect.SQLiteDialect")
.setProperty("hibernate.hbm2ddl.auto", "create")
.setProperty("hibernate.hbm2ddl.auto", "update")
.setProperty("hibernate.show_sql", "true")
.addAnnotatedClass(PlayerEntity.class)
.buildSessionFactory();
@ -21,6 +21,9 @@ public class HibernateUtil {
}
public static void shutdown() {
if(sessionFactory.isClosed())
return;
sessionFactory.close();
}
}

View File

@ -15,5 +15,10 @@ import lombok.NoArgsConstructor;
public class PlayerEntity {
@Id
private Long id;
private String name;
private String uuid;
private int games;
private int wins;
private int losses;
private int kills;
private int deaths;
}

View File

@ -1,14 +0,0 @@
package de.polyfish0.survivalGames.events;
import de.polyfish0.survivalGames.annotations.EventClass;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
@EventClass
public class ChestGuiInteractionEvent implements Listener {
@EventHandler
public void onUserInteractWithChestGuiEvent(InventoryClickEvent e) {
}
}

View File

@ -0,0 +1,15 @@
package de.polyfish0.survivalGames.events;
import de.polyfish0.survivalGames.annotations.EventClass;
import de.polyfish0.survivalGames.gui.GuiManager;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerQuitEvent;
@EventClass
public class OnPlayerDisconnect implements Listener {
@EventHandler
public void onPlayerQuit(PlayerQuitEvent e) {
GuiManager.getInstance().clearPlayerInventoryHistory(e.getPlayer());
}
}

View File

@ -0,0 +1,26 @@
package de.polyfish0.survivalGames.events;
import lombok.Getter;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
@Getter
public class StartGameEvent extends Event {
private static final HandlerList handlers = new HandlerList();
private final Player executor;
public StartGameEvent(Player executor) {
this.executor = executor;
}
public static HandlerList getHandlerList() {
return handlers;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
}

View File

@ -1,12 +0,0 @@
package de.polyfish0.survivalGames.gui;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryView;
public interface GuiInterface {
void setInventoryView(InventoryView view);
Inventory getInventory();
InventoryView getInventoryView();
void click(InventoryClickEvent event);
}

View File

@ -1,54 +1,70 @@
package de.polyfish0.survivalGames.gui;
import com.samjakob.spigui.SpiGUI;
import de.polyfish0.survivalGames.SurvivalGames;
import de.polyfish0.survivalGames.annotations.EventClass;
import de.polyfish0.survivalGames.config.ConfigManager;
import de.polyfish0.survivalGames.config.ConfigPath;
import de.polyfish0.survivalGames.gui.menus.Menu;
import lombok.Getter;
import net.wesjd.anvilgui.AnvilGUI;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryView;
import org.bukkit.inventory.ItemStack;
import javax.security.auth.callback.Callback;
import java.lang.reflect.InvocationTargetException;
import java.util.EmptyStackException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Stack;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;
import java.util.function.Function;
@EventClass
public class GuiManager implements Listener {
private final static GuiManager INSTANCE = new GuiManager();
private final HashMap<Player, Stack<GuiInterface>> interfaceHistory = new HashMap<>();
private final HashSet<Inventory> openedGuiInterfaces = new HashSet<>();
private static GuiManager instance;
@Getter
private static SpiGUI spiGui;
private final ConcurrentHashMap<Player, Stack<Menu>> interfaceHistory = new ConcurrentHashMap<>();
public static GuiManager getInstance() {
return INSTANCE;
private GuiManager() {
spiGui = new SpiGUI(SurvivalGames.plugin);
}
public void openInventory(Player p, Class<? extends GuiInterface> guiInterface) {
public static GuiManager getInstance() {
if(instance == null)
instance = new GuiManager();
return instance;
}
public void openInventory(Player p, Class<? extends Menu> guiInterface) {
try {
GuiInterface interfaceInstance = guiInterface.getDeclaredConstructor().newInstance();
Menu interfaceInstance = guiInterface.getDeclaredConstructor().newInstance();
p.openInventory(interfaceInstance.getMenu().getInventory());
if(!interfaceHistory.containsKey(p)) {
Stack<GuiInterface> stack = new Stack<>();
Stack<Menu> stack = new Stack<>();
stack.push(interfaceInstance);
interfaceHistory.put(p, stack);
}else {
interfaceHistory.get(p).push(interfaceInstance);
}
p.closeInventory();
InventoryView view = p.openInventory(interfaceInstance.getInventory());
interfaceInstance.setInventoryView(view);
openedGuiInterfaces.add(view.getTopInventory());
} catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
public void openNewInventory(Player p, Class<? extends GuiInterface> guiInterface) {
public void openNewInventory(Player p, Class<? extends Menu> guiInterface) {
if(interfaceHistory.containsKey(p)) {
p.closeInventory();
interfaceHistory.remove(p);
@ -59,29 +75,42 @@ public class GuiManager implements Listener {
public void popInventory(Player p) {
try {
interfaceHistory.get(p).pop().getInventoryView().close();
InventoryView view = p.openInventory(interfaceHistory.get(p).peek().getInventory());
interfaceHistory.get(p).peek().setInventoryView(view);
openedGuiInterfaces.add(view.getTopInventory());
interfaceHistory.get(p).pop();
p.openInventory(interfaceHistory.get(p).peek().getMenu().getInventory());
} catch (EmptyStackException e) {
p.closeInventory();
}
}
@EventHandler
public void onInventoryClosed(InventoryCloseEvent e) {
getInstance().openedGuiInterfaces.remove(e.getInventory());
public void clearPlayerInventoryHistory(Player p) {
interfaceHistory.remove(p);
}
@EventHandler
public void onInventoryClick(InventoryClickEvent e) {
if(!(e.getWhoClicked() instanceof Player)) return;
public void openSettingInAnvilGui(ConfigPath path, Player p, String title) {
new AnvilGUI.Builder()
.onClick((slot, state) -> {
if (slot != AnvilGUI.Slot.OUTPUT)
return Collections.emptyList();
Player p = (Player) e.getWhoClicked();
if (ConfigManager.getInstance().getClassForConfigPath(path) == Integer.class) {
try {
ConfigManager.getInstance().setValue(path, Integer.parseInt(state.getText()));
}catch (NumberFormatException e) {
state.getPlayer().sendMessage(SurvivalGames.prefix + "You have to enter a valid number without decimal places.");
return List.of();
}
}else {
ConfigManager.getInstance().setValue(path, state.getText());
}
if(!getInstance().interfaceHistory.containsKey(p) || !getInstance().openedGuiInterfaces.contains(e.getClickedInventory())) return;
state.getPlayer().sendMessage(SurvivalGames.prefix + "Config updated: " + state.getText());
getInstance().interfaceHistory.get(p).peek().click(e);
return List.of(AnvilGUI.ResponseAction.close());
})
.title(title)
.itemLeft(new ItemStack(Material.BOOK))
.text(ConfigManager.getInstance().getValue(path).toString())
.plugin(SurvivalGames.plugin)
.open(p);
}
}
}

View File

@ -1,64 +1,30 @@
package de.polyfish0.survivalGames.gui.menus;
import de.polyfish0.survivalGames.gui.GuiInterface;
import com.samjakob.spigui.buttons.SGButton;
import com.samjakob.spigui.item.ItemBuilder;
import com.samjakob.spigui.menu.SGMenu;
import de.polyfish0.survivalGames.SurvivalGames;
import de.polyfish0.survivalGames.events.StartGameEvent;
import de.polyfish0.survivalGames.gui.GuiManager;
import lombok.Getter;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryView;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.HashMap;
import java.util.function.Consumer;
@Getter
public class MainMenu extends Menu {
private final SGMenu menu;
public class MainMenu implements GuiInterface {
private Inventory inventory;
private final HashMap<ItemStack, Consumer<Player>> methodRegister = new HashMap<>();
private InventoryView inventoryView;
@Override
public Inventory getInventory() {
if(inventory != null)
return inventory;
inventory = Bukkit.createInventory(null, 18);
ItemStack backButton = new ItemStack(Material.RED_STAINED_GLASS_PANE, 1);
ItemMeta meta = backButton.getItemMeta();
meta.setDisplayName("Back Button");
backButton.setItemMeta(meta);
inventory.addItem(backButton);
methodRegister.put(backButton, GuiManager.getInstance()::popInventory);
for(int i = 1; i <= 8; i++)
inventory.setItem(i, new ItemStack(Material.GRAY_STAINED_GLASS_PANE));
return inventory;
}
@Override
public void click(InventoryClickEvent e) {
if(!methodRegister.containsKey(e.getCurrentItem())) {
e.setCancelled(true);
return;
}
methodRegister.get(e.getCurrentItem()).accept(Bukkit.getPlayer(e.getWhoClicked().getName()));
}
@Override
public void setInventoryView(InventoryView view) {
inventoryView = view;
}
@Override
public InventoryView getInventoryView() {
return inventoryView;
public MainMenu() {
menu = GuiManager.getSpiGui().create("Main Menu", 3);
menu.addButton(
new SGButton(
new ItemBuilder(Material.GREEN_STAINED_GLASS_PANE).name("Start Game").build()
).withListener(e -> SurvivalGames.plugin.getServer().getPluginManager().callEvent(new StartGameEvent(Bukkit.getPlayer(e.getWhoClicked().getUniqueId()))))
);
menu.addButton(
new SGButton(
new ItemBuilder(Material.ANVIL).name("Settings").build()
).withListener(e -> GuiManager.getInstance().openInventory(Bukkit.getPlayer(e.getWhoClicked().getUniqueId()), WorldMenu.class))
);
}
}

View File

@ -0,0 +1,21 @@
package de.polyfish0.survivalGames.gui.menus;
import com.samjakob.spigui.buttons.SGButton;
import com.samjakob.spigui.item.ItemBuilder;
import com.samjakob.spigui.menu.SGMenu;
import de.polyfish0.survivalGames.SurvivalGames;
import de.polyfish0.survivalGames.gui.GuiManager;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.event.inventory.InventoryClickEvent;
public abstract class Menu {
public abstract SGMenu getMenu();
protected SGButton backButton = new SGButton(
new ItemBuilder(Material.RED_STAINED_GLASS_PANE)
.name("Zurück")
.enchant(Enchantment.INFINITY, 255)
.build())
.withListener((InventoryClickEvent e) -> GuiManager.getInstance().popInventory(SurvivalGames.plugin.getServer().getPlayer(e.getWhoClicked().getUniqueId())));
}

View File

@ -0,0 +1,17 @@
package de.polyfish0.survivalGames.gui.menus;
import com.samjakob.spigui.buttons.SGButton;
import com.samjakob.spigui.item.ItemBuilder;
import com.samjakob.spigui.menu.SGMenu;
import de.polyfish0.survivalGames.gui.GuiManager;
import lombok.Getter;
import org.bukkit.Material;
@Getter
public class SettingsMenu extends Menu {
private final SGMenu menu;
public SettingsMenu() {
menu = GuiManager.getSpiGui().create("Settings", 3);
}
}

View File

@ -0,0 +1,28 @@
package de.polyfish0.survivalGames.gui.menus;
import com.samjakob.spigui.buttons.SGButton;
import com.samjakob.spigui.item.ItemBuilder;
import com.samjakob.spigui.menu.SGMenu;
import de.polyfish0.survivalGames.config.ConfigValues;
import de.polyfish0.survivalGames.gui.GuiManager;
import lombok.Getter;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.event.inventory.InventoryClickEvent;
@Getter
public class WorldMenu extends Menu {
private final SGMenu menu;
public WorldMenu() {
menu = GuiManager.getSpiGui().create("World Menu", 3);
menu.addButton(
new SGButton(
new ItemBuilder(Material.COMPASS)
.name("Test")
.build()
).withListener((InventoryClickEvent e) -> GuiManager.getInstance().openSettingInAnvilGui(ConfigValues.Game.MINPLAYERS, Bukkit.getPlayer(e.getWhoClicked().getName()), "Minimum player count"))
);
menu.addButton(backButton);
}
}

View File

@ -0,0 +1,39 @@
package de.polyfish0.survivalGames.managers;
import de.polyfish0.survivalGames.SurvivalGames;
import de.polyfish0.survivalGames.annotations.EventClass;
import de.polyfish0.survivalGames.events.StartGameEvent;
import lombok.Getter;
import org.apache.commons.io.FileUtils;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.WorldCreator;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import java.io.File;
import java.io.IOException;
@Getter
@EventClass
public class GameManager implements Listener {
private World world;
@EventHandler
public void onNewGameStart(StartGameEvent e) {
if (world != null) {
world.getPlayers().forEach(p -> p.teleport(Bukkit.getWorlds().getFirst().getSpawnLocation(), TeleportCause.PLUGIN));
Bukkit.unloadWorld(world, false);
try {
FileUtils.deleteDirectory(world.getWorldFolder());
} catch (IOException ex) {
throw new RuntimeException(ex);
}
world = null;
}
world = SurvivalGames.plugin.getServer().createWorld(new WorldCreator("sg_map"));
Bukkit.getOnlinePlayers().forEach(p -> p.teleport(world.getSpawnLocation(), TeleportCause.PLUGIN));
}
}