Ver Fonte

Merge pull request #119 from daniel-naegele/1-20-final-rc

1.20 stable
Daniel há 1 ano atrás
pai
commit
b9ba6002cd
26 ficheiros alterados com 200 adições e 223 exclusões
  1. 0 3
      README.md
  2. 2 2
      missilewars-plugin/pom.xml
  3. 2 8
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/MissileWars.java
  4. 26 19
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/commands/StatsCommands.java
  5. 2 8
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/configuration/Lobby.java
  6. 4 0
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/configuration/arena/MissileConfiguration.java
  7. 11 4
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/Arenas.java
  8. 39 22
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/Game.java
  9. 4 4
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/GameManager.java
  10. 1 12
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/GameWorld.java
  11. 5 8
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/MapVoting.java
  12. 1 1
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/equipment/MissileGameEquipment.java
  13. 1 1
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/equipment/SpecialGameEquipment.java
  14. 1 1
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/misc/RespawnGoldBlock.java
  15. 20 16
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/misc/ScoreboardManager.java
  16. 0 1
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/missile/Missile.java
  17. 1 1
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/timer/EndTimer.java
  18. 1 1
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/timer/LobbyTimer.java
  19. 1 1
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/inventory/pages/PageGUICreator.java
  20. 9 2
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/listener/PlayerListener.java
  21. 21 73
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/util/SetupUtil.java
  22. 1 1
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/util/geometry/GameArea.java
  23. 24 9
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/util/stats/GameProfileBuilder.java
  24. 23 25
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/util/stats/PlayerGuiFactory.java
  25. BIN
      missilewars-plugin/src/main/resources/Dam-Arena.zip
  26. BIN
      missilewars-plugin/src/main/resources/missiles.zip

+ 0 - 3
README.md

@@ -7,9 +7,6 @@ MissileWars is a famous, fun and fast minigame spigot-plugin for Minecraft
 You can download the latest jar in the [latest release](https://github.com/Butzlabben/missilewars/releases/latest) or build it yourself (
 see [BUILDING](#building))
 
-However, if you [buy the resource](https://www.spigotmc.org/resources/62947) and leave a review,
-you will also receive an extra map and some more missiles.
-
 ## Building
 
 To build MissileWars, you need to install the Java 17 JDK. Then you can build it via the Maven Wrapper.

+ 2 - 2
missilewars-plugin/pom.xml

@@ -26,7 +26,7 @@
         <version>1.0</version>
     </parent>
 
-    <version>4.5.3</version>
+    <version>4.6.0</version>
 
     <modelVersion>4.0.0</modelVersion>
 
@@ -117,7 +117,7 @@
         <dependency>
             <groupId>com.mojang</groupId>
             <artifactId>authlib</artifactId>
-            <version>1.5.25</version>
+            <version>4.0.43</version>
             <scope>provided</scope>
         </dependency>
 

+ 2 - 8
missilewars-plugin/src/main/java/de/butzlabben/missilewars/MissileWars.java

@@ -57,6 +57,7 @@ import org.bukkit.plugin.java.JavaPlugin;
 @Getter
 public class MissileWars extends JavaPlugin {
 
+    @Getter
     private static MissileWars instance;
     public final String version = getDescription().getVersion();
     private SignRepository signRepository;
@@ -71,13 +72,6 @@ public class MissileWars extends JavaPlugin {
         instance = this;
     }
 
-    /**
-     * @return the instance of the plugin
-     */
-    public static MissileWars getInstance() {
-        return instance;
-    }
-
     @Override
     public void onEnable() {
         long startTime;
@@ -116,7 +110,7 @@ public class MissileWars extends JavaPlugin {
         GameManager.getInstance().getGames().values().forEach(game -> {
             for (Player player : Bukkit.getOnlinePlayers()) {
                 if (!game.isIn(player.getLocation())) continue;
-                game.teleportToLobbySpawn(player);
+                game.playerJoinInGame(player, false);
             }
         });
 

+ 26 - 19
missilewars-plugin/src/main/java/de/butzlabben/missilewars/commands/StatsCommands.java

@@ -47,6 +47,7 @@ import java.util.stream.Collectors;
 import org.bukkit.Material;
 import org.bukkit.command.CommandSender;
 import org.bukkit.entity.Player;
+import org.jetbrains.annotations.NotNull;
 
 @CommandAlias("mw|missilewars")
 @Subcommand("stats")
@@ -58,6 +59,28 @@ public class StatsCommands extends BaseCommand {
     private final SimpleDateFormat format = new SimpleDateFormat("dd.MM.yyyy");
     private final SimpleDateFormat preciseFormat = new SimpleDateFormat("hh:mm dd.MM.yyyy");
 
+    @NotNull
+    private static List<String> generateRecommendations(StatsFetcher fetcher, SavedStats avgStatsWithoutDraws) {
+        List<String> recommendations = new ArrayList<>();
+        int gameCount = fetcher.getGameCount();
+
+        double avgWins = avgStatsWithoutDraws.getTeamWon();
+        if (Math.abs(avgWins - 1) > MAX_AVIATION_WIN) {
+            recommendations.add("It could be, that your map is biased to one team, as wins are not equally distributed");
+        }
+
+        int draws = fetcher.getDrawFights();
+        if ((((double) draws / (double) gameCount) * 100) > MAX_FIGHT_DRAW_PERCENTAGE) {
+            recommendations.add("Increase the game_length option. More than 15% of your games are draws");
+        }
+
+        Duration duration = Duration.ofMillis(avgStatsWithoutDraws.getTimeElapsed());
+        if (((double) duration.getSeconds() / 60.0) <= MIN_FIGHT_DURATION) {
+            recommendations.add("Remove some overpowered features. The average game length at won games is under 5 minutes");
+        }
+        return recommendations;
+    }
+
     @Default
     @CommandPermission("mw.stats")
     public void onStats(CommandSender sender, String[] args) {
@@ -72,7 +95,7 @@ public class StatsCommands extends BaseCommand {
         PreFetcher.PrePlayerFetchRunnable preFetchRunnable = PreFetcher.preFetchPlayers(fetcher);
 
         CustomInv inv = new CustomInv("§eMissileWars statistics", 3);
-        List<String> criteriaLore = Arrays.asList("§7Statistics since: §e" + format.format(fetcher.getFrom()), "§7Specified arena: §e" + (arena.equals("") ? "any" : arena));
+        List<String> criteriaLore = Arrays.asList("§7Statistics since: §e" + format.format(fetcher.getFrom()), "§7Specified arena: §e" + (arena.isEmpty() ? "any" : arena));
         inv.addItem(4, new OrcItem(Material.FEATHER, "§aStatistics search criteria", criteriaLore));
 
         int gameCount = fetcher.getGameCount();
@@ -121,26 +144,10 @@ public class StatsCommands extends BaseCommand {
         if (fetcher == null) return;
         SavedStats avgStatsWithDraws = fetcher.getAverageSavedStats(false);
         SavedStats avgStatsWithoutDraws = fetcher.getAverageSavedStats(true);
-        List<String> recommendations = new ArrayList<>();
-        int gameCount = fetcher.getGameCount();
-
-        double avgWins = avgStatsWithoutDraws.getTeamWon();
-        if (Math.abs(avgWins - 1) > MAX_AVIATION_WIN) {
-            recommendations.add("It could be, that your map is biased to one team, as wins are not equally distributed");
-        }
-
-        int draws = fetcher.getDrawFights();
-        if ((((double) draws / (double) gameCount) * 100) > MAX_FIGHT_DRAW_PERCENTAGE) {
-            recommendations.add("Increase the game_length option. More than 15% of your games are draws");
-        }
-
-        Duration duration = Duration.ofMillis(avgStatsWithoutDraws.getTimeElapsed());
-        if (((double) duration.getSeconds() / 60.0) <= MIN_FIGHT_DURATION) {
-            recommendations.add("Remove some overpowered features. The average game length at won games is under 5 minutes");
-        }
+        List<String> recommendations = generateRecommendations(fetcher, avgStatsWithoutDraws);
         // TODO implement more features
 
-        if (recommendations.size() == 0) {
+        if (recommendations.isEmpty()) {
             player.sendMessage(Messages.getPrefix() + "§aThere are currently no recommendations, everything seems fine :)");
         } else {
             player.sendMessage(Messages.getPrefix() + "§7=====[ §eMissileWars recommendations §7]=====");

+ 2 - 8
missilewars-plugin/src/main/java/de/butzlabben/missilewars/configuration/Lobby.java

@@ -30,7 +30,6 @@ import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Optional;
 import java.util.stream.Collectors;
 import lombok.Getter;
 import lombok.RequiredArgsConstructor;
@@ -40,12 +39,6 @@ import org.bukkit.Bukkit;
 import org.bukkit.Location;
 import org.bukkit.World;
 
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.stream.Collectors;
-
 @Getter
 @ToString
 @RequiredArgsConstructor
@@ -67,9 +60,10 @@ public class Lobby {
     @Setter @SerializedName("spawn_point") private Location spawnPoint = getBukkitDefaultWorld().getSpawnLocation();
     @Setter @SerializedName("after_game_spawn") private Location afterGameSpawn = getBukkitDefaultWorld().getSpawnLocation();
     @Setter @SerializedName("area") private AreaConfiguration areaConfig = AreaConfiguration.aroundLocation(getBukkitDefaultWorld().getSpawnLocation(), 30);
-    @SerializedName("map_choose_procedure") private MapChooseProcedure mapChooseProcedure = MapChooseProcedure.FIRST;
+    @SerializedName("map_choose_procedure") private MapChooseProcedure mapChooseProcedure = MapChooseProcedure.MAPCYCLE;
     @SerializedName("possible_arenas") private List<String> possibleArenas = new ArrayList<>() {{
         add("arena0");
+        add("dam");
     }};
 
     // These values are only set after the Config has been read.

+ 4 - 0
missilewars-plugin/src/main/java/de/butzlabben/missilewars/configuration/arena/MissileConfiguration.java

@@ -54,6 +54,10 @@ public class MissileConfiguration {
         add(new Missile("Juggernaut.schematic", "&4Juggernaut", EntityType.MUSHROOM_COW, 2, 2, 1));
         add(new Missile("Piranha.schematic", "&3Piranha", EntityType.HORSE, 2, 2, 3));
         add(new Missile("Tunnelbore.schematic", "&0Tunnelbore", EntityType.ENDERMAN, 2, 2, 1));
+        add(new Missile("Minuteman.schematic", "&3Minuteman", EntityType.CAVE_SPIDER, 2, 3, 2));
+        add(new Missile("Skybolt.schematic", "&bSkybolt", EntityType.SKELETON_HORSE, 2, 2, 2));
+        add(new Missile("Medusa.schematic", "&5Medusa", EntityType.PARROT, 2, 2, 1));
+
     }};
 
     public List<MissileFacing> getEnabledFacings() {

+ 11 - 4
missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/Arenas.java

@@ -24,13 +24,12 @@ import de.butzlabben.missilewars.configuration.Config;
 import de.butzlabben.missilewars.configuration.arena.Arena;
 import de.butzlabben.missilewars.util.SetupUtil;
 import de.butzlabben.missilewars.util.serialization.Serializer;
-import lombok.Getter;
-import org.bukkit.Bukkit;
-
 import java.io.File;
 import java.io.IOException;
 import java.util.HashMap;
 import java.util.Map;
+import lombok.Getter;
+import org.bukkit.Bukkit;
 
 public class Arenas {
 
@@ -59,9 +58,17 @@ public class Arenas {
                 Bukkit.getPluginManager().disablePlugin(MissileWars.getInstance());
                 return;
             }
-            files = new File[] {defaultArena};
+
+            // Also unpack additional arenas
+            try {
+                SetupUtil.copyAndUnzip("Dam-Arena.zip", folder.getAbsolutePath());
+            } catch (IOException e) {
+                Logger.ERROR.log("Could not extract Dam Arena");
+                e.printStackTrace();
+            }
         }
 
+        files = folder.listFiles();
         for (File config : files) {
             if (!config.getName().endsWith(".yml") && !config.getName().endsWith(".yaml")) continue;
             try {

+ 39 - 22
missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/Game.java

@@ -52,9 +52,19 @@ import de.butzlabben.missilewars.util.PlayerDataProvider;
 import de.butzlabben.missilewars.util.geometry.GameArea;
 import de.butzlabben.missilewars.util.geometry.Geometry;
 import de.butzlabben.missilewars.util.serialization.Serializer;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.function.Consumer;
 import lombok.Getter;
 import lombok.ToString;
-import org.bukkit.*;
+import org.bukkit.Bukkit;
+import org.bukkit.GameMode;
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.Sound;
+import org.bukkit.World;
 import org.bukkit.entity.Fireball;
 import org.bukkit.entity.Player;
 import org.bukkit.event.HandlerList;
@@ -63,12 +73,6 @@ import org.bukkit.inventory.ItemStack;
 import org.bukkit.scheduler.BukkitTask;
 import org.bukkit.util.Vector;
 
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-import java.util.function.Consumer;
-
 /**
  * @author Butzlabben
  * @since 01.01.2018
@@ -117,7 +121,7 @@ public class Game {
             return;
         }
 
-        if (lobby.getPossibleArenas().size() == 0) {
+        if (lobby.getPossibleArenas().isEmpty()) {
             Logger.ERROR.log("At least one valid arena must be set at lobby \"" + lobby.getName() + "\".");
             return;
         }
@@ -163,7 +167,7 @@ public class Game {
         } else if (lobby.getMapChooseProcedure() == MapChooseProcedure.MAPCYCLE) {
             final int lastMapIndex = cycles.getOrDefault(lobby.getName(), -1);
             List<Arena> arenas = lobby.getArenas();
-            int index = lastMapIndex >= arenas.size() - 1 ? 0 : lastMapIndex + 1;
+            int index = (lastMapIndex + 1) % arenas.size();
             cycles.put(lobby.getName(), index);
             setArena(arenas.get(index));
             prepareGame();
@@ -179,6 +183,14 @@ public class Game {
             }
         }
 
+        // Add players if they are in the game area
+        for (Player player : Bukkit.getOnlinePlayers()) {
+            if (!isIn(player.getLocation())) {
+                continue;
+            }
+
+            playerJoinInGame(player, false);
+        }
     }
 
     /**
@@ -295,7 +307,7 @@ public class Game {
         Bukkit.getPluginManager().callEvent(new GameStopEvent(this));
     }
 
-    public void reset() {
+    public void triggerRestart() {
         if (Config.isSetup()) return;
 
         if (restart) {
@@ -401,10 +413,8 @@ public class Game {
         Team team = mwPlayer.getTeam();
         boolean playerWasTeamMember = false;
 
-        if (state == GameState.INGAME) {
-            BukkitTask task = playerTasks.get(mwPlayer.getUuid());
-            if (task != null) task.cancel();
-        }
+        BukkitTask task = playerTasks.get(mwPlayer.getUuid());
+        if (task != null) task.cancel();
 
         PlayerDataProvider.getInstance().loadInventory(player);
 
@@ -476,6 +486,12 @@ public class Game {
         HandlerList.unregisterAll(listener);
         taskManager.stopTimer();
 
+        // Just in case this wasn't executed in stopGame() already
+        // This can happen if a game restart gets issued while it's still active
+        for (BukkitTask bt : playerTasks.values()) {
+            bt.cancel();
+        }
+
         if (gameWorld != null) {
             gameWorld.unload();
             gameWorld.delete();
@@ -649,7 +665,7 @@ public class Game {
         itemStack.setAmount(amount - 1);
 
         Fireball fb = player.launchProjectile(Fireball.class);
-        fb.setVelocity(player.getLocation().getDirection().multiply(2.5D));
+        fb.setDirection(player.getLocation().getDirection().multiply(2.5D));
         player.playSound(fb.getLocation(), Sound.BLOCK_ANVIL_LAND, 100.0F, 2.0F);
         player.playSound(fb.getLocation(), Sound.ITEM_FLINTANDSTEEL_USE, 100.0F, 1.0F);
         fb.setYield(3F);
@@ -663,7 +679,7 @@ public class Game {
         }
 
         arena.getMissileConfiguration().check();
-        if (arena.getMissileConfiguration().getMissiles().size() == 0) {
+        if (arena.getMissileConfiguration().getMissiles().isEmpty()) {
             throw new IllegalStateException("The game cannot be started, when 0 missiles are configured");
         }
 
@@ -811,20 +827,21 @@ public class Game {
     }
 
     /**
-     * This method checks whether a team switch would be fair based on 
-     * the new team size. If no empty team results or if the team size 
-     * difference does not exceed a certain value, the switch is 
+     * This method checks whether a team switch would be fair based on
+     * the new team size. If no empty team results or if the team size
+     * difference does not exceed a certain value, the switch is
      * considered acceptable.
-     * 
+     *
      * @param targetTeam the new team
+     *
      * @return (boolean) 'true' if it's a fair team switch
      */
     public boolean isValidTeamSwitch(Team targetTeam) {
-        
+
         // original team sizes
         int targetTeamSize = targetTeam.getMembers().size();
         int currentTeamSize = targetTeam.getEnemyTeam().getMembers().size();
-        
+
         // Preventing an empty team when previously both teams had at least one player:
         if ((currentTeamSize == 1) && (targetTeamSize >= 1)) return false;
 

+ 4 - 4
missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/GameManager.java

@@ -24,14 +24,13 @@ import de.butzlabben.missilewars.configuration.Config;
 import de.butzlabben.missilewars.configuration.Lobby;
 import de.butzlabben.missilewars.util.geometry.GameArea;
 import de.butzlabben.missilewars.util.serialization.Serializer;
-import lombok.Getter;
-import org.bukkit.Bukkit;
-import org.bukkit.Location;
-
 import java.io.File;
 import java.io.IOException;
 import java.util.HashMap;
 import java.util.Map;
+import lombok.Getter;
+import org.bukkit.Bukkit;
+import org.bukkit.Location;
 
 @Getter
 public class GameManager {
@@ -47,6 +46,7 @@ public class GameManager {
     }
 
     public void restartAll() {
+        // We use an iterator to prevent a possible ConcurrentModificationException
         var iterator = games.values().iterator();
         //noinspection WhileLoopReplaceableByForEach
         while (iterator.hasNext()) {

+ 1 - 12
missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/GameWorld.java

@@ -20,7 +20,6 @@ package de.butzlabben.missilewars.game;
 
 import de.butzlabben.missilewars.Logger;
 import de.butzlabben.missilewars.configuration.Config;
-import de.butzlabben.missilewars.configuration.Messages;
 import java.io.File;
 import java.io.IOException;
 import lombok.Getter;
@@ -61,16 +60,6 @@ public class GameWorld {
         return Bukkit.getWorld(worldName);
     }
 
-    public void kickInactivity() {
-        synchronized (lock) {
-            Bukkit.getOnlinePlayers().forEach(p -> {
-                if (p.isDead() && p.getWorld().getName().equals(worldName)) {
-                    p.kickPlayer(Messages.getMessage(true, Messages.MessageEnum.ARENA_KICK_INACTIVITY));
-                }
-            });
-        }
-    }
-
     public void unload() {
         synchronized (lock) {
             World w = Bukkit.getWorld(worldName);
@@ -95,7 +84,7 @@ public class GameWorld {
             FileUtils.deleteQuietly(file);
             if (file.exists() || file.isDirectory()) {
                 Logger.WARN.log("Could not delete old world!");
-                file.delete();
+                file.deleteOnExit();
             }
         }
     }

+ 5 - 8
missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/MapVoting.java

@@ -23,18 +23,17 @@ import de.butzlabben.missilewars.configuration.arena.Arena;
 import de.butzlabben.missilewars.game.enums.MapChooseProcedure;
 import de.butzlabben.missilewars.game.enums.VoteState;
 import de.butzlabben.missilewars.player.MWPlayer;
-import lombok.Getter;
-import org.bukkit.entity.Player;
-
 import java.util.HashMap;
 import java.util.Map;
 import java.util.function.Function;
 import java.util.stream.Collectors;
+import lombok.Getter;
+import org.bukkit.entity.Player;
 
 public class MapVoting {
 
     private final Map<MWPlayer, Arena> arenaVotes = new HashMap<>();
-    private Game game;
+    private final Game game;
     @Getter private VoteState state = VoteState.NULL;
 
     public MapVoting(Game game) {
@@ -103,15 +102,13 @@ public class MapVoting {
     private Arena getVotedArena() {
 
         // If no one voted:
-        if (arenaVotes.size() == 0) return game.getLobby().getArenas().get(0);
+        if (arenaVotes.isEmpty()) return game.getLobby().getArenas().get(0);
 
-        Arena arena = arenaVotes.values().stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
+        return arenaVotes.values().stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
                 .entrySet()
                 .stream()
                 .max(Map.Entry.comparingByValue()).orElseThrow()
                 .getKey();
-
-        return arena;
     }
 
     /**

+ 1 - 1
missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/equipment/MissileGameEquipment.java

@@ -34,7 +34,7 @@ public class MissileGameEquipment {
 
     private final Game game;
 
-    private List<Missile> missileEquipmentList = new ArrayList<>();
+    private final List<Missile> missileEquipmentList = new ArrayList<>();
 
 
     public MissileGameEquipment(Game game) {

+ 1 - 1
missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/equipment/SpecialGameEquipment.java

@@ -40,7 +40,7 @@ public class SpecialGameEquipment {
     private ItemStack arrow;
     private ItemStack fireball;
 
-    private List<ItemStack> specialEquipmentList = new ArrayList<>();
+    private final List<ItemStack> specialEquipmentList = new ArrayList<>();
 
 
     public SpecialGameEquipment(Game game) {

+ 1 - 1
missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/misc/RespawnGoldBlock.java

@@ -142,7 +142,7 @@ public class RespawnGoldBlock implements Listener {
     @EventHandler
     public void onSneak(PlayerToggleSneakEvent e) {
         Player eventPlayer = e.getPlayer();
-        if (eventPlayer == player && (map.size() != 0) && (eventPlayer.isSneaking())) {
+        if (eventPlayer == player && (!map.isEmpty()) && (eventPlayer.isSneaking())) {
             for (Location loc : map.keySet()) {
                 loc.getBlock().setType(map.get(loc).getKey());
                 BlockSetterProvider.getBlockDataSetter().setData(loc.getBlock(), map.get(loc).getValue());

+ 20 - 16
missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/misc/ScoreboardManager.java

@@ -23,6 +23,9 @@ import de.butzlabben.missilewars.game.Game;
 import de.butzlabben.missilewars.game.Team;
 import de.butzlabben.missilewars.game.enums.GameState;
 import de.butzlabben.missilewars.player.MWPlayer;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 import lombok.Getter;
 import lombok.RequiredArgsConstructor;
 import lombok.Setter;
@@ -32,10 +35,6 @@ import org.bukkit.scoreboard.DisplaySlot;
 import org.bukkit.scoreboard.Objective;
 import org.bukkit.scoreboard.Scoreboard;
 
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
 // Scoreboard Management: https://www.spigotmc.org/wiki/making-scoreboard-with-teams-no-flicker
 
 @RequiredArgsConstructor
@@ -62,7 +61,7 @@ public class ScoreboardManager {
 
     @Getter private Scoreboard board;
     private Objective obj;
-    private Map<Integer, org.bukkit.scoreboard.Team> teams = new HashMap<>();
+    private final Map<Integer, org.bukkit.scoreboard.Team> teams = new HashMap<>();
     private static final String[] COLOR_CODES = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};
 
     /**
@@ -244,17 +243,7 @@ public class ScoreboardManager {
      */
     private String replaceScoreboardPlaceholders(String text) {
 
-        String time = "";
-        if (game.getState() == GameState.LOBBY) {
-            // Show the planned duration of the next game:
-            time = arenaGameDuration;
-        } else if (game.getState() == GameState.INGAME) {
-            // Show the remaining duration of the running game:
-            time = Integer.toString(game.getTaskManager().getTimer().getSeconds() / 60);
-        } else if (game.getState() == GameState.END) {
-            // Show the remaining duration of the last game:
-            time = Integer.toString(game.getRemainingGameDuration() / 60);
-        }
+        String time = getTimeString();
 
 
         text = ChatColor.translateAlternateColorCodes('&', text);
@@ -276,4 +265,19 @@ public class ScoreboardManager {
         return text;
     }
 
+    private String getTimeString() {
+        String time = "";
+        if (game.getState() == GameState.LOBBY) {
+            // Show the planned duration of the next game:
+            time = arenaGameDuration;
+        } else if (game.getState() == GameState.INGAME) {
+            // Show the remaining duration of the running game:
+            time = Integer.toString(game.getTaskManager().getTimer().getSeconds() / 60);
+        } else if (game.getState() == GameState.END) {
+            // Show the remaining duration of the last game:
+            time = Integer.toString(game.getRemainingGameDuration() / 60);
+        }
+        return time;
+    }
+
 }

+ 0 - 1
missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/missile/Missile.java

@@ -38,7 +38,6 @@ import org.bukkit.util.Vector;
  * @author Butzlabben
  * @since 06.01.2018
  */
-@SuppressWarnings("deprecation")
 @RequiredArgsConstructor
 public class Missile {
 

+ 1 - 1
missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/timer/EndTimer.java

@@ -40,7 +40,7 @@ public class EndTimer extends Timer {
                 broadcast(Messages.getMessage(true, Messages.MessageEnum.ENDGAME_TIMER_GAME_STARTS_NEW_IN).replace("%seconds%", Integer.toString(seconds)));
                 break;
             case 0:
-                getGame().reset();
+                getGame().triggerRestart();
                 break;
             default:
                 break;

+ 1 - 1
missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/timer/LobbyTimer.java

@@ -42,7 +42,7 @@ public class LobbyTimer extends Timer implements Runnable {
 
     @Override
     public void tick() {
-        if (getGame().getPlayers().size() == 0) return;
+        if (getGame().getPlayers().isEmpty()) return;
 
         for (MWPlayer mwPlayer : getGame().getPlayers().values()) {
             if (mwPlayer.getPlayer() == null) continue;

+ 1 - 1
missilewars-plugin/src/main/java/de/butzlabben/missilewars/inventory/pages/PageGUICreator.java

@@ -62,7 +62,7 @@ public class PageGUICreator<T> {
 
     public void show(Player p) {
         List<OrcItem> items = elements.stream().map(converter::convert).collect(Collectors.toList());
-        if (items.size() == 0)
+        if (items.isEmpty())
             return;
 
         int pages = (int) (Math.ceil((items.size() / (double) elementsPerPage) < 1 ? 1 : Math.ceil((double) items.size() / (double) elementsPerPage)));

+ 9 - 2
missilewars-plugin/src/main/java/de/butzlabben/missilewars/listener/PlayerListener.java

@@ -34,7 +34,12 @@ import org.bukkit.event.EventHandler;
 import org.bukkit.event.Listener;
 import org.bukkit.event.block.BlockPlaceEvent;
 import org.bukkit.event.entity.FoodLevelChangeEvent;
-import org.bukkit.event.player.*;
+import org.bukkit.event.player.PlayerDropItemEvent;
+import org.bukkit.event.player.PlayerJoinEvent;
+import org.bukkit.event.player.PlayerMoveEvent;
+import org.bukkit.event.player.PlayerPickupItemEvent;
+import org.bukkit.event.player.PlayerQuitEvent;
+import org.bukkit.event.player.PlayerTeleportEvent;
 import org.bukkit.event.server.ServerListPingEvent;
 import org.bukkit.scheduler.BukkitRunnable;
 
@@ -89,7 +94,9 @@ public class PlayerListener implements Listener {
         if (game == null) return;
 
         Player player = event.getPlayer();
-        game.teleportToFallbackSpawn(player);
+
+        PlayerArenaJoinEvent joinEvent = registerPlayerArenaJoinEvent(player, game);
+        if (joinEvent.isCancelled()) game.teleportToFallbackSpawn(player);
     }
 
     @EventHandler

+ 21 - 73
missilewars-plugin/src/main/java/de/butzlabben/missilewars/util/SetupUtil.java

@@ -23,18 +23,20 @@ import de.butzlabben.missilewars.MissileWars;
 import de.butzlabben.missilewars.configuration.Config;
 import de.butzlabben.missilewars.configuration.arena.Arena;
 import de.butzlabben.missilewars.game.Arenas;
-import org.bukkit.configuration.file.YamlConfiguration;
-import org.bukkit.plugin.java.JavaPlugin;
-
-import java.io.*;
-import java.net.URL;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
-import java.util.Enumeration;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipInputStream;
+import org.bukkit.configuration.file.YamlConfiguration;
+import org.bukkit.plugin.java.JavaPlugin;
 
 /**
  * @author Butzlabben
@@ -122,7 +124,7 @@ public class SetupUtil {
             Logger.BOOT.log("Copying default map (" + resource + ")");
 
             try {
-                copyZip(resource, file.getPath());
+                copyAndUnzip(resource, file.getPath());
             } catch (IOException e) {
                 Logger.ERROR.log("Unable to copy new map!");
                 e.printStackTrace();
@@ -138,7 +140,7 @@ public class SetupUtil {
             Logger.BOOT.log("Copying default missiles folder (" + resource + ")");
 
             try {
-                copyZip(resource, file.getPath());
+                copyAndUnzip(resource, file.getPath());
             } catch (IOException e) {
                 Logger.ERROR.log("Unable to copy missiles!");
                 e.printStackTrace();
@@ -159,29 +161,23 @@ public class SetupUtil {
         }
     }
 
-    private static void copyFolder(String resource, String outputFolder) throws IOException {
-        copyResourcesToDirectory(jarForClass(MissileWars.class, null), resource, outputFolder);
-    }
-
-    public static void copyZip(String resource, String outputFolder) throws IOException {
-        File out = new File(MissileWars.getInstance().getDataFolder(), resource);
-
+    public static void copyAndUnzip(String resource, String outputFolder) throws IOException {
         InputStream in = JavaPlugin.getPlugin(MissileWars.class).getResource(resource);
 
-        Files.copy(in, out.toPath());
-
-        unzip(out.getPath(), outputFolder);
-
-        // delete the ZIP files after server stopping
-        out.deleteOnExit();
+        unzip(in, outputFolder);
     }
 
-    public static void unzip(String zipFilePath, String destDirectory) throws IOException {
+    public static void unzip(InputStream inputStream, String destDirectory) throws IOException {
+        if (inputStream == null) {
+            return;
+        }
+
         File destDir = new File(destDirectory);
         if (!destDir.exists()) {
             destDir.mkdir();
         }
-        ZipInputStream zipIn = new ZipInputStream(new FileInputStream(zipFilePath));
+
+        ZipInputStream zipIn = new ZipInputStream(inputStream);
 
         ZipEntry entry = zipIn.getNextEntry();
         // iterates over entries in the zip file
@@ -216,52 +212,4 @@ public class SetupUtil {
         }
         bos.close();
     }
-
-    public static JarFile jarForClass(Class<?> clazz, JarFile defaultJar) {
-        String path = "/" + clazz.getName().replace('.', '/') + ".class";
-        URL jarUrl = clazz.getResource(path);
-        if (jarUrl == null) {
-            return defaultJar;
-        }
-
-        String url = jarUrl.toString();
-        int bang = url.indexOf("!");
-        String JAR_URI_PREFIX = "jar:file:";
-        if (url.startsWith(JAR_URI_PREFIX) && bang != -1) {
-            try {
-                return new JarFile(url.substring(JAR_URI_PREFIX.length(), bang));
-            } catch (IOException e) {
-                throw new IllegalStateException("Error loading jar file.", e);
-            }
-        } else {
-            return defaultJar;
-        }
-    }
-
-    /**
-     * Copies a directory from a jar file to an external directory.
-     */
-    public static void copyResourcesToDirectory(JarFile fromJar, String jarDir, String destDir) throws IOException {
-        for (Enumeration<JarEntry> entries = fromJar.entries(); entries.hasMoreElements(); ) {
-            JarEntry entry = entries.nextElement();
-            if (entry.getName().startsWith(jarDir + "/") && !entry.isDirectory()) {
-                File dest = new File(destDir + "/" + entry.getName().substring(jarDir.length() + 1));
-                File parent = dest.getParentFile();
-                if (parent != null) {
-                    parent.mkdirs();
-                }
-
-                try (FileOutputStream out = new FileOutputStream(dest); InputStream in = fromJar.getInputStream(entry)) {
-                    byte[] buffer = new byte[8 * 1024];
-
-                    int s;
-                    while ((s = in.read(buffer)) > 0) {
-                        out.write(buffer, 0, s);
-                    }
-                } catch (IOException e) {
-                    throw new IOException("Could not copy asset from jar file", e);
-                }
-            }
-        }
-    }
 }

+ 1 - 1
missilewars-plugin/src/main/java/de/butzlabben/missilewars/util/geometry/GameArea.java

@@ -27,7 +27,7 @@ import org.bukkit.World;
 @Getter
 public class GameArea {
 
-    private World world;
+    private final World world;
     @Setter private Location position1, position2;
 
     private int minX, minY, minZ;

+ 24 - 9
missilewars-plugin/src/main/java/de/butzlabben/missilewars/util/stats/GameProfileBuilder.java

@@ -18,21 +18,32 @@
 
 package de.butzlabben.missilewars.util.stats;
 
-import com.google.gson.*;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonDeserializationContext;
+import com.google.gson.JsonDeserializer;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParseException;
+import com.google.gson.JsonSerializationContext;
+import com.google.gson.JsonSerializer;
 import com.mojang.authlib.GameProfile;
 import com.mojang.authlib.properties.Property;
 import com.mojang.authlib.properties.PropertyMap;
 import com.mojang.util.UUIDTypeAdapter;
-import lombok.Getter;
-import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder;
-
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.lang.reflect.Type;
 import java.net.URL;
 import java.net.URLConnection;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import lombok.Getter;
+import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder;
 
 /**
  * @author Butzlabben
@@ -59,14 +70,17 @@ public class GameProfileBuilder {
         }
 
         String json = getText(String.format("https://sessionserver.mojang.com/session/minecraft/profile/%s?unsigned=false",
-                UUIDTypeAdapter.fromUUID(uuid)));
+                uuid.toString().replace("-", "")));
 
         try {
             GameProfile result = gson.fromJson(json, GameProfile.class);
+            if (result == null) {
+                throw new IllegalStateException("Serialized game profile lookup result for UUID " + uuid + " is null");
+            }
             cache.put(uuid, new CachedProfile(result));
             return result;
         } catch (Exception exception) {
-            throw new IOException("Could not read response: " + json);
+            throw new IOException("Could not read response: " + json, exception);
         }
     }
 
@@ -80,7 +94,7 @@ public class GameProfileBuilder {
 
         List<Object> args = new ArrayList<>();
         args.add(System.currentTimeMillis());
-        args.add(UUIDTypeAdapter.fromUUID(uuid));
+        args.add(uuid.toString().replaceAll("-", ""));
         args.add(name);
         args.add(skinUrl);
         if (cape) {
@@ -150,11 +164,12 @@ public class GameProfileBuilder {
         }
     }
 
+    @Getter
     public static class CachedProfile {
 
-        @Getter
         private final GameProfile profile;
 
+
         public CachedProfile(GameProfile profile) {
             this.profile = profile;
         }

+ 23 - 25
missilewars-plugin/src/main/java/de/butzlabben/missilewars/util/stats/PlayerGuiFactory.java

@@ -62,8 +62,7 @@ public class PlayerGuiFactory {
             if (offlinePlayer.getName() != null) {
                 names.put(stat.getUuid(), offlinePlayer.getName());
                 stat.setName(offlinePlayer.getName());
-            }
-            if (GameProfileBuilder.getCache().containsKey(stat.getUuid())) {
+            } else if (GameProfileBuilder.getCache().containsKey(stat.getUuid())) {
                 String name = GameProfileBuilder.getCache().get(stat.getUuid()).getProfile().getName();
                 names.put(stat.getUuid(), name);
                 stat.setName(name);
@@ -74,34 +73,33 @@ public class PlayerGuiFactory {
     public void openWhenReady(Player player) {
         int realSize = stats.size();
         int currentSize = names.size();
-        if (realSize > currentSize) {
-            if (Config.isContactAuth()) {
-                player.sendMessage(Messages.getMessage(true, Messages.MessageEnum.STATS_FETCHING_PLAYERS)
-                        .replace("%current_size%", Integer.toString(currentSize))
-                        .replace("%real_size%", Integer.toString(realSize)));
-                ForkJoinPool.commonPool().execute(() -> {
-                    List<UUID> missing = getMissingUUIDs();
-                    int maxFetches = Math.min(missing.size(), MAX_FETCHES);
-                    for (int i = 0; i < maxFetches; i++) {
-                        UUID uuid = missing.get(i);
-                        try {
-                            GameProfile profile = GameProfileBuilder.fetch(uuid);
-                            names.put(uuid, profile.getName());
-                        } catch (IOException e) {
-                            names.put(uuid, "Error getting name");
-                            if (!e.getMessage().contains("Could not connect to mojang servers for unknown player"))
-                                Logger.WARN.log("Could not fetch name for " + uuid.toString() + ". Reason: " + e.getMessage());
-                        }
+        if (realSize > currentSize && Config.isContactAuth()) {
+            player.sendMessage(Messages.getMessage(true, Messages.MessageEnum.STATS_FETCHING_PLAYERS)
+                    .replace("%current_size%", Integer.toString(currentSize))
+                    .replace("%real_size%", Integer.toString(realSize)));
+            ForkJoinPool.commonPool().execute(() -> {
+                List<UUID> missing = getMissingUUIDs();
+                int maxFetches = Math.min(missing.size(), MAX_FETCHES);
+                for (int i = 0; i < maxFetches; i++) {
+                    UUID uuid = missing.get(i);
+                    try {
+                        GameProfile profile = GameProfileBuilder.fetch(uuid);
+                        names.put(uuid, profile.getName());
+                    } catch (IOException e) {
+                        names.put(uuid, "Error getting name");
+                        if (!e.getMessage().contains("Could not connect to mojang servers for unknown player"))
+                            Logger.WARN.log("Could not fetch name for " + uuid.toString() + ". Reason: " + e.getMessage());
                     }
+                }
 
-                    openWhenReady(player);
-                });
-                return;
-            }
+                openWhenReady(player);
+            });
+            return;
         }
+
         for (PlayerStats stat : stats) {
             stat.setName(names.get(stat.getUuid()));
-            if (stat.getName() == null || stat.getName().equals("")) {
+            if (stat.getName() == null || stat.getName().isEmpty()) {
                 Logger.WARN.log("Could not find name for: " + stat.getUuid());
             }
         }

BIN
missilewars-plugin/src/main/resources/Dam-Arena.zip


BIN
missilewars-plugin/src/main/resources/missiles.zip