diff --git a/pom.xml b/pom.xml
index 5cb3fe3..38fc361 100644
--- a/pom.xml
+++ b/pom.xml
@@ -156,5 +156,10 @@
2.11.2
provided
+
+ com.zaxxer
+ HikariCP
+ 6.2.1
+
diff --git a/src/main/java/xyz/soukup/ecoCraftCore/EcoCraftCore.java b/src/main/java/xyz/soukup/ecoCraftCore/EcoCraftCore.java
index 93c70d4..380c6df 100644
--- a/src/main/java/xyz/soukup/ecoCraftCore/EcoCraftCore.java
+++ b/src/main/java/xyz/soukup/ecoCraftCore/EcoCraftCore.java
@@ -5,10 +5,13 @@ import com.github.retrooper.packetevents.event.PacketListenerPriority;
import com.infernalsuite.asp.api.AdvancedSlimePaperAPI;
import com.infernalsuite.asp.api.world.SlimeWorldInstance;
import com.j256.ormlite.dao.DaoManager;
+import com.j256.ormlite.jdbc.DataSourceConnectionSource;
import com.j256.ormlite.jdbc.JdbcConnectionSource;
import com.j256.ormlite.stmt.UpdateBuilder;
import com.j256.ormlite.support.ConnectionSource;
import com.j256.ormlite.table.TableUtils;
+import com.zaxxer.hikari.HikariConfig;
+import com.zaxxer.hikari.HikariDataSource;
import io.github.retrooper.packetevents.factory.spigot.SpigotPacketEventsBuilder;
import io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager;
import org.bukkit.Bukkit;
@@ -27,6 +30,8 @@ import xyz.soukup.ecoCraftCore.player.OnKill;
import xyz.soukup.ecoCraftCore.player.PreparePlayer;
import xyz.soukup.ecoCraftCore.player.TeleportRequestsHandler;
import xyz.soukup.ecoCraftCore.positionMarker.MarkerCommand;
+import xyz.soukup.ecoCraftCore.regions.RegionAdminCommand;
+import xyz.soukup.ecoCraftCore.regions.RegionEvents;
import xyz.soukup.ecoCraftCore.shop.ShopCommand;
import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents;
import xyz.soukup.ecoCraftCore.inventory.VirtualChest;
@@ -187,7 +192,18 @@ public final class EcoCraftCore extends JavaPlugin {
String databasePassword = config.getString("database.password");
String databaseUrl = "jdbc:mysql://" + databaseHost + ":" + databasePort + "/" + databaseName;
- connectionSource = new JdbcConnectionSource(databaseUrl, databaseUsername, databasePassword);
+
+ HikariConfig hikariConfig = new HikariConfig();
+ hikariConfig.setJdbcUrl(databaseUrl);
+ hikariConfig.setUsername(databaseUsername);
+ hikariConfig.setPassword(databasePassword);
+ hikariConfig.setMaximumPoolSize(5);
+ hikariConfig.setKeepaliveTime(60000);
+ hikariConfig.setMaxLifetime(1800000);
+
+ HikariDataSource dataSource = new HikariDataSource(hikariConfig);
+
+ connectionSource = new DataSourceConnectionSource(dataSource, databaseUrl);
Logger.getLogger("com.j256.ormlite.table.TableUtils").setLevel(Level.OFF);
TableUtils.createTableIfNotExists(connectionSource, ActiveServer.class);
@@ -245,6 +261,7 @@ public final class EcoCraftCore extends JavaPlugin {
lm.registerEventHandler(LifecycleEvents.COMMANDS, event -> event.registrar().register(MoneyCommand.getCommand().build()));
lm.registerEventHandler(LifecycleEvents.COMMANDS, event -> event.registrar().register(IslandAdminCommand.getCommand().build()));
lm.registerEventHandler(LifecycleEvents.COMMANDS, event -> event.registrar().register(IslandSelectorCommand.getCommand().build()));
+ lm.registerEventHandler(LifecycleEvents.COMMANDS, event -> event.registrar().register(RegionAdminCommand.getCommand().build()));
}
private void registerEvents(){
@@ -256,6 +273,7 @@ public final class EcoCraftCore extends JavaPlugin {
pm.registerEvents(new VirtualChestLogic(), this);
pm.registerEvents(new ShopLogic(), this);
pm.registerEvents(new PreparePlayer(), this);
+ pm.registerEvents(new RegionEvents(), this);
EventManager events = PacketEvents.getAPI().getEventManager();
diff --git a/src/main/java/xyz/soukup/ecoCraftCore/database/objects/Region.java b/src/main/java/xyz/soukup/ecoCraftCore/database/objects/Region.java
index 212a496..ea06c7c 100644
--- a/src/main/java/xyz/soukup/ecoCraftCore/database/objects/Region.java
+++ b/src/main/java/xyz/soukup/ecoCraftCore/database/objects/Region.java
@@ -29,12 +29,18 @@ public class Region {
@DatabaseField(canBeNull = false)
private int y1;
+ @DatabaseField(canBeNull = false)
+ private int z1;
+
@DatabaseField(canBeNull = false)
private int x2;
@DatabaseField(canBeNull = false)
private int y2;
+ @DatabaseField(canBeNull = false)
+ private int z2;
+
@ForeignCollectionField(eager = true)
private ForeignCollection regionMembers;
@@ -45,15 +51,20 @@ public class Region {
}
- public Region(String island, int regionType, int x1, int y1, int x2, int y2) {
+ public Region(String island, int regionType, int x1, int y1, int z1, int x2, int y2, int z2) {
this.island = island;
this.regionType = regionType;
this.x1 = Math.min(x1, x2);
this.y1 = Math.min(y1, y2);
- this.x2 = Math.max(x1, x2) ;
+ this.x2 = Math.max(x1, x2);
this.y2 = Math.max(y1, y2);
+ this.z1 = Math.min(z1, z2);
+ this.z2 = Math.max(z1, z2);
}
+ public int getId() {
+ return id;
+ }
public int getRegionType() {
return regionType;
@@ -63,6 +74,14 @@ public class Region {
return x1;
}
+ public int getZ1() {
+ return z1;
+ }
+
+ public int getZ2() {
+ return z2;
+ }
+
public int getY1() {
return y1;
}
@@ -101,7 +120,16 @@ public class Region {
public void save(){
try {
+
DaoRegistry.getRegionDao().createOrUpdate(this);
+ List regions = cache.get(island);
+
+ if (regions == null) {
+ return;
+ }
+
+ regions.removeIf(region -> region.getId() == this.id);
+ regions.add(this);
} catch (Exception e) {
e.printStackTrace();
}
@@ -110,10 +138,21 @@ public class Region {
public void addRegionMember(String memberType, String member, String membershipType){
RegionMember regionMember = new RegionMember(this, memberType, member, membershipType);
regionMember.save();
+
+ Region updatedRegion = Region.findById(this.id);
+ List regions = cache.get(island);
+
+ if (regions == null) {
+ return;
+ }
+
+ regions.removeIf(region -> region.getId() == this.id);
+ regions.add(updatedRegion);
+
}
- public boolean isInside(int x, int y) {
- return x >= this.x1 && x <= this.x2 && y >= this.y1 && y <= this.y2;
+ public boolean isInside(int x, int y, int z) {
+ return x >= this.x1 && x <= this.x2 && y >= this.y1 && y <= this.y2 && z >= this.z1 && z <= this.z2;
}
public static Region findById(int id) {
@@ -136,7 +175,7 @@ public class Region {
}
}
- public static Region findRegion(int x, int y, String island) {
+ public static Region findRegion(int x, int y, int z, String island) {
Region region = null;
int highestType = -1;
@@ -146,7 +185,7 @@ public class Region {
}
for (Region cachedRegion : cache.get(island)) {
- if (!cachedRegion.isInside(x, y)) {
+ if (!cachedRegion.isInside(x, y, z)) {
continue;
}
if (highestType >= cachedRegion.getRegionType()){
@@ -160,6 +199,15 @@ public class Region {
}
+ public void changeBoundaries(int x1, int y1, int z1, int x2, int y2, int z2){
+ this.x1 = Math.min(x1, x2);
+ this.y1 = Math.min(y1, y2);
+ this.x2 = Math.max(x1, x2);
+ this.y2 = Math.max(y1, y2);
+ this.z1 = Math.min(z1, z2);
+ this.z2 = Math.max(z1, z2);
+ }
+
}
diff --git a/src/main/java/xyz/soukup/ecoCraftCore/islands/IslandManager.java b/src/main/java/xyz/soukup/ecoCraftCore/islands/IslandManager.java
index 12ee841..301594f 100644
--- a/src/main/java/xyz/soukup/ecoCraftCore/islands/IslandManager.java
+++ b/src/main/java/xyz/soukup/ecoCraftCore/islands/IslandManager.java
@@ -19,6 +19,7 @@ import org.bukkit.entity.Player;
import org.bukkit.persistence.PersistentDataType;
import xyz.soukup.ecoCraftCore.database.objects.Island;
import xyz.soukup.ecoCraftCore.database.DaoRegistry;
+import xyz.soukup.ecoCraftCore.database.objects.Region;
import xyz.soukup.ecoCraftCore.database.objects.TeleportRequest;
import xyz.soukup.ecoCraftCore.utilities.PDC;
@@ -82,6 +83,8 @@ public class IslandManager {
});
} catch (Exception e) { e.printStackTrace(); }
+ createWorldRegion(uuid, owner, ownerType, type);
+
return uuid;
}
@@ -238,6 +241,20 @@ public class IslandManager {
return future;
}
+
+ private void createWorldRegion(String uuid, String owner, String ownerType, String islandType) {
+ int x1 = -32;
+ int x2 = 31;
+ int y1 = -64;
+ int y2 = 320;
+ int z1 = -32;
+ int z2 = 31;
+
+
+ Region region = new Region(uuid, -1, x1, y1, z1, x2, y2, z2);
+ region.save();
+ region.addRegionMember(ownerType, owner, "owner");
+ }
public void changeSpawn(Location location, String uuid) {
SlimeWorld slimeWorld = asp.getLoadedWorld(uuid);
@@ -369,10 +386,7 @@ public class IslandManager {
}
}
- PDC.setUniversal(world, "borderx1", x1, PersistentDataType.INTEGER);
- PDC.setUniversal(world, "borderx2", x2, PersistentDataType.INTEGER);
- PDC.setUniversal(world, "bordery1", z1, PersistentDataType.INTEGER);
- PDC.setUniversal(world, "bordery2", z2, PersistentDataType.INTEGER);
+ changeBoundaries(world, x1, x2, z1, z2);
int chunkMaxX = ((Math.max(x1, x2) + 15) & ~15) + 16;
int chunkMinX = (Math.min(x1, x2) & ~15) - 16;
@@ -397,6 +411,26 @@ public class IslandManager {
;
}
+ private void changeBoundaries(World world, int x1, int x2, int z1, int z2){
+ PDC.setUniversal(world, "borderx1", x1, PersistentDataType.INTEGER);
+ PDC.setUniversal(world, "borderx2", x2, PersistentDataType.INTEGER);
+ PDC.setUniversal(world, "bordery1", z1, PersistentDataType.INTEGER);
+ PDC.setUniversal(world, "bordery2", z2, PersistentDataType.INTEGER);
+
+ QueryBuilder queryBuilder = DaoRegistry.getRegionDao().queryBuilder();
+ try {
+ queryBuilder.where()
+ .eq("island", world.getName())
+ .and()
+ .eq("region_type", 0);
+ Region region = queryBuilder.queryForFirst();
+ region.changeBoundaries(x1, 320, z1, x2,-64, z2);
+ region.save();
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
diff --git a/src/main/java/xyz/soukup/ecoCraftCore/regions/RegionAdminCommand.java b/src/main/java/xyz/soukup/ecoCraftCore/regions/RegionAdminCommand.java
index 0817148..a9c9b6d 100644
--- a/src/main/java/xyz/soukup/ecoCraftCore/regions/RegionAdminCommand.java
+++ b/src/main/java/xyz/soukup/ecoCraftCore/regions/RegionAdminCommand.java
@@ -1,21 +1,64 @@
package xyz.soukup.ecoCraftCore.regions;
+import com.j256.ormlite.stmt.QueryBuilder;
import com.mojang.brigadier.arguments.IntegerArgumentType;
+import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.context.CommandContext;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.Commands;
+import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
+import xyz.soukup.ecoCraftCore.database.DaoRegistry;
+import xyz.soukup.ecoCraftCore.database.objects.Region;
import xyz.soukup.ecoCraftCore.messages.Messages;
+import java.sql.SQLException;
+import java.util.List;
+
+import static xyz.soukup.ecoCraftCore.EcoCraftCore.plugin;
+
public class RegionAdminCommand {
- public static LiteralArgumentBuilder createCommand() {
+ public static LiteralArgumentBuilder getCommand() {
LiteralArgumentBuilder create = Commands.literal("create")
- .then(Commands.argument("type", IntegerArgumentType.integer(0, 1)))
- .executes(RegionAdminCommand::createRegion);
+ .then(Commands.argument("type", IntegerArgumentType.integer(0, 1))
+ .executes(RegionAdminCommand::createRegion));
+
+ LiteralArgumentBuilder addMember = Commands.literal("addMember")
+ .then(Commands.argument("id", IntegerArgumentType.integer())
+ .suggests((context, builder) -> {
+ try {
+ QueryBuilder queryBuilder = DaoRegistry.getRegionDao().queryBuilder();
+ queryBuilder.selectColumns("id");
+ List regions = queryBuilder.query();
+ for (Region region : regions) {
+ builder.suggest(region.getId());
+ }
+ return builder.buildFuture();
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ })
+ .then(Commands.argument("player", StringArgumentType.word())
+ .suggests((context, builder) -> {
+ for (Player onlinePlayer : plugin.getServer().getOnlinePlayers()) {
+ builder.suggest(onlinePlayer.getName());
+ }
+ return builder.buildFuture();
+ })
+ .then(Commands.argument("membership", StringArgumentType.word())
+ .suggests(((context, builder) -> {
+ builder.suggest("owner");
+ builder.suggest("editor");
+ builder.suggest("member");
+ return builder.buildFuture();
+ }))
+ .executes(RegionAdminCommand::addMember))));
+
return Commands.literal("region")
- .then(create);
+ .then(create)
+ .then(addMember);
}
private static int createRegion(CommandContext context) {
@@ -35,4 +78,20 @@ public class RegionAdminCommand {
return 0;
}
+
+ private static int addMember(CommandContext context) {
+ Integer id = context.getArgument("id", Integer.class);
+ String player = context.getArgument("player", String.class);
+ String membership = context.getArgument("membership", String.class);
+ CommandSender commandSender = context.getSource().getSender();
+
+ int status = RegionManager.addMember(id, "player", player, membership);
+ switch (status){
+ case 0 -> Messages.send(commandSender, "generic.success.created");
+ case 1 -> Messages.send(commandSender, "region.error.not-exist");
+ }
+ return 0;
+ }
+
+
}
diff --git a/src/main/java/xyz/soukup/ecoCraftCore/regions/RegionEvents.java b/src/main/java/xyz/soukup/ecoCraftCore/regions/RegionEvents.java
index 1e5f8ad..151a597 100644
--- a/src/main/java/xyz/soukup/ecoCraftCore/regions/RegionEvents.java
+++ b/src/main/java/xyz/soukup/ecoCraftCore/regions/RegionEvents.java
@@ -1,10 +1,13 @@
package xyz.soukup.ecoCraftCore.regions;
+import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
-import org.bukkit.event.player.PlayerInteractEvent;
-import org.bukkit.event.player.PlayerJoinEvent;
+import org.bukkit.event.block.BlockBreakEvent;
+import org.bukkit.event.block.BlockPlaceEvent;
+import org.bukkit.event.player.*;
+import org.bukkit.inventory.ItemStack;
import xyz.soukup.ecoCraftCore.database.objects.Region;
import xyz.soukup.ecoCraftCore.database.objects.RegionMember;
@@ -12,25 +15,119 @@ public class RegionEvents implements Listener {
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event){
- event.setCancelled(!isRegionMember(event.getClickedBlock().getWorld().getName(), event.getPlayer(), event.getClickedBlock().getX(), event.getClickedBlock().getY()));
+ switch (event.getAction()) {
+ case RIGHT_CLICK_BLOCK:
+ case LEFT_CLICK_BLOCK:
+ break;
+ default:
+ return;
+ }
+
+
+ Block block = event.getClickedBlock();
+ ItemStack item = event.getItem();
+ if (block == null) return;
+
+ if (item != null && item.getType().isBlock() && !block.getType().isInteractable()) {
+ return;
+ }
+
+ boolean allowed = isAllowedToInteract(
+ block.getWorld().getName(),
+ event.getPlayer(),
+ block.getX(),
+ block.getY(),
+ block.getZ()
+ );
+
+ event.setCancelled(!allowed);
}
+ @EventHandler
+ public void onBlockPlace(BlockPlaceEvent event) {
+ Block block = event.getBlockPlaced();
- private boolean isRegionMember(String island, Player player, int x, int y){
- Region region = Region.findRegion(x, y, island);
+ boolean allowed = isAllowedToInteract(
+ block.getWorld().getName(),
+ event.getPlayer(),
+ block.getX(),
+ block.getY(),
+ block.getZ()
+ );
- if (region == null){
- return false;
- }
+ event.setCancelled(!allowed);
+ }
- String name = player.getName();
+ @EventHandler
+ public void onBlockBreak(BlockBreakEvent event) {
- for (RegionMember regionMember : region.getRegionMembers()){
- if (regionMember.getMembertype().equals("player") && regionMember.getName().equals(name)){
- return true;
- }
- }
+ Block block = event.getBlock();
+
+ boolean allowed = isAllowedToInteract(
+ block.getWorld().getName(),
+ event.getPlayer(),
+ block.getX(),
+ block.getY(),
+ block.getZ()
+ );
+
+ event.setCancelled(!allowed);
+ }
+ @EventHandler
+ public void onBucketUse(PlayerBucketEmptyEvent event) {
+ Block clickedBlock = event.getBlockClicked();
+
+ boolean allowed = isAllowedToInteract(
+ clickedBlock.getWorld().getName(),
+ event.getPlayer(),
+ clickedBlock.getX(),
+ clickedBlock.getY(),
+ clickedBlock.getZ()
+ );
+
+ event.setCancelled(!allowed);
+ }
+
+ @EventHandler
+ public void onBucketUse(PlayerBucketFillEvent event) {
+ Block clickedBlock = event.getBlockClicked();
+
+ boolean allowed = isAllowedToInteract(
+ clickedBlock.getWorld().getName(),
+ event.getPlayer(),
+ clickedBlock.getX(),
+ clickedBlock.getY(),
+ clickedBlock.getZ()
+ );
+
+ event.setCancelled(!allowed);
+ }
+
+
+
+ private boolean isAllowedToInteract(String island, Player player, int x, int y, int z){
+ if (player.isOp()){
+ return true;
+ }
+
+ Region region = Region.findRegion(x, y, z, island);
+
+ if (region == null){
return false;
+ }
+
+ String name = player.getName();
+
+ for (RegionMember regionMember : region.getRegionMembers()){
+
+ if (regionMember.getMembertype().equals("player") && regionMember.getName().equals(name)){
+ return true;
+ }
+ }
+
+ return false;
}
+
+
}
diff --git a/src/main/java/xyz/soukup/ecoCraftCore/regions/RegionManager.java b/src/main/java/xyz/soukup/ecoCraftCore/regions/RegionManager.java
index 47800c0..14c480d 100644
--- a/src/main/java/xyz/soukup/ecoCraftCore/regions/RegionManager.java
+++ b/src/main/java/xyz/soukup/ecoCraftCore/regions/RegionManager.java
@@ -20,15 +20,29 @@ public class RegionManager {
String worldName = primaryLocation.getWorld().getName();
int x1 = primaryLocation.getBlockX();
- int y1 = primaryLocation.getBlockZ();
+ int y1 = primaryLocation.getBlockY();
+ int z1 = primaryLocation.getBlockZ();
int x2 = secondaryLocation.getBlockX();
- int y2 = secondaryLocation.getBlockZ();
+ int y2 = secondaryLocation.getBlockY();
+ int z2 = secondaryLocation.getBlockZ();
- Region region = new Region(worldName, type, x1, y1, x2, y2);
+ Region region = new Region(worldName, type, x1, y1, z1, x2, y2, z2);
region.save();
region.addRegionMember(ownerType, owner, "owner");
return 0;
}
+
+ public static int addMember(int id, String memberType, String member, String membershipType){
+ Region region = Region.findById(id);
+
+ if (region == null){
+ return 1;
+ }
+
+ region.addRegionMember(memberType, member, membershipType);
+
+ return 0;
+ }
}
diff --git a/src/main/resources/messages.yml b/src/main/resources/messages.yml
index f8336df..2ccf9e7 100644
--- a/src/main/resources/messages.yml
+++ b/src/main/resources/messages.yml
@@ -15,6 +15,7 @@ generic:
region:
error:
not-marked: "Musíš nejprve označit pozice"
+ not-exist: "Region neexistuje"
shop:
error:
already-shop: "Tato cedule již je obchod"