Gate Functionality, TNT Functionality started, Gates 100% working AND persistent.

This commit is contained in:
Laika 2022-05-06 12:08:34 -07:00
parent 38a5a4bcd4
commit d20b0f4982
17 changed files with 874 additions and 30 deletions

16
pom.xml
View File

@ -55,6 +55,10 @@
</build>
<repositories>
<repository>
<id>WorldEdit Repo</id>
<url>https://maven.enginehub.org/repo/</url>
</repository>
<repository>
<id>codemc-releases</id>
<url>https://repo.codemc.io/repository/maven-releases/</url>
@ -70,6 +74,18 @@
</repositories>
<dependencies>
<dependency>
<groupId>com.sk89q.worldedit</groupId>
<artifactId>worldedit-bukkit</artifactId>
<version>7.2.10</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.sk89q.worldguard</groupId>
<artifactId>worldguard-bukkit</artifactId>
<version>7.0.7</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.papermc.paper</groupId>
<artifactId>paper-api</artifactId>

View File

@ -1,8 +1,10 @@
package moe.oko.opennaw;
import moe.oko.opennaw.command.CityCommand;
import moe.oko.opennaw.command.GateCommand;
import moe.oko.opennaw.command.NationCommand;
import moe.oko.opennaw.listener.ActionListener;
import moe.oko.opennaw.listener.GateListener;
import moe.oko.opennaw.storage.NAWDatabase;
import moe.oko.opennaw.util.*;
import net.luckperms.api.LuckPerms;
@ -23,6 +25,10 @@ public final class OpenNAW extends JavaPlugin {
public CityHandler cityHandler;
public GateHandler gateHandler;
public TNTHandler tntHandler;
public NAWDatabase database;
public ConfigHelper configHelper;
@ -44,6 +50,12 @@ public final class OpenNAW extends JavaPlugin {
public CityHandler getCityHandler(){ return cityHandler; }
public GroupHandler getGroupHandler() { return groupHandler; }
public GateHandler getGateHandler() { return gateHandler; }
public TNTHandler getTntHandler() {
return tntHandler;
}
@Override
public void onEnable() {
// Initialize internals
@ -58,7 +70,9 @@ public final class OpenNAW extends JavaPlugin {
actionLogger = new ActionLogger();
nationHandler = new NationHandler();
cityHandler = new CityHandler();
gateHandler = new GateHandler();
groupHandler = new GroupHandler(this.luckPerms);
tntHandler = new TNTHandler();
info("OpenNAW is initialized.");
info("Starting database load.");
@ -67,13 +81,16 @@ public final class OpenNAW extends JavaPlugin {
nationHandler.loadNationList(database.loadNations());
database.loadPlayers();
cityHandler.loadCityList(database.loadCities());
database.loadGates();
//Do not change above load order.
// Register Commands & Events
this.getCommand("nation").setExecutor(new NationCommand());
this.getCommand("city").setExecutor(new CityCommand());
this.getCommand("gate").setExecutor(new GateCommand());
getServer().getPluginManager().registerEvents(new ChatHandler(), this);
getServer().getPluginManager().registerEvents(new ActionListener(), this);
getServer().getPluginManager().registerEvents(new GateListener(), this);
if(Bukkit.getPluginManager().isPluginEnabled("dynmap")) {
this.dynmapEnabled = true;
@ -84,7 +101,10 @@ public final class OpenNAW extends JavaPlugin {
@Override
public void onDisable() {
gateHandler.closeAllGates(); //Close gates before stopping.
tntHandler.shutdown();
info("Starting persistence save.");
gateHandler.saveGates();
cityHandler.saveCities();
nationHandler.saveNations();
info("OpenNAW is disabled!");

View File

@ -24,7 +24,6 @@ public class CityCommand implements TabExecutor {
if (args.length < 1) { return false; }
var cityList = OpenNAW.getInstance().getCityHandler().getCityList();
switch (args[0]) {
case "add": {
var location = ((Player) sender).getLocation();

View File

@ -0,0 +1,164 @@
package moe.oko.opennaw.command;
import com.sk89q.worldedit.IncompleteRegionException;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.math.BlockVector3;
import moe.oko.opennaw.OpenNAW;
import moe.oko.opennaw.model.Gate;
import moe.oko.opennaw.util.CommandHelper;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.block.data.type.Sign;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.List;
public class GateCommand implements TabExecutor {
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String s, @NotNull String[] args) {
if (!(sender instanceof Player)) {
sender.sendMessage(CommandHelper.NOT_PLAYER);
return true;
}
if (args.length < 1) { return false; }
var player = (Player) sender;
switch (args[0]) {
case "create" -> {
if(args.length < 2) {
player.sendMessage(ChatColor.RED + "Specify a name for the new gate.");
return true;
}
var newGate = new Gate(args[1]);
OpenNAW.getInstance().getGateHandler().getGates().put(newGate.getUuid(), newGate);
player.sendMessage(ChatColor.GREEN + "Successfully created a new gate with the name " + args[1]);
return true;
}
case "delete" -> {
if(args.length < 2) {
player.sendMessage(ChatColor.RED + "Specify a name for the gate.");
return true;
}
var uid = OpenNAW.getInstance().getGateHandler().getGateUidByName(args[1]);
if(uid != null) {
OpenNAW.getInstance().getGateHandler().getGates().remove(uid);
} else {
player.sendMessage(ChatColor.RED + "That gate is invalid.");
}
return true;
}
case "modify" -> {
if(args.length < 2) {
player.sendMessage(ChatColor.RED + "Specify a name for the gate.");
return true;
}
var gate = OpenNAW.getInstance().getGateHandler().getGateByName(args[1]);
if(gate == null) {
player.sendMessage(ChatColor.RED + "That gate is invalid.");
return true;
}
try {
var sel = WorldEdit.getInstance().getSessionManager().get(BukkitAdapter.adapt(player)).getSelection();
//clear old blocks.
gate.getGateBlocks().clear();
int i = 0;
for(BlockVector3 vec : sel) {
gate.registerGateBlock(new Location(BukkitAdapter.adapt(sel.getWorld()), vec.getBlockX(), vec.getBlockY(), vec.getBlockZ()).getBlock());
i++;
}
player.sendMessage(ChatColor.GREEN + "Successfully set the new gate area to the " + i + " blocks selected.");
return true;
} catch (Exception e) {
player.sendMessage(ChatColor.RED + "Make sure you have selected a region before defining the gate.");
return true;
}
}
case "open" -> {
if(args.length < 2) {
player.sendMessage(ChatColor.RED + "Specify a name for the gate.");
return true;
}
var gate = OpenNAW.getInstance().getGateHandler().getGateByName(args[1]);
if(gate == null) {
player.sendMessage(ChatColor.RED + "That gate is invalid.");
return true;
}
gate.open();
player.sendMessage(ChatColor.GREEN + "Done.");
return true;
}
case "close" -> {
if(args.length < 2) {
player.sendMessage(ChatColor.RED + "Specify a name for the gate.");
return true;
}
var gate = OpenNAW.getInstance().getGateHandler().getGateByName(args[1]);
if(gate == null) {
player.sendMessage(ChatColor.RED + "That gate is invalid.");
return true;
}
gate.close();
player.sendMessage(ChatColor.GREEN + "Done.");
return true;
}
case "addsign" -> {
if(args.length < 2) {
player.sendMessage(ChatColor.RED + "Specify a name for the gate.");
return true;
}
var gate = OpenNAW.getInstance().getGateHandler().getGateByName(args[1]);
if(gate == null) {
player.sendMessage(ChatColor.RED + "That gate is invalid.");
return true;
}
var block = player.getTargetBlockExact(25);
if(!(block.getType().name().contains("_SIGN"))) {
player.sendMessage(ChatColor.RED + "You aren't looking at a sign block...");
return true;
}
gate.registerSign(block);
player.sendMessage(ChatColor.GREEN + "Successfully registered " + block.getLocation() + " as a sign block for gate " + gate.getName());
return true;
}
case "delsign" -> {
if(args.length < 2) {
player.sendMessage(ChatColor.RED + "Specify a name for the gate.");
return true;
}
var gate = OpenNAW.getInstance().getGateHandler().getGateByName(args[1]);
if(gate == null) {
player.sendMessage(ChatColor.RED + "That gate is invalid.");
return true;
}
var block = player.getTargetBlockExact(25);
if(!(block.getBlockData() instanceof Sign)) {
player.sendMessage(ChatColor.RED + "You aren't looking at a sign block...");
return true;
}
if(gate.isGateSign(block.getLocation())) {
gate.removeSignBlock(block);
player.sendMessage(ChatColor.GREEN + "Successfully removed " + block.getLocation() + " as a sign block for gate " + gate.getName());
} else {
player.sendMessage(ChatColor.RED + "That sign is not a registered sign block...?");
}
return true;
}
}
return true;
}
@Override
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
return switch (args.length) {
case 1 -> List.of("create", "delete", "modify", "open", "close", "addsign", "delsign");
case 2 -> OpenNAW.getInstance().getGateHandler().getGateNames();
default -> null;
};
}
}

View File

@ -0,0 +1,34 @@
package moe.oko.opennaw.listener;
import moe.oko.opennaw.OpenNAW;
import moe.oko.opennaw.util.WorldGuardHelper;
import org.bukkit.ChatColor;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
public class GateListener implements Listener {
@EventHandler
public void onBlockInteract(PlayerInteractEvent event) {
if(event.getAction().equals(Action.RIGHT_CLICK_BLOCK)) {
if(event.getClickedBlock().getType().name().contains("_SIGN")) {
//its a sign!!!
if(OpenNAW.getInstance().getGateHandler().getGateBySign(event.getClickedBlock()) != null) {
if(WorldGuardHelper.fetchCityRegionViaLoc(event.getClickedBlock().getLocation()) != null) {
//in a city, start perm check.
var rgr = WorldGuardHelper.fetchCityRegionViaLoc(event.getClickedBlock().getLocation());
if(!(WorldGuardHelper.isPlayerPermitted(rgr, event.getPlayer()))) {
event.getPlayer().sendMessage(ChatColor.RED + "" + ChatColor.ITALIC + "The gate is locked...");
return;
}
}
var gate = OpenNAW.getInstance().getGateHandler().getGateBySign(event.getClickedBlock());
gate.toggle(); //toggle gate
//TODO PERMS CHECK!!!!
}
}
}
}
}

View File

@ -0,0 +1,57 @@
package moe.oko.opennaw.listener;
import moe.oko.opennaw.OpenNAW;
import moe.oko.opennaw.util.TNTHandler;
import moe.oko.opennaw.util.WorldGuardHelper;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.TNTPrimed;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.player.PlayerInteractAtEntityEvent;
import org.bukkit.event.player.PlayerInteractEvent;
public class TNTListener implements Listener {
@EventHandler
public void onBlockPlace(BlockPlaceEvent event) {
//Explosives Prevention
if(event.getBlock().getType().equals(Material.TNT)) {
if(event.getBlock().getLocation().subtract(0, 1, 0).getBlock().getType().equals(Material.SOUL_SAND)) {
if(WorldGuardHelper.fetchCityRegionViaLoc(event.getBlock().getLocation()) != null) {
OpenNAW.getInstance().getTntHandler().startExplosive(event.getBlock(), event.getPlayer());
} else {
event.getPlayer().sendMessage(ChatColor.RED + "" + ChatColor.ITALIC
+ "It would be a waste to blow this up here... It's about sending a message isn't it?");
event.setCancelled(true);
}
} else {
event.getPlayer().sendMessage(ChatColor.RED + "" + ChatColor.ITALIC
+ "The ground here isn't sticky enough to hold together the badly constructed explosive. Maybe soul sand would work?");
event.setCancelled(true);
}
}
}
@EventHandler
public void onEntityExplosion(EntityExplodeEvent event) {
if(event.getEntity().getType().equals(EntityType.PRIMED_TNT)) {
OpenNAW.getInstance().getTntHandler().detonate(event);
}
}
@EventHandler
public void onPlayerInteract(PlayerInteractAtEntityEvent event) {
if(event.getRightClicked().getType().equals(EntityType.PRIMED_TNT)) {
if(WorldGuardHelper.fetchCityRegionViaLoc(event.getRightClicked().getLocation()) != null) {
var rg = WorldGuardHelper.fetchCityRegionViaLoc(event.getRightClicked().getLocation());
if(WorldGuardHelper.isPlayerPermitted(rg, event.getPlayer())) {
OpenNAW.getInstance().getTntHandler().defuse((TNTPrimed) event.getRightClicked());
}
}
}
}
}

View File

@ -88,7 +88,7 @@ public class City {
public boolean startSiege(Nation nation) {
if(state.equals(CityState.RECOVERY)) return false;
state = CityState.SIEGE;
Bukkit.broadcast(Component.text(ChatColor.RED + nation.getName() + ChatColor.GOLD + " has begun a siege against the city of " + ChatColor.AQUA + getName()));
Bukkit.broadcastMessage(ChatColor.RED + nation.getName() + ChatColor.GOLD + " has begun a siege against the city of " + ChatColor.AQUA + getName());
for(var player : Bukkit.getOnlinePlayers()) {
player.playSound(player.getLocation(), Sound.ITEM_TRIDENT_THUNDER, 1F, 1F);
}
@ -128,14 +128,16 @@ public class City {
public void defend() {
//successful defense logic.
Bukkit.broadcast(Component.text(ChatColor.RED + attacker.getName() + ChatColor.GOLD + "'s siege against the city of "
+ ChatColor.AQUA + getName() + ChatColor.GOLD + " has " + ChatColor.RED + "failed"));
Bukkit.broadcastMessage(ChatColor.RED + attacker.getName() + ChatColor.GOLD + "'s siege against the city of "
+ ChatColor.AQUA + getName() + ChatColor.GOLD + " has " + ChatColor.RED + "failed");
if(health < 250) {
health = (short) (health + 50);
}
OpenNAW.getInstance().getActionLogger().cancelDefenseActions(this);
attacker = null;
this.state = CityState.RECOVERY; //Start recovery, prohibit sieges until restart.
OpenNAW.getInstance().getLogger().info("Starting regen...");
OpenNAW.getInstance().getTntHandler().endSiege(this);
}
public void capture() {
@ -146,7 +148,9 @@ public class City {
//Dyn is enabled, we need to do setters.
OpenNAW.getInstance().getDynmapHandler().updateCityInfoMarker(this);
}
Bukkit.broadcast(Component.text(ChatColor.AQUA + getName() + ChatColor.GOLD + " has been successfully captured by " + ChatColor.RED + this.owner.getName()));
Bukkit.broadcastMessage(ChatColor.AQUA + getName() + ChatColor.GOLD + " has been successfully captured by " + ChatColor.RED + this.owner.getName());
OpenNAW.getInstance().getLogger().info("Starting regen...");
OpenNAW.getInstance().getTntHandler().endSiege(this);
}
public boolean isUnclaimed() {

View File

@ -0,0 +1,30 @@
package moe.oko.opennaw.model;
import org.bukkit.Material;
import org.bukkit.block.Block;
import java.util.HashMap;
import java.util.List;
public class ExplosivesData {
//The Block destroyed and the material it previously was.
private HashMap<Block, Material> blocksDestroyed;
private City city;
public ExplosivesData(List<Block> blocks, City city) {
blocksDestroyed = new HashMap<>();
this.city = city;
for(var block : blocks) {
blocksDestroyed.put(block, block.getType());
}
}
public void regenerate() {
//Regenerate all blocks previously affected.
for(var block : blocksDestroyed.keySet()) {
block.setType(blocksDestroyed.get(block));
}
}
public City getCity() { return city; }
}

View File

@ -0,0 +1,142 @@
package moe.oko.opennaw.model;
import moe.oko.opennaw.OpenNAW;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import java.util.HashMap;
import java.util.UUID;
public class Gate {
private String name;
private UUID uuid;
private boolean open;
private HashMap<UUID, GateBlock> signs = new HashMap<>();
private HashMap<GateBlock, Material> gateBlocks;
//New gate constructor.
public Gate(String name) {
this.name = name;
this.uuid = UUID.randomUUID();
this.open = false;
gateBlocks = new HashMap<>();
}
//Db Const
public Gate(UUID uid, String name) {
this.uuid = uid;
this.name = name;
this.open = false;
gateBlocks = new HashMap<>();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public UUID getUuid() {
return uuid;
}
public HashMap<UUID, GateBlock> getSigns() {
return signs;
}
public HashMap<GateBlock, Material> getGateBlocks() {
return gateBlocks;
}
public void registerSign(Block block) {
var gate = new GateBlock(block);
if(signs.containsValue(gate)) {
signs.replace(gate.getId(), gate);
return;
}
signs.put(gate.getId(), gate);
}
public void registerSignFromDB(GateBlock block) {
if(signs.containsValue(block)) {
signs.replace(block.getId(), block);
return;
}
signs.put(block.getId(), block);
}
public boolean isGateSign(Location location) {
for(var block : signs.values()) {
if(block.getBlock().getLocation().equals(location)) { return true; }
}
return false;
}
public void removeSignBlock(Block block) {
for(var blocks : signs.values()) {
if(blocks.getBlock().equals(block)) {
signs.remove(blocks.getId());
}
}
}
public boolean registerGateBlock(Block block) {
var newBlock = new GateBlock(block);
if(gateBlocks.containsKey(newBlock)) { return false; }
gateBlocks.put(newBlock, newBlock.getBlock().getType());
return true;
}
public void registerGateBlockDb(GateBlock block) {
if(gateBlocks.containsKey(block)) {
signs.replace(block.getId(), block);
return;
}
gateBlocks.put(block, block.getBlock().getType());
}
public void toggle() {
if(!open) {
open();
open = !open;
} else {
close();
open = !open;
}
}
public boolean open() {
try {
for (var block : gateBlocks.keySet()) {
block.getBlock().setType(Material.AIR);
block.getBlock().getWorld().playSound(block.getBlock().getLocation(), Sound.BLOCK_PISTON_CONTRACT, 1, 1);
}
return true;
} catch (Exception ex) {
ex.printStackTrace();
OpenNAW.getInstance().getLogger().severe("Failed to open gate " + name);
return false;
}
}
public boolean close() {
try {
for (var block : gateBlocks.keySet()) {
block.getBlock().setType(gateBlocks.get(block));
block.getBlock().getWorld().playSound(block.getBlock().getLocation(), Sound.BLOCK_PISTON_EXTEND, 1, 1);
}
return true;
} catch (Exception ex) {
ex.printStackTrace();
OpenNAW.getInstance().getLogger().severe("Failed to open gate " + name);
return false;
}
}
}

View File

@ -0,0 +1,31 @@
package moe.oko.opennaw.model;
import org.bukkit.block.Block;
import java.util.UUID;
//Used primarily for SQL storage
//Used BOTH for Signs & Actual Openable blocks.
public class GateBlock {
private UUID id;
private Block block;
public GateBlock(Block block) {
this.block = block;
this.id = UUID.randomUUID();
}
//Db Const
public GateBlock(UUID uid, Block block) {
this.id = uid;
this.block = block;
}
public Block getBlock() {
return block;
}
public UUID getId() {
return id;
}
}

View File

@ -2,8 +2,9 @@ package moe.oko.opennaw.storage;
import moe.oko.opennaw.OpenNAW;
import moe.oko.opennaw.model.City;
import moe.oko.opennaw.model.Gate;
import moe.oko.opennaw.model.GateBlock;
import moe.oko.opennaw.model.Nation;
import moe.oko.opennaw.model.type.CityType;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
@ -39,10 +40,26 @@ public class NAWDatabase {
"`pointx` INT NOT NULL DEFAULT 0," +
"`pointy` INT NOT NULL DEFAULT 0," +
"`pointz` INT NOT NULL DEFAULT 0) COMMENT='Cities on the NAW map';";
private final String INITIALIZE_GATES = "CREATE TABLE IF NOT EXISTS `gates` (" +
"`name` VARCHAR(50) NOT NULL,`uuid` VARCHAR(50) NOT NULL, PRIMARY KEY (`uuid`));";
private final String INITIALITE_GATE_SIGNS = "CREATE TABLE IF NOT EXISTS `gateSigns`(" +
"`uuid` VARCHAR(50) NOT NULL, `id` VARCHAR(50) NOT NULL, `world` VARCHAR(50) NOT NULL, `x` INT NOT NULL, `y` INT NOT NULL, `z` INT NOT NULL, PRIMARY KEY (`id`));";
private final String INITIALIZE_GATE_BLOCKS = "CREATE TABLE IF NOT EXISTS `gateBlocks`(" +
"`uuid` VARCHAR(50) NOT NULL, `id` VARCHAR(50) NOT NULL, `world` VARCHAR(50) NOT NULL, `x` INT NOT NULL, `y` INT NOT NULL, `z` INT NOT NULL, PRIMARY KEY (`id`));";
private final String SELECT_CITIES = "SELECT * FROM `cities`;";
private final String SELECT_NATION = "SELECT * FROM `nations`;";
private final String SELECT_PLAYERS = "SELECT * FROM `nation_players`;";
private final String SELECT_GATES = "SELECT * FROM `gates`;";
private final String SELECT_GATE_SIGNS = "SELECT * FROM `gateSigns`;";
private final String SELECT_GATE_BLOCKS = "SELECT * FROM `gateBlocks`;";
//name 1,9; group 2,10; icon 3,11; colour 4, 12; world 5,13; x 6,14; y 7,15; z 8,16;
private final String SAVE_NATION = "INSERT INTO `nations`(nation_name,groupName,dynmapIcon, colour, spawnworld,spawnx,spawny,spawnz) VALUES " +
"(?,?,?,?,?,?,?,?)" +
@ -51,9 +68,20 @@ public class NAWDatabase {
private final String SAVE_PLAYER = "INSERT INTO `nation_players`(nation_name, player_uuid) VALUES (?,?) " +
"ON DUPLICATE KEY UPDATE nation_name=?, player_uuid=?;";
//name 1,9; resource 2,10; type 3,11; owner 4,12; world 5,13; x 6,14; y 7,15; z 8,16;
private final String SAVE_CITY = "INSERT INTO `cities`(city_name, resource, type, OWNER, pointworld, pointx, pointy, pointz) VALUES (?,?,?,?,?,?,?,?)" +
private final String SAVE_CITY = "INSERT INTO `cities`(city_name, resource, type, OWNER, pointworld, pointx, pointy, pointz) VALUES (?,?,?,?,?,?,?,?) " +
"ON DUPLICATE KEY UPDATE city_name=?, resource=?, type=?, OWNER=?, pointworld=?, pointx=?, pointy=?, pointz=?;";
//name, 1 3; uuid 2 4;
private final String SAVE_GATE = "INSERT INTO `gates`(name, uuid) VALUES (?,?) " +
"ON DUPLICATE KEY UPDATE name=?, uuid=?;";
//uuid 1, 7; id 2, 8; world 3, 9; x 4 10; y 5 11; z 6 12;
private final String SAVE_GATE_SIGN = "INSERT INTO `gateSigns`(uuid, id, world, x, y, z) VALUES (?,?,?,?,?,?)" +
"ON DUPLICATE KEY UPDATE uuid=?, id=?, world=?, x=?, y=?, z=?;";
private final String SAVE_GATE_BLOCK = "INSERT INTO `gateBlocks`(uuid, id, world, x, y, z) VALUES (?,?,?,?,?,?) " +
"ON DUPLICATE KEY UPDATE uuid=?, id=?, world=?, x=?, y=?, z=?;";
public NAWDatabase(String username, String password, String host, int port, String database) {
//all relevant
try {
@ -75,6 +103,12 @@ public class NAWDatabase {
nationsInit.execute();
PreparedStatement cityInit = connection.prepareStatement(INITIALIZE_CITIES);
cityInit.execute();
PreparedStatement gatesInit = connection.prepareStatement(INITIALIZE_GATES);
gatesInit.execute();
PreparedStatement gatesInit2 = connection.prepareStatement(INITIALITE_GATE_SIGNS);
gatesInit2.execute();
PreparedStatement gatesInit3 = connection.prepareStatement(INITIALIZE_GATE_BLOCKS);
gatesInit3.execute();
} catch (Exception ex) {
ex.printStackTrace();
OpenNAW.getInstance().getLogger().severe("Failed to initialize tables for sql.");
@ -234,4 +268,112 @@ public class NAWDatabase {
OpenNAW.getInstance().getLogger().severe("Failed to save cities.");
}
}
public void loadGates() {
try {
List<Gate> gateLoad = new ArrayList<>();
PreparedStatement gateload = connection.prepareStatement(SELECT_GATES);
ResultSet rs = gateload.executeQuery();
int i = 0;
while(rs.next()) {
var newGate = new Gate(UUID.fromString(rs.getString(2)), rs.getString(1));
OpenNAW.getInstance().getGateHandler().getGates().put(newGate.getUuid(), newGate);
i++;
}
OpenNAW.getInstance().getLogger().info("Loaded " + i + " gates.");
PreparedStatement gateSignLoad = connection.prepareStatement(SELECT_GATE_SIGNS);
ResultSet rs2 = gateSignLoad.executeQuery();
i = 0;
while(rs2.next()) {
var gate = OpenNAW.getInstance().getGateHandler().getGateByUuid(UUID.fromString(rs2.getString(1)));
//uuid 1, 7; id 2, 8; world 3, 9; x 4 10; y 5 11; z 6 12;
gate.registerSignFromDB(new GateBlock(UUID.fromString(rs2.getString(2)),
new Location(Bukkit.getWorld(rs2.getString(3)), rs2.getInt(4)
, rs2.getInt(5), rs2.getInt(6)).getBlock()));
i++;
}
OpenNAW.getInstance().getLogger().info("Loaded " + i + " signs for gates.");
PreparedStatement gateBlockLoad = connection.prepareStatement(SELECT_GATE_BLOCKS);
ResultSet rs3 = gateBlockLoad.executeQuery();
i = 0;
while(rs3.next()) {
var gate = OpenNAW.getInstance().getGateHandler().getGateByUuid(UUID.fromString(rs3.getString(1)));
gate.registerGateBlockDb(new GateBlock(UUID.fromString(rs3.getString(2)),
new Location(Bukkit.getWorld(rs3.getString(3)), rs3.getInt(4)
, rs3.getInt(5), rs3.getInt(6)).getBlock()));
i++;
}
OpenNAW.getInstance().getLogger().info("Loaded " + i + " blocks for gates.");
} catch (Exception ex) {
ex.printStackTrace();
OpenNAW.getInstance().getLogger().severe("Failed to save gates.");
}
}
public void saveGates(Collection<Gate> gates) {
try {
OpenNAW.getInstance().getLogger().info("Starting gate save.");
//name, 1 3; uid 2, 4;
//for signs and blocks uuid 1, 7; id 2, 8; world 3, 9; x 4 10; y 5 11; z 6 12;
PreparedStatement gateSave = connection.prepareStatement(SAVE_GATE);
PreparedStatement gateSignSave = connection.prepareStatement(SAVE_GATE_SIGN);
PreparedStatement gateBlockSave = connection.prepareStatement(SAVE_GATE_BLOCK);
int g = 0;
for(var gate : gates) {
int i = 0;
gateSave.setString(1, gate.getName());
gateSave.setString(3, gate.getName());
gateSave.setString(2, gate.getUuid().toString());
gateSave.setString(4, gate.getUuid().toString());
gateSave.execute();
for(var sign : gate.getSigns().values()) {
//sign save
gateSignSave.setString(1, gate.getUuid().toString()); //UUID for gate identification (so we know where
gateSignSave.setString(7, gate.getUuid().toString()); //to put blocks on load).
gateSignSave.setString(2, sign.getId().toString()); //Id's to prevent duplicates in the DB
gateSignSave.setString(8, sign.getId().toString());
var loc = sign.getBlock().getLocation();
gateSignSave.setString(3, loc.getWorld().getName());
gateSignSave.setString(9, loc.getWorld().getName());
gateSignSave.setInt(4, loc.getBlockX());
gateSignSave.setInt(10, loc.getBlockX());
gateSignSave.setInt(5, loc.getBlockY());
gateSignSave.setInt(11, loc.getBlockY());
gateSignSave.setInt(6, loc.getBlockZ());
gateSignSave.setInt(12, loc.getBlockZ());
gateSignSave.addBatch();
i++;
}
gateSignSave.executeBatch();
OpenNAW.getInstance().getLogger().info("Saved " + i + " signs for gate " + gate.getName());
i = 0;
//Now we save all blocks
for(var block : gate.getGateBlocks().keySet()) {
//sign save
gateBlockSave.setString(1, gate.getUuid().toString()); //UUID for gate identification (so we know where
gateBlockSave.setString(7, gate.getUuid().toString()); //to put blocks on load).
gateBlockSave.setString(2, block.getId().toString()); //Id's to prevent duplicates in the DB
gateBlockSave.setString(8, block.getId().toString());
var loc = block.getBlock().getLocation();
gateBlockSave.setString(3, loc.getWorld().getName());
gateBlockSave.setString(9, loc.getWorld().getName());
gateBlockSave.setInt(4, loc.getBlockX());
gateBlockSave.setInt(10, loc.getBlockX());
gateBlockSave.setInt(5, loc.getBlockY());
gateBlockSave.setInt(11, loc.getBlockY());
gateBlockSave.setInt(6, loc.getBlockZ());
gateBlockSave.setInt(12, loc.getBlockZ());
gateBlockSave.addBatch();
i++;
}
gateBlockSave.executeBatch();
OpenNAW.getInstance().getLogger().info("Saved " + i + " blocks for gate " + gate.getName());
g++;
}
OpenNAW.getInstance().getLogger().info("Saved " + g + " gates.");
} catch (Exception ex) {
ex.printStackTrace();
OpenNAW.getInstance().getLogger().severe("Failed to save gates.");
}
}
}

View File

@ -26,12 +26,17 @@ public class ChatHandler implements Listener {
e.setCancelled(true);
/*
Kyori support broken?
audience = Audience.audience(Bukkit.getOnlinePlayers());
audience.sendMessage(prefix
.append(player.displayName().color(TextColor.fromHexString("#939597")))
.append(Component.text(player.getDisplayName()))
.color(TextColor.fromHexString("#939597"))
.append(Component.text(": "))
.append(message));
*/
Bukkit.broadcastMessage(prefix + player.getDisplayName() + TextColor.fromHexString("#939597") + ": " + message);
}
}

View File

@ -0,0 +1,79 @@
package moe.oko.opennaw.util;
import moe.oko.opennaw.OpenNAW;
import moe.oko.opennaw.model.Gate;
import org.bukkit.block.Block;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
public class GateHandler {
private HashMap<UUID, Gate> gates = new HashMap<>();
public GateHandler() {
}
public Gate getGateByUuid(UUID uid) {
return gates.get(uid);
}
public Gate getGateBySign(Block block) {
for(var gate : gates.values()) {
for(var sign : gate.getSigns().values()) {
if(sign.getBlock().equals(block)) {
return gate;
}
}
}
return null; //no gate.
}
public UUID getGateUidByName(String name) {
for(var gate : gates.values()) {
if(gate.getName().equals(name)) {
return gate.getUuid();
}
}
return null;
}
public Gate getGateByName(String name) {
for(var gate : gates.values()) {
if(gate.getName().equals(name)) {
return gate;
}
}
return null;
}
public HashMap<UUID, Gate> getGates() {
return gates;
}
public List<String> getGateNames() {
List<String> names = new ArrayList<>();
for(var gate : gates.values()) {
names.add(gate.getName());
}
return names;
}
public void setGates(HashMap<UUID, Gate> gates) {
this.gates = gates;
}
public void closeAllGates() {
var i = 0;
for(var gate : gates.values()) {
gate.close();
i++;
}
OpenNAW.getInstance().getLogger().info("Closed " + i + " gates.");
}
public void saveGates() {
OpenNAW.getInstance().getDatabase().saveGates(gates.values());
}
}

View File

@ -35,7 +35,7 @@ public class GuiHelper {
for(var nation : OpenNAW.getInstance().getNationHandler().getNationList()) {
var is = new ItemStack(Material.getMaterial(nation.getColour() + "_WOOL"));
var meta = is.getItemMeta();
meta.displayName(Component.text(ChatColor.valueOf(nation.getColour()) + nation.getName()));
meta.setDisplayName(ChatColor.valueOf(nation.getColour()) + nation.getName());
is.setItemMeta(meta);
menu.setButton(s, new ItemButton<>(is) {
@Override
@ -64,7 +64,7 @@ public class GuiHelper {
var colour = new ItemStack(Material.valueOf(nation.getColour() + "_WOOL"));
var meta = colour.getItemMeta();
meta.displayName(Component.text(colour.getType().name().replace("_WOOL", "").toUpperCase()));
meta.setDisplayName(colour.getType().name().replace("_WOOL", "").toUpperCase());
colour.setItemMeta(meta);
var woolCollection = new ArrayList<>();
for(var mat : Material.values()) {
@ -84,7 +84,7 @@ public class GuiHelper {
var player = (Player) event.getViewers().get(0);
var is = (ItemStack) woolCollection.get(i);
var meta = is.getItemMeta();
meta.displayName(Component.text(is.getType().name().replace("_WOOL", "").toUpperCase()));
meta.setDisplayName(is.getType().name().replace("_WOOL", "").toUpperCase());
is.setItemMeta(meta);
setIcon(is);
nation.setColour(this.getIcon().getType().name().replace("_WOOL", ""));
@ -98,7 +98,7 @@ public class GuiHelper {
var player = (Player) event.getViewers().get(0);
var is = (ItemStack) woolCollection.get(i);
var meta = is.getItemMeta();
meta.displayName(Component.text(is.getType().name().replace("_WOOL", "").toUpperCase()));
meta.setDisplayName(is.getType().name().replace("_WOOL", "").toUpperCase());
is.setItemMeta(meta);
setIcon(is);
nation.setColour(this.getIcon().getType().name().replace("_WOOL", ""));
@ -111,10 +111,10 @@ public class GuiHelper {
*/
var is = new ItemStack(Material.BARRIER);
var meta1 = is.getItemMeta();
meta1.displayName(Component.text("Spawn Location"));
var lore = new ArrayList<Component>();
lore.add(Component.text(ChatColor.GRAY + "Click to set your current location as the spawn for this nation."));
meta1.lore(lore);
meta1.setDisplayName("Spawn Location");
var lore = new ArrayList<String>();
lore.add(ChatColor.GRAY + "Click to set your current location as the spawn for this nation.");
meta1.setLore(lore);
is.setItemMeta(meta1);
menu.setButton(1, new ItemButton<>(is) {
@Override
@ -136,10 +136,10 @@ public class GuiHelper {
var typeis = new ItemStack(map.get(city.getType()));
var typemeta = typeis.getItemMeta();
typemeta.displayName(Component.text(city.getType().name()));
List<Component> list = new ArrayList<>();
list.add(Component.text(city.getType().getDescription()));
typemeta.lore(list);
typemeta.setDisplayName(city.getType().name());
List<String> list = new ArrayList<>();
list.add(city.getType().getDescription());
typemeta.setLore(list);
typeis.setItemMeta(typemeta);
menu.setButton(0, new CycleButton<>(typeis, map.keySet().stream().toList(), 0) {
@Override
@ -149,10 +149,10 @@ public class GuiHelper {
var player = (Player) event.getViewers().get(0);
var typeis = new ItemStack(map.get(map.keySet().stream().toList().get(i)));
var typemeta = typeis.getItemMeta();
typemeta.displayName(Component.text(map.keySet().stream().toList().get(i).name()));
List<Component> list = new ArrayList<>();
list.add(Component.text(map.keySet().stream().toList().get(i).getDescription()));
typemeta.lore(list);
typemeta.setDisplayName(map.keySet().stream().toList().get(i).name());
List<String> list = new ArrayList<>();
list.add(map.keySet().stream().toList().get(i).getDescription());
typemeta.setLore(list);
typeis.setItemMeta(typemeta);
setIcon(typeis);
city.setType(map.keySet().stream().toList().get(i));
@ -166,10 +166,10 @@ public class GuiHelper {
var player = (Player) event.getViewers().get(0);
var typeis = new ItemStack(map.get(map.keySet().stream().toList().get(i)));
var typemeta = typeis.getItemMeta();
typemeta.displayName(Component.text(map.keySet().stream().toList().get(i).name()));
List<Component> list = new ArrayList<>();
list.add(Component.text(map.keySet().stream().toList().get(i).getDescription()));
typemeta.lore(list);
typemeta.setDisplayName(map.keySet().stream().toList().get(i).name());
List<String> list = new ArrayList<>();
list.add(map.keySet().stream().toList().get(i).getDescription());
typemeta.setLore(list);
typeis.setItemMeta(typemeta);
setIcon(typeis);
city.setType(map.keySet().stream().toList().get(i));
@ -179,7 +179,7 @@ public class GuiHelper {
var nameis = new ItemStack(Material.OAK_SIGN);
var namemeta = nameis.getItemMeta();
namemeta.displayName(Component.text("Set City Name"));
namemeta.setDisplayName("Set City Name");
nameis.setItemMeta(namemeta);
menu.setButton(1, new ItemButton<>(nameis) {
@Override

View File

@ -0,0 +1,71 @@
package moe.oko.opennaw.util;
import moe.oko.opennaw.OpenNAW;
import moe.oko.opennaw.model.City;
import moe.oko.opennaw.model.ExplosivesData;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.Particle;
import org.bukkit.block.Block;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.entity.TNTPrimed;
import org.bukkit.event.entity.EntityExplodeEvent;
import java.util.*;
public class TNTHandler {
List<ExplosivesData> explosiveSave = new ArrayList<>();
List<TNTPrimed> pendingExplosives = new ArrayList<>();
public void startExplosive(Block block, Player player) {
var city = OpenNAW.getInstance().getCityHandler().fetchCityViaName(WorldGuardHelper.fetchCityRegionViaLoc(block.getLocation()).getId());
block.setType(Material.AIR);
if(WorldGuardHelper.isPlayerPermitted(WorldGuardHelper.fetchCityRegionViaLoc(block.getLocation()), player)) {
//Betrayal has its benefits... (10 Second explosive time)
player.sendMessage(ChatColor.YELLOW + "" + ChatColor.ITALIC + "Your knowledge of the city allows you to evade the guards who may call out for help...");
var tnt = (TNTPrimed) block.getWorld().spawnEntity(block.getLocation(), EntityType.PRIMED_TNT, false);
tnt.setFuseTicks(200);
pendingExplosives.add(tnt);
} else {
//Normal start. (60 Second explosive time + warning)
Bukkit.broadcastMessage(ChatColor.RED + player.getDisplayName()
+ ChatColor.GOLD + " has placed an improvised explosive at the walls of " + ChatColor.AQUA + city.getName() + ChatColor.GOLD + "!");
var tnt = (TNTPrimed) block.getWorld().spawnEntity(block.getLocation(), EntityType.PRIMED_TNT, false);
tnt.setFuseTicks(1200);
pendingExplosives.add(tnt);
}
}
public void defuse(TNTPrimed tnt) {
pendingExplosives.remove(tnt);
var loc = tnt.getLocation();
tnt.remove(); //Delete tnt
loc.getWorld().spawnParticle(Particle.WHITE_ASH, loc, 1000, .5, .5, .5);
}
public void detonate(EntityExplodeEvent event) {
var city = OpenNAW.getInstance().getCityHandler().fetchCityViaName(WorldGuardHelper.fetchCityRegionViaLoc(event.getLocation()).getId());
explosiveSave.add(new ExplosivesData(event.blockList(), city));
pendingExplosives.remove((TNTPrimed) event.getEntity());
}
public void endSiege(City city) {
for (var explosive : explosiveSave) {
if(explosive.getCity().equals(city)) {
explosive.regenerate();
explosiveSave.remove(explosive);
}
}
}
public void shutdown() {
for(var data : explosiveSave) {
data.regenerate(); //Regen all before shutdown of server.
}
for(var tnt : pendingExplosives) {
tnt.remove(); //Remove all tnt
}
}
}

View File

@ -0,0 +1,46 @@
package moe.oko.opennaw.util;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import moe.oko.opennaw.OpenNAW;
import moe.oko.opennaw.model.Nation;
import org.bukkit.Location;
import org.bukkit.entity.Player;
public class WorldGuardHelper {
/*
Used to set the owner when a city is captured namely.
*/
public static void setRegionOwner(ProtectedRegion region, Nation nation) {
region.getMembers().clear(); //Clear prior owner.
region.getMembers().addGroup(nation.getGroup().getName());
}
/*
Used to determine whether a player can open a gate, or BETRAY epicly.
*/
public static boolean isPlayerPermitted(ProtectedRegion region, Player player) {
var nation = OpenNAW.getInstance().getNationHandler().getNationByPlayer(player.getUniqueId());
if(region.getMembers().getGroups().contains(nation.getGroup().getName())) {
return true;
} else {
return false;
}
}
/*
This will ONLY return city regions. DO NOT LET CITY REGIONS OVERLAP, THIS CAN CAUSE A LOT OF BUGS.
*/
public static ProtectedRegion fetchCityRegionViaLoc(Location location) {
var regionsOnLoc = WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery().getApplicableRegions(BukkitAdapter.adapt(location)).getRegions();
var cityStrs = OpenNAW.getInstance().getCityHandler().getCityList();
for(var protreg : regionsOnLoc) {
if(cityStrs.contains(protreg.getId())) {
return protreg;
}
}
return null;
}
}

View File

@ -4,7 +4,7 @@ main: moe.oko.opennaw.OpenNAW
api-version: 1.18
prefix: OpenNAW
softdepend: [dynmap]
depend: [GuiLib]
depend: [GuiLib, WorldEdit, WorldGuard]
authors: [ oko ]
description: Open source recreation of Nations at War
website: https://oko.moe
@ -15,4 +15,8 @@ commands:
city:
description: Manages cities
usage: /<command>
permission: naw.admin
gate:
description: Manages gates
usage: /<command>
permission: naw.admin