package com.walrusone.skywars.controllers; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.LinkedList; import java.util.Map; import java.util.Queue; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.block.Sign; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; import com.google.common.collect.Maps; import com.walrusone.skywars.SkyWarsReloaded; import com.walrusone.skywars.game.Game; import com.walrusone.skywars.game.GamePlayer; import com.walrusone.skywars.game.Game.GameState; import com.walrusone.skywars.utilities.Messaging; public class GameController { private Map<Integer, Game> gameNumbers = Maps.newHashMap(); private Map<Integer, GameSign> signJoinGames = Maps.newHashMap(); private boolean shutdown = false; private Queue<GamePlayer> waitingPlayers = new LinkedList<GamePlayer>(); private int gameNumber = 0; org.bukkit.material.Sign meteSign = new org.bukkit.material.Sign(); public Game findGame() { ArrayList<Game> games = getGames(); for (int i = 0; i < getGames().size(); i++) { if (!games.get(i).isFull() && games.get(i).getState() == GameState.PREGAME) { return games.get(i); } } return createGame(); } public Game createGame() { gameNumber = findAvailableNumber(); if (gameNumber != -1) { final Game game = new Game(gameNumber, ""); gameNumbers.put(gameNumber, game); if (!waitingPlayers.isEmpty()) { while (!game.isFull() && !waitingPlayers.isEmpty()) { game.addPlayer(waitingPlayers.remove()); } if (game.isFull()) { createGame(); } } return game; } else { return null; } } private int findAvailableNumber() { int maxNum = SkyWarsReloaded.getCfg().getMaxNumberOfGames(); if (maxNum == -1) { maxNum = Integer.MAX_VALUE; } int gameNumber = -1; for (int i = 1; i <= maxNum; i++) { if (gameNumbers.get(i) == null) { return i; } } return gameNumber; } public void signJoinLoad() { File signJoinFile = new File(SkyWarsReloaded.get().getDataFolder(), "signJoinGames.yml"); if (!signJoinFile.exists()) { SkyWarsReloaded.get().saveResource("signJoinGames.yml", false); } if (signJoinFile.exists()) { FileConfiguration storage = YamlConfiguration.loadConfiguration(signJoinFile); try { for (String gameNumber : storage.getConfigurationSection("games.").getKeys(false)) { String mapName = storage.getString("games." + gameNumber + ".map"); String world = storage.getString("games." + gameNumber + ".world"); if (mapName != null && world != null) { GameSign gs = new GameSign(storage.getInt("games." + gameNumber + ".x"), storage.getInt("games." + gameNumber + ".y"), storage.getInt("games." + gameNumber + ".z"), world, mapName); signJoinGames.put(Integer.valueOf(gameNumber), gs); createGame(Integer.valueOf(gameNumber), gs); } } } catch (NullPointerException e) { } } } public boolean addSignJoinGame(Location loc, String mapName) { if (SkyWarsReloaded.getMC().mapRegistered(mapName)) { String world = loc.getWorld().getName().toString(); int x = loc.getBlockX(); int y = loc.getBlockY(); int z = loc.getBlockZ(); GameSign gs = new GameSign(x, y, z, world, mapName); gameNumber = -1; File signJoinFile = new File(SkyWarsReloaded.get().getDataFolder(), "signJoinGames.yml"); if (!signJoinFile.exists()) { SkyWarsReloaded.get().saveResource("signJoinGames.yml", false); } if (signJoinFile.exists()) { FileConfiguration storage = YamlConfiguration.loadConfiguration(signJoinFile); for (int i = 1; i < 1000; i++) { if (storage.getString("games." + i + ".map") == null) { gameNumber = i; break; } } storage.set("games." + gameNumber + ".x", x); storage.set("games." + gameNumber + ".y", y); storage.set("games." + gameNumber + ".z", z); storage.set("games." + gameNumber + ".world", world); storage.set("games." + gameNumber + ".map", mapName); try { storage.save(signJoinFile); } catch (IOException e) { e.printStackTrace(); } signJoinGames.put(gameNumber, gs); createGame(gameNumber, gs); return true; } else { return false; } } return false; } public void removeSignJoinGame(String gameNumber) { File signJoinFile = new File(SkyWarsReloaded.get().getDataFolder(), "signJoinGames.yml"); FileConfiguration storage = YamlConfiguration.loadConfiguration(signJoinFile); storage.set("games." + gameNumber, null); try { storage.save(signJoinFile); } catch (IOException e) { e.printStackTrace(); } signJoinGames.remove(Integer.valueOf(gameNumber)); Game game = getGame(Integer.valueOf(gameNumber)); if (game != null) { if (game.getState() != GameState.PLAYING) { game.endGame(); } } } protected void createGame(int gameNumber, GameSign gs) { Game game = new Game(gameNumber, gs.getName()); gameNumbers.put(gameNumber, game); updateSign(Integer.valueOf(gameNumber)); } public void updateSign(int gameNumber) { GameSign gameSign = signJoinGames.get(gameNumber); if (gameSign != null) { World world = SkyWarsReloaded.get().getServer().getWorld(gameSign.getWorld()); if (world != null) { Block b = world.getBlockAt(gameSign.getX(), gameSign.getY(), gameSign.getZ()); if(b.getType() == Material.WALL_SIGN || b.getType() == Material.SIGN_POST) { Sign s = (Sign) b.getState(); meteSign = (org.bukkit.material.Sign) b.getState().getData(); Block attachedBlock = b.getRelative(meteSign.getAttachedFace()); String state = getStatusName(getGame(gameNumber)); setMaterial(getStatus(getGame(gameNumber)), attachedBlock); int max = getGame(gameNumber).getNumberOfSpawns(); int count = getGame(gameNumber).getPlayers().size(); if (s != null) { s.getBlock().getChunk().load(); s.setLine(0, new Messaging.MessageFormatter().format("signJoinSigns.line1")); s.setLine(1, new Messaging.MessageFormatter().setVariable("mapName", gameSign.getName().toUpperCase()).format("signJoinSigns.line2")); s.setLine(2, new Messaging.MessageFormatter().setVariable("gameStatus", state).format("signJoinSigns.line3")); s.setLine(3, new Messaging.MessageFormatter().setVariable("count", "" + count).setVariable("max", "" + max).format("signJoinSigns.line4")); s.update(); } } } } } public enum GameStatus { JOINABLE, FULL, INPROGRESS, RESTARTING, } public GameStatus getStatus(Game game) { if (game.getState() == GameState.PREGAME && !game.isFull()) { return GameStatus.JOINABLE; } else if (game.getState() == GameState.PREGAME && game.isFull()) { return GameStatus.FULL; } else if (game.getState() == GameState.PLAYING) { return GameStatus.INPROGRESS; } else { return GameStatus.RESTARTING; } } public String getStatusName(Game game) { if (game.getState() == GameState.PREGAME && !game.isFull()) { return new Messaging.MessageFormatter().format("signJoinSigns.joinable"); } else if (game.getState() == GameState.PREGAME && game.isFull()) { return new Messaging.MessageFormatter().format("signJoinSigns.full"); } else if (game.getState() == GameState.PLAYING) { return new Messaging.MessageFormatter().format("signJoinSigns.inprogress"); } else { return new Messaging.MessageFormatter().format("signJoinSigns.restarting"); } } @SuppressWarnings("deprecation") private void setMaterial(GameStatus gs, Block attachedBlock) { String material = SkyWarsReloaded.getCfg().getSignJoinMaterial(); Material sMat; if (material.equalsIgnoreCase("wool")) { sMat = Material.WOOL; } else if (material.equalsIgnoreCase("clay")) { sMat = Material.STAINED_CLAY; } else if (material.equalsIgnoreCase("glass")) { sMat = Material.STAINED_GLASS; } else { sMat = null; } if (sMat != null) { if (gs == GameStatus.JOINABLE) { attachedBlock.setType(sMat); attachedBlock.setData((byte) 5); } else if (gs == GameStatus.FULL || gs == GameStatus.INPROGRESS) { attachedBlock.setType(sMat); attachedBlock.setData((byte) 14); } else if (gs == GameStatus.RESTARTING) { attachedBlock.setType(sMat); attachedBlock.setData((byte) 11); } } } public void deleteGame(final int gameNumber) { final GameSign gs = signJoinGames.get(gameNumber); gameNumbers.remove(gameNumber); if (SkyWarsReloaded.getCfg().bungeeEnabled() && !shutdown) { SkyWarsReloaded.get().getServer().getScheduler().runTaskLater(SkyWarsReloaded.get(), new Runnable() { public void run() { createGame(); } }, 40); } if (SkyWarsReloaded.getCfg().signJoinMode() && !shutdown && gs != null) { SkyWarsReloaded.get().getServer().getScheduler().runTaskLater(SkyWarsReloaded.get(), new Runnable() { public void run() { createGame(gameNumber, gs); } }, 40); } } public void shutdown() { shutdown = true; for (Game game : getGames()) { game.shutdown(); game.endGame(); } } public ArrayList<Game> getGames() { ArrayList<Game> games = new ArrayList<Game>(); for (Game g: gameNumbers.values()) { games.add(g); } return games; } public Game getGame(int gameNumber) { return gameNumbers.get(gameNumber); } public boolean inGame(GamePlayer gPlayer) { for (Game game: getGames()) { for (GamePlayer gamePlayer: game.getPlayers()) { if (gamePlayer == gPlayer) { return true; } } } return false; } public void addToQueue(GamePlayer gPlayer) { if (!waitingPlayers.contains(gPlayer)) { waitingPlayers.add(gPlayer); } } private class GameSign { private int x; private int y; private int z; private String mapName; private String world; GameSign(int x, int y, int z, String world, String mapName) { this.x = x; this.y = y; this.z = z; this.world = world; this.mapName = mapName; } public int getX() { return x; } public int getY() { return y; } public int getZ() { return z; } public String getWorld() { return world; } public String getName() { return mapName; } } }