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;