Skip to content

Commit

Permalink
Add ability to select worlds for the plugin to work in (#21)
Browse files Browse the repository at this point in the history
* Add basic black/whitelist functionality

* Implement grace system

* Fix timing

* Add new config keys to README

Co-authored-by: BuildTools <[email protected]>
  • Loading branch information
WasabiThumb and BuildTools authored Aug 21, 2022
1 parent 35b094b commit 9968a9f
Show file tree
Hide file tree
Showing 11 changed files with 228 additions and 5 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,12 @@ See all options in the [config section](#config).
| dynmap-integration.enabled | If true, XClaim will look for dynmap on startup and hook into it. Mild speedup if turned off. | true |
| dynmap-integration.use-old-outline-style | If true, the dynmap will use the old convex hull outlines on claims. This is mainly for debugging, as the new outline system is experimental. | false |
| disable-paper-warning | Disables the message posted to console on startup when the server is running Spigot instead of Paper | false |
| worlds.use-whitelist | If worlds.whitelist should be considered | false |
| worlds.use-blacklist | If worlds.blacklist should be considered | false |
| worlds.case-sensitive | Whether capitalization in world names in the white/blacklist matter | true |
| worlds.whitelist | A list that a world must be in for it to work with XClaim | a sample list |
| worlds.blacklist | A list that a world must NOT be in for it to work with XClaim | a sample list |
| worlds.grace-time | If a claim is in a disallowed world, players have this much time in seconds before the claim is automatically removed | 604800 (1 week) |

## Permissions
Don't worry, there aren't that many.
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/codes/wasabi/xclaim/XClaim.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package codes.wasabi.xclaim;

import codes.wasabi.xclaim.api.Claim;
import codes.wasabi.xclaim.api.GraceRoutine;
import codes.wasabi.xclaim.api.MovementRoutine;
import codes.wasabi.xclaim.api.dynmap.DynmapInterfaceFactory;
import codes.wasabi.xclaim.command.CommandManager;
Expand Down Expand Up @@ -229,6 +230,8 @@ private void startServices() {
commandManager.registerDefaults();
logger.log(Level.INFO, lang.get("services-movement"));
MovementRoutine.initialize();
logger.log(Level.INFO, lang.get("services-grace"));
GraceRoutine.refresh();
}
/* END STARTUP TASKS */

Expand Down Expand Up @@ -281,6 +284,7 @@ private void stopServices() {
commandManager.unregisterAll();
OfflinePlayerType.clearListener();
MovementRoutine.cleanup();
GraceRoutine.stop();
GUIHandler.closeAll();
unloadDynmap();
}
Expand Down
18 changes: 17 additions & 1 deletion src/main/java/codes/wasabi/xclaim/api/Claim.java
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,11 @@ public class Claim {
}
players.put(uuid, set);
}
return new Claim(name, chunks, XCPlayer.of(owner), global, players);
Claim ret = new Claim(name, chunks, XCPlayer.of(owner), global, players);
if (section.contains("graceStart")) {
ret.graceStart = section.getLong("graceStart", -1);
}
return ret;
}

private String name;
Expand All @@ -155,6 +159,7 @@ public class Claim {
private final List<java.util.function.Consumer<Claim>> ownerChangeCallbacks = new ArrayList<>();
private BoundingBox outerBounds;
private boolean manageHandlers = false;
private long graceStart = -1;

private BoundingBox getChunkBounds(Chunk c) {
World w = c.getWorld();
Expand Down Expand Up @@ -243,6 +248,14 @@ public void onOwnerChanged(@NotNull java.util.function.Consumer<Claim> callback)
return null;
}

public long getGraceStart() {
return graceStart;
}

public void setGraceStart(long graceStart) {
this.graceStart = graceStart;
}

public boolean addChunk(@NotNull Chunk chunk) throws IllegalArgumentException {
boolean claim = false;
if (chunks.size() > 0) {
Expand Down Expand Up @@ -417,6 +430,9 @@ public void serialize(@NotNull ConfigurationSection section) {
List<String> list = entry.getValue().stream().flatMap((Permission p) -> Stream.of(p.name())).collect(Collectors.toList());
sec.set(entry.getKey().toString(), list);
}
if (graceStart > 0) {
section.set("graceStart", graceStart);
}
}

private final Map<Permission, PermissionHandler> handlers = new HashMap<>();
Expand Down
125 changes: 125 additions & 0 deletions src/main/java/codes/wasabi/xclaim/api/GraceRoutine.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
package codes.wasabi.xclaim.api;

import codes.wasabi.xclaim.XClaim;
import codes.wasabi.xclaim.platform.Platform;
import codes.wasabi.xclaim.util.ConfigUtil;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.scheduler.BukkitTask;

import java.util.HashMap;
import java.util.Map;

public class GraceRoutine implements Listener {

private static GraceRoutine instance = null;
private static boolean active = false;

public static void start() {
if (!active) {
instance = new GraceRoutine();
Bukkit.getPluginManager().registerEvents(instance, XClaim.instance);
active = true;
}
}

public static void stop() {
if (active) {
HandlerList.unregisterAll(instance);
instance.timerTask.cancel();
instance = null;
active = false;
}
}

public static void refresh() {
Map<World, Boolean> allowedMap = new HashMap<>();
for (Claim claim : Claim.getAll()) {
World world = claim.getWorld();
if (world == null) continue;
Boolean allowed = allowedMap.get(world);
if (allowed == null) {
allowed = ConfigUtil.worldIsAllowed(XClaim.mainConfig, world);
allowedMap.put(world, allowed);
}
if (!allowed) {
start();
return;
}
}
stop();
}

private final BukkitTask timerTask;
private final long graceTimeMillis;
private final BukkitAudiences adv = Platform.getAdventure();
private GraceRoutine() {
long graceTime = Math.max(XClaim.mainConfig.getLong("worlds.grace-time", 604800L), 0L);
graceTimeMillis = graceTime * 1000L;
// Approximate how often we need to run the routine in order to fall within the requested period
// By default this will be 3024000 ticks or 1.75 days w/o lag (a quarter of a week) which is excessively long
long ticks = Math.max((long) Math.floor((graceTime / 4d) * 20d), 1L);
// So we provide a lower limit of 200 ticks (about 10 seconds without lag) which any server should be
// able to handle
ticks = Math.min(ticks, 200L);
timerTask = Bukkit.getScheduler().runTaskTimerAsynchronously(XClaim.instance, this::evaluate, 0L, ticks);
}

private void evaluate() {
long now = System.currentTimeMillis();
int count = 0;
Map<World, Boolean> allowedMap = new HashMap<>();
for (Claim c : Claim.getAll()) {
World world = c.getWorld();
if (world == null) continue;
Boolean allowed = allowedMap.get(world);
if (allowed == null) {
allowed = ConfigUtil.worldIsAllowed(XClaim.mainConfig, world);
allowedMap.put(world, allowed);
}
if (!allowed) {
count++;
long start = c.getGraceStart();
if (start <= 0) {
start = now;
c.setGraceStart(start);
}
long elapsed = now - start;
if (elapsed >= graceTimeMillis) {
OfflinePlayer op = c.getOwner().getOfflinePlayer();
c.unclaim();
Player ply = op.getPlayer();
if (ply != null) {
adv.player(ply).sendMessage(XClaim.lang.getComponent("grace-remove", c.getName()));
}
count--;
}
}
}
if (count < 1) stop();
}

@EventHandler(priority = EventPriority.MONITOR)
public void onJoin(PlayerJoinEvent event) {
Player ply = event.getPlayer();
int count = 0;
for (Claim c : Claim.getByOwner(ply)) {
World world = c.getWorld();
if (world == null) continue;
if (!ConfigUtil.worldIsAllowed(XClaim.mainConfig, world)) {
count++;
}
}
if (count < 1) return;
Platform.getAdventure().player(ply).sendMessage(XClaim.lang.getComponent("grace-alert", count));
}

}
14 changes: 11 additions & 3 deletions src/main/java/codes/wasabi/xclaim/command/sub/ChunksCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,10 @@
import codes.wasabi.xclaim.command.argument.type.StandardTypes;
import codes.wasabi.xclaim.gui.ChunkEditor;
import codes.wasabi.xclaim.platform.Platform;
import codes.wasabi.xclaim.util.ConfigUtil;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.Location;
import org.bukkit.Sound;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
Expand Down Expand Up @@ -86,6 +85,15 @@ public void execute(@NotNull CommandSender sender, @NotNull Object @NotNull ...
audience.sendMessage(XClaim.lang.getComponent("cmd-chunks-err-perm"));
return;
}
World w = claim.getWorld();
if (w == null) {
audience.sendMessage(XClaim.lang.getComponent("cmd-chunks-err-404"));
return;
}
if (!ConfigUtil.worldIsAllowed(XClaim.mainConfig, w)) {
audience.sendMessage(XClaim.lang.getComponent("cmd-chunks-err-disallowed"));
return;
}
Platform.get().sendActionBar(ply, XClaim.lang.getComponent(
"cmd-chunks-success",
claim.getName()
Expand Down
9 changes: 8 additions & 1 deletion src/main/java/codes/wasabi/xclaim/gui/page/MainPage.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
import codes.wasabi.xclaim.gui.GUIHandler;
import codes.wasabi.xclaim.gui.Page;
import codes.wasabi.xclaim.platform.Platform;
import codes.wasabi.xclaim.util.ConfigUtil;
import codes.wasabi.xclaim.util.DisplayItem;
import net.kyori.adventure.audience.Audience;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
Expand Down Expand Up @@ -113,10 +115,15 @@ protected void onSelect(@NotNull OfflinePlayer ply) {
switchPage(new ClaimSelectorPage(getParent(), claim -> {
Player ply = getTarget();
World w = ply.getWorld();
Audience audience = Platform.getAdventure().player(ply);
if (!ConfigUtil.worldIsAllowed(XClaim.mainConfig, w)) {
audience.sendMessage(XClaim.lang.getComponent("gui-edit-chunk-disallowed"));
return;
}
World cw = claim.getWorld();
if (cw != null) {
if (w != cw) {
Platform.getAdventure().player(ply).sendMessage(XClaim.lang.getComponent("gui-edit-chunk-fail"));
audience.sendMessage(XClaim.lang.getComponent("gui-edit-chunk-fail"));
getParent().close();
return;
}
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/codes/wasabi/xclaim/gui/page/NewClaimPage.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import codes.wasabi.xclaim.gui.GUIHandler;
import codes.wasabi.xclaim.gui.Page;
import codes.wasabi.xclaim.platform.Platform;
import codes.wasabi.xclaim.util.ConfigUtil;
import codes.wasabi.xclaim.util.DisplayItem;
import org.bukkit.Chunk;
import org.bukkit.World;
Expand Down Expand Up @@ -78,6 +79,10 @@ public void onClick(int slot) {
// do stuff
Player ply = getTarget();
Chunk chunk = ply.getLocation().getChunk();
if (!ConfigUtil.worldIsAllowed(XClaim.mainConfig, chunk.getWorld())) {
Platform.getAdventure().player(ply).sendMessage(XClaim.lang.getComponent("gui-new-disallowed"));
return;
}
Claim cur = Claim.getByChunk(chunk);
if (cur != null) {
if (!cur.getOwner().getUniqueId().equals(ply.getUniqueId())) {
Expand Down
27 changes: 27 additions & 0 deletions src/main/java/codes/wasabi/xclaim/util/ConfigUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package codes.wasabi.xclaim.util;

import org.bukkit.World;
import org.bukkit.configuration.file.FileConfiguration;

public final class ConfigUtil {

public static boolean worldIsAllowed(FileConfiguration cfg, World world) {
String worldName = world.getName();
boolean cs = cfg.getBoolean("worlds.case-sensitive", true);
boolean black = cfg.getBoolean("worlds.use-blacklist", false);
if (black) {
for (String name : cfg.getStringList("worlds.blacklist")) {
if (cs ? name.equals(worldName) : name.equalsIgnoreCase(worldName)) return false;
}
}
boolean white = cfg.getBoolean("worlds.use-whitelist", false);
if (white) {
for (String name : cfg.getStringList("worlds.whitelist")) {
if (cs ? name.equals(worldName) : name.equalsIgnoreCase(worldName)) return true;
}
return false;
}
return true;
}

}
13 changes: 13 additions & 0 deletions src/main/resources/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,16 @@ dynmap-integration:
enabled: true
use-old-outline-style: false
disable-paper-warning: false
worlds:
grace-time: 604800 # if a claim exists in a blacklisted world, the owner has this much time before it is removed (seconds)
use-whitelist: false
use-blacklist: false
case-sensitive: true
whitelist:
- world
- world_nether
- world_the_end
blacklist:
- minigames
- pvp
- etc
6 changes: 6 additions & 0 deletions src/main/resources/lang/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"services-command": "Lade Befehlsmanager...",
"services-command-register": "Registriere Standardbefehle...",
"services-movement": "Starte Bewegungsüberwachung...",
"services-grace": "Erfrischende Gnade Routine...",
"trust-save": "Speichere vertrauenswürdige Spieler...",
"trust-save-new": "Neue trust.yml Datei wurde erstellt.",
"trust-save-err": "Es ist ein Fehler während des Speicherns der vertrauenswürdigen Spieler aufgetreten. Für Details sehen Sie bitte weiter unten.",
Expand Down Expand Up @@ -154,10 +155,12 @@
"gui-new-cancel-line1": "\u003cred\u003eZurück zum\u003c/red\u003e",
"gui-new-cancel-line2": "\u003cred\u003eHauptmenü.\u003c/red\u003e",
"gui-new-claimed": "\u003cred\u003e* Dieser Chunk ist bereits beansprucht!\u003c/red\u003e",
"gui-new-disallowed": "<red>* Sie können keine neue Behauptung in einer schwarzen Welt erheben!</red>",
"gui-new-max-claims": "\u003cred\u003e* Sie haben das Maximum Ihrer beanspruchbaren Chunks erreicht! Versuche ein paar Ansprüche zu löschen.\u003c/red\u003e",
"gui-new-max-chunks": "\u003cred\u003e* Sie können dieses Gebiet nicht beanspruchen, da Sie sonst über Ihrem maximalen Limit an beanspruchbaren Chunks wären.\u003c/red\u003e",
"gui-new-success": "\u003cb\u003e\u003cwhite\u003e* Chunks beansprucht bei:\u003c/white\u003e \u003ci\u003e\u003cgold\u003e$1\u003c/gold\u003e\u003c/i\u003e\u003c/b\u003e",
"gui-edit-chunk-fail": "\u003cred\u003e* Sie können nicht ein Gebiet über mehrere Dimensionen beanspruchen!\u003c/red\u003e",
"gui-edit-chunk-disallowed": "<red>* Sie befinden sich in einer schwarzen Welt</red>",
"gui-rename-chunk-prompt": "Geben Sie einen neuen Namen für das Gebiet ein: ",
"gui-rename-chunk-fail": "\u003cred\u003e* Der Name ist zu lang! Es müssen weniger als 50 Zeichen sein.\u003c/red\u003e",
"gui-clear-yes": "\u003cgreen\u003eJa, ich bin mir sicher!\u003c/green\u003e",
Expand Down Expand Up @@ -300,6 +303,7 @@
"cmd-chunks-err-state": "\u003cred\u003e* Sie sind bereits im Chunk Editor! Schließen sie diesen zuerst, um ihn erneut öffnen zu können.\u003c/red\u003e",
"cmd-chunks-err-404": "\u003cred\u003e* Sie befinden sich aktuell nicht auf beanspruchtem Gebiet!\u003c/red\u003e",
"cmd-chunks-err-perm": "\u003cred\u003e* Sie haben nicht die Berechtigung dieses Gebiet zu bearbeiten!\u003c/red\u003e",
"cmd-chunks-err-disallowed": "<red>* Sie können Ansprüche nicht in einer schwarze Liste bearbeiten</red>",
"cmd-chunks-success": "\u003cgreen\u003eBearbeite \u003cgold\u003e$1\u003c/gold\u003e\u003c/green\u003e",
"arg-string-name": "Text",
"arg-string-sample": "text",
Expand All @@ -321,5 +325,7 @@
"arg-choice-or": " oder ",
"move-enter": "\u003cwhite\u003eSie betreten \u003cgold\u003e$1\u003c/gold\u003e\u0027s \u003cgreen\u003e$2\u003c/green\u003e\u003c/white\u003e",
"move-exit": "\u003cwhite\u003eSie verlassen \u003cgreen\u003e$1\u003c/green\u003e\u003c/white\u003e",
"grace-alert": "<red><dark_red>WARNUNG</dark_red>: Sie haben $1 Ansprüche in schwarzenlisteten Welten, die bald entfernt werden</red>",
"grace-remove": "<red>Ihre Behauptung mit dem Namen <dark_red>$1</dark_red> wurde aufgrund der schwarzen Welt entfernt entfernt</red>",
"unknown": "Unbekannt"
}
Loading

0 comments on commit 9968a9f

Please sign in to comment.