parent
e70e526d93
commit
f355dcfa1e
38 changed files with 1255 additions and 488 deletions
@ -0,0 +1,19 @@ |
||||
Copyright (c) 2025-2026 Jakub Soukup, Erik Radovan and contributors |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
of this software and associated documentation files (the "Software"), to deal |
||||
in the Software without restriction, including without limitation the rights |
||||
to copy, modify, merge, publish, distribute, sublicense, and/or sell copies |
||||
of the Software, but NOT including the right to run, execute or use the |
||||
Software or any executable binaries built from the source code. |
||||
|
||||
The above copyright notice and this permission notice shall be included in all |
||||
copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||
SOFTWARE |
||||
@ -1,34 +0,0 @@ |
||||
package xyz.soukup.ecoCraftCore.database.objects; |
||||
|
||||
public enum Permission { |
||||
PLACE(1), |
||||
BREAK(2), |
||||
REDSTONE_INTERACT(3), |
||||
ENTITY_INTERACT(4), |
||||
VEHICLE_INTERACT(5), |
||||
ENTER(6), |
||||
EXIT(7), |
||||
MANAGE_MEMBERS(8), |
||||
MANAGE_GROUPS(9), |
||||
MANAGE_REGIONS(10), |
||||
TRANSFER_OWNERSHIP(11), |
||||
USE_HOPPER(12), |
||||
HARVEST(13), |
||||
PLANT(14), |
||||
PICKUP_ITEMS(15), |
||||
DROP_ITEMS(16), |
||||
PLOUGH(17), |
||||
SIT(18), |
||||
SHOP_INTERACT(19), |
||||
HARM_ENTITIES(20), |
||||
HARM_PLAYERS(21); |
||||
|
||||
private final int bit; |
||||
Permission(int bit) { |
||||
this.bit = bit; |
||||
} |
||||
|
||||
public int getBit() { |
||||
return bit; |
||||
} |
||||
} |
||||
@ -1,284 +0,0 @@ |
||||
package xyz.soukup.ecoCraftCore.database.objects; |
||||
|
||||
import com.j256.ormlite.dao.Dao; |
||||
import com.j256.ormlite.dao.ForeignCollection; |
||||
import com.j256.ormlite.field.DatabaseField; |
||||
import com.j256.ormlite.field.ForeignCollectionField; |
||||
import com.j256.ormlite.table.DatabaseTable; |
||||
import org.bukkit.Material; |
||||
import org.bukkit.entity.Player; |
||||
import xyz.soukup.ecoCraftCore.messages.Messages; |
||||
|
||||
import java.sql.SQLException; |
||||
import java.util.HashMap; |
||||
import java.util.List; |
||||
|
||||
@DatabaseTable(tableName = "regions") |
||||
public class Region { |
||||
|
||||
public static Dao<Region, Integer> dao; |
||||
|
||||
public static void setDao(Dao<Region, Integer> dao) { |
||||
Region.dao = dao; |
||||
} |
||||
|
||||
public static Dao<Region, Integer> getDao() { |
||||
return dao; |
||||
} |
||||
|
||||
public static final HashMap<String, List<Region>> cache = new HashMap<>(); |
||||
|
||||
@DatabaseField(generatedId = true) |
||||
private int id; |
||||
|
||||
@DatabaseField(canBeNull = false) |
||||
private String island; |
||||
|
||||
@DatabaseField(columnName = "region_type", canBeNull = false) |
||||
private int regionType; |
||||
|
||||
@DatabaseField(canBeNull = false) |
||||
private int x1; |
||||
|
||||
@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<RegionMember> regionMembers; |
||||
|
||||
@DatabaseField() |
||||
private Integer value; |
||||
|
||||
public Region() { |
||||
|
||||
} |
||||
|
||||
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.y2 = Math.max(y1, y2); |
||||
this.z1 = Math.min(z1, z2); |
||||
this.z2 = Math.max(z1, z2); |
||||
|
||||
save(); |
||||
createDefaultGroupsAndReturnOwner(); |
||||
|
||||
} |
||||
|
||||
public PermissionGroup getPermissionGroup(String name){ |
||||
return PermissionGroup.getPermissionGroup(this, name); |
||||
} |
||||
|
||||
public Region(String island, int regionType, int x1, int y1, int z1, int x2, int y2, int z2, Player owner) { |
||||
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.y2 = Math.max(y1, y2); |
||||
this.z1 = Math.min(z1, z2); |
||||
this.z2 = Math.max(z1, z2); |
||||
|
||||
this.save(); |
||||
|
||||
PermissionGroup ownerGroup = this.createDefaultGroupsAndReturnOwner(); |
||||
addRegionMember("player", owner.getName(), ownerGroup); |
||||
|
||||
|
||||
} |
||||
|
||||
public int getId() { |
||||
return id; |
||||
} |
||||
|
||||
public int getRegionType() { |
||||
return regionType; |
||||
} |
||||
|
||||
public int getX1() { |
||||
return x1; |
||||
} |
||||
|
||||
public int getZ1() { |
||||
return z1; |
||||
} |
||||
|
||||
public int getZ2() { |
||||
return z2; |
||||
} |
||||
|
||||
public int getY1() { |
||||
return y1; |
||||
} |
||||
|
||||
public int getX2() { |
||||
return x2; |
||||
} |
||||
|
||||
public int getY2() { |
||||
return y2; |
||||
} |
||||
|
||||
public ForeignCollection<RegionMember> getRegionMembers() { |
||||
return regionMembers; |
||||
} |
||||
|
||||
public Integer getValue() { |
||||
return value; |
||||
} |
||||
|
||||
public String getIsland() { |
||||
return island; |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void setRegionType(int regionType) { |
||||
this.regionType = regionType; |
||||
} |
||||
|
||||
public void setValue(Integer value) { |
||||
this.value = value; |
||||
} |
||||
|
||||
public void save(){ |
||||
try { |
||||
|
||||
getDao().createOrUpdate(this); |
||||
List<Region> regions = cache.get(island); |
||||
|
||||
if (regions == null) { |
||||
return; |
||||
} |
||||
|
||||
regions.removeIf(region -> region.getId() == this.id); |
||||
regions.add(this); |
||||
} catch (Exception e) { |
||||
e.printStackTrace(); |
||||
} |
||||
} |
||||
|
||||
public void addRegionMember(String memberType, String member, PermissionGroup permissionGroup){ |
||||
RegionMember regionMember = new RegionMember(this, memberType, member, permissionGroup); |
||||
regionMember.save(); |
||||
|
||||
List<Region> regions = cache.get(island); |
||||
|
||||
if (regions == null) { |
||||
return; |
||||
} |
||||
|
||||
regions.removeIf(region -> region.getId() == this.id); |
||||
regions.add(this); |
||||
|
||||
} |
||||
|
||||
public void removeRegionMember(String memberType, String member){ |
||||
try { |
||||
RegionMember.getDao().queryBuilder().where().eq("region", this).query(); |
||||
} catch (SQLException e) { |
||||
throw new RuntimeException(e); |
||||
} |
||||
} |
||||
|
||||
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) { |
||||
try { |
||||
return getDao().queryForId(id); |
||||
} catch (Exception e) { |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
public static void cacheRegions(String island) { |
||||
try { |
||||
List<Region> regions = getDao().queryBuilder() |
||||
.where() |
||||
.eq("island", island) |
||||
.query(); |
||||
cache.put(island, regions); |
||||
} catch (Exception e) { |
||||
|
||||
} |
||||
} |
||||
|
||||
public static Region findRegion(int x, int y, int z, String island) { |
||||
|
||||
Region region = null; |
||||
int highestType = -1; |
||||
|
||||
if (!cache.containsKey(island)) { |
||||
cacheRegions(island); |
||||
} |
||||
|
||||
for (Region cachedRegion : cache.get(island)) { |
||||
if (!cachedRegion.isInside(x, y, z)) { |
||||
continue; |
||||
} |
||||
if (highestType >= cachedRegion.getRegionType()){ |
||||
continue; |
||||
} |
||||
region = cachedRegion; |
||||
} |
||||
|
||||
return 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); |
||||
} |
||||
|
||||
public PermissionGroup createDefaultGroupsAndReturnOwner(){ |
||||
String ownerDisplayName = Messages.getAsString("region.permission-groups.owner.name"); |
||||
String ownerDescription = Messages.getAsString("region.permission-groups.owner.description"); |
||||
PermissionGroup owner = new PermissionGroup(this, "owner", ownerDisplayName, ownerDescription, Material.RED_CONCRETE, false, false, 101); |
||||
owner.save(); |
||||
|
||||
String adminDisplayName = Messages.getAsString("region.permission-groups.admin.name"); |
||||
String adminDescription = Messages.getAsString("region.permission-groups.admin.description"); |
||||
PermissionGroup admin = new PermissionGroup(this, "admin", adminDisplayName, adminDescription, Material.YELLOW_CONCRETE, true, true, 90); |
||||
admin.save(); |
||||
|
||||
String memberDisplayName = Messages.getAsString("region.permission-groups.member.name"); |
||||
String memberDescription = Messages.getAsString("region.permission-groups.member.description"); |
||||
PermissionGroup member = new PermissionGroup(this, "member", memberDisplayName, memberDescription, Material.GREEN_CONCRETE, true, true, 10); |
||||
member.save(); |
||||
|
||||
String defaultDisplayName = Messages.getAsString("region.permission-groups.default"); |
||||
String defaultDescription = Messages.getAsString("region.permission-groups.default.description"); |
||||
PermissionGroup defaultGroup = new PermissionGroup(this, "default", defaultDisplayName, defaultDescription, Material.GRAY_CONCRETE, true, true, 0); |
||||
defaultGroup.save(); |
||||
|
||||
return owner; |
||||
} |
||||
|
||||
|
||||
} |
||||
|
||||
@ -1,4 +0,0 @@ |
||||
package xyz.soukup.ecoCraftCore.islands; |
||||
|
||||
public class UnloadIsland { |
||||
} |
||||
@ -0,0 +1,15 @@ |
||||
package xyz.soukup.ecoCraftCore.messages; |
||||
|
||||
public class Replace { |
||||
private final String key; |
||||
private final String value; |
||||
|
||||
public Replace(String key, String value) { |
||||
this.key = key; |
||||
this.value = value; |
||||
} |
||||
|
||||
public String process(String input) { |
||||
return input.replace("<" + key + ">", value); |
||||
} |
||||
} |
||||
@ -1,4 +1,4 @@ |
||||
package xyz.soukup.ecoCraftCore.database.objects; |
||||
package xyz.soukup.ecoCraftCore.objects; |
||||
|
||||
|
||||
import com.j256.ormlite.dao.Dao; |
||||
@ -1,4 +1,4 @@ |
||||
package xyz.soukup.ecoCraftCore.database.objects; |
||||
package xyz.soukup.ecoCraftCore.objects; |
||||
|
||||
import com.j256.ormlite.dao.Dao; |
||||
import com.j256.ormlite.field.DataType; |
||||
@ -0,0 +1,43 @@ |
||||
package xyz.soukup.ecoCraftCore.objects; |
||||
|
||||
public enum Permission { |
||||
PLACE(0), |
||||
BREAK(1), |
||||
INTERACT(2), |
||||
ENTITY_INTERACT(3), |
||||
OPEN_CHESTS(4), |
||||
ENTER(5), |
||||
EXIT(6), |
||||
MANAGE_MEMBERS(7), |
||||
MANAGE_GROUPS(8), |
||||
MANAGE_REGIONS(9), |
||||
TRANSFER_OWNERSHIP(10), |
||||
USE_HOPPER(11), |
||||
HARVEST(12), |
||||
PLANT(13), |
||||
PICKUP_ITEMS(14), |
||||
DROP_ITEMS(15), |
||||
REDSTONE_INTERACT(16), |
||||
SIT(17), |
||||
SHOP_INTERACT(18), |
||||
HARM_ENTITIES(19), |
||||
HARM_PLAYERS(20), |
||||
VEHICLE_RIDE(21), |
||||
VEHICLE_PLACE(22), |
||||
VEHICLE_BREAK(23), |
||||
VEHICLE_INTERACT(24), |
||||
BUCKET_USE(25); |
||||
|
||||
|
||||
private final int mask; |
||||
|
||||
Permission(int position) { |
||||
// This creates the power of two: 1, 2, 4, 8, 16...
|
||||
this.mask = 1 << position; |
||||
} |
||||
|
||||
public int getMask() { |
||||
return mask; |
||||
} |
||||
} |
||||
|
||||
@ -0,0 +1,468 @@ |
||||
package xyz.soukup.ecoCraftCore.objects; |
||||
|
||||
import com.j256.ormlite.dao.Dao; |
||||
import com.j256.ormlite.dao.ForeignCollection; |
||||
import com.j256.ormlite.field.DatabaseField; |
||||
import com.j256.ormlite.field.ForeignCollectionField; |
||||
import com.j256.ormlite.stmt.DeleteBuilder; |
||||
import com.j256.ormlite.stmt.Where; |
||||
import com.j256.ormlite.table.DatabaseTable; |
||||
import org.bukkit.Location; |
||||
import org.bukkit.Material; |
||||
import org.bukkit.entity.Player; |
||||
import xyz.soukup.ecoCraftCore.messages.Messages; |
||||
|
||||
import java.sql.SQLException; |
||||
import java.util.Comparator; |
||||
import java.util.HashMap; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
@DatabaseTable(tableName = "regions") |
||||
public class Region { |
||||
|
||||
public static Dao<Region, Integer> dao; |
||||
|
||||
public static void setDao(Dao<Region, Integer> dao) { |
||||
Region.dao = dao; |
||||
} |
||||
|
||||
public static Dao<Region, Integer> getDao() { |
||||
return dao; |
||||
} |
||||
|
||||
public static final HashMap<String, List<Region>> cache = new HashMap<>(); |
||||
|
||||
@DatabaseField(generatedId = true) |
||||
private int id; |
||||
|
||||
@DatabaseField(canBeNull = false) |
||||
private String island; |
||||
|
||||
@DatabaseField(columnName = "region_level", canBeNull = false) |
||||
private int regionLevel; |
||||
|
||||
@DatabaseField(canBeNull = false) |
||||
private int x1; |
||||
|
||||
@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<RegionMember> regionMembers; |
||||
|
||||
@DatabaseField() |
||||
private Integer value; |
||||
|
||||
public Region() { |
||||
|
||||
} |
||||
|
||||
public Region(String island, int regionLevel, int x1, int y1, int z1, int x2, int y2, int z2) { |
||||
this.island = island; |
||||
this.regionLevel = regionLevel; |
||||
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); |
||||
|
||||
save(); |
||||
createDefaultGroupsAndReturnOwner(); |
||||
|
||||
} |
||||
|
||||
public PermissionGroup getPermissionGroup(String name){ |
||||
return PermissionGroup.getPermissionGroup(this, name); |
||||
} |
||||
|
||||
public Region(Region parentRegion, int x1, int y1, int z1, int x2, int y2, int z2) { |
||||
this.island = parentRegion.getIsland(); |
||||
this.regionLevel = parentRegion.getRegionLevel() + 1; |
||||
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); |
||||
|
||||
save(); |
||||
|
||||
copyDataFrom(parentRegion); |
||||
} |
||||
|
||||
private void copyDataFrom(Region source) { |
||||
try { |
||||
Map<String, PermissionGroup> groupMapping = new HashMap<>(); |
||||
|
||||
List<PermissionGroup> sourceGroups = PermissionGroup.getDao().queryBuilder() |
||||
.where().eq("region_id", source.getId()).query(); |
||||
|
||||
for (PermissionGroup sourceGroup : sourceGroups) { |
||||
PermissionGroup clonedGroup = sourceGroup.copyTo(this); |
||||
clonedGroup.save(); |
||||
groupMapping.put(clonedGroup.getName(), clonedGroup); |
||||
} |
||||
|
||||
for (RegionMember sourceMember : source.getRegionMembers()) { |
||||
PermissionGroup targetGroup = groupMapping.get(sourceMember.getPermissionGroup().getName()); |
||||
|
||||
if (targetGroup != null) { |
||||
addRegionMember(sourceMember.getMemberType(), sourceMember.getName(), targetGroup); |
||||
} |
||||
} |
||||
} catch (SQLException e) { |
||||
e.printStackTrace(); |
||||
} |
||||
} |
||||
|
||||
public Region(String island, int regionType, int x1, int y1, int z1, int x2, int y2, int z2, Player owner) { |
||||
this.island = island; |
||||
this.regionLevel = regionType; |
||||
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); |
||||
|
||||
this.save(); |
||||
|
||||
PermissionGroup ownerGroup = this.createDefaultGroupsAndReturnOwner(); |
||||
addRegionMember("player", owner.getName(), ownerGroup); |
||||
|
||||
|
||||
} |
||||
|
||||
public int getId() { |
||||
return id; |
||||
} |
||||
|
||||
public int getRegionLevel() { |
||||
return regionLevel; |
||||
} |
||||
|
||||
public int getX1() { |
||||
return x1; |
||||
} |
||||
|
||||
public int getZ1() { |
||||
return z1; |
||||
} |
||||
|
||||
public int getZ2() { |
||||
return z2; |
||||
} |
||||
|
||||
public int getY1() { |
||||
return y1; |
||||
} |
||||
|
||||
public int getX2() { |
||||
return x2; |
||||
} |
||||
|
||||
public int getY2() { |
||||
return y2; |
||||
} |
||||
|
||||
public ForeignCollection<RegionMember> getRegionMembers() { |
||||
return regionMembers; |
||||
} |
||||
|
||||
public Integer getValue() { |
||||
return value; |
||||
} |
||||
|
||||
public String getIsland() { |
||||
return island; |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void setRegionLevel(int regionLevel) { |
||||
this.regionLevel = regionLevel; |
||||
} |
||||
|
||||
public void setValue(Integer value) { |
||||
this.value = value; |
||||
} |
||||
|
||||
public void save(){ |
||||
try { |
||||
|
||||
getDao().createOrUpdate(this); |
||||
List<Region> regions = cache.get(island); |
||||
|
||||
if (regions == null) { |
||||
return; |
||||
} |
||||
|
||||
regions.removeIf(region -> region.getId() == this.id); |
||||
regions.add(this); |
||||
} catch (Exception e) { |
||||
e.printStackTrace(); |
||||
} |
||||
} |
||||
|
||||
public void refreshCache(){ |
||||
List<Region> regions = cache.get(island); |
||||
|
||||
if (regions == null) { |
||||
return; |
||||
} |
||||
|
||||
try { |
||||
Region fefreshedRegion = getDao().queryForId(this.id); |
||||
regions.removeIf(region -> region.getId() == this.id); |
||||
regions.add(fefreshedRegion); |
||||
} catch (SQLException e) { |
||||
throw new RuntimeException(e); |
||||
} |
||||
} |
||||
|
||||
public void addRegionMember(Player player, PermissionGroup group){ |
||||
addRegionMember("player", player.getName(), group); |
||||
} |
||||
|
||||
public void addRegionMember(String memberType, String member, PermissionGroup permissionGroup){ |
||||
RegionMember regionMember = new RegionMember(this, memberType, member, permissionGroup); |
||||
regionMember.save(); |
||||
|
||||
List<Region> regions = cache.get(island); |
||||
|
||||
if (regions == null) { |
||||
return; |
||||
} |
||||
|
||||
regions.removeIf(region -> region.getId() == this.id); |
||||
regions.add(this); |
||||
|
||||
} |
||||
|
||||
public void removeRegionMember(Player player){ |
||||
removeRegionMember("player", player.getName()); |
||||
} |
||||
|
||||
public void removeRegionMember(String memberType, String member){ |
||||
try { |
||||
RegionMember.getDao().queryBuilder().where().eq("region", this).query(); |
||||
} catch (SQLException e) { |
||||
throw new RuntimeException(e); |
||||
} |
||||
} |
||||
|
||||
public RegionMember getRegionMember(Player player){ |
||||
return getRegionMember("player", player.getName()); |
||||
} |
||||
|
||||
public boolean hasPermission(Player player, Permission permission){ |
||||
RegionMember regionMember = getRegionMember(player); |
||||
PermissionGroup permissionGroup; |
||||
|
||||
if (regionMember == null) { |
||||
permissionGroup = getPermissionGroup("default"); |
||||
}else { |
||||
permissionGroup = regionMember.getPermissionGroup(); |
||||
} |
||||
|
||||
return permissionGroup.hasPermission(permission); |
||||
} |
||||
|
||||
public boolean hasPermission(String memberType, String memberName, Permission permission){ |
||||
RegionMember regionMember = getRegionMember(memberType, memberName); |
||||
PermissionGroup permissionGroup; |
||||
|
||||
if (regionMember == null) { |
||||
permissionGroup = getPermissionGroup("default"); |
||||
}else { |
||||
permissionGroup = regionMember.getPermissionGroup(); |
||||
} |
||||
|
||||
return permissionGroup.hasPermission(permission); |
||||
} |
||||
|
||||
|
||||
|
||||
public static List<Region> getOverlappingRegions(Location loc1, Location loc2) { |
||||
if (loc1.getWorld() != loc2.getWorld()){ |
||||
return null; |
||||
} |
||||
|
||||
String island = loc1.getWorld().getName(); |
||||
|
||||
List<Region> overlapping = new java.util.ArrayList<>(); |
||||
|
||||
if (!cache.containsKey(island)) { |
||||
cacheRegions(island); |
||||
} |
||||
|
||||
int minX = Math.min(loc1.getBlockX(), loc2.getBlockX()); |
||||
int maxX = Math.max(loc1.getBlockX(), loc2.getBlockX()); |
||||
int minY = Math.min(loc1.getBlockY(), loc2.getBlockY()); |
||||
int maxY = Math.max(loc1.getBlockY(), loc2.getBlockY()); |
||||
int minZ = Math.min(loc1.getBlockZ(), loc2.getBlockZ()); |
||||
int maxZ = Math.max(loc1.getBlockZ(), loc2.getBlockZ()); |
||||
|
||||
for (Region region : cache.get(island)) { |
||||
if ((region.getX1() <= maxX |
||||
&& region.getX2() >= minX) && (region.getY1() <= maxY |
||||
&& region.getY2() >= minY) && (region.getZ1() <= maxZ |
||||
&& region.getZ2() >= minZ)) { |
||||
overlapping.add(region); |
||||
} |
||||
} |
||||
|
||||
return overlapping; |
||||
} |
||||
|
||||
public static Region getHighestLevelRegion(Location loc1, Location loc2) { |
||||
List<Region> regions = getOverlappingRegions(loc1, loc2); |
||||
|
||||
if (regions.isEmpty()) { |
||||
return null; |
||||
} |
||||
|
||||
return regions.stream().max(Comparator.comparingInt(Region::getRegionLevel)).orElse(null); |
||||
} |
||||
|
||||
public RegionMember getRegionMember(String type, String name){ |
||||
return this.regionMembers.stream().filter(regionMember -> regionMember.getMemberType().equals(type) && regionMember.getName().equals(name)).findFirst().orElse(null); |
||||
} |
||||
|
||||
|
||||
|
||||
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 boolean envelops(Location loc1, Location loc2) { |
||||
int minX = Math.min(loc1.getBlockX(), loc2.getBlockX()); |
||||
int maxX = Math.max(loc1.getBlockX(), loc2.getBlockX()); |
||||
int minY = Math.min(loc1.getBlockY(), loc2.getBlockY()); |
||||
int maxY = Math.max(loc1.getBlockY(), loc2.getBlockY()); |
||||
int minZ = Math.min(loc1.getBlockZ(), loc2.getBlockZ()); |
||||
int maxZ = Math.max(loc1.getBlockZ(), loc2.getBlockZ()); |
||||
|
||||
return this.x1 <= minX && this.x2 >= maxX && |
||||
this.y1 <= minY && this.y2 >= maxY && |
||||
this.z1 <= minZ && this.z2 >= maxZ; |
||||
} |
||||
|
||||
public static Region findById(int id) { |
||||
try { |
||||
return getDao().queryForId(id); |
||||
} catch (Exception e) { |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
public static void cacheRegions(String island) { |
||||
try { |
||||
List<Region> regions = getDao().queryBuilder() |
||||
.where() |
||||
.eq("island", island) |
||||
.query(); |
||||
cache.put(island, regions); |
||||
} catch (Exception e) { |
||||
|
||||
} |
||||
} |
||||
|
||||
public static Region findRegion(Location location){ |
||||
return findRegion(location.getBlockX(), location.getBlockY(), location.getBlockZ(), location.getWorld().getName()); |
||||
} |
||||
|
||||
public static Region findRegion(int x, int y, int z, String island) { |
||||
|
||||
Region region = null; |
||||
int highestType = -1; |
||||
|
||||
if (!cache.containsKey(island)) { |
||||
cacheRegions(island); |
||||
} |
||||
|
||||
for (Region cachedRegion : cache.get(island)) { |
||||
if (!cachedRegion.isInside(x, y, z)) { |
||||
continue; |
||||
} |
||||
if (highestType >= cachedRegion.getRegionLevel()){ |
||||
continue; |
||||
} |
||||
region = cachedRegion; |
||||
} |
||||
|
||||
return 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); |
||||
} |
||||
|
||||
public PermissionGroup createDefaultGroupsAndReturnOwner(){ |
||||
String ownerDisplayName = Messages.getAsString("region.permission-groups.owner.name"); |
||||
String ownerDescription = Messages.getAsString("region.permission-groups.owner.description"); |
||||
PermissionGroup owner = new PermissionGroup(this, "owner", ownerDisplayName, ownerDescription, Material.RED_CONCRETE, false, false, 101, 2147483647); |
||||
owner.save(); |
||||
|
||||
String adminDisplayName = Messages.getAsString("region.permission-groups.admin.name"); |
||||
String adminDescription = Messages.getAsString("region.permission-groups.admin.description"); |
||||
PermissionGroup admin = new PermissionGroup(this, "admin", adminDisplayName, adminDescription, Material.YELLOW_CONCRETE, true, true, 90, 2147482623); |
||||
admin.save(); |
||||
|
||||
String memberDisplayName = Messages.getAsString("region.permission-groups.member.name"); |
||||
String memberDescription = Messages.getAsString("region.permission-groups.member.description"); |
||||
PermissionGroup member = new PermissionGroup(this, "member", memberDisplayName, memberDescription, Material.GREEN_CONCRETE, true, true, 10, 2095231); |
||||
member.save(); |
||||
|
||||
String defaultDisplayName = Messages.getAsString("region.permission-groups.default"); |
||||
String defaultDescription = Messages.getAsString("region.permission-groups.default.description"); |
||||
PermissionGroup defaultGroup = new PermissionGroup(this, "default", defaultDisplayName, defaultDescription, Material.GRAY_CONCRETE, true, false, 0,96); |
||||
defaultGroup.save(); |
||||
|
||||
return owner; |
||||
} |
||||
|
||||
|
||||
public void delete() { |
||||
try { |
||||
getDao().delete(this); |
||||
cache.get(this.island).remove(this); |
||||
Dao<PermissionGroup, Integer> permissionGroupDao = PermissionGroup.getDao(); |
||||
Dao<RegionMember, Integer> regionMemberDao = RegionMember.getDao(); |
||||
|
||||
DeleteBuilder<PermissionGroup, Integer> groupDeleteBuilder = permissionGroupDao.deleteBuilder(); |
||||
groupDeleteBuilder.where().eq("region_id", this.id); |
||||
groupDeleteBuilder.delete(); |
||||
|
||||
DeleteBuilder<RegionMember, Integer> memberDeleteBuilder= regionMemberDao.deleteBuilder(); |
||||
memberDeleteBuilder.where().eq("region_id", this.id); |
||||
memberDeleteBuilder.delete(); |
||||
} catch (SQLException e) { |
||||
throw new RuntimeException(e); |
||||
} |
||||
} |
||||
} |
||||
|
||||
@ -0,0 +1,15 @@ |
||||
package xyz.soukup.ecoCraftCore.objects; |
||||
|
||||
public enum Status { |
||||
OK, |
||||
INVALID_SELECTION, |
||||
NO_PERMISSION, |
||||
NO_SELECTION, |
||||
REGION_NOT_ENVELOPS, |
||||
NOT_EXIST, |
||||
PLAYER_NOT_ON_ISLAND, |
||||
NOT_EXIST_GROUP, |
||||
ALREADY_MEMBER, |
||||
NOT_MEMBER, |
||||
|
||||
} |
||||
@ -1,4 +1,4 @@ |
||||
package xyz.soukup.ecoCraftCore.database.objects; |
||||
package xyz.soukup.ecoCraftCore.objects; |
||||
|
||||
import com.j256.ormlite.dao.Dao; |
||||
import com.j256.ormlite.field.DatabaseField; |
||||
@ -1,4 +1,4 @@ |
||||
package xyz.soukup.ecoCraftCore.database.objects; |
||||
package xyz.soukup.ecoCraftCore.objects; |
||||
|
||||
import com.j256.ormlite.dao.Dao; |
||||
import com.j256.ormlite.field.DatabaseField; |
||||
@ -1,4 +1,4 @@ |
||||
package xyz.soukup.ecoCraftCore.database.objects; |
||||
package xyz.soukup.ecoCraftCore.objects; |
||||
|
||||
import com.j256.ormlite.dao.Dao; |
||||
import com.j256.ormlite.field.DataType; |
||||
@ -0,0 +1,225 @@ |
||||
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.builder.RequiredArgumentBuilder; |
||||
import com.mojang.brigadier.context.CommandContext; |
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException; |
||||
import com.mojang.brigadier.suggestion.Suggestions; |
||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder; |
||||
import io.papermc.paper.command.brigadier.CommandSourceStack; |
||||
import io.papermc.paper.command.brigadier.Commands; |
||||
import io.papermc.paper.command.brigadier.argument.ArgumentTypes; |
||||
import io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver; |
||||
import io.papermc.paper.registry.RegistryKey; |
||||
import org.bukkit.Material; |
||||
import org.bukkit.entity.Player; |
||||
import org.bukkit.inventory.ItemStack; |
||||
import xyz.soukup.ecoCraftCore.messages.Messages; |
||||
import xyz.soukup.ecoCraftCore.messages.Replace; |
||||
import xyz.soukup.ecoCraftCore.objects.Permission; |
||||
import xyz.soukup.ecoCraftCore.objects.PermissionGroup; |
||||
import xyz.soukup.ecoCraftCore.objects.Region; |
||||
import xyz.soukup.ecoCraftCore.objects.RegionMember; |
||||
|
||||
import java.sql.SQLException; |
||||
import java.util.List; |
||||
import java.util.concurrent.CompletableFuture; |
||||
|
||||
public class RegionCommand { |
||||
|
||||
public static LiteralArgumentBuilder<CommandSourceStack> command(){ |
||||
LiteralArgumentBuilder<CommandSourceStack> confirm = Commands.literal("confirm"); |
||||
RequiredArgumentBuilder<CommandSourceStack, PlayerSelectorArgumentResolver> playerArgument = Commands.argument("player", ArgumentTypes.player()); |
||||
RequiredArgumentBuilder<CommandSourceStack, String> memberArgument = Commands.argument("member", StringArgumentType.word()).suggests(RegionCommand::memberGroupSuggestions); |
||||
RequiredArgumentBuilder<CommandSourceStack, String> groupArgument = Commands.argument("group", StringArgumentType.word()).suggests(RegionCommand::memberGroupSuggestions); |
||||
RequiredArgumentBuilder<CommandSourceStack, ItemStack> materialArgument = Commands.argument("icon", ArgumentTypes.itemStack()); |
||||
|
||||
LiteralArgumentBuilder<CommandSourceStack> create = Commands.literal("create") |
||||
.executes(RegionCommand::create); |
||||
|
||||
LiteralArgumentBuilder<CommandSourceStack> delete = Commands.literal("delete") |
||||
.executes(RegionCommand::delete) |
||||
.then(confirm.executes(RegionCommand::delete)); |
||||
|
||||
LiteralArgumentBuilder<CommandSourceStack> addMember = Commands.literal("add-member") |
||||
.then(playerArgument.then(groupArgument.executes(RegionCommand::addMember))); |
||||
|
||||
LiteralArgumentBuilder<CommandSourceStack> removeMember = Commands.literal("remove-member") |
||||
.then(playerArgument.executes(RegionCommand::removeMember)); |
||||
|
||||
LiteralArgumentBuilder<CommandSourceStack> member = Commands.literal("member") |
||||
.then(addMember) |
||||
.then(removeMember); |
||||
|
||||
LiteralArgumentBuilder<CommandSourceStack> group = Commands.literal("group"); |
||||
|
||||
LiteralArgumentBuilder<CommandSourceStack> groupAdd = Commands.literal("create") |
||||
; |
||||
LiteralArgumentBuilder<CommandSourceStack> groupRemove = Commands.literal("remove"); |
||||
|
||||
RequiredArgumentBuilder<CommandSourceStack, Integer> regionEdits = Commands.argument("id", IntegerArgumentType.integer(1, 2147483647)) |
||||
.then(delete) |
||||
.then(member) |
||||
.then(group); |
||||
|
||||
return Commands.literal("region") |
||||
.requires(c -> c.getSender() instanceof Player) |
||||
.then(create) |
||||
.then(regionEdits); |
||||
} |
||||
|
||||
private static CompletableFuture<Suggestions> memberGroupSuggestions(CommandContext<CommandSourceStack> context, SuggestionsBuilder builder){ |
||||
Player player = (Player) context.getSource().getSender(); |
||||
int id = context.getArgument("id", Integer.class); |
||||
Region region = Region.findById(id); |
||||
|
||||
if (region == null){ |
||||
return builder.buildFuture(); |
||||
} |
||||
|
||||
if (!region.hasPermission(player, Permission.MANAGE_MEMBERS)){ |
||||
return builder.buildFuture(); |
||||
} |
||||
|
||||
RegionMember regionMember = region.getRegionMember(player); |
||||
|
||||
if (regionMember == null){ |
||||
return builder.buildFuture(); |
||||
} |
||||
|
||||
PermissionGroup senderGroup = regionMember.getPermissionGroup(); |
||||
|
||||
QueryBuilder<PermissionGroup, Integer> queryBuilder = PermissionGroup.getDao().queryBuilder(); |
||||
try { |
||||
queryBuilder.selectColumns("name"); |
||||
queryBuilder.where().eq("region_id", id).and().lt("weight", senderGroup.getWeight()); |
||||
List<PermissionGroup> permissionGroups = queryBuilder.query(); |
||||
for (PermissionGroup permissionGroup : permissionGroups){ |
||||
builder.suggest(permissionGroup.getName()); |
||||
} |
||||
} catch (SQLException e) { |
||||
throw new RuntimeException(e); |
||||
} |
||||
|
||||
|
||||
return builder.buildFuture(); |
||||
} |
||||
|
||||
private static CompletableFuture<Suggestions> memberSuggestions(CommandContext<CommandSourceStack> context, SuggestionsBuilder builder){ |
||||
Player player = (Player) context.getSource().getSender(); |
||||
int id = context.getArgument("id", Integer.class); |
||||
Region region = Region.findById(id); |
||||
|
||||
if (region == null){ |
||||
return builder.buildFuture(); |
||||
} |
||||
|
||||
if (!region.hasPermission(player, Permission.MANAGE_MEMBERS)){ |
||||
return builder.buildFuture(); |
||||
} |
||||
|
||||
RegionMember regionMember = region.getRegionMember(player); |
||||
|
||||
if (regionMember == null){ |
||||
return builder.buildFuture(); |
||||
} |
||||
|
||||
PermissionGroup senderGroup = regionMember.getPermissionGroup(); |
||||
|
||||
QueryBuilder<RegionMember, Integer> queryBuilder = RegionMember.getDao().queryBuilder(); |
||||
try { |
||||
queryBuilder.selectColumns("member_name"); |
||||
queryBuilder.where().eq("region_id", id); |
||||
List<RegionMember> regionMembers = queryBuilder.query(); |
||||
for (RegionMember member : regionMembers){ |
||||
if (member.getPermissionGroup().getWeight() >= senderGroup.getWeight()){ |
||||
continue; |
||||
} |
||||
builder.suggest(member.getName()); |
||||
} |
||||
} catch (SQLException e) { |
||||
throw new RuntimeException(e); |
||||
} |
||||
|
||||
|
||||
return builder.buildFuture(); |
||||
} |
||||
|
||||
private static int removeMember(CommandContext<CommandSourceStack> context) { |
||||
int id = context.getArgument("id", Integer.class); |
||||
Player senderPlayer = (Player) context.getSource().getSender(); |
||||
String memberToRemove = context.getArgument("member", String.class); |
||||
|
||||
|
||||
switch (RegionManager.removeMemberSafely(id, memberToRemove, senderPlayer)){ |
||||
case OK -> Messages.send(senderPlayer, "region.command.removed-member"); |
||||
case NOT_EXIST -> Messages.send(senderPlayer, "region.command.error.not-exist"); |
||||
case NO_PERMISSION -> Messages.send(senderPlayer, "region.command.error.no-permission"); |
||||
case NOT_MEMBER -> Messages.send(senderPlayer, "region.command.error.not-member"); |
||||
|
||||
} |
||||
|
||||
return 0; |
||||
|
||||
} |
||||
|
||||
private static int addMember(CommandContext<CommandSourceStack> context){ |
||||
int id = context.getArgument("id", Integer.class); |
||||
String groupName = context.getArgument("group", String.class); |
||||
Player senderPlayer = (Player) context.getSource().getSender(); |
||||
PlayerSelectorArgumentResolver playerSelectorArgumentResolver = context.getArgument("player", PlayerSelectorArgumentResolver.class); |
||||
try { |
||||
Player playerToAdd = playerSelectorArgumentResolver.resolve(context.getSource()).getFirst(); |
||||
|
||||
switch (RegionManager.addMemberSafely(id, playerToAdd, senderPlayer, groupName)){ |
||||
case OK -> Messages.send(senderPlayer, "region.command.added-member"); |
||||
case NOT_EXIST -> Messages.send(senderPlayer, "region.command.error.not-exist"); |
||||
case NO_PERMISSION -> Messages.send(senderPlayer, "region.command.error.no-permission"); |
||||
case NOT_EXIST_GROUP -> Messages.send(senderPlayer, "region.command.error.not-exist-group"); |
||||
case PLAYER_NOT_ON_ISLAND -> Messages.send(senderPlayer, "region.command.error.player-not-on-island"); |
||||
case ALREADY_MEMBER -> Messages.send(senderPlayer, "region.command.error.already-member"); |
||||
} |
||||
} catch (CommandSyntaxException e) { |
||||
throw new RuntimeException(e); |
||||
} |
||||
return 0; |
||||
} |
||||
|
||||
private static int delete(CommandContext<CommandSourceStack> context) { |
||||
Player player = (Player) context.getSource().getSender(); |
||||
int id = context.getArgument("id", Integer.class); |
||||
|
||||
if (!context.getInput().endsWith("confirm")){ |
||||
Messages.send(player, "region.command.confirm-warning.delete", new Replace("id", String.valueOf(id))); |
||||
return 1; |
||||
} |
||||
|
||||
switch (RegionManager.deleteRegionSafely(id, player)){ |
||||
case OK -> Messages.send(player, "region.command.deleted"); |
||||
case NOT_EXIST -> Messages.send(player, "region.command.error.not-exist"); |
||||
case NO_PERMISSION -> Messages.send(player, "region.command.error.no-permission"); |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
private static int create(CommandContext<CommandSourceStack> context) { |
||||
Player player = (Player) context.getSource().getSender(); |
||||
|
||||
switch (RegionManager.createRegionSafely(player)){ |
||||
case OK -> Messages.send(player, "region.command.created"); |
||||
case NO_SELECTION -> Messages.send(player, "region.command.error.no-selection"); |
||||
case NO_PERMISSION -> Messages.send(player, "region.command.error.no-permission"); |
||||
case INVALID_SELECTION -> Messages.send(player, "region.command.error.invalid-selection"); |
||||
case REGION_NOT_ENVELOPS -> Messages.send(player, "region.command.error.region-not-envelops"); |
||||
} |
||||
return 0; |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
} |
||||
Loading…
Reference in new issue