Răsfoiți Sursa

Undoing changes

RedstoneFuture 1 an în urmă
părinte
comite
d81e301cf2
26 a modificat fișierele cu 223 adăugiri și 200 ștergeri
  1. 3 0
      README.md
  2. 2 2
      missilewars-plugin/pom.xml
  3. 8 2
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/MissileWars.java
  4. 19 26
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/commands/StatsCommands.java
  5. 8 2
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/configuration/Lobby.java
  6. 0 4
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/configuration/arena/MissileConfiguration.java
  7. 4 11
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/Arenas.java
  8. 22 39
      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. 12 1
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/GameWorld.java
  11. 8 5
      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. 16 20
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/misc/ScoreboardManager.java
  16. 1 0
      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. 2 9
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/listener/PlayerListener.java
  21. 73 21
      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. 9 24
      missilewars-plugin/src/main/java/de/butzlabben/missilewars/util/stats/GameProfileBuilder.java
  24. 25 23
      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

+ 3 - 0
README.md

@@ -7,6 +7,9 @@ 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 (
 You can download the latest jar in the [latest release](https://github.com/Butzlabben/missilewars/releases/latest) or build it yourself (
 see [BUILDING](#building))
 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
 ## Building
 
 
 To build MissileWars, you need to install the Java 17 JDK. Then you can build it via the Maven Wrapper.
 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>
         <version>1.0</version>
     </parent>
     </parent>
 
 
-    <version>4.6.0</version>
+    <version>4.5.3</version>
 
 
     <modelVersion>4.0.0</modelVersion>
     <modelVersion>4.0.0</modelVersion>
 
 
@@ -117,7 +117,7 @@
         <dependency>
         <dependency>
             <groupId>com.mojang</groupId>
             <groupId>com.mojang</groupId>
             <artifactId>authlib</artifactId>
             <artifactId>authlib</artifactId>
-            <version>4.0.43</version>
+            <version>1.5.25</version>
             <scope>provided</scope>
             <scope>provided</scope>
         </dependency>
         </dependency>
 
 

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

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

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

@@ -47,7 +47,6 @@ import java.util.stream.Collectors;
 import org.bukkit.Material;
 import org.bukkit.Material;
 import org.bukkit.command.CommandSender;
 import org.bukkit.command.CommandSender;
 import org.bukkit.entity.Player;
 import org.bukkit.entity.Player;
-import org.jetbrains.annotations.NotNull;
 
 
 @CommandAlias("mw|missilewars")
 @CommandAlias("mw|missilewars")
 @Subcommand("stats")
 @Subcommand("stats")
@@ -59,28 +58,6 @@ public class StatsCommands extends BaseCommand {
     private final SimpleDateFormat format = new SimpleDateFormat("dd.MM.yyyy");
     private final SimpleDateFormat format = new SimpleDateFormat("dd.MM.yyyy");
     private final SimpleDateFormat preciseFormat = new SimpleDateFormat("hh:mm 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
     @Default
     @CommandPermission("mw.stats")
     @CommandPermission("mw.stats")
     public void onStats(CommandSender sender, String[] args) {
     public void onStats(CommandSender sender, String[] args) {
@@ -95,7 +72,7 @@ public class StatsCommands extends BaseCommand {
         PreFetcher.PrePlayerFetchRunnable preFetchRunnable = PreFetcher.preFetchPlayers(fetcher);
         PreFetcher.PrePlayerFetchRunnable preFetchRunnable = PreFetcher.preFetchPlayers(fetcher);
 
 
         CustomInv inv = new CustomInv("§eMissileWars statistics", 3);
         CustomInv inv = new CustomInv("§eMissileWars statistics", 3);
-        List<String> criteriaLore = Arrays.asList("§7Statistics since: §e" + format.format(fetcher.getFrom()), "§7Specified arena: §e" + (arena.isEmpty() ? "any" : arena));
+        List<String> criteriaLore = Arrays.asList("§7Statistics since: §e" + format.format(fetcher.getFrom()), "§7Specified arena: §e" + (arena.equals("") ? "any" : arena));
         inv.addItem(4, new OrcItem(Material.FEATHER, "§aStatistics search criteria", criteriaLore));
         inv.addItem(4, new OrcItem(Material.FEATHER, "§aStatistics search criteria", criteriaLore));
 
 
         int gameCount = fetcher.getGameCount();
         int gameCount = fetcher.getGameCount();
@@ -144,10 +121,26 @@ public class StatsCommands extends BaseCommand {
         if (fetcher == null) return;
         if (fetcher == null) return;
         SavedStats avgStatsWithDraws = fetcher.getAverageSavedStats(false);
         SavedStats avgStatsWithDraws = fetcher.getAverageSavedStats(false);
         SavedStats avgStatsWithoutDraws = fetcher.getAverageSavedStats(true);
         SavedStats avgStatsWithoutDraws = fetcher.getAverageSavedStats(true);
-        List<String> recommendations = generateRecommendations(fetcher, 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");
+        }
         // TODO implement more features
         // TODO implement more features
 
 
-        if (recommendations.isEmpty()) {
+        if (recommendations.size() == 0) {
             player.sendMessage(Messages.getPrefix() + "§aThere are currently no recommendations, everything seems fine :)");
             player.sendMessage(Messages.getPrefix() + "§aThere are currently no recommendations, everything seems fine :)");
         } else {
         } else {
             player.sendMessage(Messages.getPrefix() + "§7=====[ §eMissileWars recommendations §7]=====");
             player.sendMessage(Messages.getPrefix() + "§7=====[ §eMissileWars recommendations §7]=====");

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

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

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

@@ -54,10 +54,6 @@ public class MissileConfiguration {
         add(new Missile("Juggernaut.schematic", "&4Juggernaut", EntityType.MUSHROOM_COW, 2, 2, 1));
         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("Piranha.schematic", "&3Piranha", EntityType.HORSE, 2, 2, 3));
         add(new Missile("Tunnelbore.schematic", "&0Tunnelbore", EntityType.ENDERMAN, 2, 2, 1));
         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() {
     public List<MissileFacing> getEnabledFacings() {

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

@@ -24,12 +24,13 @@ import de.butzlabben.missilewars.configuration.Config;
 import de.butzlabben.missilewars.configuration.arena.Arena;
 import de.butzlabben.missilewars.configuration.arena.Arena;
 import de.butzlabben.missilewars.util.SetupUtil;
 import de.butzlabben.missilewars.util.SetupUtil;
 import de.butzlabben.missilewars.util.serialization.Serializer;
 import de.butzlabben.missilewars.util.serialization.Serializer;
+import lombok.Getter;
+import org.bukkit.Bukkit;
+
 import java.io.File;
 import java.io.File;
 import java.io.IOException;
 import java.io.IOException;
 import java.util.HashMap;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Map;
-import lombok.Getter;
-import org.bukkit.Bukkit;
 
 
 public class Arenas {
 public class Arenas {
 
 
@@ -58,17 +59,9 @@ public class Arenas {
                 Bukkit.getPluginManager().disablePlugin(MissileWars.getInstance());
                 Bukkit.getPluginManager().disablePlugin(MissileWars.getInstance());
                 return;
                 return;
             }
             }
-
-            // 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 = new File[] {defaultArena};
         }
         }
 
 
-        files = folder.listFiles();
         for (File config : files) {
         for (File config : files) {
             if (!config.getName().endsWith(".yml") && !config.getName().endsWith(".yaml")) continue;
             if (!config.getName().endsWith(".yml") && !config.getName().endsWith(".yaml")) continue;
             try {
             try {

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

@@ -52,19 +52,9 @@ import de.butzlabben.missilewars.util.PlayerDataProvider;
 import de.butzlabben.missilewars.util.geometry.GameArea;
 import de.butzlabben.missilewars.util.geometry.GameArea;
 import de.butzlabben.missilewars.util.geometry.Geometry;
 import de.butzlabben.missilewars.util.geometry.Geometry;
 import de.butzlabben.missilewars.util.serialization.Serializer;
 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.Getter;
 import lombok.ToString;
 import lombok.ToString;
-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.*;
 import org.bukkit.entity.Fireball;
 import org.bukkit.entity.Fireball;
 import org.bukkit.entity.Player;
 import org.bukkit.entity.Player;
 import org.bukkit.event.HandlerList;
 import org.bukkit.event.HandlerList;
@@ -73,6 +63,12 @@ import org.bukkit.inventory.ItemStack;
 import org.bukkit.scheduler.BukkitTask;
 import org.bukkit.scheduler.BukkitTask;
 import org.bukkit.util.Vector;
 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
  * @author Butzlabben
  * @since 01.01.2018
  * @since 01.01.2018
@@ -121,7 +117,7 @@ public class Game {
             return;
             return;
         }
         }
 
 
-        if (lobby.getPossibleArenas().isEmpty()) {
+        if (lobby.getPossibleArenas().size() == 0) {
             Logger.ERROR.log("At least one valid arena must be set at lobby \"" + lobby.getName() + "\".");
             Logger.ERROR.log("At least one valid arena must be set at lobby \"" + lobby.getName() + "\".");
             return;
             return;
         }
         }
@@ -167,7 +163,7 @@ public class Game {
         } else if (lobby.getMapChooseProcedure() == MapChooseProcedure.MAPCYCLE) {
         } else if (lobby.getMapChooseProcedure() == MapChooseProcedure.MAPCYCLE) {
             final int lastMapIndex = cycles.getOrDefault(lobby.getName(), -1);
             final int lastMapIndex = cycles.getOrDefault(lobby.getName(), -1);
             List<Arena> arenas = lobby.getArenas();
             List<Arena> arenas = lobby.getArenas();
-            int index = (lastMapIndex + 1) % arenas.size();
+            int index = lastMapIndex >= arenas.size() - 1 ? 0 : lastMapIndex + 1;
             cycles.put(lobby.getName(), index);
             cycles.put(lobby.getName(), index);
             setArena(arenas.get(index));
             setArena(arenas.get(index));
             prepareGame();
             prepareGame();
@@ -183,14 +179,6 @@ 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);
-        }
     }
     }
 
 
     /**
     /**
@@ -307,7 +295,7 @@ public class Game {
         Bukkit.getPluginManager().callEvent(new GameStopEvent(this));
         Bukkit.getPluginManager().callEvent(new GameStopEvent(this));
     }
     }
 
 
-    public void triggerRestart() {
+    public void reset() {
         if (Config.isSetup()) return;
         if (Config.isSetup()) return;
 
 
         if (restart) {
         if (restart) {
@@ -413,8 +401,10 @@ public class Game {
         Team team = mwPlayer.getTeam();
         Team team = mwPlayer.getTeam();
         boolean playerWasTeamMember = false;
         boolean playerWasTeamMember = false;
 
 
-        BukkitTask task = playerTasks.get(mwPlayer.getUuid());
-        if (task != null) task.cancel();
+        if (state == GameState.INGAME) {
+            BukkitTask task = playerTasks.get(mwPlayer.getUuid());
+            if (task != null) task.cancel();
+        }
 
 
         PlayerDataProvider.getInstance().loadInventory(player);
         PlayerDataProvider.getInstance().loadInventory(player);
 
 
@@ -486,12 +476,6 @@ public class Game {
         HandlerList.unregisterAll(listener);
         HandlerList.unregisterAll(listener);
         taskManager.stopTimer();
         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) {
         if (gameWorld != null) {
             gameWorld.unload();
             gameWorld.unload();
             gameWorld.delete();
             gameWorld.delete();
@@ -665,7 +649,7 @@ public class Game {
         itemStack.setAmount(amount - 1);
         itemStack.setAmount(amount - 1);
 
 
         Fireball fb = player.launchProjectile(Fireball.class);
         Fireball fb = player.launchProjectile(Fireball.class);
-        fb.setDirection(player.getLocation().getDirection().multiply(2.5D));
+        fb.setVelocity(player.getLocation().getDirection().multiply(2.5D));
         player.playSound(fb.getLocation(), Sound.BLOCK_ANVIL_LAND, 100.0F, 2.0F);
         player.playSound(fb.getLocation(), Sound.BLOCK_ANVIL_LAND, 100.0F, 2.0F);
         player.playSound(fb.getLocation(), Sound.ITEM_FLINTANDSTEEL_USE, 100.0F, 1.0F);
         player.playSound(fb.getLocation(), Sound.ITEM_FLINTANDSTEEL_USE, 100.0F, 1.0F);
         fb.setYield(3F);
         fb.setYield(3F);
@@ -679,7 +663,7 @@ public class Game {
         }
         }
 
 
         arena.getMissileConfiguration().check();
         arena.getMissileConfiguration().check();
-        if (arena.getMissileConfiguration().getMissiles().isEmpty()) {
+        if (arena.getMissileConfiguration().getMissiles().size() == 0) {
             throw new IllegalStateException("The game cannot be started, when 0 missiles are configured");
             throw new IllegalStateException("The game cannot be started, when 0 missiles are configured");
         }
         }
 
 
@@ -827,21 +811,20 @@ 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.
      * considered acceptable.
-     *
+     * 
      * @param targetTeam the new team
      * @param targetTeam the new team
-     *
      * @return (boolean) 'true' if it's a fair team switch
      * @return (boolean) 'true' if it's a fair team switch
      */
      */
     public boolean isValidTeamSwitch(Team targetTeam) {
     public boolean isValidTeamSwitch(Team targetTeam) {
-
+        
         // original team sizes
         // original team sizes
         int targetTeamSize = targetTeam.getMembers().size();
         int targetTeamSize = targetTeam.getMembers().size();
         int currentTeamSize = targetTeam.getEnemyTeam().getMembers().size();
         int currentTeamSize = targetTeam.getEnemyTeam().getMembers().size();
-
+        
         // Preventing an empty team when previously both teams had at least one player:
         // Preventing an empty team when previously both teams had at least one player:
         if ((currentTeamSize == 1) && (targetTeamSize >= 1)) return false;
         if ((currentTeamSize == 1) && (targetTeamSize >= 1)) return false;
 
 

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

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

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

@@ -20,6 +20,7 @@ package de.butzlabben.missilewars.game;
 
 
 import de.butzlabben.missilewars.Logger;
 import de.butzlabben.missilewars.Logger;
 import de.butzlabben.missilewars.configuration.Config;
 import de.butzlabben.missilewars.configuration.Config;
+import de.butzlabben.missilewars.configuration.Messages;
 import java.io.File;
 import java.io.File;
 import java.io.IOException;
 import java.io.IOException;
 import lombok.Getter;
 import lombok.Getter;
@@ -60,6 +61,16 @@ public class GameWorld {
         return Bukkit.getWorld(worldName);
         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() {
     public void unload() {
         synchronized (lock) {
         synchronized (lock) {
             World w = Bukkit.getWorld(worldName);
             World w = Bukkit.getWorld(worldName);
@@ -84,7 +95,7 @@ public class GameWorld {
             FileUtils.deleteQuietly(file);
             FileUtils.deleteQuietly(file);
             if (file.exists() || file.isDirectory()) {
             if (file.exists() || file.isDirectory()) {
                 Logger.WARN.log("Could not delete old world!");
                 Logger.WARN.log("Could not delete old world!");
-                file.deleteOnExit();
+                file.delete();
             }
             }
         }
         }
     }
     }

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

@@ -23,17 +23,18 @@ import de.butzlabben.missilewars.configuration.arena.Arena;
 import de.butzlabben.missilewars.game.enums.MapChooseProcedure;
 import de.butzlabben.missilewars.game.enums.MapChooseProcedure;
 import de.butzlabben.missilewars.game.enums.VoteState;
 import de.butzlabben.missilewars.game.enums.VoteState;
 import de.butzlabben.missilewars.player.MWPlayer;
 import de.butzlabben.missilewars.player.MWPlayer;
+import lombok.Getter;
+import org.bukkit.entity.Player;
+
 import java.util.HashMap;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Map;
 import java.util.function.Function;
 import java.util.function.Function;
 import java.util.stream.Collectors;
 import java.util.stream.Collectors;
-import lombok.Getter;
-import org.bukkit.entity.Player;
 
 
 public class MapVoting {
 public class MapVoting {
 
 
     private final Map<MWPlayer, Arena> arenaVotes = new HashMap<>();
     private final Map<MWPlayer, Arena> arenaVotes = new HashMap<>();
-    private final Game game;
+    private Game game;
     @Getter private VoteState state = VoteState.NULL;
     @Getter private VoteState state = VoteState.NULL;
 
 
     public MapVoting(Game game) {
     public MapVoting(Game game) {
@@ -102,13 +103,15 @@ public class MapVoting {
     private Arena getVotedArena() {
     private Arena getVotedArena() {
 
 
         // If no one voted:
         // If no one voted:
-        if (arenaVotes.isEmpty()) return game.getLobby().getArenas().get(0);
+        if (arenaVotes.size() == 0) return game.getLobby().getArenas().get(0);
 
 
-        return arenaVotes.values().stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
+        Arena arena = arenaVotes.values().stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
                 .entrySet()
                 .entrySet()
                 .stream()
                 .stream()
                 .max(Map.Entry.comparingByValue()).orElseThrow()
                 .max(Map.Entry.comparingByValue()).orElseThrow()
                 .getKey();
                 .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 final Game game;
 
 
-    private final List<Missile> missileEquipmentList = new ArrayList<>();
+    private List<Missile> missileEquipmentList = new ArrayList<>();
 
 
 
 
     public MissileGameEquipment(Game game) {
     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 arrow;
     private ItemStack fireball;
     private ItemStack fireball;
 
 
-    private final List<ItemStack> specialEquipmentList = new ArrayList<>();
+    private List<ItemStack> specialEquipmentList = new ArrayList<>();
 
 
 
 
     public SpecialGameEquipment(Game game) {
     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
     @EventHandler
     public void onSneak(PlayerToggleSneakEvent e) {
     public void onSneak(PlayerToggleSneakEvent e) {
         Player eventPlayer = e.getPlayer();
         Player eventPlayer = e.getPlayer();
-        if (eventPlayer == player && (!map.isEmpty()) && (eventPlayer.isSneaking())) {
+        if (eventPlayer == player && (map.size() != 0) && (eventPlayer.isSneaking())) {
             for (Location loc : map.keySet()) {
             for (Location loc : map.keySet()) {
                 loc.getBlock().setType(map.get(loc).getKey());
                 loc.getBlock().setType(map.get(loc).getKey());
                 BlockSetterProvider.getBlockDataSetter().setData(loc.getBlock(), map.get(loc).getValue());
                 BlockSetterProvider.getBlockDataSetter().setData(loc.getBlock(), map.get(loc).getValue());

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

@@ -23,9 +23,6 @@ import de.butzlabben.missilewars.game.Game;
 import de.butzlabben.missilewars.game.Team;
 import de.butzlabben.missilewars.game.Team;
 import de.butzlabben.missilewars.game.enums.GameState;
 import de.butzlabben.missilewars.game.enums.GameState;
 import de.butzlabben.missilewars.player.MWPlayer;
 import de.butzlabben.missilewars.player.MWPlayer;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
 import lombok.Getter;
 import lombok.Getter;
 import lombok.RequiredArgsConstructor;
 import lombok.RequiredArgsConstructor;
 import lombok.Setter;
 import lombok.Setter;
@@ -35,6 +32,10 @@ import org.bukkit.scoreboard.DisplaySlot;
 import org.bukkit.scoreboard.Objective;
 import org.bukkit.scoreboard.Objective;
 import org.bukkit.scoreboard.Scoreboard;
 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
 // Scoreboard Management: https://www.spigotmc.org/wiki/making-scoreboard-with-teams-no-flicker
 
 
 @RequiredArgsConstructor
 @RequiredArgsConstructor
@@ -61,7 +62,7 @@ public class ScoreboardManager {
 
 
     @Getter private Scoreboard board;
     @Getter private Scoreboard board;
     private Objective obj;
     private Objective obj;
-    private final Map<Integer, org.bukkit.scoreboard.Team> teams = new HashMap<>();
+    private 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"};
     private static final String[] COLOR_CODES = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};
 
 
     /**
     /**
@@ -243,7 +244,17 @@ public class ScoreboardManager {
      */
      */
     private String replaceScoreboardPlaceholders(String text) {
     private String replaceScoreboardPlaceholders(String text) {
 
 
-        String time = 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);
+        }
 
 
 
 
         text = ChatColor.translateAlternateColorCodes('&', text);
         text = ChatColor.translateAlternateColorCodes('&', text);
@@ -265,19 +276,4 @@ public class ScoreboardManager {
         return text;
         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;
-    }
-
 }
 }

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

@@ -38,6 +38,7 @@ import org.bukkit.util.Vector;
  * @author Butzlabben
  * @author Butzlabben
  * @since 06.01.2018
  * @since 06.01.2018
  */
  */
+@SuppressWarnings("deprecation")
 @RequiredArgsConstructor
 @RequiredArgsConstructor
 public class Missile {
 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)));
                 broadcast(Messages.getMessage(true, Messages.MessageEnum.ENDGAME_TIMER_GAME_STARTS_NEW_IN).replace("%seconds%", Integer.toString(seconds)));
                 break;
                 break;
             case 0:
             case 0:
-                getGame().triggerRestart();
+                getGame().reset();
                 break;
                 break;
             default:
             default:
                 break;
                 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
     @Override
     public void tick() {
     public void tick() {
-        if (getGame().getPlayers().isEmpty()) return;
+        if (getGame().getPlayers().size() == 0) return;
 
 
         for (MWPlayer mwPlayer : getGame().getPlayers().values()) {
         for (MWPlayer mwPlayer : getGame().getPlayers().values()) {
             if (mwPlayer.getPlayer() == null) continue;
             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) {
     public void show(Player p) {
         List<OrcItem> items = elements.stream().map(converter::convert).collect(Collectors.toList());
         List<OrcItem> items = elements.stream().map(converter::convert).collect(Collectors.toList());
-        if (items.isEmpty())
+        if (items.size() == 0)
             return;
             return;
 
 
         int pages = (int) (Math.ceil((items.size() / (double) elementsPerPage) < 1 ? 1 : Math.ceil((double) items.size() / (double) elementsPerPage)));
         int pages = (int) (Math.ceil((items.size() / (double) elementsPerPage) < 1 ? 1 : Math.ceil((double) items.size() / (double) elementsPerPage)));

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

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

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

@@ -23,20 +23,18 @@ import de.butzlabben.missilewars.MissileWars;
 import de.butzlabben.missilewars.configuration.Config;
 import de.butzlabben.missilewars.configuration.Config;
 import de.butzlabben.missilewars.configuration.arena.Arena;
 import de.butzlabben.missilewars.configuration.arena.Arena;
 import de.butzlabben.missilewars.game.Arenas;
 import de.butzlabben.missilewars.game.Arenas;
-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 org.bukkit.configuration.file.YamlConfiguration;
+import org.bukkit.plugin.java.JavaPlugin;
+
+import java.io.*;
+import java.net.URL;
 import java.nio.charset.StandardCharsets;
 import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 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.ZipEntry;
 import java.util.zip.ZipInputStream;
 import java.util.zip.ZipInputStream;
-import org.bukkit.configuration.file.YamlConfiguration;
-import org.bukkit.plugin.java.JavaPlugin;
 
 
 /**
 /**
  * @author Butzlabben
  * @author Butzlabben
@@ -124,7 +122,7 @@ public class SetupUtil {
             Logger.BOOT.log("Copying default map (" + resource + ")");
             Logger.BOOT.log("Copying default map (" + resource + ")");
 
 
             try {
             try {
-                copyAndUnzip(resource, file.getPath());
+                copyZip(resource, file.getPath());
             } catch (IOException e) {
             } catch (IOException e) {
                 Logger.ERROR.log("Unable to copy new map!");
                 Logger.ERROR.log("Unable to copy new map!");
                 e.printStackTrace();
                 e.printStackTrace();
@@ -140,7 +138,7 @@ public class SetupUtil {
             Logger.BOOT.log("Copying default missiles folder (" + resource + ")");
             Logger.BOOT.log("Copying default missiles folder (" + resource + ")");
 
 
             try {
             try {
-                copyAndUnzip(resource, file.getPath());
+                copyZip(resource, file.getPath());
             } catch (IOException e) {
             } catch (IOException e) {
                 Logger.ERROR.log("Unable to copy missiles!");
                 Logger.ERROR.log("Unable to copy missiles!");
                 e.printStackTrace();
                 e.printStackTrace();
@@ -161,23 +159,29 @@ public class SetupUtil {
         }
         }
     }
     }
 
 
-    public static void copyAndUnzip(String resource, String outputFolder) throws IOException {
+    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);
+
         InputStream in = JavaPlugin.getPlugin(MissileWars.class).getResource(resource);
         InputStream in = JavaPlugin.getPlugin(MissileWars.class).getResource(resource);
 
 
-        unzip(in, outputFolder);
-    }
+        Files.copy(in, out.toPath());
 
 
-    public static void unzip(InputStream inputStream, String destDirectory) throws IOException {
-        if (inputStream == null) {
-            return;
-        }
+        unzip(out.getPath(), outputFolder);
+
+        // delete the ZIP files after server stopping
+        out.deleteOnExit();
+    }
 
 
+    public static void unzip(String zipFilePath, String destDirectory) throws IOException {
         File destDir = new File(destDirectory);
         File destDir = new File(destDirectory);
         if (!destDir.exists()) {
         if (!destDir.exists()) {
             destDir.mkdir();
             destDir.mkdir();
         }
         }
-
-        ZipInputStream zipIn = new ZipInputStream(inputStream);
+        ZipInputStream zipIn = new ZipInputStream(new FileInputStream(zipFilePath));
 
 
         ZipEntry entry = zipIn.getNextEntry();
         ZipEntry entry = zipIn.getNextEntry();
         // iterates over entries in the zip file
         // iterates over entries in the zip file
@@ -212,4 +216,52 @@ public class SetupUtil {
         }
         }
         bos.close();
         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
 @Getter
 public class GameArea {
 public class GameArea {
 
 
-    private final World world;
+    private World world;
     @Setter private Location position1, position2;
     @Setter private Location position1, position2;
 
 
     private int minX, minY, minZ;
     private int minX, minY, minZ;

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

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

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

@@ -62,7 +62,8 @@ public class PlayerGuiFactory {
             if (offlinePlayer.getName() != null) {
             if (offlinePlayer.getName() != null) {
                 names.put(stat.getUuid(), offlinePlayer.getName());
                 names.put(stat.getUuid(), offlinePlayer.getName());
                 stat.setName(offlinePlayer.getName());
                 stat.setName(offlinePlayer.getName());
-            } else if (GameProfileBuilder.getCache().containsKey(stat.getUuid())) {
+            }
+            if (GameProfileBuilder.getCache().containsKey(stat.getUuid())) {
                 String name = GameProfileBuilder.getCache().get(stat.getUuid()).getProfile().getName();
                 String name = GameProfileBuilder.getCache().get(stat.getUuid()).getProfile().getName();
                 names.put(stat.getUuid(), name);
                 names.put(stat.getUuid(), name);
                 stat.setName(name);
                 stat.setName(name);
@@ -73,33 +74,34 @@ public class PlayerGuiFactory {
     public void openWhenReady(Player player) {
     public void openWhenReady(Player player) {
         int realSize = stats.size();
         int realSize = stats.size();
         int currentSize = names.size();
         int currentSize = names.size();
-        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());
+        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());
+                        }
                     }
                     }
-                }
 
 
-                openWhenReady(player);
-            });
-            return;
+                    openWhenReady(player);
+                });
+                return;
+            }
         }
         }
-
         for (PlayerStats stat : stats) {
         for (PlayerStats stat : stats) {
             stat.setName(names.get(stat.getUuid()));
             stat.setName(names.get(stat.getUuid()));
-            if (stat.getName() == null || stat.getName().isEmpty()) {
+            if (stat.getName() == null || stat.getName().equals("")) {
                 Logger.WARN.log("Could not find name for: " + stat.getUuid());
                 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