Skip to content

Commit

Permalink
Implement basic WorldGuard support
Browse files Browse the repository at this point in the history
  • Loading branch information
Moulberry committed Apr 13, 2024
1 parent 68d2fe6 commit 9f25de7
Show file tree
Hide file tree
Showing 12 changed files with 412 additions and 30 deletions.
41 changes: 41 additions & 0 deletions src/main/java/com/moulberry/axiom/integration/Box.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import net.minecraft.core.BlockPos;
import org.jetbrains.annotations.Nullable;

import java.util.List;

public record Box(int minX, int minY, int minZ, int maxX, int maxY, int maxZ) {

@Nullable
Expand Down Expand Up @@ -44,6 +46,27 @@ public Box tryCombine(Box other) {
return null; // Not able to combine
}

public static void combineAll(List<Box> boxes) {
main:
while (boxes.size() >= 2) {
for (int i = 0; i < boxes.size() - 1; i++) {
Box first = boxes.get(i);
for (int j = i + 1; j < boxes.size(); j++) {
Box second = boxes.get(j);

Box combined = first.tryCombine(second);
if (combined != null) {
boxes.remove(j);
boxes.remove(i);
boxes.add(combined);
continue main;
}
}
}
break;
}
}

public boolean completelyOverlaps(Box other) {
return this.minX() <= other.minX() && this.minY() <= other.minY() && this.minZ() <= other.minZ() &&
this.maxX() >= other.maxX() && this.maxY() >= other.maxY() && this.maxZ() >= other.maxZ();
Expand All @@ -54,6 +77,24 @@ public boolean contains(int x, int y, int z) {
this.maxX() >= x && this.maxY() >= y && this.maxZ() >= z;
}

@Nullable
public static Box intersection(Box first, Box second) {
if (first.minX > second.maxX || second.minX > first.maxX ||
first.minY > second.maxY || second.minY > first.maxY ||
first.minZ > second.maxZ || second.minZ > first.maxZ) {
return null;
}

return new Box(
Math.max(first.minX, second.minX),
Math.max(first.minY, second.minY),
Math.max(first.minZ, second.minZ),
Math.min(first.maxX, second.maxX),
Math.min(first.maxY, second.maxY),
Math.min(first.maxZ, second.maxZ)
);
}

private static boolean areLineSegmentsContinuous(int min1, int max1, int min2, int max2) {
int size1 = max1 - min1 + 1;
int size2 = max2 - min2 + 1;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.moulberry.axiom.integration;

public record BoxWithBoolean(Box box, boolean value) {
}
28 changes: 28 additions & 0 deletions src/main/java/com/moulberry/axiom/integration/Integration.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.moulberry.axiom.integration;

import com.moulberry.axiom.integration.plotsquared.PlotSquaredIntegration;
import com.moulberry.axiom.integration.worldguard.WorldGuardIntegration;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;

public class Integration {

// todo: test if all this is working for both plotsqured, worldguard, plotsquared+worldguard

public static boolean canBreakBlock(Player player, Block block) {
return PlotSquaredIntegration.canBreakBlock(player, block) && WorldGuardIntegration.canBreakBlock(player, block.getLocation());
}

public static boolean canPlaceBlock(Player player, org.bukkit.Location loc) {
return PlotSquaredIntegration.canPlaceBlock(player, loc) && WorldGuardIntegration.canPlaceBlock(player, loc);
}

public static SectionPermissionChecker checkSection(Player player, World world, int cx, int cy, int cz) {
SectionPermissionChecker plotSquared = PlotSquaredIntegration.checkSection(player, world, cz, cy, cz);
SectionPermissionChecker worldGuard = WorldGuardIntegration.checkSection(player, world, cz, cy, cz);

return SectionPermissionChecker.combine(plotSquared, worldGuard);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,45 @@ public interface SectionPermissionChecker {
boolean allowed(int x, int y, int z);
Box bounds();

static SectionPermissionChecker combine(SectionPermissionChecker first, SectionPermissionChecker second) {
if (first.noneAllowed() || second.noneAllowed()) {
return NONE_ALLOWED;
}
if (first.allAllowed()) {
return second;
}
if (second.allAllowed()) {
return first;
}

Box intersect = Box.intersection(first.bounds(), second.bounds());
if (intersect == null) {
return NONE_ALLOWED;
}

return new SectionPermissionChecker() {
@Override
public boolean allAllowed() {
return false;
}

@Override
public boolean noneAllowed() {
return false;
}

@Override
public boolean allowed(int x, int y, int z) {
return first.allowed(x, y, z) && second.allowed(x, y, z);
}

@Override
public Box bounds() {
return intersect;
}
};
}

static SectionPermissionChecker fromAllowedBoxes(List<Box> allowed) {
if (allowed.isEmpty()) return NONE_ALLOWED;

Expand Down Expand Up @@ -40,6 +79,51 @@ static SectionPermissionChecker fromAllowedBoxes(List<Box> allowed) {
return new AllAllowedBoxes(new Box(minBoundsX, minBoundsY, minBoundsZ, maxBoundsX, maxBoundsY, maxBoundsZ), allowed);
}

static SectionPermissionChecker fromBoxWithBooleans(List<BoxWithBoolean> boxes, boolean defaultValue) {
if (boxes.isEmpty()) return defaultValue ? ALL_ALLOWED : NONE_ALLOWED;

if (boxes.size() == 1) {
BoxWithBoolean boxWithBoolean = boxes.get(0);
if (boxWithBoolean.value()) {
if (defaultValue) {
return ALL_ALLOWED;
} else if (boxWithBoolean.box().completelyOverlaps(FULL_BOUNDS)) {
return ALL_ALLOWED;
} else {
return new AllAllowedInBox(boxWithBoolean.box());
}
} else {
if (!defaultValue) {
return NONE_ALLOWED;
} else if (boxWithBoolean.box().completelyOverlaps(FULL_BOUNDS)) {
return NONE_ALLOWED;
}
}
}

int minBoundsX = 15;
int minBoundsY = 15;
int minBoundsZ = 15;
int maxBoundsX = 0;
int maxBoundsY = 0;
int maxBoundsZ = 0;

for (BoxWithBoolean boxWithBoolean : boxes) {
if (boxWithBoolean.value()) {
Box box = boxWithBoolean.box();
minBoundsX = Math.min(box.minX(), minBoundsX);
minBoundsY = Math.min(box.minY(), minBoundsY);
minBoundsZ = Math.min(box.minZ(), minBoundsZ);
maxBoundsX = Math.max(box.maxX(), maxBoundsX);
maxBoundsY = Math.max(box.maxY(), maxBoundsY);
maxBoundsZ = Math.max(box.maxZ(), maxBoundsZ);
}
}

Box bounds = new Box(minBoundsX, minBoundsY, minBoundsZ, maxBoundsX, maxBoundsY, maxBoundsZ);
return new BooleanBoxes(bounds, boxes, defaultValue);
}

record AllAllowedInBox(Box box) implements SectionPermissionChecker {
@Override
public boolean allAllowed() {
Expand Down Expand Up @@ -87,6 +171,33 @@ public Box bounds() {
}
}

record BooleanBoxes(Box bounds, List<BoxWithBoolean> boxes, boolean defaultValue) implements SectionPermissionChecker {
@Override
public boolean allAllowed() {
return false;
}

@Override
public boolean noneAllowed() {
return false;
}

@Override
public boolean allowed(int x, int y, int z) {
for (BoxWithBoolean boxWithBoolean : this.boxes) {
if (boxWithBoolean.box().contains(x, y, z)) {
return boxWithBoolean.value();
}
}
return this.defaultValue;
}

@Override
public Box bounds() {
return this.bounds;
}
}

Box FULL_BOUNDS = new Box(0, 0, 0, 15, 15, 15);
SectionPermissionChecker ALL_ALLOWED = new SectionPermissionChecker() {
@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,24 +245,7 @@ static SectionPermissionChecker checkSection(Player player, World world, int sec
}

// Combine
main:
while (allowed.size() >= 2) {
for (int i = 0; i < allowed.size() - 1; i++) {
Box first = allowed.get(i);
for (int j = i + 1; j < allowed.size(); j++) {
Box second = allowed.get(j);

Box combined = first.tryCombine(second);
if (combined != null) {
allowed.remove(j);
allowed.remove(i);
allowed.add(combined);
continue main;
}
}
}
break;
}
Box.combineAll(allowed);

return SectionPermissionChecker.fromAllowedBoxes(allowed);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.moulberry.axiom.integration.worldguard;

import com.moulberry.axiom.integration.SectionPermissionChecker;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.entity.Player;

public class WorldGuardIntegration {

public static boolean canBreakBlock(Player player, org.bukkit.Location loc) {
if (!Bukkit.getPluginManager().isPluginEnabled("WorldGuard")) {
return true;
}
return WorldGuardIntegrationImpl.canBreakBlock(player, loc);
}

public static boolean canPlaceBlock(Player player, org.bukkit.Location loc) {
if (!Bukkit.getPluginManager().isPluginEnabled("WorldGuard")) {
return true;
}
return WorldGuardIntegrationImpl.canPlaceBlock(player, loc);
}

public static SectionPermissionChecker checkSection(Player player, World world, int cx, int cy, int cz) {
if (!Bukkit.getPluginManager().isPluginEnabled("WorldGuard")) {
return SectionPermissionChecker.ALL_ALLOWED;
}
return WorldGuardIntegrationImpl.checkSection(player, world, cx, cy, cz);
}

}
Loading

0 comments on commit 9f25de7

Please sign in to comment.