From ce060a26bfa95a695f64651bc8508f5c5a3ac617 Mon Sep 17 00:00:00 2001 From: LunarAkai Date: Wed, 20 Mar 2024 16:52:25 +0100 Subject: [PATCH] progress? --- pom.xml | 26 +- .../de/lunarakai/minecleaner/ArenaList.java | 63 ++++- .../minecleaner/MinecleanerArena.java | 225 ++++++++++++++++-- .../minecleaner/MinecleanerListener.java | 1 + .../minecleaner/MinecleanerManager.java | 50 ++++ .../minecleaner/MinecleanerPlugin.java | 41 +++- .../minecleaner/PlayerStatisticsData.java | 34 +++ .../minecleaner/commands/CreateCommand.java | 156 ++++++++++++ .../minecleaner/commands/DeleteCommand.java | 67 ++++++ .../minecleaner/commands/ListCommand.java | 61 +++++ .../minecleaner/commands/StatsCommand.java | 71 ++++++ .../lunarakai/minecleaner/game/BoardSize.java | 16 +- .../de/lunarakai/minecleaner/game/Game.java | 4 +- 13 files changed, 758 insertions(+), 57 deletions(-) create mode 100644 src/main/java/de/lunarakai/minecleaner/PlayerStatisticsData.java create mode 100644 src/main/java/de/lunarakai/minecleaner/commands/CreateCommand.java create mode 100644 src/main/java/de/lunarakai/minecleaner/commands/DeleteCommand.java create mode 100644 src/main/java/de/lunarakai/minecleaner/commands/ListCommand.java create mode 100644 src/main/java/de/lunarakai/minecleaner/commands/StatsCommand.java diff --git a/pom.xml b/pom.xml index e861afd..40adcf4 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ Minecleaner - 1.8 + 1.21 UTF-8 @@ -23,8 +23,8 @@ maven-compiler-plugin 3.8.1 - 16 - 16 + 17 + 17 @@ -54,8 +54,8 @@ - spigotmc-repo - https://hub.spigotmc.org/nexus/content/repositories/snapshots/ + papermc + https://repo.papermc.io/repository/maven-public/ sonatype @@ -69,8 +69,8 @@ - org.spigotmc - spigot-api + io.papermc.paper + paper-api 1.20.4-R0.1-SNAPSHOT provided @@ -80,5 +80,17 @@ 1.16-SNAPSHOT provided + + de.iani.cubeside + CubesideStatistics + 1.0.0-SNAPSHOT + provided + + + de.iani.cubeside + PlayerUUIDCache + 2.0.0-SNAPSHOT + provided + diff --git a/src/main/java/de/lunarakai/minecleaner/ArenaList.java b/src/main/java/de/lunarakai/minecleaner/ArenaList.java index 519a65d..197e45f 100644 --- a/src/main/java/de/lunarakai/minecleaner/ArenaList.java +++ b/src/main/java/de/lunarakai/minecleaner/ArenaList.java @@ -2,6 +2,7 @@ package de.lunarakai.minecleaner; import java.io.File; import java.io.IOException; +import java.util.Collection; import java.util.HashMap; import java.util.UUID; import java.util.logging.Level; @@ -17,15 +18,18 @@ public class ArenaList { private final MinecleanerPlugin plugin; private File arenaFile; private final HashMap arenas; + private final HashMap playersInArena; private final HashMap arenaBlocks; + private final HashMap arenaBlockDisplays; public ArenaList(MinecleanerPlugin plugin) { this.plugin = plugin; this.arenas = new HashMap<>(); - this.arenaFile = new File(plugin.getDataFolder(), ARENAS_FILENAME); this.arenaBlocks = new HashMap<>(); this.playersInArena = new HashMap<>(); + this.arenaBlockDisplays = new HashMap<>(); + this.arenaFile = new File(plugin.getDataFolder(), ARENAS_FILENAME); } public void load() { @@ -47,7 +51,7 @@ public class ArenaList { if(arenaSection != null) { MinecleanerArena arena = new MinecleanerArena(plugin, arenaSection); this.arenas.put(arena.getName(), arena); - + setArenaBlocks(arena); } } } @@ -68,11 +72,39 @@ public class ArenaList { } } - /*private void setArenaBlocks(MinecleanerArena arena) { - for(Location location : arena.getBlocks()) { - arenaBlocks + private void setArenaBlocks(MinecleanerArena arena) { + for(Location loc : arena.getBlocks()) { + arenaBlocks.put(loc.clone(), arena); } - }*/ + for(UUID id : arena.getBlockDisplays()) { + if(id != null) { + arenaBlockDisplays.put(id, arena); + } + } + } + + public MinecleanerArena getArena(String name) { + return arenas.get(name); + } + + public Collection getArenas() { + return arenas.values(); + } + + public void addArena(MinecleanerArena arena) { + this.arenas.put(arena.getName(), arena); + setArenaBlocks(arena); + save(); + } + + public boolean collidesWithArena(MinecleanerArena newArena) { + for(Location location : newArena.getBlocks()) { + if(arenaBlocks.get(location) != null) { + return true; + } + } + return false; + } public void setArenaForPlayer(Player player, MinecleanerArena arena) { if(arena != null) { @@ -89,6 +121,23 @@ public class ArenaList { public MinecleanerArena getArenaAtBlock(Block block) { return arenaBlocks.get(block.getLocation()); } + + public void removeArena(MinecleanerArena arena) { + if(arena.hasPlayer()) { + plugin.getManager().leaveArena(arena.getCurrentPlayer(), true); + } + + for(UUID id : arena.getBlockDisplays()) { // TODO + if(id != null) { + arenaBlockDisplays.remove(id); + } + } + for(Location block : arena.getBlocks()) { // TODO + arenaBlocks.remove(block); + } + arena.removeBlockDisplays(); // TODO - + arenas.remove(arena.getName()); + save(); + } } diff --git a/src/main/java/de/lunarakai/minecleaner/MinecleanerArena.java b/src/main/java/de/lunarakai/minecleaner/MinecleanerArena.java index b1ed6e1..037a4f2 100644 --- a/src/main/java/de/lunarakai/minecleaner/MinecleanerArena.java +++ b/src/main/java/de/lunarakai/minecleaner/MinecleanerArena.java @@ -1,11 +1,23 @@ package de.lunarakai.minecleaner; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import java.util.UUID; import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; import org.bukkit.block.BlockFace; +import org.bukkit.block.data.BlockData; import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.BlockDisplay; +import org.bukkit.entity.Display; +import org.bukkit.entity.Entity; import org.bukkit.entity.Player; +import org.bukkit.util.Transformation; +import org.joml.Vector3f; import com.google.common.base.Preconditions; +import de.lunarakai.minecleaner.game.BoardSize; import de.lunarakai.minecleaner.game.Game; public class MinecleanerArena { @@ -13,18 +25,23 @@ public class MinecleanerArena { private final String name; private final Location location; private final Location centerLocation; + private int widthIndex = 0; private final BlockFace orientation; private ArenaStatus arenaStatus = ArenaStatus.INACTIVE; - private UUID[] displayEntities; + private UUID[] blockDisplays = new UUID[widthIndex * widthIndex]; private Player currentPlayer; private long currentGameStartTime; private Game currentMinecleanerGame; + private final Location tempLoc = new Location(null, 0, 0, 0); + public MinecleanerArena(MinecleanerPlugin plugin, ConfigurationSection arenaSection) { this.plugin = plugin; this.name = Preconditions.checkNotNull(arenaSection.getString("name")); this.location = Preconditions.checkNotNull(arenaSection.getLocation("location")); + this.widthIndex = Preconditions.checkNotNull(arenaSection.getInt("fieldwidth")); + BlockFace orientation = BlockFace.NORTH; try { orientation = BlockFace.valueOf(arenaSection.getString("orientation")); @@ -34,13 +51,23 @@ public class MinecleanerArena { this.orientation = orientation; this.centerLocation = location.clone().add(0.5, 0, 0.5); - displayEntities = new UUID[Game.width * Game.height]; + + List list = arenaSection.getStringList("blockdisplays"); + for(int i = 0; i < list.size(); i++) { + String blockDisplay = list.get(i); + if(blockDisplay != null) { + blockDisplays[i] = UUID.fromString(blockDisplay); + } + } + blockDisplays = new UUID[widthIndex * widthIndex]; } - public MinecleanerArena(MinecleanerPlugin plugin, String name, Location location, BlockFace orientation) { + public MinecleanerArena(MinecleanerPlugin plugin, String name, Location location, int widthIndex, BlockFace orientation) { this.plugin = plugin; this.name = Preconditions.checkNotNull(name, "name"); this.location = Preconditions.checkNotNull(location, "location"); + this.widthIndex = Preconditions.checkNotNull(widthIndex, ("fieldwidth")); + Preconditions.checkArgument(Math.abs(orientation.getModX()) + Math.abs(orientation.getModZ()) == 1, "no cardinal direction"); this.orientation = orientation; int d0x = orientation.getModX(); @@ -50,9 +77,92 @@ public class MinecleanerArena { this.centerLocation = location.clone().add(0.5, 0, 0.5); } + public void generateBackgroundBlocks() { + World world = location.getWorld(); + int d0x = orientation.getModX(); + int d0z = orientation.getModZ(); + int d1x = -d0z; + int d1z = d0x; + Location loc = location.clone(); + + BlockData block0 = Material.NETHER_BRICKS.createBlockData(); + BlockData block1 = Material.BRICKS.createBlockData(); + + for(int fx = -1; fx < 2; fx++) { + for(int fy = -1; fy < 2; fy++) { + loc.set(location.getX() + d1x * fx, location.getY() + fy, location.getZ() + d1z + fx); + boolean f = (fx + fy) % 2 == 0; + world.setBlockData(loc, f ? block0 : block1); + } + } + } + + public void generateBlockDisplays() { + World world = location.getWorld(); + for(UUID id : blockDisplays) { + if(id != null) { + Entity blockdisplay = world.getEntity(id); + if(blockdisplay instanceof Display) { + blockdisplay.remove(); + } + } + } + Arrays.fill(blockDisplays, null); + + float rotation0 = 0; + if(orientation == BlockFace.EAST) { + rotation0 = 90; + } else if(orientation == BlockFace.SOUTH) { + rotation0 = 180; + } else if(orientation == BlockFace.WEST) { + rotation0 = 270; + } + + float rotation = rotation0; + + int d0x = orientation.getModX(); + int d0z = orientation.getModZ(); + int d1x = -d0z; + int d1z = d0x; + + // QWing sudoku = plugin.getGeneratorThread().getSudoku(Difficulty.EASY, true); + // int[] puzzle = sudoku == null ? new int[81] : sudoku.getPuzzle(); + + Location loc = location.clone(); + for(int fx = 0; fx < 9; fx++) { + final int fxf = fx; + for(int fz = 0; fz < 9; fz++) { + final int fzf = fz; + + loc.set(location.getX() + 0.5 - (d1x * fz) / 3.0 + d0x * 0.501 + d1x * 1.847, location.getY() + fxf / 3.0, location.getZ() + 0.5 - (d1z * fz) / 3.0 + d0z * 0.501 + d1z * 1.847); + + Display blockDisplay = world.spawn(loc, BlockDisplay.class, blockdisplay -> { + Transformation transformation = blockdisplay.getTransformation(); + Transformation newTransform; + Vector3f newTranslationScale = new Vector3f(0.25f, 0.25f, 0.25f); + newTransform = new Transformation( + transformation.getTranslation(), + transformation.getLeftRotation(), + newTranslationScale, + transformation.getRightRotation()); + + blockdisplay.setTransformation(newTransform); + blockdisplay.setRotation(rotation + 90, 0); + blockdisplay.setBlock(Material.BEDROCK.createBlockData()); + }); + if(blockDisplay != null) { + blockDisplays[fxf + fzf * 9] = blockDisplay.getUniqueId(); + } + } + } + + // show Displays + } + public void save(ConfigurationSection arenaSection) { arenaSection.set("name", this.name); arenaSection.set("location", this.location); + arenaSection.set("fieldwidth", this.widthIndex); arenaSection.set("orientation", this.orientation.name()); } @@ -61,11 +171,95 @@ public class MinecleanerArena { arenaStatus = ArenaStatus.PLAYING; } + public void addJoiningPlayer(Player player) { + Preconditions.checkNotNull(player); + Preconditions.checkState(arenaStatus == ArenaStatus.INACTIVE); + this.arenaStatus = ArenaStatus.CONFIRM_PLAYING; + this.currentPlayer = player; + + } + + + public void removePlayer() { this.arenaStatus = ArenaStatus.INACTIVE; this.currentPlayer = null; } + public void removeBlockDisplays() { + World world = location.getWorld(); + for(int fx = 0; fx < matchWidthIndexToActualWidth(widthIndex); fx++) { + for(int fy = 0; fy < matchWidthIndexToActualWidth(widthIndex); fy++) { + UUID blockDisplayUuid = blockDisplays[fx + fy * matchWidthIndexToActualWidth(widthIndex)]; + Entity blockDisplayEntity = blockDisplayUuid != null ? world.getEntity(blockDisplayUuid) : null; + if(blockDisplayEntity instanceof Display blockdisplay) { + blockDisplayEntity.remove(); + } + } + } + } + + public void flagCell(int x, int y) { + if(currentMinecleanerGame != null) { + int id = x + y * matchWidthIndexToActualWidth(widthIndex); + boolean unflaggedCell = currentMinecleanerGame.flag(x, y); + if(!unflaggedCell) { + // todo set flag head on block display + } else { + // todo set normal head on block display + } + } + } + + public void revealCell(int x, int y) { + if(currentMinecleanerGame != null) { + int id = x + y * matchWidthIndexToActualWidth(widthIndex); + // todo check if cell is flagged already + currentMinecleanerGame.reveal(x, y); + // todo update block of blockdisplay + } + } + + private int matchWidthIndexToActualWidth(int widthIndex) { + switch (widthIndex) { + case 0: + return BoardSize.boardSizes[0]; + case 1: + return BoardSize.boardSizes[1]; + case 2: + return BoardSize.boardSizes[2]; + default: + return BoardSize.boardSizes[0]; + } + } + + public List getBlocks() { + ArrayList blocks = new ArrayList<>(); + int d0x = orientation.getModX(); + int d0z = orientation.getModZ(); + int d1x = -d0z; + int d1z = d0x; + + Location loc = location.clone(); + for(int fx = -1; fx < 2; fx++) { + for(int fy = -1; fy < 2; fy++) { + loc.set(location.getX() + d1x + fx, location.getY() + fy, location.getZ() + d1z * fx); + blocks.add(loc.clone()); + } + } + + return blocks; + } + + public boolean isTooFarAway(Player player) { + if(player.getWorld() != location.getWorld()) { + return true; + } + player.getLocation(tempLoc); + double dist = tempLoc.distanceSquared(centerLocation); + return dist > 64.0; + } + public String getName() { return name; } @@ -82,29 +276,16 @@ public class MinecleanerArena { return location; } + public BlockFace getOrientation() { + return orientation; + } + public ArenaStatus getArenaStatus() { return arenaStatus; } - public void flagCell(int x, int y) { - if(currentMinecleanerGame != null) { - int id = x + y * 8; - boolean unflaggedCell = currentMinecleanerGame.flag(x, y); - if(!unflaggedCell) { - // todo set flag head on block display - } else { - // todo set normal head on block display - } - } - } - - public void revealCell(int x, int y) { - if(currentMinecleanerGame != null) { - int id = x + y * 8; - // todo check if cell is flagged already - currentMinecleanerGame.reveal(x, y); - // todo update block of blockdisplay - } + public UUID[] getBlockDisplays() { + return blockDisplays; } } diff --git a/src/main/java/de/lunarakai/minecleaner/MinecleanerListener.java b/src/main/java/de/lunarakai/minecleaner/MinecleanerListener.java index 807d090..06c75b9 100644 --- a/src/main/java/de/lunarakai/minecleaner/MinecleanerListener.java +++ b/src/main/java/de/lunarakai/minecleaner/MinecleanerListener.java @@ -25,6 +25,7 @@ public class MinecleanerListener implements Listener { if(arena != null) { // TODO + e.getPlayer().sendMessage(ChatColor.GREEN + "Minecleaner Arena!!"); } else { arena = plugin.getArenaList().getArenaAtBlock(block); diff --git a/src/main/java/de/lunarakai/minecleaner/MinecleanerManager.java b/src/main/java/de/lunarakai/minecleaner/MinecleanerManager.java index c7cc855..516c543 100644 --- a/src/main/java/de/lunarakai/minecleaner/MinecleanerManager.java +++ b/src/main/java/de/lunarakai/minecleaner/MinecleanerManager.java @@ -1,14 +1,33 @@ package de.lunarakai.minecleaner; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import java.util.function.Consumer; +import org.bukkit.OfflinePlayer; import org.bukkit.entity.Player; import com.google.common.base.Preconditions; +import de.iani.cubesidestats.api.PlayerStatistics; +import de.iani.cubesidestats.api.PlayerStatisticsQueryKey; +import de.iani.cubesidestats.api.PlayerStatisticsQueryKey.QueryType; +import de.iani.cubesidestats.api.StatisticKey; +import de.iani.cubesidestats.api.StatisticsQueryKey; +import de.iani.cubesidestats.api.TimeFrame; +import de.iani.playerUUIDCache.CachedPlayer; import net.md_5.bungee.api.ChatColor; public class MinecleanerManager { private final MinecleanerPlugin plugin; + private final StatisticKey statisticsGamesTotal; + public MinecleanerManager(MinecleanerPlugin plugin) { this.plugin = plugin; + + statisticsGamesTotal = plugin.getCubesideStatistics().getStatisticKey("minecleaner.gamesTotal"); + statisticsGamesTotal.setIsMonthlyStats(true); + statisticsGamesTotal.setDisplayName("Runden gespielt"); + } public void joinArena(Player player, MinecleanerArena arena) { @@ -30,4 +49,35 @@ public class MinecleanerManager { player.sendMessage(ChatColor.YELLOW + "Das Minecleanerspiel wurde abgebrochen."); } } + + public void getStatisticsForPlayer(OfflinePlayer player, Consumer callback) { + List keys = new ArrayList<>(); + PlayerStatistics pStatistics = plugin.getCubesideStatistics().getStatistics(player.getUniqueId()); + + PlayerStatisticsQueryKey kMatchesPlayed; + keys.add(kMatchesPlayed = new PlayerStatisticsQueryKey(pStatistics, statisticsGamesTotal, QueryType.SCORE)); + PlayerStatisticsQueryKey kMatchesPlayedMonth; + keys.add(kMatchesPlayedMonth = new PlayerStatisticsQueryKey(pStatistics, statisticsGamesTotal, QueryType.SCORE, TimeFrame.MONTH)); + + plugin.getCubesideStatistics().queryStats(keys, (c) -> { + int matchesPlayed = c.getOrDefault(kMatchesPlayed, 0); + int matchesPlayedMonth = c.getOrDefault(kMatchesPlayedMonth, 0); + + callback.accept(new PlayerStatisticsData(player.getUniqueId(), player.getName(), matchesPlayed, matchesPlayedMonth)); + }); + } + + public void getStatisticsForPlayerIfExists(String player, Consumer callback) { + CachedPlayer cPlayer = plugin.getPlayerUUIDCache().getPlayerFromNameOrUUID(player); + if(cPlayer == null) { + callback.accept(null); + } else { + getStatisticsForPlayer(cPlayer, callback); + } + } + + public void deleteScores(UUID playerId) { + PlayerStatistics statsPlayer = plugin.getCubesideStatistics().getStatistics(playerId); + statsPlayer.deleteScore(statisticsGamesTotal); + } } diff --git a/src/main/java/de/lunarakai/minecleaner/MinecleanerPlugin.java b/src/main/java/de/lunarakai/minecleaner/MinecleanerPlugin.java index 846e3a8..1833190 100644 --- a/src/main/java/de/lunarakai/minecleaner/MinecleanerPlugin.java +++ b/src/main/java/de/lunarakai/minecleaner/MinecleanerPlugin.java @@ -1,6 +1,13 @@ package de.lunarakai.minecleaner; import org.bukkit.plugin.java.JavaPlugin; +import de.iani.cubesidestats.api.CubesideStatisticsAPI; +import de.iani.cubesideutils.bukkit.commands.CommandRouter; +import de.iani.playerUUIDCache.PlayerUUIDCache; +import de.lunarakai.minecleaner.commands.CreateCommand; +import de.lunarakai.minecleaner.commands.DeleteCommand; +import de.lunarakai.minecleaner.commands.ListCommand; +import de.lunarakai.minecleaner.commands.StatsCommand; public final class MinecleanerPlugin extends JavaPlugin { @@ -16,24 +23,30 @@ public final class MinecleanerPlugin extends JavaPlugin { private MinecleanerManager minecleanerManager; private ArenaList arenaList; + private CubesideStatisticsAPI cubesideStatistics; + private PlayerUUIDCache playerUUIDCache; @Override public void onEnable() { - // Plugin startup logic + getServer().getScheduler().runTask(this, this::onLateEnable); + + } + + public void onLateEnable() { + playerUUIDCache = (PlayerUUIDCache) getServer().getPluginManager().getPlugin("PlayerUUIDCache"); + cubesideStatistics = getServer().getServicesManager().load(CubesideStatisticsAPI.class); arenaList = new ArenaList(this); arenaList.load(); - //CommandRouter minecleanerCommand = new CommandRouter(getCommand("minecleaner")); - //minecleanerCommand.addCommandMapping(new CreateCommand(this), "create"); - //minecleanerCommand.addCommandMapping(new DeleteCommand(this), "delete"); - //minecleanerCommand.addCommandMapping(new ListCommand(this), "list"); + minecleanerManager = new MinecleanerManager(this); + getServer().getPluginManager().registerEvents(new MinecleanerListener(this), this); - - - //Test Commands - //minecleanerCommand.addCommandMapping(new TestCommand(this), "testSingle"); - //minecleanerCommand.addCommandMapping(new TestArrayCommand(this), "testArray"); + CommandRouter minecleanerCommand = new CommandRouter(getCommand("minecleaner")); + minecleanerCommand.addCommandMapping(new CreateCommand(this), "create"); + minecleanerCommand.addCommandMapping(new DeleteCommand(this), "delete"); + minecleanerCommand.addCommandMapping(new ListCommand(this), "list"); + minecleanerCommand.addCommandMapping(new StatsCommand(this), "stats"); } @Override @@ -48,4 +61,12 @@ public final class MinecleanerPlugin extends JavaPlugin { public MinecleanerManager getManager() { return minecleanerManager; } + + public CubesideStatisticsAPI getCubesideStatistics() { + return cubesideStatistics; + } + + public PlayerUUIDCache getPlayerUUIDCache() { + return playerUUIDCache; + } } diff --git a/src/main/java/de/lunarakai/minecleaner/PlayerStatisticsData.java b/src/main/java/de/lunarakai/minecleaner/PlayerStatisticsData.java new file mode 100644 index 0000000..fd8271f --- /dev/null +++ b/src/main/java/de/lunarakai/minecleaner/PlayerStatisticsData.java @@ -0,0 +1,34 @@ +package de.lunarakai.minecleaner; + +import java.util.UUID; + +public class PlayerStatisticsData { + private UUID playerUUID; + private String playerName; + private int gamesPlayed; + private int gamesPlayedThisMonth; + + public PlayerStatisticsData(UUID playerUUID, String playerName, int gamesPlayed, int gamesPlayedThisMonth) { + this.playerUUID = playerUUID; + this.playerName = playerName; + this.gamesPlayed = gamesPlayed; + this.gamesPlayedThisMonth = gamesPlayedThisMonth; + } + + public UUID getPlayerID() { + return playerUUID; + } + + public String getPlayerName() { + return playerName; + } + + public int getGamesPlayed() { + return gamesPlayed; + } + + public int getGamesPlayedThisMonth() { + return gamesPlayedThisMonth; + } + +} diff --git a/src/main/java/de/lunarakai/minecleaner/commands/CreateCommand.java b/src/main/java/de/lunarakai/minecleaner/commands/CreateCommand.java new file mode 100644 index 0000000..1663bfe --- /dev/null +++ b/src/main/java/de/lunarakai/minecleaner/commands/CreateCommand.java @@ -0,0 +1,156 @@ +package de.lunarakai.minecleaner.commands; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.regex.Pattern; +import javax.annotation.Nullable; +import org.bukkit.Location; +import org.bukkit.block.BlockFace; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.util.RayTraceResult; +import de.iani.cubesideutils.bukkit.commands.SubCommand; +import de.iani.cubesideutils.bukkit.commands.exceptions.DisallowsCommandBlockException; +import de.iani.cubesideutils.bukkit.commands.exceptions.IllegalSyntaxException; +import de.iani.cubesideutils.bukkit.commands.exceptions.InternalCommandException; +import de.iani.cubesideutils.bukkit.commands.exceptions.NoPermissionException; +import de.iani.cubesideutils.bukkit.commands.exceptions.RequiresPlayerException; +import de.iani.cubesideutils.commands.ArgsParser; +import de.lunarakai.minecleaner.MinecleanerArena; +import de.lunarakai.minecleaner.MinecleanerPlugin; +import net.md_5.bungee.api.ChatColor; + +public class CreateCommand extends SubCommand { + private static final Pattern VALID_ARENA_NAME = Pattern.compile("^[a-z0-9_]+$"); + + private final MinecleanerPlugin plugin; + + public CreateCommand(MinecleanerPlugin plugin) { + this.plugin = plugin; + } + + + @Override + public String getUsage() { + return " [noblocks] [widthindex]"; + } + + @Override + public boolean requiresPlayer() { + return true; + } + + @Override + public String getRequiredPermission() { + return MinecleanerPlugin.PERMISSION_ADMIN; + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String arg2, String commandString, ArgsParser args) throws DisallowsCommandBlockException, RequiresPlayerException, NoPermissionException, IllegalSyntaxException, InternalCommandException { + final Player player = (Player) sender; + if(args.remaining() < 1 || args.remaining() > 3) { + sender.sendMessage(ChatColor.DARK_RED + commandString + getUsage()); + return true; + } + String name = args.getNext().toLowerCase().trim(); + if(!VALID_ARENA_NAME.matcher(name).matches()) { + sender.sendMessage(ChatColor.DARK_RED + "Ungültiger Arenaname. Erlaubt sind Buchstaben, Zahlen und der Unterstrich"); + return true; + } + if(plugin.getArenaList().getArena(name) != null) { + sender.sendMessage(ChatColor.DARK_RED + "Eine Arena mit diesem Namen existiert bereits"); + return true; + } + boolean noblocks = false; + int widthindex = 0; + + while(args.hasNext()) { + String arg = args.getNext().toLowerCase().trim(); + if(arg.equals("noblocks")) { + noblocks = true; + } else if(arg.matches("^-?\\d+$")) { + try { + widthindex = Integer.parseInt(arg); + } catch(NumberFormatException e) { + sender.sendMessage(ChatColor.DARK_RED + "Kein Valider Arena WidthIndex!"); + sender.sendMessage(ChatColor.DARK_RED + "0 (oder weglassen) = 9*9, 1 = 15*15, 2 = 24*24"); + return true; + } + if(widthindex > 2) { + sender.sendMessage(ChatColor.DARK_RED + "Arena WidthIndex darf nicht größer als 2 sein"); + sender.sendMessage(ChatColor.DARK_RED + "0 (oder weglassen) = 9*9, 1 = 15*15, 2 = 24*24"); + return true; + } + } else { + sender.sendMessage(ChatColor.DARK_RED + commandString + getUsage()); + return true; + } + } + + BlockFace orientation = null; + Location location = null; + + @Nullable + RayTraceResult target = player.rayTraceBlocks(6); + if(target == null || target.getHitBlock() == null) { + sender.sendMessage(ChatColor.DARK_RED + "Bitte gucke den Block an, der im Zentrum des Minecleaner-Spielfelds sein soll."); + return true; + } + BlockFace face = target.getHitBlockFace(); + if(face != BlockFace.NORTH && face != BlockFace.WEST && face != BlockFace.EAST && face != BlockFace.SOUTH) { + sender.sendMessage(ChatColor.DARK_RED + "Bitte gucke die Seite des Blockes an, wo das Minecleaner-Spielfeld erstellt werden soll."); + return true; + } + location = target.getHitBlock().getLocation(); + orientation = face; + + MinecleanerArena newArena = new MinecleanerArena(plugin, name, location, widthindex, orientation); + if(plugin.getArenaList().collidesWithArena(newArena)) { + sender.sendMessage(ChatColor.DARK_RED + "An dieser Stelle befindet sich bereits eine Arena."); + return true; + } + newArena.generateBlockDisplays(); // Todo + if(!noblocks) { + newArena.generateBackgroundBlocks(); // Todo; + } + plugin.getArenaList().addArena(newArena); + sender.sendMessage(ChatColor.GREEN + "Die Arena wurde erfolgreich angelegt."); + return true; + } + + @Override + public Collection onTabComplete(CommandSender sender, Command command, String alias, ArgsParser args) { + if(args.remaining() == 2 || args.remaining() == 3) { + args.getNext(); + + boolean noblocks = false; + int widthindex = 0; + while(args.remaining() > 1) { + String arg = args.getNext().toLowerCase().trim(); + if(arg.equals("noblocks")) { + noblocks = true; + } else if(arg.matches("^-?\\d+$")) { + try { + widthindex = Integer.parseInt(arg); + } catch(NumberFormatException e) { + } + } else { + return List.of(); + } + } + ArrayList result = new ArrayList<>(); + result.add(""); + if(!noblocks) { + result.add("noblocks"); + } + if(widthindex != 0 || widthindex != 1 || widthindex != 2) { + result.add("widthindex"); + } + return result; + } + return List.of(); + } + +} diff --git a/src/main/java/de/lunarakai/minecleaner/commands/DeleteCommand.java b/src/main/java/de/lunarakai/minecleaner/commands/DeleteCommand.java new file mode 100644 index 0000000..bb7c577 --- /dev/null +++ b/src/main/java/de/lunarakai/minecleaner/commands/DeleteCommand.java @@ -0,0 +1,67 @@ +package de.lunarakai.minecleaner.commands; + +import java.util.Collection; +import java.util.List; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import de.iani.cubesideutils.bukkit.commands.SubCommand; +import de.iani.cubesideutils.bukkit.commands.exceptions.DisallowsCommandBlockException; +import de.iani.cubesideutils.bukkit.commands.exceptions.IllegalSyntaxException; +import de.iani.cubesideutils.bukkit.commands.exceptions.InternalCommandException; +import de.iani.cubesideutils.bukkit.commands.exceptions.NoPermissionException; +import de.iani.cubesideutils.bukkit.commands.exceptions.RequiresPlayerException; +import de.iani.cubesideutils.commands.ArgsParser; +import de.lunarakai.minecleaner.MinecleanerArena; +import de.lunarakai.minecleaner.MinecleanerPlugin; +import net.md_5.bungee.api.ChatColor; + +public class DeleteCommand extends SubCommand { + private final MinecleanerPlugin plugin; + + public DeleteCommand(MinecleanerPlugin plugin) { + this.plugin = plugin; + } + + @Override + public String getUsage() { + return ""; + } + + @Override + public boolean requiresPlayer() { + return true; + } + + @Override + public String getRequiredPermission() { + return MinecleanerPlugin.PERMISSION_ADMIN; + } + + @Override + public boolean onCommand(CommandSender sender, Command arg1, String arg2, String commandString, ArgsParser args) throws DisallowsCommandBlockException, RequiresPlayerException, NoPermissionException, IllegalSyntaxException, InternalCommandException { + Player player = (Player) sender; + MinecleanerArena arena = plugin.getArenaList().getArenaAtBlock(player.getLocation().getBlock().getRelative(BlockFace.DOWN)); + if(arena == null) { + Block target = player.getTargetBlockExact(6); + if(target != null) { + arena = plugin.getArenaList().getArenaAtBlock(target); + } + } + if(arena != null) { + plugin.getArenaList().removeArena(arena); + sender.sendMessage(ChatColor.YELLOW + "Die Minecleaner-Arena " + arena.getName() + " wurde gelöscht."); + } else { + sender.sendMessage(ChatColor.YELLOW + "Hier befindet sich keine Minecleaner-Arena."); + } + return true; + } + + @Override + public Collection onTabComplete(CommandSender sender, Command command, String alias, ArgsParser args) { + return List.of(); + } + +} diff --git a/src/main/java/de/lunarakai/minecleaner/commands/ListCommand.java b/src/main/java/de/lunarakai/minecleaner/commands/ListCommand.java new file mode 100644 index 0000000..7824b7b --- /dev/null +++ b/src/main/java/de/lunarakai/minecleaner/commands/ListCommand.java @@ -0,0 +1,61 @@ +package de.lunarakai.minecleaner.commands; + +import java.util.Collection; +import java.util.List; +import org.bukkit.Location; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import de.iani.cubesideutils.bukkit.commands.SubCommand; +import de.iani.cubesideutils.bukkit.commands.exceptions.DisallowsCommandBlockException; +import de.iani.cubesideutils.bukkit.commands.exceptions.IllegalSyntaxException; +import de.iani.cubesideutils.bukkit.commands.exceptions.InternalCommandException; +import de.iani.cubesideutils.bukkit.commands.exceptions.NoPermissionException; +import de.iani.cubesideutils.bukkit.commands.exceptions.RequiresPlayerException; +import de.iani.cubesideutils.commands.ArgsParser; +import de.lunarakai.minecleaner.MinecleanerArena; +import de.lunarakai.minecleaner.MinecleanerPlugin; +import net.md_5.bungee.api.ChatColor; + +public class ListCommand extends SubCommand{ + + private final MinecleanerPlugin plugin; + + public ListCommand(MinecleanerPlugin plugin) { + this.plugin = plugin; + } + + @Override + public String getUsage() { + return ""; + } + + @Override + public boolean requiresPlayer() { + return true; + } + + @Override + public String getRequiredPermission() { + return MinecleanerPlugin.PERMISSION_ADMIN; + } + + @Override + public boolean onCommand(CommandSender sender, Command arg1, String arg2, String commandString, ArgsParser args) throws DisallowsCommandBlockException, RequiresPlayerException, NoPermissionException, IllegalSyntaxException, InternalCommandException { + sender.sendMessage(ChatColor.YELLOW + "Angelegte Minecleaner-Arenen"); + boolean any = false; + for(MinecleanerArena arena : plugin.getArenaList().getArenas()) { + Location location = arena.getLocation(); + sender.sendMessage(ChatColor.GRAY + " " + arena.getName() + " @ " + location.getBlockX() + "," + location.getBlockY() + "," + location.getBlockZ()); + any = true; + } + if(!any) { + sender.sendMessage(ChatColor.GRAY + " (keine)"); + } + return true; + } + + @Override + public Collection onTabComplete(CommandSender sender, Command command, String alias, ArgsParser args) { + return List.of(); + } +} diff --git a/src/main/java/de/lunarakai/minecleaner/commands/StatsCommand.java b/src/main/java/de/lunarakai/minecleaner/commands/StatsCommand.java new file mode 100644 index 0000000..d3616c0 --- /dev/null +++ b/src/main/java/de/lunarakai/minecleaner/commands/StatsCommand.java @@ -0,0 +1,71 @@ +package de.lunarakai.minecleaner.commands; + +import java.util.function.Consumer; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import de.iani.cubesideutils.bukkit.commands.SubCommand; +import de.iani.cubesideutils.bukkit.commands.exceptions.DisallowsCommandBlockException; +import de.iani.cubesideutils.bukkit.commands.exceptions.IllegalSyntaxException; +import de.iani.cubesideutils.bukkit.commands.exceptions.InternalCommandException; +import de.iani.cubesideutils.bukkit.commands.exceptions.NoPermissionException; +import de.iani.cubesideutils.bukkit.commands.exceptions.RequiresPlayerException; +import de.iani.cubesideutils.commands.ArgsParser; +import de.lunarakai.minecleaner.MinecleanerPlugin; +import de.lunarakai.minecleaner.PlayerStatisticsData; +import net.md_5.bungee.api.ChatColor; + +public class StatsCommand extends SubCommand { + private final MinecleanerPlugin plugin; + + public StatsCommand(MinecleanerPlugin plugin) { + this.plugin = plugin; + } + + @Override + public String getUsage() { + return "[name]"; + } + + @Override + public boolean requiresPlayer() { + return false; + } + + @Override + public String getRequiredPermission() { + return MinecleanerPlugin.PERMISSION_PLAY; + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String alias, String commandString, ArgsParser args) throws DisallowsCommandBlockException, RequiresPlayerException, NoPermissionException, IllegalSyntaxException, InternalCommandException { + String playerName = args.getNext(null); + + Consumer callback = new Consumer<>() { + @Override + public void accept(PlayerStatisticsData data) { + if(data == null) { + sender.sendMessage(ChatColor.GREEN + "Für Spieler '" + playerName + "' existieren keine Daten."); + return; + } + if(playerName == null) { + sender.sendMessage(ChatColor.GREEN + "Deine Minecleaner Statistik:"); + } else { + sender.sendMessage(ChatColor.GREEN + "Minecleaner-Statitik von " + data.getPlayerName() + ":"); + } + sender.sendMessage(ChatColor.BLUE + " Runden gespielt: " + ChatColor.GREEN + data.getGamesPlayed() + " (Dieser Monat: " + data.getGamesPlayedThisMonth() + ")"); + } + }; + if(playerName == null) { + if(sender instanceof Player) { + plugin.getManager().getStatisticsForPlayer((Player) sender, callback); + } else { + sender.sendMessage(ChatColor.GREEN + "Für die Konsole existieren keine Daten."); + } + } else { + plugin.getManager().getStatisticsForPlayerIfExists(playerName, callback); + } + return true; + } + +} diff --git a/src/main/java/de/lunarakai/minecleaner/game/BoardSize.java b/src/main/java/de/lunarakai/minecleaner/game/BoardSize.java index 789cc69..a2c2597 100644 --- a/src/main/java/de/lunarakai/minecleaner/game/BoardSize.java +++ b/src/main/java/de/lunarakai/minecleaner/game/BoardSize.java @@ -1,17 +1,15 @@ package de.lunarakai.minecleaner.game; public class BoardSize { - public int[] boardSizes = { - 8, - 16, - 32, // nicht größer als 24 - 64 + public static int[] boardSizes = { + 9, + 15, + 24, // nicht größer als 24 }; - public int[] mineCounter = { - 10, + public static int[] mineCounter = { + 12, 40, - 128, - 512 + 100, }; } diff --git a/src/main/java/de/lunarakai/minecleaner/game/Game.java b/src/main/java/de/lunarakai/minecleaner/game/Game.java index a0aa0d7..abb40c3 100644 --- a/src/main/java/de/lunarakai/minecleaner/game/Game.java +++ b/src/main/java/de/lunarakai/minecleaner/game/Game.java @@ -5,8 +5,8 @@ import de.lunarakai.minecleaner.utils.MathUtils; public class Game { - public static int width; - public static int height; + public int width; + public int height; private int mineCount = 10; private Cell[][] state; private boolean gameover;