From 144fbe77035399f4a437f5e40741d09df0e47d02 Mon Sep 17 00:00:00 2001 From: Marco Date: Sat, 17 Jun 2023 15:18:18 +0100 Subject: [PATCH] tier zero --- build.gradle | 1 + .../SimpleCivilisations.java | 148 ++++++++++++-- .../commands/CivilisationsCommand.java | 2 + .../commands/ReloadCommand.java | 28 +++ .../commands/subcommands/CreateCommand.java | 30 +-- .../subcommands/DescriptionCommand.java | 34 ++-- .../commands/subcommands/DisbandCommand.java | 31 ++- .../commands/subcommands/InfoCommand.java | 26 +-- .../commands/subcommands/InviteCommand.java | 66 +++---- .../commands/subcommands/JoinCommand.java | 14 +- .../commands/subcommands/KickCommand.java | 64 +++---- .../commands/subcommands/LeaveCommand.java | 23 +-- .../subcommands/PlacePillarCommand.java | 181 ++++++++++++++++++ .../subcommands/RemovePillarCommand.java | 78 ++++++++ .../commands/subcommands/RenameCommand.java | 38 ++-- .../subcommands/SetleaderCommand.java | 54 +++--- .../subcommands/SetwaypointCommand.java | 29 +-- .../commands/subcommands/UninviteCommand.java | 59 +++--- .../commands/subcommands/WaypointCommand.java | 23 +-- .../listeners/BlockBreakListener.java | 75 ++++++++ .../listeners/BlockDamageListener.java | 66 +++++++ .../listeners/BlockPlaceListener.java | 36 ++++ .../listeners/EntityExplodeListener.java | 30 +++ .../listeners/PlayerInteractListener.java | 37 ++++ .../listeners/PlayerJoinListener.java | 5 +- .../listeners/PlayerMoveListener.java | 55 ++++++ .../listeners/PlayerRespawnEvent.java | 2 +- .../simplecivilisations/sql/Civilisation.java | 68 ++++++- .../marco/simplecivilisations/sql/MySQL.java | 59 +++--- .../marco/simplecivilisations/sql/Pillar.java | 86 +++++++++ src/main/resources/config.yml | 18 ++ src/main/resources/plugin.yml | 7 +- 32 files changed, 1166 insertions(+), 307 deletions(-) create mode 100644 src/main/java/com/marco/simplecivilisations/commands/ReloadCommand.java create mode 100644 src/main/java/com/marco/simplecivilisations/commands/subcommands/PlacePillarCommand.java create mode 100644 src/main/java/com/marco/simplecivilisations/commands/subcommands/RemovePillarCommand.java create mode 100644 src/main/java/com/marco/simplecivilisations/listeners/BlockBreakListener.java create mode 100644 src/main/java/com/marco/simplecivilisations/listeners/BlockDamageListener.java create mode 100644 src/main/java/com/marco/simplecivilisations/listeners/BlockPlaceListener.java create mode 100644 src/main/java/com/marco/simplecivilisations/listeners/EntityExplodeListener.java create mode 100644 src/main/java/com/marco/simplecivilisations/listeners/PlayerInteractListener.java create mode 100644 src/main/java/com/marco/simplecivilisations/listeners/PlayerMoveListener.java create mode 100644 src/main/java/com/marco/simplecivilisations/sql/Pillar.java create mode 100644 src/main/resources/config.yml diff --git a/build.gradle b/build.gradle index 79caa17..0195efa 100644 --- a/build.gradle +++ b/build.gradle @@ -23,6 +23,7 @@ repositories { dependencies { compileOnly "org.spigotmc:spigot-api:1.19.4-R0.1-SNAPSHOT" + compileOnly files("/Users/marco/Documents/build/Spigot/Spigot-Server/target/spigot-1.19.4-R0.1-SNAPSHOT.jar") compileOnly "com.mojang:authlib:1.5.21" } diff --git a/src/main/java/com/marco/simplecivilisations/SimpleCivilisations.java b/src/main/java/com/marco/simplecivilisations/SimpleCivilisations.java index 7b59ffa..f1726df 100644 --- a/src/main/java/com/marco/simplecivilisations/SimpleCivilisations.java +++ b/src/main/java/com/marco/simplecivilisations/SimpleCivilisations.java @@ -1,20 +1,17 @@ package com.marco.simplecivilisations; -import com.marco.simplecivilisations.commands.CivilisationsCommand; -import com.marco.simplecivilisations.commands.OfflineTeleportCommand; -import com.marco.simplecivilisations.commands.ReviveCommand; -import com.marco.simplecivilisations.commands.SeenCommand; -import com.marco.simplecivilisations.listeners.PlayerRespawnEvent; -import com.marco.simplecivilisations.listeners.PlayerJoinListener; -import com.marco.simplecivilisations.listeners.PlayerKickListener; -import com.marco.simplecivilisations.listeners.PlayerQuitListener; -import com.marco.simplecivilisations.sql.MySQL; +import com.marco.simplecivilisations.commands.*; +import com.marco.simplecivilisations.listeners.*; +import com.marco.simplecivilisations.sql.*; import org.bukkit.*; import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; +import java.sql.PreparedStatement; +import java.sql.ResultSet; import java.sql.SQLException; +import java.time.Instant; import java.util.*; // Yes, this is the British spelling. @@ -26,17 +23,20 @@ public final class SimpleCivilisations extends JavaPlugin { public List spawns = new ArrayList<>(); + public Map users = new HashMap<>(); + public Map civilisations = new HashMap<>(); @Override public void onEnable() { - // Get these from config file at some point. + saveDefaultConfig(); + this.SQL = new MySQL( this, - "localhost", - "3306", - "test", - "root", - "" + getConfig().getString("host"), + getConfig().getString("port"), + getConfig().getString("database"), + getConfig().getString("username"), + getConfig().getString("password") ); try { @@ -53,16 +53,107 @@ public void onEnable() { Objects.requireNonNull(getCommand("revive")).setExecutor(new ReviveCommand(this)); Objects.requireNonNull(getCommand("seen")).setExecutor(new SeenCommand(this)); Objects.requireNonNull(getCommand("offlinetp")).setExecutor(new OfflineTeleportCommand(this)); + Objects.requireNonNull(getCommand("screload")).setExecutor(new ReloadCommand(this)); Bukkit.getPluginManager().registerEvents(new PlayerJoinListener(this), this); Bukkit.getPluginManager().registerEvents(new PlayerQuitListener(this), this); Bukkit.getPluginManager().registerEvents(new PlayerKickListener(this), this); Bukkit.getPluginManager().registerEvents(new PlayerRespawnEvent(this), this); + Bukkit.getPluginManager().registerEvents(new PlayerMoveListener(this), this); + Bukkit.getPluginManager().registerEvents(new BlockPlaceListener(this), this); + Bukkit.getPluginManager().registerEvents(new BlockBreakListener(this), this); + Bukkit.getPluginManager().registerEvents(new BlockDamageListener(this), this); + Bukkit.getPluginManager().registerEvents(new PlayerInteractListener(this), this); + Bukkit.getPluginManager().registerEvents(new EntityExplodeListener(this), this); getLogger().info("Calculating spawns (faster on preloaded worlds)..."); generateSpawns(20); getLogger().info("Spawns calculated."); + + getLogger().info("Fetching users..."); + try { + PreparedStatement ps = SQL.getConnection().prepareStatement("SELECT * FROM users"); + ResultSet results = ps.executeQuery(); + while (results.next()) { + try { + String potentialUuid = results.getString("civilisation"); + UUID uuid = UUID.fromString(results.getString("uuid")); + users.put(uuid, new User( + this, + uuid, + potentialUuid != null ? UUID.fromString(potentialUuid) : null, + results.getInt("role"), + MySQL.deserialiseLocation(results.getString("spawnPoint")), + results.getTimestamp("lastSession"), + MySQL.deserialiseLocation(results.getString("lastLocation")), + results.getInt("lives"), + results.getTimestamp("lastDeath") + )); + } catch (Exception e) { + e.printStackTrace(); + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + getLogger().info(users.size() + " user(s) found."); + + getLogger().info("Fetching civilisations..."); + try { + PreparedStatement ps = SQL.getConnection().prepareStatement("SELECT * FROM civilisations"); + ResultSet results = ps.executeQuery(); + while (results.next()) { + // Literally just copied this code from another class, didn't even read it properly. + UUID uuid = UUID.fromString(results.getString("uuid")); + ArrayList members = new ArrayList<>(); + PreparedStatement psm = SQL.getConnection().prepareStatement("SELECT * FROM users WHERE civilisation = ?"); + psm.setString(1, uuid.toString()); + ResultSet membersResult = psm.executeQuery(); + while (membersResult.next()) { + String mUUID = membersResult.getString("uuid"); + members.add(UUID.fromString(mUUID)); + } + + ArrayList pillars = new ArrayList<>(); + PreparedStatement psp = SQL.getConnection().prepareStatement("SELECT * FROM pillars WHERE civilisation = ?"); + psp.setString(1, uuid.toString()); + ResultSet pillarsResult = psp.executeQuery(); + while (pillarsResult.next()) { + pillars.add(new Pillar( + this, + uuid, + MySQL.deserialiseLocation(pillarsResult.getString("location")), + pillarsResult.getTimestamp("destroyed") + )); + } + + String waypoint = results.getString("waypoint"); + + try { + civilisations.put(uuid, new Civilisation( + this, + uuid, + results.getString("name"), + results.getString("description"), + UUID.fromString(results.getString("leader")), + members, + results.getBoolean("open"), + pillars, + results.getInt("pillarsAvailable"), + waypoint != null ? MySQL.deserialiseLocation(waypoint) : null + )); + } catch (Exception e) { + e.printStackTrace(); + } + // IT WORKED! + } + } catch (SQLException e) { + e.printStackTrace(); + } + getLogger().info(civilisations.size() + " civilisation(s) found."); + + getLogger().info("Ready"); } @Override @@ -89,13 +180,12 @@ public static UUID uuidFromName(String name) { public void generateSpawns(int t) { Random r = new Random(); - // TODO: Get these from config World world = Bukkit.getWorld("world"); assert world != null; - int maxX = 4000; - int minX = 0; - int maxZ = 4000; - int minZ = 0; + int maxX = getConfig().getInt("max-x"); + int minX = getConfig().getInt("min-x"); + int maxZ = getConfig().getInt("max-z"); + int minZ = getConfig().getInt("min-z"); for (int i = 0; i < t; i++) { int x = r.nextInt(minX, maxX); int z = r.nextInt(minZ, maxZ); @@ -109,8 +199,24 @@ public void generateSpawns(int t) { private boolean isValid(Block block) { if (block.isEmpty() || block.isLiquid()) return false; if (block.getType().toString().endsWith("LEAVES")) return false; - //noinspection RedundantIfStatement if (List.of(Material.CACTUS, Material.MAGMA_BLOCK, Material.SWEET_BERRY_BUSH, Material.POWDER_SNOW).contains(block.getType())) return false; return true; } + + public static boolean inRangeOfPillar(Location location, Pillar pillar) { + double x = location.getChunk().getX() * 16 + 7.5; + double z = location.getChunk().getZ() * 16 + 7.5; + double halfLength = (4 * 16 + 7.5); // This means 4 chunks in each direction. + + + double cx = pillar.getLocation().getChunk().getX() * 16 + 7.5; + double cz = pillar.getLocation().getChunk().getZ() * 16 + 7.5; + + double ax = cx - halfLength; + double az = cz - halfLength; + double bx = cx + halfLength; + double bz = cz + halfLength; + + return x > ax && x < bx && z > az && z < bz; + } } diff --git a/src/main/java/com/marco/simplecivilisations/commands/CivilisationsCommand.java b/src/main/java/com/marco/simplecivilisations/commands/CivilisationsCommand.java index 59134a1..5554416 100644 --- a/src/main/java/com/marco/simplecivilisations/commands/CivilisationsCommand.java +++ b/src/main/java/com/marco/simplecivilisations/commands/CivilisationsCommand.java @@ -16,6 +16,8 @@ public class CivilisationsCommand implements TabExecutor { public CivilisationsCommand(SimpleCivilisations plugin) { subcommands.add(new InfoCommand(plugin)); subcommands.add(new CreateCommand(plugin)); + subcommands.add(new PlacePillarCommand(plugin)); + subcommands.add(new RemovePillarCommand(plugin)); subcommands.add(new RenameCommand(plugin)); subcommands.add(new DescriptionCommand(plugin)); subcommands.add(new DisbandCommand(plugin)); diff --git a/src/main/java/com/marco/simplecivilisations/commands/ReloadCommand.java b/src/main/java/com/marco/simplecivilisations/commands/ReloadCommand.java new file mode 100644 index 0000000..f7c55bd --- /dev/null +++ b/src/main/java/com/marco/simplecivilisations/commands/ReloadCommand.java @@ -0,0 +1,28 @@ +package com.marco.simplecivilisations.commands; + +import com.marco.simplecivilisations.SimpleCivilisations; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabExecutor; + +import java.util.Collections; +import java.util.List; + +public class ReloadCommand implements TabExecutor { + private final SimpleCivilisations plugin; + public ReloadCommand(SimpleCivilisations plugin) { + this.plugin = plugin; + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + plugin.reloadConfig(); + sender.sendMessage("SimpleCivilisations config reloaded."); + return true; + } + + @Override + public List onTabComplete(CommandSender sender, Command command, String label, String[] args) { + return Collections.emptyList(); + } +} diff --git a/src/main/java/com/marco/simplecivilisations/commands/subcommands/CreateCommand.java b/src/main/java/com/marco/simplecivilisations/commands/subcommands/CreateCommand.java index 2550d29..777fc7b 100644 --- a/src/main/java/com/marco/simplecivilisations/commands/subcommands/CreateCommand.java +++ b/src/main/java/com/marco/simplecivilisations/commands/subcommands/CreateCommand.java @@ -2,6 +2,7 @@ import com.marco.simplecivilisations.SimpleCivilisations; import com.marco.simplecivilisations.commands.SubCommand; +import com.marco.simplecivilisations.sql.Civilisation; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; @@ -32,21 +33,22 @@ public String getUsage() { @Override public void perform(CommandSender sender, String[] args) { if (sender instanceof Player player) { + if (plugin.users.get(player.getUniqueId()).getCivilisationId() != null) { + player.sendMessage(SimpleCivilisations.color + "You are already in a civilisation."); + return; + } else if (args.length == 0) { + player.sendMessage(SimpleCivilisations.color + "Usage: " + getUsage()); + return; + } else if (args.length > 1) { + player.sendMessage(SimpleCivilisations.color + "Civilisation names cannot contain spaces."); + return; + } else if (args[0].length() > 20) { + player.sendMessage(SimpleCivilisations.color + "Civilisation names cannot exceed 20 characters."); + return; + } Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { - if (plugin.getSQL().isInCivilisation(player)) { - player.sendMessage(SimpleCivilisations.color + "You are already in a civilisation."); - return; - } else if (args.length == 0) { - player.sendMessage(SimpleCivilisations.color + "Usage: " + getUsage()); - return; - } else if (args.length > 1) { - player.sendMessage(SimpleCivilisations.color + "Civilisation names cannot contain spaces."); - return; - } else if (args[0].length() > 20) { - player.sendMessage(SimpleCivilisations.color + "Civilisation names cannot exceed 20 characters."); - return; - } - SQL.createCivilisation(args[0], player); + Civilisation civilisation = SQL.createCivilisation(args[0], player); + plugin.civilisations.put(civilisation.getUniqueId(), civilisation); }); } else { sender.sendMessage(ChatColor.RED + "Only players may run this command."); diff --git a/src/main/java/com/marco/simplecivilisations/commands/subcommands/DescriptionCommand.java b/src/main/java/com/marco/simplecivilisations/commands/subcommands/DescriptionCommand.java index 5c9f1c8..5c37590 100644 --- a/src/main/java/com/marco/simplecivilisations/commands/subcommands/DescriptionCommand.java +++ b/src/main/java/com/marco/simplecivilisations/commands/subcommands/DescriptionCommand.java @@ -3,6 +3,7 @@ import com.marco.simplecivilisations.SimpleCivilisations; import com.marco.simplecivilisations.commands.SubCommand; import com.marco.simplecivilisations.sql.Civilisation; +import com.marco.simplecivilisations.sql.User; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; @@ -33,23 +34,24 @@ public String getUsage() { @Override public void perform(CommandSender sender, String[] args) { if (sender instanceof Player player) { - Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { - Civilisation civilisation = SQL.getCivilisationFromPlayerUUID(player.getUniqueId()); - - if (civilisation == null) { - player.sendMessage(SimpleCivilisations.color + "You must be in a civilisation to run this command."); - return; - } else if (!civilisation.getLeader().toString().equals(player.getUniqueId().toString())) { - player.sendMessage(SimpleCivilisations.color + "Only the leader may set the civilisation description."); - return; - } else if (args.length == 0) { - player.sendMessage(SimpleCivilisations.color + getUsage()); - return; - } else if (String.join(" ", args).length() > 100) { - player.sendMessage(SimpleCivilisations.color + "Civilisation descriptions cannot exceed 100 characters."); - return; - } + User user = plugin.users.get(player.getUniqueId()); + Civilisation civilisation = plugin.civilisations.get(user.getCivilisationId()); + + if (civilisation == null) { + player.sendMessage(SimpleCivilisations.color + "You must be in a civilisation to run this command."); + return; + } else if (!civilisation.getLeader().toString().equals(player.getUniqueId().toString())) { + player.sendMessage(SimpleCivilisations.color + "Only the leader may set the civilisation description."); + return; + } else if (args.length == 0) { + player.sendMessage(SimpleCivilisations.color + getUsage()); + return; + } else if (String.join(" ", args).length() > 100) { + player.sendMessage(SimpleCivilisations.color + "Civilisation descriptions cannot exceed 100 characters."); + return; + } + Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { civilisation.setDescription(String.join(" ", args)); player.sendMessage(SimpleCivilisations.color + "Civilisation description updated."); }); diff --git a/src/main/java/com/marco/simplecivilisations/commands/subcommands/DisbandCommand.java b/src/main/java/com/marco/simplecivilisations/commands/subcommands/DisbandCommand.java index f3535ad..3ebdb53 100644 --- a/src/main/java/com/marco/simplecivilisations/commands/subcommands/DisbandCommand.java +++ b/src/main/java/com/marco/simplecivilisations/commands/subcommands/DisbandCommand.java @@ -34,23 +34,20 @@ public String getUsage() { @Override public void perform(CommandSender sender, String[] args) { if (sender instanceof Player player) { - Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { - User user = SQL.getUser(player.getUniqueId()); - if (user == null) { - player.sendMessage(ChatColor.RED + "Something went wrong!"); - return; - } else if (user.getCivilisationId() == null) { - player.sendMessage(SimpleCivilisations.color + "You must be in a civilisation to run this command."); - return; - } else if (user.getRole() < 3) { - player.sendMessage(SimpleCivilisations.color + "Only the leader of your civilisation can run this command."); - return; - } - - Civilisation civilisation = SQL.getCivilisation(user); - civilisation.messageOnlineMembers(civilisation.getName() + " has been disbanded."); - civilisation.disband(); - }); + User user = plugin.users.get(player.getUniqueId()); + if (user.getCivilisationId() == null) { + player.sendMessage(SimpleCivilisations.color + "You must be in a civilisation to run this command."); + return; + } else if (user.getRole() < 3) { + player.sendMessage(SimpleCivilisations.color + "Only the leader of your civilisation can run this command."); + return; + } + + Civilisation civilisation = plugin.civilisations.get(user.getCivilisationId()); + civilisation.messageOnlineMembers(civilisation.getName() + " has been disbanded."); + plugin.civilisations.remove(civilisation.getUniqueId()); + + Bukkit.getScheduler().runTaskAsynchronously(plugin, civilisation::disband); return; } sender.sendMessage(ChatColor.RED + "Only player can run this command."); diff --git a/src/main/java/com/marco/simplecivilisations/commands/subcommands/InfoCommand.java b/src/main/java/com/marco/simplecivilisations/commands/subcommands/InfoCommand.java index ca64be9..4f9a97c 100644 --- a/src/main/java/com/marco/simplecivilisations/commands/subcommands/InfoCommand.java +++ b/src/main/java/com/marco/simplecivilisations/commands/subcommands/InfoCommand.java @@ -33,26 +33,24 @@ public String getUsage() { @Override public void perform(CommandSender sender, String[] args) { - Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { - if (args.length == 0) { - if (sender instanceof Player player) { - Civilisation civilisation = SQL.getCivilisationFromPlayerUUID(player.getUniqueId()); - if (civilisation != null) sender.sendMessage(civilisationInfo(civilisation,sender)); - else sender.sendMessage(SimpleCivilisations.color + "You are not a member of a civilisation."); - } else { - sender.sendMessage(ChatColor.GRAY + "Console must provide full usage: " + getUsage()); - } - return; + if (args.length == 0) { + if (sender instanceof Player player) { + Civilisation civilisation = plugin.civilisations.get(plugin.users.get(player.getUniqueId()).getCivilisationId()); + if (civilisation != null) sender.sendMessage(civilisationInfo(civilisation, sender)); + else sender.sendMessage(SimpleCivilisations.color + "You are not a member of a civilisation."); + } else { + sender.sendMessage(ChatColor.GRAY + "Console must provide full usage: " + getUsage()); } + return; + } + Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { @SuppressWarnings("deprecation") OfflinePlayer player = Bukkit.getOfflinePlayer(args[0]); - Civilisation civilisation = player.hasPlayedBefore() ? SQL.getCivilisationFromPlayerUUID(player.getUniqueId()) : SQL.getCivilisation(args[0]); if (civilisation == null) { sender.sendMessage(SimpleCivilisations.color + "No civilisation found."); return; } - sender.sendMessage(civilisationInfo(civilisation, sender)); }); } @@ -67,19 +65,21 @@ public List getTabCompletions(CommandSender sender, String[] args) { private String civilisationInfo(Civilisation civilisation, CommandSender sender) { // I am reassigning a local variable. - @SuppressWarnings("ReassignedVariable") int online = 0; + int online = 0; ArrayList members = new ArrayList<>(); for (UUID member : civilisation.getMembers()) { if (Bukkit.getPlayer(member) != null) online += 1; if (!Objects.equals(member.toString(), civilisation.getLeader().toString())) members.add(formatPlayerName(member)); } + boolean showPillarsAvailable = sender instanceof Player player && civilisation.getLeader().equals(player.getUniqueId()); boolean showWaypoint = sender instanceof Player player && civilisation.hasMember((player.getUniqueId())); return ( ChatColor.GRAY + "-------------------------------\n" + ChatColor.DARK_AQUA + civilisation.getName() + ChatColor.GRAY + " (" + online + "/" + civilisation.getMembers().size() + ")" + "\n" + SimpleCivilisations.color + "Description: " + ChatColor.GRAY + civilisation.getDescription() + + (showPillarsAvailable ? "\n" + SimpleCivilisations.color + "Pillars available: " + ChatColor.GRAY + civilisation.getPillarsAvailable() : "") + (showWaypoint ? "\n" + SimpleCivilisations.color + "Waypoint: " + ChatColor.GRAY + (civilisation.getWaypoint() != null ? civilisation.getWaypoint().getBlockX() + " " + civilisation.getWaypoint().getBlockZ() : "None") : "") + "\n" + SimpleCivilisations.color + "Leader: " + formatPlayerName(civilisation.getLeader()) + (members.size() > 0 ? "\n" + SimpleCivilisations.color + "Members: " + String.join(ChatColor.GRAY + ", ", members) : "") diff --git a/src/main/java/com/marco/simplecivilisations/commands/subcommands/InviteCommand.java b/src/main/java/com/marco/simplecivilisations/commands/subcommands/InviteCommand.java index 268ab2b..2fbb936 100644 --- a/src/main/java/com/marco/simplecivilisations/commands/subcommands/InviteCommand.java +++ b/src/main/java/com/marco/simplecivilisations/commands/subcommands/InviteCommand.java @@ -37,42 +37,44 @@ public String getUsage() { @Override public void perform(CommandSender sender, String[] args) { if (sender instanceof Player player) { - Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { - User user = SQL.getUser(player.getUniqueId()); - if (user == null) { - player.sendMessage(ChatColor.RED + "Something went wrong!"); - return; - } else if (user.getCivilisationId() == null) { - player.sendMessage(SimpleCivilisations.color + "You must be in a civilisation to run this command."); - return; - } else if (user.getRole() < 2) { - player.sendMessage(SimpleCivilisations.color + "You need a higher seniority level within your civilisation to run this command."); - return; - } else if (args.length != 1) { - player.sendMessage(SimpleCivilisations.color + "Usage: " + getUsage()); - return; - } + User user = plugin.users.get(player.getUniqueId()); + if (user == null) { + player.sendMessage(ChatColor.RED + "Something went wrong!"); + return; + } else if (user.getCivilisationId() == null) { + player.sendMessage(SimpleCivilisations.color + "You must be in a civilisation to run this command."); + return; + } else if (user.getRole() < 2) { + player.sendMessage(SimpleCivilisations.color + "You need a higher seniority level within your civilisation to run this command."); + return; + } else if (args.length != 1) { + player.sendMessage(SimpleCivilisations.color + "Usage: " + getUsage()); + return; + } - UUID uuid = SimpleCivilisations.uuidFromName(args[0]); - Player targetPlayer = Bukkit.getPlayer(args[0]); - String targetName = targetPlayer == null ? args[0] : targetPlayer.getName(); - if (uuid == null) { - player.sendMessage(SimpleCivilisations.color + "Player not found."); - return; - } + UUID uuid = SimpleCivilisations.uuidFromName(args[0]); + Player targetPlayer = Bukkit.getPlayer(args[0]); + String targetName = targetPlayer == null ? args[0] : targetPlayer.getName(); + if (uuid == null) { + player.sendMessage(SimpleCivilisations.color + "Player not found."); + return; + } - User target = SQL.getUser(uuid); - if (target.getCivilisationId() != null) { - player.sendMessage(SimpleCivilisations.color + targetName + " is already a member of a civilisation."); - return; - } + User target = plugin.users.get(uuid); + if (target.getCivilisationId() != null) { + player.sendMessage(SimpleCivilisations.color + targetName + " is already a member of a civilisation."); + return; + } - Civilisation civilisation = SQL.getCivilisation(user); + Civilisation civilisation = plugin.civilisations.get(user.getCivilisationId()); - if (civilisation.isOpen()) { - player.sendMessage(SimpleCivilisations.color + "Your civilisation is open and anyone can join."); - return; - } else if (civilisation.hasInvited(target)) { + if (civilisation.isOpen()) { + player.sendMessage(SimpleCivilisations.color + "Your civilisation is open and anyone can join."); + return; + } + + Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { + if (civilisation.hasInvited(target)) { player.sendMessage(SimpleCivilisations.color + targetName + " has already been invited."); return; } diff --git a/src/main/java/com/marco/simplecivilisations/commands/subcommands/JoinCommand.java b/src/main/java/com/marco/simplecivilisations/commands/subcommands/JoinCommand.java index 401b50f..d81f87f 100644 --- a/src/main/java/com/marco/simplecivilisations/commands/subcommands/JoinCommand.java +++ b/src/main/java/com/marco/simplecivilisations/commands/subcommands/JoinCommand.java @@ -38,16 +38,16 @@ public void perform(CommandSender sender, String[] args) { if (args.length == 0) { player.sendMessage(SimpleCivilisations.color + getUsage()); return; - } - Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { - User user = SQL.getUser(player.getUniqueId()); + } + User user = plugin.users.get(player.getUniqueId()); - if (user.getCivilisationId() != null) { - player.sendMessage(SimpleCivilisations.color + "You are already a member of a civilisation."); - return; - } + if (user.getCivilisationId() != null) { + player.sendMessage(SimpleCivilisations.color + "You are already a member of a civilisation."); + return; + } + Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { @SuppressWarnings("deprecation") OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(args[0]); Civilisation civilisation = offlinePlayer.hasPlayedBefore() ? SQL.getCivilisationFromPlayerUUID(offlinePlayer.getUniqueId()) : SQL.getCivilisation(args[0]); if (civilisation == null) { diff --git a/src/main/java/com/marco/simplecivilisations/commands/subcommands/KickCommand.java b/src/main/java/com/marco/simplecivilisations/commands/subcommands/KickCommand.java index 166b84b..94c97f8 100644 --- a/src/main/java/com/marco/simplecivilisations/commands/subcommands/KickCommand.java +++ b/src/main/java/com/marco/simplecivilisations/commands/subcommands/KickCommand.java @@ -37,42 +37,42 @@ public String getUsage() { @Override public void perform(CommandSender sender, String[] args) { if (sender instanceof Player player) { - Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { - User user = SQL.getUser(player.getUniqueId()); - if (user == null) { - player.sendMessage(ChatColor.RED + "Something went wrong!"); - return; - } + User user = plugin.users.get(player.getUniqueId()); + if (user == null) { + player.sendMessage(ChatColor.RED + "Something went wrong!"); + return; + } - Civilisation civilisation = SQL.getCivilisation(user); - if (civilisation == null) { - player.sendMessage(SimpleCivilisations.color + "You must be in a civilisation to run this command."); - return; - } else if (user.getRole() < 2) { - player.sendMessage(SimpleCivilisations.color + "You need a higher seniority level within your civilisation to run this command."); - return; - } else if (args.length != 1) { - player.sendMessage(SimpleCivilisations.color + "Usage: " + getUsage()); - return; - } + Civilisation civilisation = plugin.civilisations.get(user.getCivilisationId()); + if (civilisation == null) { + player.sendMessage(SimpleCivilisations.color + "You must be in a civilisation to run this command."); + return; + } else if (user.getRole() < 2) { + player.sendMessage(SimpleCivilisations.color + "You need a higher seniority level within your civilisation to run this command."); + return; + } else if (args.length != 1) { + player.sendMessage(SimpleCivilisations.color + "Usage: " + getUsage()); + return; + } - UUID uuid = SimpleCivilisations.uuidFromName(args[0]); - Player targetPlayer = Bukkit.getPlayer(args[0]); - String targetName = targetPlayer == null ? args[0] : targetPlayer.getName(); - if (uuid == null) { - player.sendMessage(SimpleCivilisations.color + "Player not found."); - return; - } else if (targetPlayer == player) { - player.sendMessage(SimpleCivilisations.color + "No."); - return; - } + UUID uuid = SimpleCivilisations.uuidFromName(args[0]); + Player targetPlayer = Bukkit.getPlayer(args[0]); + String targetName = targetPlayer == null ? args[0] : targetPlayer.getName(); + if (uuid == null) { + player.sendMessage(SimpleCivilisations.color + "Player not found."); + return; + } else if (targetPlayer == player) { + player.sendMessage(SimpleCivilisations.color + "No."); + return; + } - User target = SQL.getUser(uuid); - if (!civilisation.hasMember(target)) { - player.sendMessage(SimpleCivilisations.color + targetName + " is not a member of the civilisation."); - return; - } + User target = plugin.users.get(uuid); + if (!civilisation.hasMember(target)) { + player.sendMessage(SimpleCivilisations.color + targetName + " is not a member of the civilisation."); + return; + } + Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { civilisation.removeMember(target); civilisation.messageOnlineMembers(targetName + " has been kicked from the civilisation."); if (targetPlayer != null) { diff --git a/src/main/java/com/marco/simplecivilisations/commands/subcommands/LeaveCommand.java b/src/main/java/com/marco/simplecivilisations/commands/subcommands/LeaveCommand.java index d03c3bf..64865c0 100644 --- a/src/main/java/com/marco/simplecivilisations/commands/subcommands/LeaveCommand.java +++ b/src/main/java/com/marco/simplecivilisations/commands/subcommands/LeaveCommand.java @@ -34,20 +34,17 @@ public String getUsage() { @Override public void perform(CommandSender sender, String[] args) { if (sender instanceof Player player) { + User user = plugin.users.get(player.getUniqueId()); + Civilisation civilisation = plugin.civilisations.get(user.getCivilisationId()); + if (civilisation == null) { + player.sendMessage(SimpleCivilisations.color + "You are not a member of a civilisation."); + return; + } else if (user.getRole() == 3) { + player.sendMessage(SimpleCivilisations.color + "Leaders cannot leave their civilisations. You must promote another player or disband."); + return; + } + Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { - // Get user and civilisation - User user = SQL.getUser(player.getUniqueId()); - Civilisation civilisation = SQL.getCivilisation(user); - // Is there any reason they can't leave? - if (civilisation == null) { - player.sendMessage(SimpleCivilisations.color + "You are not a member of a civilisation."); - return; - } else if (user.getRole() == 3) { - player.sendMessage(SimpleCivilisations.color + "Leaders cannot leave their civilisations. You must promote another player or disband."); - return; - } - - // Leave civilisation.messageOnlineMembers(player.getName() + " has left the civilisation."); civilisation.removeMember(user); player.sendMessage(SimpleCivilisations.color + "You have left " + civilisation.getName() + "."); diff --git a/src/main/java/com/marco/simplecivilisations/commands/subcommands/PlacePillarCommand.java b/src/main/java/com/marco/simplecivilisations/commands/subcommands/PlacePillarCommand.java new file mode 100644 index 0000000..5357802 --- /dev/null +++ b/src/main/java/com/marco/simplecivilisations/commands/subcommands/PlacePillarCommand.java @@ -0,0 +1,181 @@ +package com.marco.simplecivilisations.commands.subcommands; + +import com.marco.simplecivilisations.SimpleCivilisations; +import com.marco.simplecivilisations.commands.SubCommand; +import com.marco.simplecivilisations.sql.Civilisation; +import com.marco.simplecivilisations.sql.Pillar; +import com.marco.simplecivilisations.sql.User; +import org.bukkit.*; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.data.Bisected; +import org.bukkit.block.data.type.DaylightDetector; +import org.bukkit.block.data.type.Stairs; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.List; +import java.util.UUID; + +public class PlacePillarCommand extends SubCommand { + public PlacePillarCommand(SimpleCivilisations plugin) { + super(plugin); + } + + @Override + public List getLabels() { + return List.of("placepillar"); + } + + @Override + public String getDescription() { + return "Place a pillar on the block you are looking at."; + } + + @Override + public String getUsage() { + return "/cv placepillar"; + } + + @Override + public void perform(CommandSender sender, String[] args) { + if (sender instanceof Player player) { + User user = plugin.users.get(player.getUniqueId()); + Civilisation civilisation = plugin.civilisations.get(user.getCivilisationId()); + + if (civilisation == null) { + player.sendMessage(SimpleCivilisations.color + "You must be in a civilisation to run this command."); + return; + } else if (!civilisation.getLeader().toString().equals(player.getUniqueId().toString())) { + player.sendMessage(SimpleCivilisations.color + "Only the leader may rename the civilisation."); + return; + } else if (civilisation.getPillarsAvailable() < 1) { + player.sendMessage(SimpleCivilisations.color + "Your civilisation has no available pillars."); + return; + } + + Block block = player.getTargetBlockExact(5); + if (block == null) { + player.sendMessage(SimpleCivilisations.color + "The block you are looking at is too far away."); + return; + } + + World world = block.getWorld(); + if (block.isLiquid() || block.isPassable()) { + player.sendMessage(SimpleCivilisations.color + "You can't place a pillar on this block."); + return; + } else if (List.of( + Material.AIR, + Material.CAVE_AIR, + Material.VOID_AIR + ).contains(world.getBlockAt(block.getX(), block.getY() - 1, block.getZ()).getType())) { + player.sendMessage(SimpleCivilisations.color + "The area underneath this block is not suitable for a pillar."); + return; + } + + if (overlapsTerritory(block.getLocation(), civilisation.getUniqueId())) { + player.sendMessage(SimpleCivilisations.color + "This is too close to another pillar."); + return; + } + + Block above = world.getBlockAt(block.getX(), block.getY() + 1, block.getZ()); + if (above.isLiquid()) { + player.sendMessage(SimpleCivilisations.color + "Pillars cannot be submerged."); + return; + } + + if (!world.getHighestBlockAt(block.getLocation()).equals(block)) { + player.sendMessage(SimpleCivilisations.color + "Pillars cannot have any blocks above them."); + return; + } + + int levels = 0, total = 0; + Chunk chunk = block.getChunk(); + for (int x = chunk.getX() * 16; x < chunk.getX() * 16 + 16; x++) { + for (int z = chunk.getZ() * 16; z < chunk.getZ() * 16 + 16; z++) { + Block b = world.getHighestBlockAt(x, z); + if (b.getType().toString().endsWith("LEAVES")) continue; + levels += world.getHighestBlockYAt(x, z); + total += 1; + } + } + int average = levels / total; + + if (Math.abs(block.getY() - average) > 2) { + player.sendMessage(SimpleCivilisations.color + "Pillars can only be placed on an even, above ground surface."); + return; + } + + int x = above.getX(), y = above.getY(), z = above.getZ(); + + Location location = new Location(world, x, y, z); + if (player.getLocation().distance(location) < 1) { + player.teleport(new Location(world, x - 0.5, world.getHighestBlockYAt(x - 1, z - 1) + 1, z - 0.5, -45, 0)); + } + player.playEffect(EntityEffect.TELEPORT_ENDER); + + Block b1 = world.getBlockAt(x, y, z); + b1.setType(Material.SPRUCE_LOG); + surroundWithStairs(b1, false); + world.getBlockAt(x, y + 1, z).setType(Material.OBSIDIAN); + world.getBlockAt(x, y + 2, z).setType(Material.STONE_BRICK_WALL); + world.getBlockAt(x, y + 3, z).setType(Material.STONE_BRICK_WALL); + Block b2 = world.getBlockAt(x, y + 4, z); + b2.setType(Material.REDSTONE_LAMP); + surroundWithStairs(b2, true); + Block b3 = world.getBlockAt(x, y + 5, z); + b3.setType(Material.DAYLIGHT_DETECTOR); + DaylightDetector sensorData = (DaylightDetector) b3.getBlockData(); + sensorData.setInverted(true); + b3.setBlockData(sensorData, false); + + civilisation.addPillar(new Location(world, x, y + 1, z)); + civilisation.usePillar(); + player.sendMessage(SimpleCivilisations.color + "Pillar placed."); + return; + } + sender.sendMessage(ChatColor.RED + "Only players may run this command."); + } + + public void surroundWithStairs(Block centerBlock, boolean upsidedown) { + BlockFace[] faces = {BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST}; + + for (BlockFace face : faces) { + Block block = centerBlock.getRelative(face); + block.setType(Material.SPRUCE_STAIRS); + + Stairs stairData = (Stairs) block.getBlockData(); + if (upsidedown) stairData.setHalf(Bisected.Half.TOP); + stairData.setFacing(face.getOppositeFace()); + block.setBlockData(stairData, false); + } + } + + public boolean overlapsTerritory(Location location, UUID uuid) { + World world = location.getWorld(); + double halfLength = (4 * 16 + 7.5); + double x = location.getChunk().getX() * 16 + 7.5; + double z = location.getChunk().getZ() * 16 + 7.5; + + for (Civilisation civilisation : plugin.civilisations.values()) { + for (Pillar pillar : civilisation.getPillars()) { + if (pillar.getCivilisationId() == uuid) { + if (location.getChunk() == pillar.getLocation().getChunk()) { + return true; + } + } else { + if ( + SimpleCivilisations.inRangeOfPillar(new Location(world, x + halfLength, location.getBlockY(), z + halfLength), pillar) || + SimpleCivilisations.inRangeOfPillar(new Location(world, x + halfLength, location.getBlockY(), z - halfLength), pillar) || + SimpleCivilisations.inRangeOfPillar(new Location(world, x - halfLength, location.getBlockY(), z + halfLength), pillar) || + SimpleCivilisations.inRangeOfPillar(new Location(world, x - halfLength, location.getBlockY(), z - halfLength), pillar) + ) { + return true; + } + } + } + } + + return false; + } +} diff --git a/src/main/java/com/marco/simplecivilisations/commands/subcommands/RemovePillarCommand.java b/src/main/java/com/marco/simplecivilisations/commands/subcommands/RemovePillarCommand.java new file mode 100644 index 0000000..a7b1cf6 --- /dev/null +++ b/src/main/java/com/marco/simplecivilisations/commands/subcommands/RemovePillarCommand.java @@ -0,0 +1,78 @@ +package com.marco.simplecivilisations.commands.subcommands; + +import com.marco.simplecivilisations.SimpleCivilisations; +import com.marco.simplecivilisations.commands.SubCommand; +import com.marco.simplecivilisations.sql.Civilisation; +import com.marco.simplecivilisations.sql.Pillar; +import com.marco.simplecivilisations.sql.User; +import org.bukkit.*; +import org.bukkit.block.Block; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.List; + +public class RemovePillarCommand extends SubCommand { + public RemovePillarCommand(SimpleCivilisations plugin) { + super(plugin); + } + + @Override + public List getLabels() { + return List.of("removepillar"); + } + + @Override + public String getDescription() { + return "Remove the pillar you are looking at."; + } + + @Override + public String getUsage() { + return "/cv removepillar"; + } + + @Override + public void perform(CommandSender sender, String[] args) { + if (sender instanceof Player player) { + User user = plugin.users.get(player.getUniqueId()); + Civilisation civilisation = plugin.civilisations.get(user.getCivilisationId()); + + if (civilisation == null) { + player.sendMessage(SimpleCivilisations.color + "You must be in a civilisation to run this command."); + return; + } else if (!civilisation.getLeader().toString().equals(player.getUniqueId().toString())) { + player.sendMessage(SimpleCivilisations.color + "Only the leader may rename the civilisation."); + return; + } + + Block block = player.getTargetBlockExact(5); + if (block == null) { + player.sendMessage(SimpleCivilisations.color + "The block you are looking at is too far away."); + return; + } + + boolean found = false; + for (Pillar pillar : civilisation.getPillars()) { + if (pillar.getLocation().equals(block.getLocation())) { + found = true; + if (!pillar.isActive()) { + player.sendMessage(SimpleCivilisations.color + "This pillar cannot be removed via a command."); + } else { + civilisation.getPillars().remove(pillar); + pillar.remove(); + civilisation.gainPillar(); + player.sendMessage(SimpleCivilisations.color + "Pillar removed."); + } + break; + } + } + if (!found) { + player.sendMessage(SimpleCivilisations.color + "No pillar found at the block you are looking at."); + } + + return; + } + sender.sendMessage(ChatColor.RED + "Only players may run this command."); + } +} diff --git a/src/main/java/com/marco/simplecivilisations/commands/subcommands/RenameCommand.java b/src/main/java/com/marco/simplecivilisations/commands/subcommands/RenameCommand.java index 37b32d9..09f3e66 100644 --- a/src/main/java/com/marco/simplecivilisations/commands/subcommands/RenameCommand.java +++ b/src/main/java/com/marco/simplecivilisations/commands/subcommands/RenameCommand.java @@ -3,6 +3,7 @@ import com.marco.simplecivilisations.SimpleCivilisations; import com.marco.simplecivilisations.commands.SubCommand; import com.marco.simplecivilisations.sql.Civilisation; +import com.marco.simplecivilisations.sql.User; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; @@ -33,26 +34,27 @@ public String getUsage() { @Override public void perform(CommandSender sender, String[] args) { if (sender instanceof Player player) { - Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { - Civilisation civilisation = SQL.getCivilisationFromPlayerUUID(player.getUniqueId()); + User user = plugin.users.get(player.getUniqueId()); + Civilisation civilisation = plugin.civilisations.get(user.getCivilisationId()); - if (civilisation == null) { - player.sendMessage(SimpleCivilisations.color + "You must be in a civilisation to run this command."); - return; - } else if (!civilisation.getLeader().toString().equals(player.getUniqueId().toString())) { - player.sendMessage(SimpleCivilisations.color + "Only the leader may rename the civilisation."); - return; - } else if (args.length == 0) { - player.sendMessage(SimpleCivilisations.color + getUsage()); - return; - } else if (args.length > 1) { - player.sendMessage(SimpleCivilisations.color + "Civilisation names cannot contain spaces."); - return; - } else if (args[0].length() > 20) { - player.sendMessage(SimpleCivilisations.color + "Civilisation names cannot exceed 20 characters."); - return; - } + if (civilisation == null) { + player.sendMessage(SimpleCivilisations.color + "You must be in a civilisation to run this command."); + return; + } else if (!civilisation.getLeader().toString().equals(player.getUniqueId().toString())) { + player.sendMessage(SimpleCivilisations.color + "Only the leader may rename the civilisation."); + return; + } else if (args.length == 0) { + player.sendMessage(SimpleCivilisations.color + getUsage()); + return; + } else if (args.length > 1) { + player.sendMessage(SimpleCivilisations.color + "Civilisation names cannot contain spaces."); + return; + } else if (args[0].length() > 20) { + player.sendMessage(SimpleCivilisations.color + "Civilisation names cannot exceed 20 characters."); + return; + } + Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { civilisation.setName(args[0]); player.sendMessage(SimpleCivilisations.color + "Civilisation name updated."); }); diff --git a/src/main/java/com/marco/simplecivilisations/commands/subcommands/SetleaderCommand.java b/src/main/java/com/marco/simplecivilisations/commands/subcommands/SetleaderCommand.java index 7377b1e..d119b34 100644 --- a/src/main/java/com/marco/simplecivilisations/commands/subcommands/SetleaderCommand.java +++ b/src/main/java/com/marco/simplecivilisations/commands/subcommands/SetleaderCommand.java @@ -37,36 +37,36 @@ public String getUsage() { @Override public void perform(CommandSender sender, String[] args) { if (sender instanceof Player player) { - Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { - User user = SQL.getUser(player.getUniqueId()); - if (user == null) { - player.sendMessage(ChatColor.RED + "Something went wrong!"); - return; - } else if (user.getCivilisationId() == null) { - player.sendMessage(SimpleCivilisations.color + "You must be in a civilisation to run this command."); - return; - } else if (user.getRole() < 3) { - player.sendMessage(SimpleCivilisations.color + "Only the leader of your civilisation can run this command."); - return; - } + User user = plugin.users.get(player.getUniqueId()); + if (user == null) { + player.sendMessage(ChatColor.RED + "Something went wrong!"); + return; + } else if (user.getCivilisationId() == null) { + player.sendMessage(SimpleCivilisations.color + "You must be in a civilisation to run this command."); + return; + } else if (user.getRole() < 3) { + player.sendMessage(SimpleCivilisations.color + "Only the leader of your civilisation can run this command."); + return; + } - UUID uuid = SimpleCivilisations.uuidFromName(args[0]); - Player targetPlayer = Bukkit.getPlayer(args[0]); - String targetName = targetPlayer == null ? args[0] : targetPlayer.getName(); - if (uuid == null) { - player.sendMessage(SimpleCivilisations.color + "Player not found."); - return; - } else if (targetPlayer == player) { - player.sendMessage(SimpleCivilisations.color + "You are already the leader of this civilisation."); - return; - } + UUID uuid = SimpleCivilisations.uuidFromName(args[0]); + Player targetPlayer = Bukkit.getPlayer(args[0]); + String targetName = targetPlayer == null ? args[0] : targetPlayer.getName(); + if (uuid == null) { + player.sendMessage(SimpleCivilisations.color + "Player not found."); + return; + } else if (targetPlayer == player) { + player.sendMessage(SimpleCivilisations.color + "You are already the leader of this civilisation."); + return; + } - Civilisation civilisation = SQL.getCivilisation(user); - if (!civilisation.hasMember(uuid)) { - player.sendMessage(SimpleCivilisations.color + targetName + " is not a member of your civilisation."); - return; - } + Civilisation civilisation = plugin.civilisations.get(user.getCivilisationId()); + if (!civilisation.hasMember(uuid)) { + player.sendMessage(SimpleCivilisations.color + targetName + " is not a member of your civilisation."); + return; + } + Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { civilisation.setLeader(uuid); civilisation.messageOnlineMembers(targetName + " has been promoted to the leader of the civilisation."); }); diff --git a/src/main/java/com/marco/simplecivilisations/commands/subcommands/SetwaypointCommand.java b/src/main/java/com/marco/simplecivilisations/commands/subcommands/SetwaypointCommand.java index 757e671..c7a0181 100644 --- a/src/main/java/com/marco/simplecivilisations/commands/subcommands/SetwaypointCommand.java +++ b/src/main/java/com/marco/simplecivilisations/commands/subcommands/SetwaypointCommand.java @@ -3,6 +3,7 @@ import com.marco.simplecivilisations.SimpleCivilisations; import com.marco.simplecivilisations.commands.SubCommand; import com.marco.simplecivilisations.sql.Civilisation; +import com.marco.simplecivilisations.sql.User; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; @@ -35,21 +36,23 @@ public String getUsage() { @Override public void perform(CommandSender sender, String[] args) { if (sender instanceof Player player) { - Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { - Civilisation civilisation = SQL.getCivilisationFromPlayerUUID(player.getUniqueId()); + User user = plugin.users.get(player.getUniqueId()); + Civilisation civilisation = plugin.civilisations.get(user.getCivilisationId()); + + if (civilisation == null) { + player.sendMessage(SimpleCivilisations.color + "You must be in a civilisation to run this command."); + return; + } else if (!civilisation.getLeader().toString().equals(player.getUniqueId().toString())) { + player.sendMessage(SimpleCivilisations.color + "Only the leader may set the civilisation waypoint."); + return; + } else if (args.length > 1) { + player.sendMessage(SimpleCivilisations.color + getUsage()); + return; + } - if (civilisation == null) { - player.sendMessage(SimpleCivilisations.color + "You must be in a civilisation to run this command."); - return; - } else if (!civilisation.getLeader().toString().equals(player.getUniqueId().toString())) { - player.sendMessage(SimpleCivilisations.color + "Only the leader may set the civilisation waypoint."); - return; - } else if (args.length > 1) { - player.sendMessage(SimpleCivilisations.color + getUsage()); - return; - } + boolean clear = args.length == 1 && args[0].equalsIgnoreCase("none"); - boolean clear = args.length == 1 && args[0].equalsIgnoreCase("none"); + Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { civilisation.setWaypoint(clear ? null : player.getLocation()); player.sendMessage(SimpleCivilisations.color + "Civilisation waypoint updated."); }); diff --git a/src/main/java/com/marco/simplecivilisations/commands/subcommands/UninviteCommand.java b/src/main/java/com/marco/simplecivilisations/commands/subcommands/UninviteCommand.java index f3f36a2..11ebdc4 100644 --- a/src/main/java/com/marco/simplecivilisations/commands/subcommands/UninviteCommand.java +++ b/src/main/java/com/marco/simplecivilisations/commands/subcommands/UninviteCommand.java @@ -37,41 +37,42 @@ public String getUsage() { @Override public void perform(CommandSender sender, String[] args) { if (sender instanceof Player player) { - Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { - User user = SQL.getUser(player.getUniqueId()); - if (user == null) { - player.sendMessage(ChatColor.RED + "Something went wrong!"); - return; - } else if (user.getCivilisationId() == null) { - player.sendMessage(SimpleCivilisations.color + "You must be in a civilisation to run this command."); - return; - } else if (user.getRole() < 2) { - player.sendMessage(SimpleCivilisations.color + "You need a higher seniority level within your civilisation to run this command."); - return; - } else if (args.length != 1) { - player.sendMessage(SimpleCivilisations.color + "Usage: " + getUsage()); - return; - } + User user = plugin.users.get(player.getUniqueId()); + if (user == null) { + player.sendMessage(ChatColor.RED + "Something went wrong!"); + return; + } else if (user.getCivilisationId() == null) { + player.sendMessage(SimpleCivilisations.color + "You must be in a civilisation to run this command."); + return; + } else if (user.getRole() < 2) { + player.sendMessage(SimpleCivilisations.color + "You need a higher seniority level within your civilisation to run this command."); + return; + } else if (args.length != 1) { + player.sendMessage(SimpleCivilisations.color + "Usage: " + getUsage()); + return; + } - UUID uuid = SimpleCivilisations.uuidFromName(args[0]); - Player targetPlayer = Bukkit.getPlayer(args[0]); - String targetName = targetPlayer == null ? args[0] : targetPlayer.getName(); - if (uuid == null) { - player.sendMessage(SimpleCivilisations.color + "Player not found."); - return; - } + UUID uuid = SimpleCivilisations.uuidFromName(args[0]); + Player targetPlayer = Bukkit.getPlayer(args[0]); + String targetName = targetPlayer == null ? args[0] : targetPlayer.getName(); + if (uuid == null) { + player.sendMessage(SimpleCivilisations.color + "Player not found."); + return; + } - User target = SQL.getUser(uuid); - Civilisation civilisation = SQL.getCivilisation(user); + User target = plugin.users.get(uuid); + Civilisation civilisation = plugin.civilisations.get(user.getCivilisationId()); - if (civilisation.isOpen()) { - player.sendMessage(SimpleCivilisations.color + "Your civilisation is open and anyone can join."); - return; - } else if (!civilisation.hasInvited(target)) { + if (civilisation.isOpen()) { + player.sendMessage(SimpleCivilisations.color + "Your civilisation is open and anyone can join."); + return; + } + + Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { + if (!civilisation.hasInvited(target)) { player.sendMessage(SimpleCivilisations.color + targetName + " has not been invited."); return; } - civilisation.uninvite(target); player.sendMessage(SimpleCivilisations.color + targetName + " is no longer invited."); }); diff --git a/src/main/java/com/marco/simplecivilisations/commands/subcommands/WaypointCommand.java b/src/main/java/com/marco/simplecivilisations/commands/subcommands/WaypointCommand.java index 3d2bd7e..1f42bbe 100644 --- a/src/main/java/com/marco/simplecivilisations/commands/subcommands/WaypointCommand.java +++ b/src/main/java/com/marco/simplecivilisations/commands/subcommands/WaypointCommand.java @@ -35,18 +35,19 @@ public String getUsage() { @Override public void perform(CommandSender sender, String[] args) { if (sender instanceof Player player) { + User user = plugin.users.get(player.getUniqueId()); + Civilisation civilisation = plugin.civilisations.get(user.getCivilisationId()); + if (civilisation == null) { + player.sendMessage(SimpleCivilisations.color + "You are not a member of a civilisation."); + return; + } else if (civilisation.getWaypoint() == null) { + player.sendMessage(SimpleCivilisations.color + "Your civilisation does not have a waypoint set."); + return; + } + + Location wp = civilisation.getWaypoint(); + Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { - User user = SQL.getUser(player.getUniqueId()); - Civilisation civilisation = SQL.getCivilisation(user); - if (civilisation == null) { - player.sendMessage(SimpleCivilisations.color + "You are not a member of a civilisation."); - return; - } else if (civilisation.getWaypoint() == null) { - player.sendMessage(SimpleCivilisations.color + "Your civilisation does not have a waypoint set."); - return; - } - - Location wp = civilisation.getWaypoint(); player.sendMessage(SimpleCivilisations.color + "Waypoint: " + ChatColor.GRAY + wp.getBlockX() + ", " + wp.getBlockY() + ", " + wp.getBlockZ() + SimpleCivilisations.color + "."); }); diff --git a/src/main/java/com/marco/simplecivilisations/listeners/BlockBreakListener.java b/src/main/java/com/marco/simplecivilisations/listeners/BlockBreakListener.java new file mode 100644 index 0000000..33175f6 --- /dev/null +++ b/src/main/java/com/marco/simplecivilisations/listeners/BlockBreakListener.java @@ -0,0 +1,75 @@ +package com.marco.simplecivilisations.listeners; + +import com.marco.simplecivilisations.SimpleCivilisations; +import com.marco.simplecivilisations.commands.SeenCommand; +import com.marco.simplecivilisations.sql.Civilisation; +import com.marco.simplecivilisations.sql.Pillar; +import org.bukkit.*; +import org.bukkit.event.EventHandler; +import org.bukkit.event.block.BlockBreakEvent; + +import java.sql.Timestamp; +import java.time.Duration; +import java.time.Instant; +import java.util.concurrent.TimeUnit; + +public class BlockBreakListener extends EventListener { + public BlockBreakListener(SimpleCivilisations plugin) { + super(plugin); + } + + @EventHandler + public void listen(BlockBreakEvent event) { + Location location = event.getBlock().getLocation(); + for (Civilisation civilisation : plugin.civilisations.values()) { + for (Pillar pillar : civilisation.getPillars()) { + if (SimpleCivilisations.inRangeOfPillar(location, pillar)) { + if (!civilisation.hasMember(event.getPlayer().getUniqueId()) && pillar.isActive()) { + if (event.getPlayer().hasPermission("simplecivilisations.bypassterritory") && event.getPlayer().getGameMode() == GameMode.CREATIVE && location.distance(pillar.getLocation()) >= 5) return; + if (location.equals(pillar.getLocation())) { + // They have broken the important block. + event.setCancelled(true); + event.getBlock().setType(Material.RED_CONCRETE); + pillar.destroy(); + World world = event.getBlock().getWorld(); + double x = event.getBlock().getLocation().getX() + 0.5; + double y = event.getBlock().getLocation().getY() + 0.5; + double z = event.getBlock().getLocation().getZ() + 0.5; + Particle particle = Particle.EXPLOSION_NORMAL; + world.spawnParticle(particle, x, y, z, 100); + event.getPlayer().sendMessage(SimpleCivilisations.color + "Territory disabled!"); + Bukkit.getOnlinePlayers().forEach(p -> { + if (civilisation.hasMember(p.getUniqueId())) { + p.sendTitle("§cPillar disabled!", "§7One of your pillars has been disabled.", 1, 40, 1); + p.playSound(p.getLocation(), Sound.BLOCK_ANVIL_BREAK, 1, 1); + } + }); + } else { + event.getPlayer().sendMessage(SimpleCivilisations.color + "You cannot build in " + ChatColor.YELLOW + civilisation.getName() + SimpleCivilisations.color + "'s territory."); + event.setCancelled(true); + } + } else if (location.distance(pillar.getLocation()) < 5) { + if (civilisation.hasMember(event.getPlayer().getUniqueId()) && !pillar.isActive() && event.getBlock().getType() == Material.RED_CONCRETE && location.equals(pillar.getLocation())) { + if (Duration.between(pillar.getDestroyed().toInstant(), Instant.now()).toMinutes() >= 60) { + event.setCancelled(true); + civilisation.getPillars().remove(pillar); + pillar.remove(); + civilisation.gainPillar(); + event.getPlayer().sendMessage(SimpleCivilisations.color + "Pillar removed."); + } else { + Timestamp timeWhenNotBanned = Timestamp.from(pillar.getDestroyed().toInstant().plusSeconds(TimeUnit.MINUTES.toSeconds(60))); + String remaining = SeenCommand.getTimestampDifference(Timestamp.from(Instant.now()), timeWhenNotBanned); + event.getPlayer().sendMessage(SimpleCivilisations.color + "You cannot remove this pillar for another " + remaining + "."); + event.setCancelled(true); + } + return; + } + event.getPlayer().sendMessage(SimpleCivilisations.color + "You cannot build this close to a pillar"); + event.setCancelled(true); + } + return; + } + } + } + } +} \ No newline at end of file diff --git a/src/main/java/com/marco/simplecivilisations/listeners/BlockDamageListener.java b/src/main/java/com/marco/simplecivilisations/listeners/BlockDamageListener.java new file mode 100644 index 0000000..eb8bfbf --- /dev/null +++ b/src/main/java/com/marco/simplecivilisations/listeners/BlockDamageListener.java @@ -0,0 +1,66 @@ +package com.marco.simplecivilisations.listeners; + +import com.marco.simplecivilisations.SimpleCivilisations; +import com.marco.simplecivilisations.sql.Civilisation; +import com.marco.simplecivilisations.sql.Pillar; +import net.md_5.bungee.api.ChatMessageType; +import net.md_5.bungee.api.chat.TextComponent; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.block.BlockDamageEvent; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import java.util.UUID; + +public class BlockDamageListener extends EventListener { + public BlockDamageListener(SimpleCivilisations plugin) { + super(plugin); + } + + @EventHandler + public void listen(BlockDamageEvent event) { + if (event.getBlock().getType() != Material.OBSIDIAN) return; + Block block = event.getBlock(); + for (Civilisation civilisation : plugin.civilisations.values()) { + for (Pillar pillar : civilisation.getPillars()) { + if (block.getLocation().equals(pillar.getLocation()) && pillar.isActive()) { + Player player = event.getPlayer(); + if (!civilisation.hasMember(player.getUniqueId())) { + if (event.getItemInHand().getType() != Material.DIAMOND_PICKAXE || event.getItemInHand().getEnchantments().size() != 0) { + event.setCancelled(true); + player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText("§cYou can only break this block with an unenchanted diamond pickaxe.")); + return; + } + + int online = 0; + for (UUID uuid : civilisation.getMembers()) if (Bukkit.getPlayer(uuid) != null) online++; + int require = (civilisation.getMembers().size() + 2) / 3; + + if (online < require) { + event.setCancelled(true); + player.playSound(player.getLocation(), Sound.ENTITY_ITEM_BREAK, 1, 0.5f); + player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText("§e" + civilisation.getName() + "§c does not have enough members online (" + online + "/" + require + ").")); + return; + } + + player.playSound(player.getLocation(), Sound.ENTITY_ENDER_DRAGON_GROWL, 1, 1); + player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText("§cYou are now contesting the territory of §e" + civilisation.getName() + "§c.")); + player.addPotionEffect(new PotionEffect(PotionEffectType.SLOW_DIGGING, 20 * 90, 1)); + Bukkit.getOnlinePlayers().forEach(p -> { + if (civilisation.hasMember(p.getUniqueId())) { + p.sendTitle("§cPillar being contested!", "§7One of your pillars is being contested.", 1, 40, 1); + p.playSound(p.getLocation(), Sound.ENTITY_ENDER_DRAGON_GROWL, 1, 1); + } + }); + } + return; + } + } + } + } +} diff --git a/src/main/java/com/marco/simplecivilisations/listeners/BlockPlaceListener.java b/src/main/java/com/marco/simplecivilisations/listeners/BlockPlaceListener.java new file mode 100644 index 0000000..9a78e6e --- /dev/null +++ b/src/main/java/com/marco/simplecivilisations/listeners/BlockPlaceListener.java @@ -0,0 +1,36 @@ +package com.marco.simplecivilisations.listeners; + +import com.marco.simplecivilisations.SimpleCivilisations; +import com.marco.simplecivilisations.sql.Civilisation; +import com.marco.simplecivilisations.sql.Pillar; +import org.bukkit.ChatColor; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.event.EventHandler; +import org.bukkit.event.block.BlockPlaceEvent; + +public class BlockPlaceListener extends EventListener { + public BlockPlaceListener(SimpleCivilisations plugin) { + super(plugin); + } + + @EventHandler + public void listen(BlockPlaceEvent event) { + Location location = event.getBlock().getLocation(); + for (Civilisation civilisation : plugin.civilisations.values()) { + for (Pillar pillar : civilisation.getPillars()) { + if (SimpleCivilisations.inRangeOfPillar(location, pillar)) { + if (!civilisation.hasMember(event.getPlayer().getUniqueId()) && pillar.isActive()) { + if (event.getPlayer().hasPermission("simplecivilisations.bypassterritory") && event.getPlayer().getGameMode() == GameMode.CREATIVE && location.distance(pillar.getLocation()) >= 5) return; + event.getPlayer().sendMessage(SimpleCivilisations.color + "You cannot build in " + ChatColor.YELLOW + civilisation.getName() + SimpleCivilisations.color + "'s territory."); + event.setCancelled(true); + } else if (location.distance(pillar.getLocation()) < 5) { + event.getPlayer().sendMessage(SimpleCivilisations.color + "You cannot build this close to a pillar"); + event.setCancelled(true); + } + return; + } + } + } + } +} diff --git a/src/main/java/com/marco/simplecivilisations/listeners/EntityExplodeListener.java b/src/main/java/com/marco/simplecivilisations/listeners/EntityExplodeListener.java new file mode 100644 index 0000000..71f30fb --- /dev/null +++ b/src/main/java/com/marco/simplecivilisations/listeners/EntityExplodeListener.java @@ -0,0 +1,30 @@ +package com.marco.simplecivilisations.listeners; + +import com.marco.simplecivilisations.SimpleCivilisations; +import com.marco.simplecivilisations.sql.Civilisation; +import com.marco.simplecivilisations.sql.Pillar; +import org.bukkit.entity.EntityType; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityExplodeEvent; + +import java.util.List; + +public class EntityExplodeListener extends EventListener { + public EntityExplodeListener(SimpleCivilisations plugin) { + super(plugin); + } + + @EventHandler + public void listen(EntityExplodeEvent event) { + if (List.of(EntityType.PRIMED_TNT, EntityType.MINECART_TNT).contains(event.getEntityType())) { + for (Civilisation civilisation : plugin.civilisations.values()) { + for (Pillar pillar : civilisation.getPillars()) { + if (SimpleCivilisations.inRangeOfPillar(event.getLocation(), pillar)) { + event.setCancelled(true); + return; + } + } + } + } + } +} diff --git a/src/main/java/com/marco/simplecivilisations/listeners/PlayerInteractListener.java b/src/main/java/com/marco/simplecivilisations/listeners/PlayerInteractListener.java new file mode 100644 index 0000000..d8aa40b --- /dev/null +++ b/src/main/java/com/marco/simplecivilisations/listeners/PlayerInteractListener.java @@ -0,0 +1,37 @@ +package com.marco.simplecivilisations.listeners; + +import com.marco.simplecivilisations.SimpleCivilisations; +import com.marco.simplecivilisations.sql.Civilisation; +import com.marco.simplecivilisations.sql.Pillar; +import org.bukkit.ChatColor; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.event.EventHandler; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerInteractEvent; + +public class PlayerInteractListener extends EventListener { + public PlayerInteractListener(SimpleCivilisations plugin) { + super(plugin); + } + + @EventHandler + public void listen(PlayerInteractEvent event) { + if (event.getAction() != Action.RIGHT_CLICK_BLOCK || event.getClickedBlock() == null) return; + if (!event.getClickedBlock().getType().toString().endsWith("DOOR") && !event.getClickedBlock().getType().toString().endsWith("GATE")) return; + Location location = event.getClickedBlock().getLocation(); + + for (Civilisation civilisation : plugin.civilisations.values()) { + for (Pillar pillar : civilisation.getPillars()) { + if (SimpleCivilisations.inRangeOfPillar(location, pillar)) { + if (!civilisation.hasMember(event.getPlayer().getUniqueId()) && pillar.isActive()) { + if (event.getPlayer().hasPermission("simplecivilisations.bypassterritory") && event.getPlayer().getGameMode() == GameMode.CREATIVE) return; + event.getPlayer().sendMessage(SimpleCivilisations.color + "You cannot do this in " + ChatColor.YELLOW + civilisation.getName() + SimpleCivilisations.color + "'s territory."); + event.setCancelled(true); + } + return; + } + } + } + } +} diff --git a/src/main/java/com/marco/simplecivilisations/listeners/PlayerJoinListener.java b/src/main/java/com/marco/simplecivilisations/listeners/PlayerJoinListener.java index 324ab49..f89fcbc 100644 --- a/src/main/java/com/marco/simplecivilisations/listeners/PlayerJoinListener.java +++ b/src/main/java/com/marco/simplecivilisations/listeners/PlayerJoinListener.java @@ -20,10 +20,9 @@ public PlayerJoinListener(SimpleCivilisations plugin) { public void listen(PlayerJoinEvent event) { User user = plugin.getSQL().createUser(event.getPlayer()); if (user.getLastDeath() == null) return; - // TODO: get deathban duration from config. - int minutes = 15; + int minutes = plugin.getConfig().getInt("deathban"); Duration duration = Duration.between(user.getLastDeath().toInstant(), Instant.now()); - if (duration.toMinutes() > minutes) { + if (duration.toMinutes() >= minutes) { user.setLastDeath(null); } else { Timestamp timeWhenNotBanned = Timestamp.from(user.getLastDeath().toInstant().plusSeconds(TimeUnit.MINUTES.toSeconds(minutes))); diff --git a/src/main/java/com/marco/simplecivilisations/listeners/PlayerMoveListener.java b/src/main/java/com/marco/simplecivilisations/listeners/PlayerMoveListener.java new file mode 100644 index 0000000..8d26569 --- /dev/null +++ b/src/main/java/com/marco/simplecivilisations/listeners/PlayerMoveListener.java @@ -0,0 +1,55 @@ +package com.marco.simplecivilisations.listeners; + +import com.marco.simplecivilisations.SimpleCivilisations; +import com.marco.simplecivilisations.sql.Civilisation; +import com.marco.simplecivilisations.sql.Pillar; +import net.md_5.bungee.api.ChatMessageType; +import net.md_5.bungee.api.chat.TextComponent; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerMoveEvent; + +import java.util.List; + +public class PlayerMoveListener extends EventListener { + public PlayerMoveListener(SimpleCivilisations plugin) { + super(plugin); + } + + @EventHandler + public void listen(PlayerMoveEvent event) { + if (event.getFrom().getChunk().equals(event.getTo().getChunk())) return; + List civilisations = plugin.civilisations.values().stream().toList(); + + Pillar to = null, from = null; + + for (Civilisation civilisation : civilisations) { + if (to != null && from != null) break; + for (Pillar pillar : civilisation.getPillars()) { + if (to != null && from != null) break; + if (SimpleCivilisations.inRangeOfPillar(event.getTo(), pillar)) { + to = pillar; + } + if (SimpleCivilisations.inRangeOfPillar(event.getFrom(), pillar)) { + from = pillar; + } + } + } + + if (to == null && from == null) { + return; + } else if (to != null && from != null) { + if (to.getCivilisationId().toString().equals(from.getCivilisationId().toString())) { + return; + } else { + Civilisation civilisation = plugin.civilisations.get(to.getCivilisationId()); + event.getPlayer().spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText("§6Entering §e" + civilisation.getName() + "§6's territory.")); + } + } else if (to == null) { + Civilisation civilisation = plugin.civilisations.get(from.getCivilisationId()); + event.getPlayer().spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText("§6Leaving §e" + civilisation.getName() + "§6's territory.")); + } else if (from == null) { + Civilisation civilisation = plugin.civilisations.get(to.getCivilisationId()); + event.getPlayer().spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText("§6Entering §e" + civilisation.getName() + "§6's territory.")); + } + } +} diff --git a/src/main/java/com/marco/simplecivilisations/listeners/PlayerRespawnEvent.java b/src/main/java/com/marco/simplecivilisations/listeners/PlayerRespawnEvent.java index 3edfccc..c447c7c 100644 --- a/src/main/java/com/marco/simplecivilisations/listeners/PlayerRespawnEvent.java +++ b/src/main/java/com/marco/simplecivilisations/listeners/PlayerRespawnEvent.java @@ -17,7 +17,7 @@ public PlayerRespawnEvent(SimpleCivilisations plugin) { @EventHandler(priority = EventPriority.MONITOR) public void listen(org.bukkit.event.player.PlayerRespawnEvent event) { - User user = plugin.getSQL().getUser(event.getPlayer().getUniqueId()); + User user = plugin.users.get(event.getPlayer().getUniqueId()); user.setLastDeath(Timestamp.from(Instant.now())); Location bed = event.getPlayer().getBedSpawnLocation(); event.setRespawnLocation(bed != null ? bed : user.getSpawnPoint()); diff --git a/src/main/java/com/marco/simplecivilisations/sql/Civilisation.java b/src/main/java/com/marco/simplecivilisations/sql/Civilisation.java index 416c269..142a74c 100644 --- a/src/main/java/com/marco/simplecivilisations/sql/Civilisation.java +++ b/src/main/java/com/marco/simplecivilisations/sql/Civilisation.java @@ -9,22 +9,25 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; -import java.util.ArrayList; +import java.util.List; import java.util.UUID; public class Civilisation { + private final SimpleCivilisations plugin; private final MySQL SQL; private final Connection connection; private final UUID uuid; private String name; private String description; private UUID leader; - private ArrayList members; + private List members; private boolean open; - private ArrayList territory; + private List pillars; + private int pillarsAvailable; private Location waypoint; - public Civilisation(SimpleCivilisations plugin, UUID uuid, String name, String description, UUID leader, ArrayList members, boolean open, ArrayList territory, Location waypoint) { + public Civilisation(SimpleCivilisations plugin, UUID uuid, String name, String description, UUID leader, List members, boolean open, List pillars, int pillarsAvailable, Location waypoint) { + this.plugin = plugin; this.SQL = plugin.getSQL(); this.connection = plugin.getSQL().getConnection(); this.uuid = uuid; @@ -33,7 +36,8 @@ public Civilisation(SimpleCivilisations plugin, UUID uuid, String name, String d this.leader = leader; this.members = members; this.open = open; - this.territory = territory; + this.pillars = pillars; + this.pillarsAvailable = pillarsAvailable; this.waypoint = waypoint; } @@ -103,7 +107,7 @@ public void setLeader(UUID leader) { } } - public ArrayList getMembers() { + public List getMembers() { return members; } @@ -203,7 +207,7 @@ public void disband() { u.setInt(2, 0); u.setString(3, uuid.toString()); u.executeUpdate(); - PreparedStatement t = connection.prepareStatement("DELETE FROM territories WHERE civilisation=?"); + PreparedStatement t = connection.prepareStatement("DELETE FROM pillars WHERE civilisation=?"); t.setString(1, uuid.toString()); t.executeUpdate(); PreparedStatement i = connection.prepareStatement("DELETE FROM invites WHERE civilisation=?"); @@ -228,4 +232,54 @@ public boolean hasMember(User user) { public boolean hasMember(UUID u) { return members.contains(u); } + + public int getPillarsAvailable() { + return pillarsAvailable; + } + + public void usePillar() { + try { + PreparedStatement ps = connection.prepareStatement("UPDATE civilisations SET pillarsAvailable=? WHERE uuid=?"); + ps.setInt(1, pillarsAvailable - 1); + ps.setString(2, uuid.toString()); + ps.executeUpdate(); + pillarsAvailable--; + } catch (SQLException e ) { + e.printStackTrace(); + } + } + + public void gainPillar() { + try { + PreparedStatement ps = connection.prepareStatement("UPDATE civilisations SET pillarsAvailable=? WHERE uuid=?"); + ps.setInt(1, pillarsAvailable + 1); + ps.setString(2, uuid.toString()); + ps.executeUpdate(); + pillarsAvailable ++; + } catch (SQLException e ) { + e.printStackTrace(); + } + } + + public void addPillar(Location location) { + try { + PreparedStatement ps = connection.prepareStatement("INSERT INTO pillars (civilisation, location, active) VALUES (?, ?, ?)"); + ps.setString(1, uuid.toString()); + ps.setString(2, MySQL.serialiseLocation(location)); + ps.setBoolean(3, true); + ps.executeUpdate(); + pillars.add(new Pillar( + plugin, + uuid, + location, + null + )); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + public List getPillars() { + return pillars; + } } diff --git a/src/main/java/com/marco/simplecivilisations/sql/MySQL.java b/src/main/java/com/marco/simplecivilisations/sql/MySQL.java index 8d3efc1..5030209 100644 --- a/src/main/java/com/marco/simplecivilisations/sql/MySQL.java +++ b/src/main/java/com/marco/simplecivilisations/sql/MySQL.java @@ -56,8 +56,8 @@ public void createTables() { Bukkit.getLogger().info("[SimpleCivilisations] Completing setup..."); try { PreparedStatement ps1 = connection.prepareStatement("CREATE TABLE IF NOT EXISTS users (uuid TEXT, civilisation TEXT, role INT, spawnPoint TEXT, lastSession TIMESTAMP, lastLocation TEXT, lives INT, lastDeath TIMESTAMP NULL, PRIMARY KEY (uuid(255)))"); - PreparedStatement ps2 = connection.prepareStatement("CREATE TABLE IF NOT EXISTS civilisations (uuid TEXT, name TEXT, description TEXT, leader TEXT, open BOOLEAN, waypoint TEXT, PRIMARY KEY (uuid(255)))"); - PreparedStatement ps3 = connection.prepareStatement("CREATE TABLE IF NOT EXISTS territories (civilisation TEXT, location TEXT, PRIMARY KEY (civilisation(255), location(255)))"); + PreparedStatement ps2 = connection.prepareStatement("CREATE TABLE IF NOT EXISTS civilisations (uuid TEXT, name TEXT, description TEXT, leader TEXT, open BOOLEAN, pillarsAvailable INT, waypoint TEXT, PRIMARY KEY (uuid(255)))"); + PreparedStatement ps3 = connection.prepareStatement("CREATE TABLE IF NOT EXISTS pillars (civilisation TEXT, location TEXT, destroyed TIMESTAMP NULL, PRIMARY KEY (civilisation(255), location(255)))"); PreparedStatement ps4 = connection.prepareStatement("CREATE TABLE IF NOT EXISTS invites (civilisation TEXT, user TEXT, PRIMARY KEY (civilisation(255), user(255)))"); ps1.executeUpdate(); ps2.executeUpdate(); @@ -104,7 +104,7 @@ public User createUser(Player player) { ps.setTimestamp(8, null); ps.executeUpdate(); - return new User( + User user = new User( plugin, uuid, null, @@ -115,6 +115,8 @@ public User createUser(Player player) { 0, null ); + plugin.users.put(uuid, user); + return user; } catch (SQLException e) { e.printStackTrace(); } @@ -122,6 +124,9 @@ public User createUser(Player player) { } public void updateSession(Player player) { + // MASSIVE WARNING TO MYSELF + // I'm not updating this in memory because I don't have to rn. + // If I ever try to fetch this information from memory, and it is stale, I'm reserving the right to tell myself "I told you so". try { UUID uuid = player.getUniqueId(); if (!exists(uuid)) { @@ -167,20 +172,6 @@ public User getUser(UUID uuid) { return null; } - public boolean isInCivilisation(Player player) { - try { - PreparedStatement ps = connection.prepareStatement("SELECT * FROM users WHERE uuid = ?"); - ps.setString(1, player.getUniqueId().toString()); - ResultSet results = ps.executeQuery(); - if (results.next()) { - return results.getString("civilisation") != null; - } - } catch (SQLException e) { - e.printStackTrace(); - } - return false; - } - public Civilisation createCivilisation(String name, Player player) { try { // Check if the name is taken. @@ -197,13 +188,14 @@ public Civilisation createCivilisation(String name, Player player) { return null; } - PreparedStatement ps = connection.prepareStatement("INSERT INTO civilisations (uuid, name, description, leader, open, waypoint) VALUES (?, ?, ?, ?, ?, ?)"); + PreparedStatement ps = connection.prepareStatement("INSERT INTO civilisations (uuid, name, description, leader, open, pillarsAvailable, waypoint) VALUES (?, ?, ?, ?, ?, ?, ?)"); ps.setString(1, uuid.toString()); ps.setString(2, name); ps.setString(3, "No description."); ps.setString(4, player.getUniqueId().toString()); ps.setBoolean(5, false); - ps.setString(6, null); + ps.setInt(6, 5); // TODO: Determine how many pillars a civilisation should have access to. + ps.setString(7, null); ps.executeUpdate(); player.sendMessage(SimpleCivilisations.color + "Civilisation created."); @@ -216,6 +208,7 @@ public Civilisation createCivilisation(String name, Player player) { new ArrayList<>(), false, new ArrayList<>(), + 1, null ); civilisation.setLeader(player.getUniqueId()); @@ -271,10 +264,6 @@ public Civilisation getCivilisation(String name) { return null; } - public Civilisation getCivilisation(User user) { - return getCivilisation(user.getCivilisationId()); - } - public Civilisation getCivilisation(UUID uuid) { try { PreparedStatement ps = connection.prepareStatement("SELECT * FROM civilisations WHERE uuid = ?"); @@ -302,12 +291,17 @@ public Civilisation getCivilisation(ResultSet results) { members.add(UUID.fromString(mUUID)); } - ArrayList territory = new ArrayList<>(); - PreparedStatement pst = connection.prepareStatement("SELECT * FROM territories WHERE civilisation = ?"); - pst.setString(1, uuid.toString()); - ResultSet territoryResult = pst.executeQuery(); - while (territoryResult.next()) { - territory.add(deserialiseLocation(territoryResult.getString("location"))); + ArrayList pillars = new ArrayList<>(); + PreparedStatement psp = connection.prepareStatement("SELECT * FROM pillars WHERE civilisation = ?"); + psp.setString(1, uuid.toString()); + ResultSet pillarsResult = psp.executeQuery(); + while (pillarsResult.next()) { + pillars.add(new Pillar( + plugin, + uuid, + deserialiseLocation(pillarsResult.getString("location")), + pillarsResult.getTimestamp("destroyed") + )); } String waypoint = results.getString("waypoint"); @@ -321,7 +315,8 @@ public Civilisation getCivilisation(ResultSet results) { UUID.fromString(results.getString("leader")), members, results.getBoolean("open"), - territory, + pillars, + results.getInt("pillarsAvailable"), waypoint != null ? deserialiseLocation(waypoint) : null ); } catch (Exception e) { @@ -334,7 +329,7 @@ public Civilisation getCivilisation(ResultSet results) { return null; } - public String serialiseLocation(Location location) { + public static String serialiseLocation(Location location) { // I'm sure there are better methods of doing this, but I've done this now, so we ball. return Objects.requireNonNull(location.getWorld()).getName() + "," + location.getX() + "," + @@ -344,7 +339,7 @@ public String serialiseLocation(Location location) { location.getPitch(); } - public Location deserialiseLocation(String locationString) { + public static Location deserialiseLocation(String locationString) { String[] parts = locationString.split(","); if (parts.length >= 6) { String worldName = parts[0]; diff --git a/src/main/java/com/marco/simplecivilisations/sql/Pillar.java b/src/main/java/com/marco/simplecivilisations/sql/Pillar.java new file mode 100644 index 0000000..b87c6fc --- /dev/null +++ b/src/main/java/com/marco/simplecivilisations/sql/Pillar.java @@ -0,0 +1,86 @@ +package com.marco.simplecivilisations.sql; + +import com.marco.simplecivilisations.SimpleCivilisations; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; + +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.time.Instant; +import java.util.UUID; + +public class Pillar { + private final SimpleCivilisations plugin; + private final UUID civilisationId; + private final Location location; + private Timestamp destroyed; + public Pillar(SimpleCivilisations plugin, UUID civilisationId, Location location, Timestamp destroyed) { + this.plugin = plugin; + this.civilisationId = civilisationId; + this.location = location; + this.destroyed = destroyed; + } + + public UUID getCivilisationId() { + return civilisationId; + } + + public Location getLocation() { + return location; + } + + public Timestamp getDestroyed() { + return destroyed; + } + + public boolean isActive() { + return destroyed == null; + } + + public void destroy() { + destroyed = Timestamp.from(Instant.now()); + Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { + try { + PreparedStatement ps = plugin.getSQL().getConnection().prepareStatement("UPDATE pillars SET destroyed=? WHERE civilisation=? AND location=?"); + ps.setTimestamp(1, destroyed); + ps.setString(2, civilisationId.toString()); + ps.setString(3, MySQL.serialiseLocation(location)); + ps.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + } + }); + } + + public void remove() { + location.getBlock().setType(Material.AIR); + World world = location.getWorld(); + assert world != null; + world.getBlockAt(location.getBlockX(), location.getBlockY() - 1, location.getBlockZ()).setType(Material.AIR); + world.getBlockAt(location.getBlockX() + 1, location.getBlockY() - 1, location.getBlockZ()).setType(Material.AIR); + world.getBlockAt(location.getBlockX() - 1, location.getBlockY() - 1, location.getBlockZ()).setType(Material.AIR); + world.getBlockAt(location.getBlockX(), location.getBlockY() - 1, location.getBlockZ() + 1).setType(Material.AIR); + world.getBlockAt(location.getBlockX(), location.getBlockY() - 1, location.getBlockZ() - 1).setType(Material.AIR); + world.getBlockAt(location.getBlockX(), location.getBlockY() + 1, location.getBlockZ()).setType(Material.AIR); + world.getBlockAt(location.getBlockX(), location.getBlockY() + 2, location.getBlockZ()).setType(Material.AIR); + world.getBlockAt(location.getBlockX(), location.getBlockY() + 3, location.getBlockZ()).setType(Material.AIR); + world.getBlockAt(location.getBlockX() + 1, location.getBlockY() + 3, location.getBlockZ()).setType(Material.AIR); + world.getBlockAt(location.getBlockX() - 1, location.getBlockY() + 3, location.getBlockZ()).setType(Material.AIR); + world.getBlockAt(location.getBlockX(), location.getBlockY() + 3, location.getBlockZ() + 1).setType(Material.AIR); + world.getBlockAt(location.getBlockX(), location.getBlockY() + 3, location.getBlockZ() - 1).setType(Material.AIR); + world.getBlockAt(location.getBlockX(), location.getBlockY() + 4, location.getBlockZ()).setType(Material.AIR); + Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { + try { + PreparedStatement ps = plugin.getSQL().getConnection().prepareStatement("DELETE FROM pillars WHERE civilisation=? AND location=?"); + ps.setString(1, civilisationId.toString()); + ps.setString(2, MySQL.serialiseLocation(location)); + ps.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + } + }); + } +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml new file mode 100644 index 0000000..36502fe --- /dev/null +++ b/src/main/resources/config.yml @@ -0,0 +1,18 @@ +# SimpleCivilisations Configuration + +# MySQL +# This plugin requires a MySQL database to run. +host: localhost +port: 3306 +database: test +username: "root" +password: "" + +# Spawning +min-x: -1500 +max-x: 1500 +min-z: -1500 +max-z: 1500 + +# Deathban (integer of minutes) +deathban: 15 \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index e374776..e8b83d5 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -18,4 +18,9 @@ commands: offlinetp: description: Teleport to an offline player. aliases: [otp] - usage: / \ No newline at end of file + usage: / + screload: + description: Reload the config. + aliases: [cvreload] + usage: / + permission: simplecivilisations.reload \ No newline at end of file