Compare commits

...
Author SHA1 Message Date
Andrew Wong 9f04efb3e8 Add a sign error logger 2021-06-03 11:58:55 +02:00
Andrew Wong 5872af7466 Improve performance of tab completions 2020-10-15 18:36:11 +02:00
Andrew Wong a8315e627b Remove debug message 2020-10-15 12:59:18 +02:00
Andrew Wong 35361308a8 Add a teleportation progress notifier, changeup interal structure of the TeleportFeature 2020-10-15 12:57:19 +02:00
Andrew Wong 0c359cdfdf Make TeleportFeature#teleport perform location finding async 2020-10-14 22:11:12 +02:00
Andrew Wong 2a03e7612a Improve the performance for FileManager region getters at the expense of technical debt 2020-10-08 22:13:23 +02:00
Andrew Wong aaf4e07053 Try to save and restore regions async where possible 2020-10-07 20:50:19 +02:00
Andrew Wong fa91016613 Add experimental support for async fawe operations... 2020-10-07 20:39:25 +02:00
Andrew Wong f4bd4ee6c6 Improve performance of block scanning in TeleportFeature 2020-10-07 19:00:40 +02:00
Andrew Wong 44fd7deea5 Keep chunks loaded until the teleport passes 2020-10-07 18:56:36 +02:00
Andrew Wong 2c2f40b0ea Fix merge conflict 2020-09-25 16:55:13 +02:00
Andrew Wong 07406c3987 Improve the performance of TeleportFeature#teleportPlayer
Split chunk loading accross multiple ticks, delay 3 ticks before executing teleport logic
2020-09-25 13:01:09 +02:00
Andrew Wong 82a90b350d Minor bug fixes 2020-08-22 01:37:33 +02:00
Andrew Wong 151fbe8000 Move away from using BukkitDo; Add TaskChain as a dependency 2020-08-17 21:47:44 +02:00
Andrew Wong f2a4dd71e3 Update README.md 2020-08-16 23:44:06 +02:00
Andrew Wong d4cc70f954 Rename version 2020-08-16 23:41:56 +02:00
Andrew Wong 8001047480 Add in the spigot repo 2020-08-16 23:31:29 +02:00
Andrew Wong af1486a6fa Create maven.yml 2020-08-16 23:27:40 +02:00
Andrew Wong 36a2d054d6 Bump maven plugin versions 2020-08-16 23:24:37 +02:00
Andrew Wong 7429b0a206 Remove system dependencies. Utilise PaperLib when teleporting. Remove support for pre-1.13. Added support for 1.16.1 2020-08-16 23:17:08 +02:00
77 changed files with 5658 additions and 6694 deletions

No files matched your search

+32
View File
@@ -0,0 +1,32 @@
# This workflow will build a Java project with Maven
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
name: Java CI with Maven
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Cache local Maven repository
uses: actions/cache@v2
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-maven-
- name: Build with Maven
run: mvn -B package --file pom.xml
+65 -106
View File
@@ -1,25 +1,35 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>areashop</artifactId>
<packaging>jar</packaging>
<name>AreaShop</name>
<version>2.6.0</version> <!-- Main plugin version -->
<parent>
<groupId>me.wiefferink</groupId>
<artifactId>areashop-parent</artifactId>
<version>parent</version>
<version>1.0</version>
</parent>
<artifactId>areashop</artifactId>
<packaging>jar</packaging>
<name>AreaShop</name>
<version>2.7</version> <!-- Main plugin version -->
<repositories>
<repository>
<id>papermc</id>
<url>https://papermc.io/repo/repository/maven-public/</url>
</repository>
<repository>
<id>aikar</id>
<url>https://repo.aikar.co/content/groups/aikar/</url>
</repository>
</repositories>
<dependencies>
<!-- Bukkit, AreaShop aims to support 1.7.9+ -->
<!-- Bukkit, AreaShop aims to support 1.16.5+ -->
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>craftbukkit</artifactId>
<version>1.13-R0.1-SNAPSHOT</version>
<type>jar</type>
<optional>true</optional>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.16.5-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
@@ -30,27 +40,31 @@
<version>1.1-SNAPSHOT</version>
</dependency>
<!-- BukkitDo library -->
<!-- TaskChain library -->
<dependency>
<groupId>me.wiefferink</groupId>
<artifactId>bukkitdo</artifactId>
<version>1.0.0-SNAPSHOT</version>
<groupId>co.aikar</groupId>
<artifactId>taskchain-bukkit</artifactId>
<version>3.7.2</version>
</dependency>
<dependency>
<groupId>io.papermc</groupId>
<artifactId>paperlib</artifactId>
<version>1.0.4</version>
</dependency>
<!-- WorldEdit/WorldGuard -->
<dependency>
<groupId>com.sk89q</groupId>
<artifactId>worldedit</artifactId>
<scope>system</scope>
<version>any</version>
<systemPath>${project.basedir}/../dependencies/worldedit-bukkit-7.0.0-beta-04.jar</systemPath>
<groupId>com.sk89q.worldedit</groupId>
<artifactId>worldedit-bukkit</artifactId>
<version>7.1.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.sk89q</groupId>
<artifactId>worldguard</artifactId>
<scope>system</scope>
<version>any</version>
<systemPath>${project.basedir}/../dependencies/worldguard-legacy-7.0.0-beta-02.jar</systemPath>
<groupId>com.sk89q.worldguard</groupId>
<artifactId>worldguard-bukkit</artifactId>
<version>7.0.3</version>
<scope>provided</scope>
</dependency>
<!-- Interfaces that specific WorldGuard and WorldEdit versions are built against -->
@@ -58,93 +72,29 @@
<groupId>me.wiefferink</groupId>
<artifactId>areashop-interface</artifactId>
<version>latest</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<!-- Bukkit api implementations -->
<dependency>
<groupId>me.wiefferink</groupId>
<artifactId>areashop-bukkit-1_12</artifactId>
<version>latest</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>me.wiefferink</groupId>
<artifactId>areashop-bukkit-1_13</artifactId>
<version>latest</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<!-- WorldGuard implementations -->
<dependency>
<groupId>me.wiefferink</groupId>
<artifactId>areashop-worldguard-5</artifactId>
<artifactId>areashop-worldguard-7</artifactId>
<version>latest</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>me.wiefferink</groupId>
<artifactId>areashop-worldguard-6</artifactId>
<version>latest</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>me.wiefferink</groupId>
<artifactId>areashop-worldguard-6_1_3</artifactId>
<version>latest</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>me.wiefferink</groupId>
<artifactId>areashop-worldguard-7_beta_1</artifactId>
<version>latest</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>me.wiefferink</groupId>
<artifactId>areashop-worldguard-7_beta_2</artifactId>
<version>latest</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<!-- WorldEdit implementations -->
<dependency>
<groupId>me.wiefferink</groupId>
<artifactId>areashop-worldedit-5</artifactId>
<artifactId>areashop-worldedit-7</artifactId>
<version>latest</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<!-- FAWE compat -->
<dependency>
<groupId>me.wiefferink</groupId>
<artifactId>areashop-worldedit-6</artifactId>
<version>latest</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>me.wiefferink</groupId>
<artifactId>areashop-worldedit-7_beta_1</artifactId>
<version>latest</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>me.wiefferink</groupId>
<artifactId>areashop-worldedit-7_beta_4</artifactId>
<version>latest</version>
</dependency>
<dependency>
<groupId>me.wiefferink</groupId>
<artifactId>areashop-fastasyncworldedit</artifactId>
<artifactId>areashop-fawe-1-15</artifactId>
<version>latest</version>
<type>jar</type>
<scope>compile</scope>
@@ -154,9 +104,8 @@
<dependency>
<groupId>net.milkbowl.vault</groupId>
<artifactId>VaultAPI</artifactId>
<scope>system</scope>
<version>any</version>
<systemPath>${project.basedir}/../dependencies/VaultAPI-1.4.jar</systemPath>
<version>1.7</version>
<scope>provided</scope>
</dependency>
<!-- bStats -->
@@ -164,7 +113,9 @@
<groupId>org.bstats</groupId>
<artifactId>bstats-bukkit</artifactId>
<version>1.1</version>
<scope>compile</scope>
</dependency>
</dependencies>
<profiles>
@@ -213,7 +164,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.0</version>
<version>3.2.1</version>
<executions>
<execution>
<phase>package</phase>
@@ -241,7 +192,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.1.0</version>
<version>3.2.0</version>
<executions>
<execution>
<phase>package</phase>
@@ -288,7 +239,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<version>3.2.3</version>
<executions>
<execution>
<phase>package</phase>
@@ -297,21 +248,25 @@
</goals>
<configuration>
<relocations>
<!-- Relocate TaskChain -->
<relocation>
<pattern>co.aikar.taskchain</pattern>
<shadedPattern>me.wiefferink.areashop.shaded.taskchain</shadedPattern>
</relocation>
<!-- Relocate messaging framework -->
<relocation>
<pattern>me.wiefferink.interactivemessenger</pattern>
<shadedPattern>me.wiefferink.areashop.shaded.interactivemessenger</shadedPattern>
</relocation>
<!-- Relocate BukkitDo -->
<relocation>
<pattern>me.wiefferink.bukkitdo</pattern>
<shadedPattern>me.wiefferink.areashop.shaded.bukkitdo</shadedPattern>
</relocation>
<!-- Relocate bstats -->
<relocation>
<pattern>org.bstats</pattern>
<shadedPattern>me.wiefferink.areashop.shaded.bstats</shadedPattern>
</relocation>
<relocation>
<pattern>io.papermc</pattern>
<shadedPattern>me.wiefferink.areashop.shaded.paperlib</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
@@ -319,7 +274,11 @@
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
File diff suppressed because it is too large. Load diff
@@ -13,20 +13,13 @@ import me.wiefferink.areashop.regions.BuyRegion;
import me.wiefferink.areashop.regions.GeneralRegion;
import me.wiefferink.areashop.regions.RentRegion;
import me.wiefferink.areashop.tools.Utils;
import me.wiefferink.bukkitdo.Do;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;
import java.util.UUID;
import java.util.*;
import java.util.stream.Collectors;
public class AddCommand extends CommandAreaShop {
@@ -131,10 +124,9 @@ public class AddCommand extends CommandAreaShop {
TreeSet<String> namesBlacklisted = new TreeSet<>();
TreeSet<String> namesNoPermission = new TreeSet<>();
TreeSet<String> namesAddCancelled = new TreeSet<>(); // Denied by an event listener
Do.forAll(
Utils.runAsBatches(regions.entrySet(),
plugin.getConfig().getInt("adding.regionsPerTick"),
regions.entrySet(),
regionEntry -> {
(regionEntry) -> {
String regionName = regionEntry.getKey();
ProtectedRegion region = regionEntry.getValue();
// Determine if the player is an owner or member of the region
@@ -261,8 +253,8 @@ public class AddCommand extends CommandAreaShop {
regionsSuccess.add(buy);
}
}
},
() -> {
}, false).thenAccept(
(success) -> {
if(!regionsSuccess.isEmpty()) {
plugin.message(sender, "add-success", args[1], Utils.combinedMessage(regionsSuccess, "region"));
}
@@ -288,13 +280,12 @@ public class AddCommand extends CommandAreaShop {
if(!namesAddCancelled.isEmpty()) {
plugin.message(sender, "add-rentCancelled", Utils.createCommaSeparatedList(namesAddCancelled));
}
}
);
});
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
List<String> result = new ArrayList<>();
List<String> result = new LinkedList<>();
if(toComplete == 2) {
if(sender.hasPermission("areashop.createrent")) {
result.add("rent");
@@ -7,6 +7,10 @@ import me.wiefferink.areashop.tools.Materials;
import me.wiefferink.areashop.tools.Utils;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.type.Sign;
import org.bukkit.block.data.type.WallSign;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.util.BlockIterator;
@@ -17,99 +21,108 @@ import java.util.Set;
public class AddsignCommand extends CommandAreaShop {
@Override
public String getCommandStart() {
return "areashop addsign";
}
@Override
public String getCommandStart() {
return "areashop addsign";
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.addsign")) {
return "help-addsign";
}
return null;
}
@Override
public String getHelp(CommandSender target) {
if (target.hasPermission("areashop.addsign")) {
return "help-addsign";
}
return null;
}
@Override
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.addsign")) {
plugin.message(sender, "addsign-noPermission");
return;
}
if(!(sender instanceof Player)) {
plugin.message(sender, "cmd-onlyByPlayer");
return;
}
Player player = (Player)sender;
@Override
public void execute(CommandSender sender, String[] args) {
if (!sender.hasPermission("areashop.addsign")) {
plugin.message(sender, "addsign-noPermission");
return;
}
if (!(sender instanceof Player)) {
plugin.message(sender, "cmd-onlyByPlayer");
return;
}
Player player = (Player) sender;
// Get the sign
Block block = null;
BlockIterator blockIterator = new BlockIterator(player, 100);
while(blockIterator.hasNext() && block == null) {
Block next = blockIterator.next();
if(next.getType() != Material.AIR) {
block = next;
}
}
if(block == null || !Materials.isSign(block.getType())) {
plugin.message(sender, "addsign-noSign");
return;
}
// Get the sign
Block block = null;
BlockIterator blockIterator = new BlockIterator(player, 100);
while (blockIterator.hasNext() && block == null) {
Block next = blockIterator.next();
if (next.getType() != Material.AIR) {
block = next;
}
}
if (block == null || !Materials.isSign(block.getType())) {
plugin.message(sender, "addsign-noSign");
return;
}
GeneralRegion region;
if(args.length > 1) {
// Get region by argument
region = plugin.getFileManager().getRegion(args[1]);
if(region == null) {
plugin.message(sender, "cmd-notRegistered", args[1]);
return;
}
} else {
// Get region by sign position
List<GeneralRegion> regions = Utils.getImportantRegions(block.getLocation());
if(regions.isEmpty()) {
plugin.message(sender, "addsign-noRegions");
return;
} else if(regions.size() > 1) {
plugin.message(sender, "addsign-couldNotDetect", regions.get(0).getName(), regions.get(1).getName());
return;
}
region = regions.get(0);
}
String profile = null;
if(args.length > 2) {
profile = args[2];
Set<String> profiles = plugin.getConfig().getConfigurationSection("signProfiles").getKeys(false);
if(!profiles.contains(profile)) {
plugin.message(sender, "addsign-wrongProfile", Utils.createCommaSeparatedList(profiles), region);
return;
}
}
RegionSign regionSign = SignsFeature.getSignByLocation(block.getLocation());
if(regionSign != null) {
plugin.message(sender, "addsign-alreadyRegistered", regionSign.getRegion());
return;
}
GeneralRegion region;
if (args.length > 1) {
// Get region by argument
region = plugin.getFileManager().getRegion(args[1]);
if (region == null) {
plugin.message(sender, "cmd-notRegistered", args[1]);
return;
}
} else {
// Get region by sign position
List<GeneralRegion> regions = Utils.getImportantRegions(block.getLocation());
if (regions.isEmpty()) {
plugin.message(sender, "addsign-noRegions");
return;
} else if (regions.size() > 1) {
plugin.message(sender, "addsign-couldNotDetect", regions.get(0).getName(), regions.get(1).getName());
return;
}
region = regions.get(0);
}
String profile = null;
if (args.length > 2) {
profile = args[2];
Set<String> profiles = plugin.getConfig().getConfigurationSection("signProfiles").getKeys(false);
if (!profiles.contains(profile)) {
plugin.message(sender, "addsign-wrongProfile", Utils.createCommaSeparatedList(profiles), region);
return;
}
}
RegionSign regionSign = SignsFeature.getSignByLocation(block.getLocation());
if (regionSign != null) {
plugin.message(sender, "addsign-alreadyRegistered", regionSign.getRegion());
return;
}
region.getSignsFeature().addSign(block.getLocation(), block.getType(), plugin.getBukkitHandler().getSignFacing(block), profile);
if(profile == null) {
plugin.message(sender, "addsign-success", region);
} else {
plugin.message(sender, "addsign-successProfile", profile, region);
}
region.update();
}
final BlockData data = block.getBlockData();
final BlockFace rotation;
if (data instanceof Sign) {
rotation = ((Sign) data).getRotation();
} else if (data instanceof WallSign) {
rotation = ((WallSign) data).getFacing();
} else {
rotation = null;
}
region.getSignsFeature().addSign(block.getLocation(), block.getType(), rotation, profile);
if (profile == null) {
plugin.message(sender, "addsign-success", region);
} else {
plugin.message(sender, "addsign-successProfile", profile, region);
}
region.update();
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
List<String> result = new ArrayList<>();
if(toComplete == 2) {
result.addAll(plugin.getFileManager().getRegionNames());
} else if(toComplete == 3) {
result.addAll(plugin.getConfig().getStringList("signProfiles"));
}
return result;
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
List<String> result = new ArrayList<>();
if (toComplete == 2) {
result.addAll(plugin.getFileManager().getRegionNames());
} else if (toComplete == 3) {
result.addAll(plugin.getConfig().getStringList("signProfiles"));
}
return result;
}
}
@@ -6,10 +6,7 @@ import org.apache.commons.lang.StringUtils;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
/**
* Abstract class for generalising command classes.
@@ -31,11 +28,12 @@ public abstract class CommandAreaShop {
* @return true if it can execute the command, false otherwise
*/
public boolean canExecute(Command command, String[] args) {
String commandString = command.getName() + " " + StringUtils.join(args, " ");
if(commandString.length() > getCommandStart().length()) {
return commandString.toLowerCase().startsWith(getCommandStart().toLowerCase() + " ");
String commandString = command.getName() + " " + StringUtils.join(args, " ").toLowerCase();
final String start = getCommandStart().toLowerCase();
if(commandString.length() > start.length()) {
return commandString.startsWith(start + " ");
}
return commandString.toLowerCase().startsWith(getCommandStart().toLowerCase());
return commandString.startsWith(start);
}
/**
@@ -46,7 +44,7 @@ public abstract class CommandAreaShop {
* @return A collection with all the possibilities for argument to complete
*/
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
return new ArrayList<>();
return Collections.emptyList();
}
/**
@@ -89,7 +87,7 @@ public abstract class CommandAreaShop {
return false;
}
private class CommandTime {
private static class CommandTime {
public final String command;
public final long time;
@@ -11,6 +11,7 @@ import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
public class FindCommand extends CommandAreaShop {
@@ -82,7 +83,7 @@ public class FindCommand extends CommandAreaShop {
}
if(!results.isEmpty()) {
// Draw a random one
BuyRegion region = results.get(new Random().nextInt(results.size()));
BuyRegion region = results.get(ThreadLocalRandom.current().nextInt(results.size()));
Message onlyInGroup = Message.empty();
if(group != null) {
onlyInGroup = Message.fromKey("find-onlyInGroup").replacements(args[3]);
@@ -122,7 +123,7 @@ public class FindCommand extends CommandAreaShop {
}
if(!results.isEmpty()) {
// Draw a random one
RentRegion region = results.get(new Random().nextInt(results.size()));
RentRegion region = results.get(ThreadLocalRandom.current().nextInt(results.size()));
Message onlyInGroup = Message.empty();
if(group != null) {
onlyInGroup = Message.fromKey("find-onlyInGroup").replacements(args[3]);
@@ -5,78 +5,79 @@ import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class TeleportCommand extends CommandAreaShop {
@Override
public String getCommandStart() {
return "areashop tp";
}
/**
* Check if a person can teleport to the region (assuming he is not teleporting to a sign).
*
* @param person The person to check
* @param region The region to check for
* @return true if the person can teleport to it, otherwise false
*/
public static boolean canUse(CommandSender person, GeneralRegion region) {
if (!(person instanceof Player)) {
return false;
}
Player player = (Player) person;
return player.hasPermission("areashop.teleportall")
|| region.isOwner(player) && player.hasPermission("areashop.teleport")
|| region.isAvailable() && player.hasPermission("areashop.teleportavailable")
|| region.getFriendsFeature().getFriends().contains(player.getUniqueId()) && player.hasPermission("areashop.teleportfriend");
}
@Override
public String getHelp(CommandSender target) {
if(target.hasPermission("areashop.teleportall") || target.hasPermission("areashop.teleport")) {
return "help-teleport";
}
return null;
}
@Override
public String getCommandStart() {
return "areashop tp";
}
/**
* Check if a person can teleport to the region (assuming he is not teleporting to a sign).
* @param person The person to check
* @param region The region to check for
* @return true if the person can teleport to it, otherwise false
*/
public static boolean canUse(CommandSender person, GeneralRegion region) {
if(!(person instanceof Player)) {
return false;
}
Player player = (Player)person;
return player.hasPermission("areashop.teleportall")
|| region.isOwner(player) && player.hasPermission("areashop.teleport")
|| region.isAvailable() && player.hasPermission("areashop.teleportavailable")
|| region.getFriendsFeature().getFriends().contains(player.getUniqueId()) && player.hasPermission("areashop.teleportfriend");
}
@Override
public String getHelp(CommandSender target) {
if (target.hasPermission("areashop.teleportall") || target.hasPermission("areashop.teleport")) {
return "help-teleport";
}
return null;
}
@Override
public void execute(CommandSender sender, String[] args) {
if(!sender.hasPermission("areashop.teleport") && !sender.hasPermission("areashop.teleportall") && !sender.hasPermission("areashop.teleportavailable") && !sender.hasPermission("areashop.teleportavailablesign") && !sender.hasPermission("areashop.teleportsign") && !sender.hasPermission("areashop.teleportsignall") && !sender.hasPermission("areashop.teleportfriend") && !sender.hasPermission("teleportfriendsign")) {
plugin.message(sender, "teleport-noPermission");
return;
}
if(!(sender instanceof Player)) {
plugin.message(sender, "cmd-onlyByPlayer");
return;
}
if(args.length <= 1 || args[1] == null) {
plugin.message(sender, "teleport-help");
return;
}
Player player = (Player)sender;
GeneralRegion region = plugin.getFileManager().getRegion(args[1]);
if(region == null) {
plugin.message(player, "teleport-noRentOrBuy", args[1]);
return;
}
@Override
public void execute(CommandSender sender, String[] args) {
if (!sender.hasPermission("areashop.teleport") && !sender.hasPermission("areashop.teleportall") && !sender.hasPermission("areashop.teleportavailable") && !sender.hasPermission("areashop.teleportavailablesign") && !sender.hasPermission("areashop.teleportsign") && !sender.hasPermission("areashop.teleportsignall") && !sender.hasPermission("areashop.teleportfriend") && !sender.hasPermission("teleportfriendsign")) {
plugin.message(sender, "teleport-noPermission");
return;
}
if (!(sender instanceof Player)) {
plugin.message(sender, "cmd-onlyByPlayer");
return;
}
if (args.length <= 1 || args[1] == null) {
plugin.message(sender, "teleport-help");
return;
}
Player player = (Player) sender;
GeneralRegion region = plugin.getFileManager().getRegion(args[1]);
if (region == null) {
plugin.message(player, "teleport-noRentOrBuy", args[1]);
return;
}
boolean toSign = args.length >= 3 && (
args[2].equalsIgnoreCase("sign")
|| args[2].equalsIgnoreCase("yes")
|| args[2].equalsIgnoreCase("true")
);
region.getTeleportFeature().teleportPlayer(player, toSign);
}
boolean toSign = args.length >= 3 && (
args[2].equalsIgnoreCase("sign")
|| args[2].equalsIgnoreCase("yes")
|| args[2].equalsIgnoreCase("true")
);
region.getTeleportFeature().teleportPlayer(player, toSign, true);
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
ArrayList<String> result = new ArrayList<>();
if(toComplete == 2) {
result.addAll(plugin.getFileManager().getRegionNames());
} else if(toComplete == 3) {
result.add("sign");
}
return result;
}
@Override
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
if (toComplete == 2) {
return plugin.getFileManager().getRegionNames();
} else if (toComplete == 3) {
return Collections.singletonList("sign");
}
return Collections.emptyList();
}
}
@@ -30,7 +30,7 @@ Possible future feature classes:
public abstract class RegionFeature implements Listener {
public static final AreaShop plugin = AreaShop.getInstance();
public YamlConfiguration config = plugin.getConfig();
protected YamlConfiguration config = plugin.getConfig();
private GeneralRegion region;
/**
@@ -1,560 +0,0 @@
package me.wiefferink.areashop.features;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import me.wiefferink.areashop.AreaShop;
import me.wiefferink.areashop.features.signs.RegionSign;
import me.wiefferink.areashop.regions.GeneralRegion;
import me.wiefferink.areashop.tools.Utils;
import me.wiefferink.areashop.tools.Value;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class TeleportFeature extends RegionFeature {
public TeleportFeature() {
}
public TeleportFeature(GeneralRegion region) {
setRegion(region);
}
/**
* Get the teleportlocation set for this region.
* @return The teleport location, or null if not set
*/
public Location getTeleportLocation() {
return Utils.configToLocation(getRegion().getConfigurationSectionSetting("general.teleportLocation"));
}
/**
* Check if the region has a teleportLocation specified.
* @return true if the region has a teleportlocation, false otherwise
*/
public boolean hasTeleportLocation() {
return getRegion().getConfigurationSectionSetting("general.teleportLocation") != null;
}
/**
* Set the teleport location of this region.
* @param location The location to set as teleport location
*/
public void setTeleport(Location location) {
if(location == null) {
getRegion().setSetting("general.teleportLocation", null);
} else {
getRegion().setSetting("general.teleportLocation", Utils.locationToConfig(location, true));
}
}
/**
* Teleport a player to the region or sign.
* @param player Player that should be teleported
* @param toSign true to teleport to the first sign of the region, false for teleporting to the region itself
* @param checkRestrictions Set to true if teleport permissions should be checked, false otherwise, also toggles cross-world check
* @return true if the teleport succeeded, otherwise false
*/
public boolean teleportPlayer(Player player, boolean toSign, boolean checkRestrictions) {
// Check basics
if(getRegion().getWorld() == null) {
getRegion().message(player, "general-noWorld");
return false;
}
if(getRegion().getRegion() == null) {
getRegion().message(player, "general-noRegion");
return false;
}
if(checkRestrictions) {
// Check correct world
if(!getRegion().getBooleanSetting("general.teleportCrossWorld") && !player.getWorld().equals(getRegion().getWorld())) {
getRegion().message(player, "teleport-wrongWorld", player.getWorld().getName());
return false;
}
boolean owner = player.getUniqueId().equals(getRegion().getOwner());
boolean friend = getRegion().getFriendsFeature().getFriends().contains(player.getUniqueId());
boolean available = getRegion().isAvailable();
// Teleport to sign instead if they dont have permission for teleporting to region
if((!toSign && owner && !player.hasPermission("areashop.teleport") && player.hasPermission("areashop.teleportsign")
|| !toSign && !owner && !friend && !player.hasPermission("areashop.teleportall") && player.hasPermission("areashop.teleportsignall")
|| !toSign && !owner && friend && !player.hasPermission("areashop.teleportfriend") && player.hasPermission("areashop.teleportfriendsign")
|| !toSign && !owner && !friend && available && !player.hasPermission("areashop.teleportavailable") && player.hasPermission("areashop.teleportavailablesign"))) {
getRegion().message(player, "teleport-changedToSign");
toSign = true;
}
// Check permissions
if(owner && !available && !player.hasPermission("areashop.teleport") && !toSign) {
getRegion().message(player, "teleport-noPermission");
return false;
} else if(!owner && !available && !player.hasPermission("areashop.teleportall") && !toSign && !friend) {
getRegion().message(player, "teleport-noPermissionOther");
return false;
} else if(!owner && !available && !player.hasPermission("areashop.teleportfriend") && !toSign && friend) {
getRegion().message(player, "teleport-noPermissionFriend");
return false;
} else if(available && !player.hasPermission("areashop.teleportavailable") && !toSign) {
getRegion().message(player, "teleport-noPermissionAvailable");
return false;
} else if(owner && !available && !player.hasPermission("areashop.teleportsign") && toSign) {
getRegion().message(player, "teleport-noPermissionSign");
return false;
} else if(!owner && !available && !player.hasPermission("areashop.teleportsignall") && toSign && !friend) {
getRegion().message(player, "teleport-noPermissionOtherSign");
return false;
} else if(!owner && !available && !player.hasPermission("areashop.teleportfriendsign") && toSign && friend) {
getRegion().message(player, "teleport-noPermissionFriendSign");
return false;
} else if(available && !player.hasPermission("areashop.teleportavailablesign") && toSign) {
getRegion().message(player, "teleport-noPermissionAvailableSign");
return false;
}
}
// Get the starting location
Value<Boolean> toSignRef = new Value<>(toSign);
Location startLocation = getStartLocation(player, toSignRef);
toSign = toSignRef.get();
boolean insideRegion;
if(toSign) {
insideRegion = getRegion().getBooleanSetting("general.teleportToSignIntoRegion");
} else {
insideRegion = getRegion().getBooleanSetting("general.teleportIntoRegion");
}
// Check locations starting from startLocation and then a cube that increases
// radius around that (until no block in the region is found at all cube sides)
Location safeLocation = startLocation;
ProtectedRegion worldguardRegion = getRegion().getRegion();
boolean blocksInRegion = worldguardRegion.contains(startLocation.getBlockX(), startLocation.getBlockY(), startLocation.getBlockZ());
if(!blocksInRegion && insideRegion) {
getRegion().message(player, "teleport-blocked");
return false;
}
// Tries limit tracking
int radius = 1;
int checked = 1;
int maxTries = plugin.getConfig().getInt("maximumTries");
// Tracking of which sides to continue the search
boolean done = isSafe(safeLocation);
boolean northDone = false, eastDone = false, southDone = false, westDone = false, topDone = false, bottomDone = false;
boolean continueThisDirection;
while((blocksInRegion || !insideRegion) && !done) {
blocksInRegion = false;
// North side
continueThisDirection = false;
for(int x = -radius + 1; x <= radius && !done && !northDone; x++) {
for(int y = -radius + 1; y < radius && !done; y++) {
safeLocation = startLocation.clone().add(x, y, -radius);
if(safeLocation.getBlockY() > 256 || safeLocation.getBlockY() < 0) {
continue;
}
if(worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
checked++;
done = isSafe(safeLocation) || checked > maxTries;
blocksInRegion = true;
continueThisDirection = true;
}
}
}
northDone = northDone || !continueThisDirection;
// East side
continueThisDirection = false;
for(int z = -radius + 1; z <= radius && !done && !eastDone; z++) {
for(int y = -radius + 1; y < radius && !done; y++) {
safeLocation = startLocation.clone().add(radius, y, z);
if(safeLocation.getBlockY() > 256 || safeLocation.getBlockY() < 0) {
continue;
}
if(worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
checked++;
done = isSafe(safeLocation) || checked > maxTries;
blocksInRegion = true;
continueThisDirection = true;
}
}
}
eastDone = eastDone || !continueThisDirection;
// South side
continueThisDirection = false;
for(int x = radius - 1; x >= -radius && !done && !southDone; x--) {
for(int y = -radius + 1; y < radius && !done; y++) {
safeLocation = startLocation.clone().add(x, y, radius);
if(safeLocation.getBlockY() > 256 || safeLocation.getBlockY() < 0) {
continue;
}
if(worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
checked++;
done = isSafe(safeLocation) || checked > maxTries;
blocksInRegion = true;
continueThisDirection = true;
}
}
}
southDone = southDone || !continueThisDirection;
// West side
continueThisDirection = false;
for(int z = radius - 1; z >= -radius && !done && !westDone; z--) {
for(int y = -radius + 1; y < radius && !done; y++) {
safeLocation = startLocation.clone().add(-radius, y, z);
if(safeLocation.getBlockY() > 256 || safeLocation.getBlockY() < 0) {
continue;
}
if(worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
checked++;
done = isSafe(safeLocation) || checked > maxTries;
blocksInRegion = true;
continueThisDirection = true;
}
}
}
westDone = westDone || !continueThisDirection;
// Top side
continueThisDirection = false;
// Middle block of the top
if((startLocation.getBlockY() + radius) > 256) {
topDone = true;
}
if(!done && !topDone) {
safeLocation = startLocation.clone().add(0, radius, 0);
if(worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
checked++;
done = isSafe(safeLocation) || checked > maxTries;
blocksInRegion = true;
continueThisDirection = true;
}
}
for(int r = 1; r <= radius && !done && !topDone; r++) {
// North
for(int x = -r + 1; x <= r && !done; x++) {
safeLocation = startLocation.clone().add(x, radius, -r);
if(worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
checked++;
done = isSafe(safeLocation) || checked > maxTries;
blocksInRegion = true;
continueThisDirection = true;
}
}
// East
for(int z = -r + 1; z <= r && !done; z++) {
safeLocation = startLocation.clone().add(r, radius, z);
if(worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
checked++;
done = isSafe(safeLocation) || checked > maxTries;
blocksInRegion = true;
continueThisDirection = true;
}
}
// South side
for(int x = r - 1; x >= -r && !done; x--) {
safeLocation = startLocation.clone().add(x, radius, r);
if(worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
checked++;
done = isSafe(safeLocation) || checked > maxTries;
blocksInRegion = true;
continueThisDirection = true;
}
}
// West side
for(int z = r - 1; z >= -r && !done; z--) {
safeLocation = startLocation.clone().add(-r, radius, z);
if(worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
checked++;
done = isSafe(safeLocation) || checked > maxTries;
blocksInRegion = true;
continueThisDirection = true;
}
}
}
topDone = topDone || !continueThisDirection;
// Bottom side
continueThisDirection = false;
// Middle block of the bottom
if(startLocation.getBlockY() - radius < 0) {
bottomDone = true;
}
if(!done && !bottomDone) {
safeLocation = startLocation.clone().add(0, -radius, 0);
if(worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
checked++;
done = isSafe(safeLocation) || checked > maxTries;
blocksInRegion = true;
continueThisDirection = true;
}
}
for(int r = 1; r <= radius && !done && !bottomDone; r++) {
// North
for(int x = -r + 1; x <= r && !done; x++) {
safeLocation = startLocation.clone().add(x, -radius, -r);
if(worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
checked++;
done = isSafe(safeLocation) || checked > maxTries;
blocksInRegion = true;
continueThisDirection = true;
}
}
// East
for(int z = -r + 1; z <= r && !done; z++) {
safeLocation = startLocation.clone().add(r, -radius, z);
if(worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
checked++;
done = isSafe(safeLocation) || checked > maxTries;
blocksInRegion = true;
continueThisDirection = true;
}
}
// South side
for(int x = r - 1; x >= -r && !done; x--) {
safeLocation = startLocation.clone().add(x, -radius, r);
if(worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
checked++;
done = isSafe(safeLocation) || checked > maxTries;
blocksInRegion = true;
continueThisDirection = true;
}
}
// West side
for(int z = r - 1; z >= -r && !done; z--) {
safeLocation = startLocation.clone().add(-r, -radius, z);
if(worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
checked++;
done = isSafe(safeLocation) || checked > maxTries;
blocksInRegion = true;
continueThisDirection = true;
}
}
}
bottomDone = bottomDone || !continueThisDirection;
// Increase cube radius
radius++;
}
if(done && isSafe(safeLocation)) {
if(toSign) {
getRegion().message(player, "teleport-successSign");
// Let the player look at the sign
Vector playerVector = safeLocation.toVector();
playerVector.setY(playerVector.getY() + player.getEyeHeight(true));
Vector signVector = getRegion().getSignsFeature().getSigns().get(0).getLocation().toVector().add(new Vector(0.5, 0.5, 0.5));
Vector direction = playerVector.clone().subtract(signVector).normalize();
safeLocation.setYaw(180 - (float)Math.toDegrees(Math.atan2(direction.getX(), direction.getZ())));
safeLocation.setPitch(90 - (float)Math.toDegrees(Math.acos(direction.getY())));
} else {
getRegion().message(player, "teleport-success");
}
player.teleport(safeLocation);
AreaShop.debug("Found location: " + safeLocation.toString() + " Tries: " + (checked - 1));
return true;
} else {
getRegion().message(player, "teleport-noSafe", checked - 1, maxTries);
AreaShop.debug("No location found, checked " + (checked - 1) + " spots of max " + maxTries);
return false;
}
}
/**
* Teleport a player to the region or sign when he has permissions for it.
* @param player Player that should be teleported
* @param toSign true to teleport to the first sign of the region, false for teleporting to the region itself
* @return true if the teleport succeeded, otherwise false
*/
public boolean teleportPlayer(Player player, boolean toSign) {
return teleportPlayer(player, toSign, true);
}
/**
* Teleport a player to the region when he has permissions for it.
* @param player Player that should be teleported
* @return true if the teleport succeeded, otherwise false
*/
public boolean teleportPlayer(Player player) {
return teleportPlayer(player, false, true);
}
/**
* Checks if a certain location is safe to teleport to.
* @param location The location to check
* @return true if it is safe, otherwise false
*/
private boolean isSafe(Location location) {
Block feet = location.getBlock();
Block head = feet.getRelative(BlockFace.UP);
Block below = feet.getRelative(BlockFace.DOWN);
Block above = head.getRelative(BlockFace.UP);
// Check the block at the feet and head of the player
if((feet.getType().isSolid() && !canSpawnIn(feet.getType())) || feet.isLiquid()) {
return false;
} else if((head.getType().isSolid() && !canSpawnIn(head.getType())) || head.isLiquid()) {
return false;
} else if(!below.getType().isSolid() || cannotSpawnOn(below.getType()) || below.isLiquid()) {
return false;
} else if(above.isLiquid() || cannotSpawnBeside(above.getType())) {
return false;
}
// Get all blocks around the player (below foot level, foot level, head level and above head level)
Set<Material> around = new HashSet<>();
for(int y = 0; y <= 3; y++) {
for(int x = -1; x <= 1; x++) {
for(int z = -1; z <= 1; z++) {
// Skip blocks in the column of the player
if(x == 0 && z == 0) {
continue;
}
around.add(below.getRelative(x, y, z).getType());
}
}
}
// Check the blocks around the player
for(Material material : around) {
if(cannotSpawnBeside(material)) {
return false;
}
}
return true;
}
/**
* Check if a player can spawn in here.
* @param material Material to check (assumed that this is at the feet or head level)
* @return true when it is safe to spawn inside, otherwise false
*/
private static boolean canSpawnIn(Material material) {
String name = material.name();
return name.contains("DOOR")
|| name.contains("SIGN")
|| name.contains("PLATE") // Redstone plates
|| name.equals("DRAGON_EGG");
}
/**
* Check if a player can spawn on here.
* @param material Material to check (assumed that this is below the feet)
* @return true when it is safe to spawn on top of, otherwise false
*/
private static boolean cannotSpawnOn(Material material) {
String name = material.name();
return name.equals("CACTUS")
|| name.contains("PISTON")
|| name.contains("SIGN")
|| name.contains("DOOR")
|| name.contains("PLATE")
|| name.contains("REDSTONE_LAMP")
|| name.contains("FENCE")
|| name.contains("GLASS_PANE") || name.contains("THIN_GLASS")
|| name.equals("DRAGON_EGG")
|| name.contains("MAGMA");
}
/**
* Check if a player can spawn next to it.
* @param material Material to check (assumed that this is somewhere around the player)
* @return true when it is safe to spawn next to, otherwise false
*/
private static boolean cannotSpawnBeside(Material material) {
String name = material.name();
return name.contains("LAVA")
|| name.contains("CACTUS")
|| name.equals("FIRE")
|| name.contains("MAGMA");
}
/**
* Get the start location of a safe teleport search.
* @param player The player to get it for
* @param toSign true to try teleporting to the first sign, false for teleporting to the region
* @return The start location
*/
private Location getStartLocation(Player player, Value<Boolean> toSign) {
Location startLocation = null;
ProtectedRegion worldguardRegion = getRegion().getRegion();
// Try to get sign location
List<RegionSign> signs = getRegion().getSignsFeature().getSigns();
boolean signAvailable = !signs.isEmpty();
if(toSign.get()) {
if(signAvailable) {
// Use the location 1 below the sign to prevent weird spawing above the sign
startLocation = signs.get(0).getLocation(); //.subtract(0.0, 1.0, 0.0);
startLocation.setPitch(player.getLocation().getPitch());
startLocation.setYaw(player.getLocation().getYaw());
// Move player x blocks away from the sign
double distance = getRegion().getDoubleSetting("general.teleportSignDistance");
if(distance > 0) {
BlockFace facing = getRegion().getSignsFeature().getSigns().get(0).getFacing();
Vector facingVector = new Vector(facing.getModX(), facing.getModY(), facing.getModZ())
.normalize()
.multiply(distance);
startLocation.setX(startLocation.getBlockX() + 0.5);
startLocation.setZ(startLocation.getBlockZ() + 0.5);
startLocation.add(facingVector);
}
} else {
// No sign available
getRegion().message(player, "teleport-changedToNoSign");
toSign.set(false);
}
}
// Use teleportation location that is set for the region
if(startLocation == null && hasTeleportLocation()) {
startLocation = getTeleportLocation();
}
// Calculate a default location
if(startLocation == null) {
// Set to block in the middle, y configured in the config
Vector regionMin = AreaShop.getInstance().getWorldGuardHandler().getMinimumPoint(worldguardRegion);
Vector regionMax = AreaShop.getInstance().getWorldGuardHandler().getMaximumPoint(worldguardRegion);
Vector middle = regionMin.clone().midpoint(regionMax);
String configSetting = getRegion().getStringSetting("general.teleportLocationY");
if("bottom".equalsIgnoreCase(configSetting)) {
middle = middle.setY(regionMin.getBlockY());
} else if("top".equalsIgnoreCase(configSetting)) {
middle = middle.setY(regionMax.getBlockY());
} else if("middle".equalsIgnoreCase(configSetting)) {
middle = middle.setY(middle.getBlockY());
} else {
try {
int vertical = Integer.parseInt(configSetting);
middle = middle.setY(vertical);
} catch(NumberFormatException e) {
AreaShop.warn("Could not parse general.teleportLocationY: '" + configSetting + "'");
}
}
startLocation = new Location(getRegion().getWorld(), middle.getX(), middle.getY(), middle.getZ(), player.getLocation().getYaw(), player.getLocation().getPitch());
}
// Set location in the center of the block
startLocation.setX(startLocation.getBlockX() + 0.5);
startLocation.setZ(startLocation.getBlockZ() + 0.5);
return startLocation;
}
}
@@ -1,7 +1,10 @@
package me.wiefferink.areashop.features.signs;
import com.google.common.base.Objects;
import io.papermc.lib.PaperLib;
import io.papermc.lib.features.blockstatesnapshot.BlockStateSnapshotResult;
import me.wiefferink.areashop.AreaShop;
import me.wiefferink.areashop.managers.SignErrorLogger;
import me.wiefferink.areashop.regions.GeneralRegion;
import me.wiefferink.areashop.tools.Materials;
import me.wiefferink.areashop.tools.Utils;
@@ -9,9 +12,13 @@ import me.wiefferink.interactivemessenger.processing.Message;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Tag;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
import org.bukkit.block.Sign;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.type.WallSign;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
@@ -24,231 +31,267 @@ import java.util.List;
*/
public class RegionSign {
private final SignsFeature signsFeature;
private final String key;
private final SignsFeature signsFeature;
private final String key;
public RegionSign(SignsFeature signsFeature, String key) {
this.signsFeature = signsFeature;
this.key = key;
}
public RegionSign(SignsFeature signsFeature, String key) {
this.signsFeature = signsFeature;
this.key = key;
}
/**
* Get the location of this sign.
* @return The location of this sign
*/
public Location getLocation() {
return Utils.configToLocation(getRegion().getConfig().getConfigurationSection("general.signs." + key + ".location"));
}
/**
* Get the location of this sign.
*
* @return The location of this sign
*/
public Location getLocation() {
return Utils.configToLocation(getRegion().getConfig().getConfigurationSection("general.signs." + key + ".location"));
}
/**
* Location string to be used as key in maps.
* @return Location string
*/
public String getStringLocation() {
return SignsFeature.locationToString(getLocation());
}
/**
* Location string to be used as key in maps.
*
* @return Location string
*/
public String getStringLocation() {
return SignsFeature.locationToString(getLocation());
}
/**
* Chunk string to be used as key in maps.
* @return Chunk string
*/
public String getStringChunk() {
return SignsFeature.chunkToString(getLocation());
}
/**
* Chunk string to be used as key in maps.
*
* @return Chunk string
*/
public String getStringChunk() {
return SignsFeature.chunkToString(getLocation());
}
/**
* Get the region this sign is linked to.
* @return The region this sign is linked to
*/
public GeneralRegion getRegion() {
return signsFeature.getRegion();
}
/**
* Get the region this sign is linked to.
*
* @return The region this sign is linked to
*/
public GeneralRegion getRegion() {
return signsFeature.getRegion();
}
/**
* Remove this sign from the region.
*/
public void remove() {
getLocation().getBlock().setType(Material.AIR);
signsFeature.getSignsRef().remove(getStringLocation());
SignsFeature.getAllSigns().remove(getStringLocation());
SignsFeature.getSignsByChunk().get(getStringChunk()).remove(this);
getRegion().setSetting("general.signs." + key, null);
}
/**
* Remove this sign from the region.
*/
public void remove() {
getLocation().getBlock().setType(Material.AIR);
signsFeature.getSignsRef().remove(getStringLocation());
SignsFeature.getAllSigns().remove(getStringLocation());
SignsFeature.getSignsByChunk().get(getStringChunk()).remove(this);
getRegion().setSetting("general.signs." + key, null);
}
/**
* Get the ConfigurationSection defining the sign layout.
* @return The sign layout config
*/
public ConfigurationSection getProfile() {
return getRegion().getConfigurationSectionSetting("general.signProfile", "signProfiles", getRegion().getConfig().get("general.signs." + key + ".profile"));
}
/**
* Get the ConfigurationSection defining the sign layout.
*
* @return The sign layout config
*/
public ConfigurationSection getProfile() {
return getRegion().getConfigurationSectionSetting("general.signProfile", "signProfiles", getRegion().getConfig().get("general.signs." + key + ".profile"));
}
/**
* Get the facing of the sign as saved in the config.
* @return BlockFace the sign faces, or null if unknown
*/
public BlockFace getFacing() {
try {
return BlockFace.valueOf(getRegion().getConfig().getString("general.signs." + key + ".facing"));
} catch(NullPointerException | IllegalArgumentException e) {
return null;
}
}
/**
* Get the facing of the sign as saved in the config.
*
* @return BlockFace the sign faces, or null if unknown
*/
public BlockFace getFacing() {
try {
return BlockFace.valueOf(getRegion().getConfig().getString("general.signs." + key + ".facing"));
} catch (NullPointerException | IllegalArgumentException e) {
return null;
}
}
/**
* Get the material of the sign as saved in the config.
* @return Material of the sign, usually {@link Material#WALL_SIGN}, {@link Material#SIGN}, or one of the other wood types (different result for 1.13-), Material.AIR if none.
*/
public Material getMaterial() {
String name = getRegion().getConfig().getString("general.signs." + key + ".signType");
Material result = Materials.signNameToMaterial(name);
return result == null ? Material.AIR : result;
}
/**
* Get the material of the sign as saved in the config.
*
* @return Material of the sign, usually or one of the other wood types (different result for 1.13-), Material.AIR if none.
*/
public Material getMaterial() {
String name = getRegion().getConfig().getString("general.signs." + key + ".signType");
Material result = Materials.signNameToMaterial(name);
return result == null ? Material.AIR : result;
}
/**
* Update this sign.
* @return true if the update was successful, otherwise false
*/
public boolean update() {
// Ignore updates of signs in chunks that are not loaded
Location signLocation = getLocation();
if(signLocation == null
|| signLocation.getWorld() == null
|| !signLocation.getWorld().isChunkLoaded(signLocation.getBlockX() >> 4, signLocation.getBlockZ() >> 4)) {
return false;
}
/**
* Update this sign.
*
* @return true if the update was successful, otherwise false
*/
public boolean update() {
if(getRegion().isDeleted()) {
return false;
}
// Ignore updates of signs in chunks that are not loaded
Location signLocation = getLocation();
if (signLocation == null
|| signLocation.getWorld() == null
|| !signLocation.getWorld().isChunkLoaded(signLocation.getBlockX() >> 4, signLocation.getBlockZ() >> 4)) {
return false;
}
YamlConfiguration regionConfig = getRegion().getConfig();
ConfigurationSection signConfig = getProfile();
Block block = signLocation.getBlock();
if(signConfig == null || !signConfig.isSet(getRegion().getState().getValue())) {
block.setType(Material.AIR);
return true;
}
final GeneralRegion region = getRegion();
ConfigurationSection stateConfig = signConfig.getConfigurationSection(getRegion().getState().getValue());
if (region.isDeleted()) {
return false;
}
// Get the lines
String[] signLines = new String[4];
boolean signEmpty = true;
for(int i = 0; i < 4; i++) {
signLines[i] = stateConfig.getString("line" + (i + 1));
signEmpty &= (signLines[i] == null || signLines[i].isEmpty());
}
if(signEmpty) {
block.setType(Material.AIR);
return true;
}
YamlConfiguration regionConfig = region.getConfig();
ConfigurationSection signConfig = getProfile();
Block block = signLocation.getBlock();
final String value = region.getState().getValue();
if (signConfig == null || !signConfig.isSet(value)) {
block.setType(Material.AIR);
return true;
}
// Place the sign back (with proper rotation and type) after it has been hidden or (indirectly) destroyed
if(!Materials.isSign(block.getType())) {
Material signType = getMaterial();
// Don't do physics here, we first need to update the direction
block.setType(signType, false);
ConfigurationSection stateConfig = signConfig.getConfigurationSection(value);
// This triggers a physics update, which pops the sign if not attached properly
if (!AreaShop.getInstance().getBukkitHandler().setSignFacing(block, getFacing())) {
AreaShop.warn("Failed to update the facing direction of the sign at", getStringLocation(), "to ", getFacing(), ", region:", getRegion().getName());
}
// Get the lines
String[] signLines = new String[4];
boolean signEmpty = true;
for (int i = 0; i < 4; i++) {
signLines[i] = stateConfig.getString("line" + (i + 1));
signEmpty &= (signLines[i] == null || signLines[i].isEmpty());
}
if (signEmpty) {
block.setType(Material.AIR);
return true;
}
// Check if the sign has popped
if(!Materials.isSign(block.getType())) {
AreaShop.warn("Setting sign", key, "of region", getRegion().getName(), "failed, could not set sign block back");
return false;
}
}
final BlockStateSnapshotResult snapshot = PaperLib.getBlockState(block, false);
final BlockState blockState = snapshot.getState();
final BlockData blockData = blockState.getBlockData();
final SignErrorLogger errorLogger = AreaShop.getInstance().getSignErrorLogger();
Material signType = getMaterial();
// Place the sign back (with proper rotation and type) after it has been hidden or (indirectly) destroyed
if (!Tag.SIGNS.isTagged(blockState.getType())) {
// Don't do physics here, we first need to update the direction
blockState.setType(signType);
if (blockData instanceof WallSign) {
((WallSign) blockData).setFacing(getFacing());
} else if (blockData instanceof Sign) {
((org.bukkit.block.data.type.Sign) blockData).setRotation(getFacing());
}
blockState.setBlockData(blockData);
blockState.update(false, true);
// Check if the sign has popped
if (!Materials.isSign(block.getType())) {
final String message = String.format("Setting sign of $1%s of region $2%s failed, could not set sign block back", key, region.getName());
errorLogger.submitWarning(message);
return false;
}
} else {
final String message = "Setting sign $1%s of region $2%s failed, RegionSign material was: $3%s";
errorLogger.submitWarning(String.format(message, key, region.getName(), signType.name()));
}
// Save current rotation and type
if(!regionConfig.isString("general.signs." + key + ".signType")) {
getRegion().setSetting("general.signs." + key + ".signType", block.getType().name());
}
if(!regionConfig.isString("general.signs." + key + ".facing")) {
BlockFace signFacing = AreaShop.getInstance().getBukkitHandler().getSignFacing(block);
getRegion().setSetting("general.signs." + key + ".facing", signFacing == null ? null : signFacing.toString());
}
// Save current rotation and type
if (!regionConfig.isString("general.signs." + key + ".signType")) {
region.setSetting("general.signs." + key + ".signType", blockState.getType().name());
}
if (!regionConfig.isString("general.signs." + key + ".facing")) {
final BlockFace rotation;
if (Materials.isSign(block.getType())) {
if (blockData instanceof org.bukkit.block.data.type.Sign) {
rotation = ((org.bukkit.block.data.type.Sign) blockData).getRotation();
} else if (blockData instanceof WallSign) {
rotation = ((WallSign) blockData).getFacing();
} else {
rotation = null;
}
} else {
rotation = null;
}
region.setSetting("general.signs." + key + ".facing", rotation == null ? null : rotation.toString());
}
// Apply replacements and color and then set it on the sign
Sign signState = (Sign) block.getState();
for(int i = 0; i < signLines.length; i++) {
if(signLines[i] == null) {
signState.setLine(i, "");
continue;
}
signLines[i] = Message.fromString(signLines[i]).replacements(getRegion()).getSingle();
signLines[i] = Utils.applyColors(signLines[i]);
signState.setLine(i, signLines[i]);
}
signState.update();
return true;
}
// Apply replacements and color and then set it on the sign
Sign signState = (Sign) blockState;
for (int i = 0; i < signLines.length; i++) {
if (signLines[i] == null) {
signState.setLine(i, "");
continue;
}
signLines[i] = Message.fromString(signLines[i]).replacements(getRegion()).getSingle();
signLines[i] = Utils.applyColors(signLines[i]);
signState.setLine(i, signLines[i]);
}
// BlockState#update *should* return true here.
blockState.update(false, false);
return true;
}
/**
* Check if the sign needs to update periodically.
* @return true if it needs periodic updates, otherwise false
*/
public boolean needsPeriodicUpdate() {
ConfigurationSection signConfig = getProfile();
if(signConfig == null || !signConfig.isSet(getRegion().getState().getValue().toLowerCase())) {
return false;
}
/**
* Check if the sign needs to update periodically.
*
* @return true if it needs periodic updates, otherwise false
*/
public boolean needsPeriodicUpdate() {
ConfigurationSection signConfig = getProfile();
if (signConfig == null || !signConfig.isSet(getRegion().getState().getValue().toLowerCase())) {
return false;
}
ConfigurationSection stateConfig = signConfig.getConfigurationSection(getRegion().getState().getValue().toLowerCase());
if(stateConfig == null) {
return false;
}
ConfigurationSection stateConfig = signConfig.getConfigurationSection(getRegion().getState().getValue().toLowerCase());
if (stateConfig == null) {
return false;
}
// Check the lines for the timeleft tag
for(int i = 1; i <= 4; i++) {
String line = stateConfig.getString("line" + i);
if(line != null && !line.isEmpty() && line.contains(Message.VARIABLE_START + AreaShop.tagTimeLeft + Message.VARIABLE_END)) {
return true;
}
}
return false;
}
// Check the lines for the timeleft tag
for (int i = 1; i <= 4; i++) {
String line = stateConfig.getString("line" + i);
if (line != null && !line.isEmpty() && line.contains(Message.VARIABLE_START + AreaShop.tagTimeLeft + Message.VARIABLE_END)) {
return true;
}
}
return false;
}
/**
* Run commands when a player clicks a sign.
* @param clicker The player that clicked the sign
* @param clickType The type of clicking
* @return true if the commands ran successfully, false if any of them failed
*/
public boolean runSignCommands(Player clicker, GeneralRegion.ClickType clickType) {
ConfigurationSection signConfig = getProfile();
if(signConfig == null) {
return false;
}
ConfigurationSection stateConfig = signConfig.getConfigurationSection(getRegion().getState().getValue().toLowerCase());
/**
* Run commands when a player clicks a sign.
*
* @param clicker The player that clicked the sign
* @param clickType The type of clicking
* @return true if the commands ran successfully, false if any of them failed
*/
public boolean runSignCommands(Player clicker, GeneralRegion.ClickType clickType) {
ConfigurationSection signConfig = getProfile();
if (signConfig == null) {
return false;
}
final GeneralRegion region = getRegion();
ConfigurationSection stateConfig = signConfig.getConfigurationSection(region.getState().getValue().toLowerCase());
// Run player commands if specified
List<String> playerCommands = new ArrayList<>();
for(String command : stateConfig.getStringList(clickType.getValue() + "Player")) {
// TODO move variable checking code to InteractiveMessenger?
playerCommands.add(command.replace(Message.VARIABLE_START + AreaShop.tagClicker + Message.VARIABLE_END, clicker.getName()));
}
getRegion().runCommands(clicker, playerCommands);
// Run player commands if specified
List<String> playerCommands = new ArrayList<>();
for (String command : stateConfig.getStringList(clickType.getValue() + "Player")) {
// TODO move variable checking code to InteractiveMessenger?
playerCommands.add(command.replace(Message.VARIABLE_START + AreaShop.tagClicker + Message.VARIABLE_END, clicker.getName()));
}
region.runCommands(clicker, playerCommands);
// Run console commands if specified
List<String> consoleCommands = new ArrayList<>();
for(String command : stateConfig.getStringList(clickType.getValue() + "Console")) {
consoleCommands.add(command.replace(Message.VARIABLE_START + AreaShop.tagClicker + Message.VARIABLE_END, clicker.getName()));
}
getRegion().runCommands(Bukkit.getConsoleSender(), consoleCommands);
// Run console commands if specified
List<String> consoleCommands = new ArrayList<>();
for (String command : stateConfig.getStringList(clickType.getValue() + "Console")) {
consoleCommands.add(command.replace(Message.VARIABLE_START + AreaShop.tagClicker + Message.VARIABLE_END, clicker.getName()));
}
region.runCommands(Bukkit.getConsoleSender(), consoleCommands);
return !playerCommands.isEmpty() || !consoleCommands.isEmpty();
}
return !playerCommands.isEmpty() || !consoleCommands.isEmpty();
}
@Override
public boolean equals(Object object) {
return object instanceof RegionSign && ((RegionSign)object).getRegion().equals(this.getRegion()) && ((RegionSign)object).key.equals(this.key);
}
@Override
public boolean equals(Object object) {
return object instanceof RegionSign && ((RegionSign) object).getRegion().equals(this.getRegion()) && ((RegionSign) object).key.equals(this.key);
}
@Override
public int hashCode() {
return Objects.hashCode(key, getRegion().getName());
}
@Override
public int hashCode() {
return Objects.hashCode(key, getRegion().getName());
}
}
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,269 @@
package me.wiefferink.areashop.features.teleport;
import co.aikar.taskchain.TaskChain;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import io.papermc.lib.PaperLib;
import me.wiefferink.areashop.AreaShop;
import me.wiefferink.areashop.features.RegionFeature;
import me.wiefferink.areashop.features.signs.RegionSign;
import me.wiefferink.areashop.regions.GeneralRegion;
import me.wiefferink.areashop.tools.Utils;
import me.wiefferink.areashop.tools.Value;
import org.bukkit.*;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
public class TeleportFeature extends RegionFeature {
public TeleportFeature() {
}
public TeleportFeature(GeneralRegion region) {
setRegion(region);
}
/**
* Checks if a certain location is safe to teleport to.
*
* @param location The location to check
* @return true if it is safe, otherwise false
*/
static boolean isSafe(Location location) {
Block feet = location.getBlock();
Block head = feet.getRelative(BlockFace.UP);
Block below = feet.getRelative(BlockFace.DOWN);
Block above = head.getRelative(BlockFace.UP);
// Check the block at the feet and head of the player
if ((feet.getType().isSolid() && !canSpawnIn(feet.getType())) || feet.isLiquid()) {
return false;
} else if ((head.getType().isSolid() && !canSpawnIn(head.getType())) || head.isLiquid()) {
return false;
} else if (!below.getType().isSolid() || cannotSpawnOn(below.getType()) || below.isLiquid()) {
return false;
} else if (above.isLiquid() || cannotSpawnBeside(above.getType())) {
return false;
}
// Get all blocks around the player (below foot level, foot level, head level and above head level)
Set<Material> around = new HashSet<>();
for (int y = 0; y <= 3; y++) {
for (int x = -1; x <= 1; x++) {
for (int z = -1; z <= 1; z++) {
// Skip blocks in the column of the player
if (x == 0 && z == 0) {
continue;
}
around.add(below.getRelative(x, y, z).getType());
}
}
}
// Check the blocks around the player
for (Material material : around) {
if (cannotSpawnBeside(material)) {
return false;
}
}
return true;
}
/**
* Check if a player can spawn in here.
*
* @param material Material to check (assumed that this is at the feet or head level)
* @return true when it is safe to spawn inside, otherwise false
*/
private static boolean canSpawnIn(Material material) {
String name = material.name();
return name.contains("DOOR")
|| name.contains("SIGN")
|| name.contains("PLATE") // Redstone plates
|| name.equals("DRAGON_EGG");
}
/**
* Check if a player can spawn on here.
*
* @param material Material to check (assumed that this is below the feet)
* @return true when it is safe to spawn on top of, otherwise false
*/
private static boolean cannotSpawnOn(Material material) {
String name = material.name();
return name.equals("CACTUS")
|| name.contains("PISTON")
|| name.contains("SIGN")
|| name.contains("DOOR")
|| name.contains("PLATE")
|| name.contains("REDSTONE_LAMP")
|| name.contains("FENCE")
|| name.contains("GLASS_PANE") || name.contains("THIN_GLASS")
|| name.equals("DRAGON_EGG")
|| name.contains("MAGMA");
}
/**
* Check if a player can spawn next to it.
*
* @param material Material to check (assumed that this is somewhere around the player)
* @return true when it is safe to spawn next to, otherwise false
*/
private static boolean cannotSpawnBeside(Material material) {
String name = material.name();
return name.contains("LAVA")
|| name.contains("CACTUS")
|| name.equals("FIRE")
|| name.contains("MAGMA");
}
/**
* Get the teleportlocation set for this region.
*
* @return The teleport location, or null if not set
*/
public Location getTeleportLocation() {
return Utils.configToLocation(getRegion().getConfigurationSectionSetting("general.teleportLocation"));
}
/**
* Check if the region has a teleportLocation specified.
*
* @return true if the region has a teleportlocation, false otherwise
*/
public boolean hasTeleportLocation() {
return getRegion().getConfigurationSectionSetting("general.teleportLocation") != null;
}
/**
* Set the teleport location of this region.
*
* @param location The location to set as teleport location
*/
public void setTeleport(Location location) {
if (location == null) {
getRegion().setSetting("general.teleportLocation", null);
} else {
getRegion().setSetting("general.teleportLocation", Utils.locationToConfig(location, true));
}
}
/**
* Teleport a player to the region or sign.
*
* @param player Player that should be teleported
* @param toSign true to teleport to the first sign of the region, false for teleporting to the region itself
* @param checkRestrictions Set to true if teleport permissions should be checked, false otherwise, also toggles cross-world check
* @return true if the teleport succeeded, otherwise false
*/
public CompletableFuture<Boolean> teleportPlayer(Player player, boolean toSign, boolean checkRestrictions) {
return new TeleportJob(this, plugin).executeTeleport(player, toSign, checkRestrictions);
}
/**
* Teleport a player to the region or sign when he has permissions for it.
*
* @param player Player that should be teleported
* @param toSign true to teleport to the first sign of the region, false for teleporting to the region itself
* @return true if the teleport succeeded, otherwise false
*/
public CompletableFuture<Boolean> teleportPlayer(Player player, boolean toSign) {
return teleportPlayer(player, toSign, true);
}
/**
* Teleport a player to the region when he has permissions for it.
*
* @param player Player that should be teleported
* @return true if the teleport succeeded, otherwise false
*/
public CompletableFuture<Boolean> teleportPlayer(Player player) {
return teleportPlayer(player, false, true);
}
/**
* Get the start location of a safe teleport search.
*
* @param player The player to get it for
* @param toSign true to try teleporting to the first sign, false for teleporting to the region
* @return The start location
*/
Location getStartLocation(Player player, Value<Boolean> toSign) {
Location startLocation = null;
ProtectedRegion worldguardRegion = getRegion().getRegion();
// Try to get sign location
List<RegionSign> signs = getRegion().getSignsFeature().getSigns();
boolean signAvailable = !signs.isEmpty();
if (toSign.get()) {
if (signAvailable) {
// Use the location 1 below the sign to prevent weird spawing above the sign
startLocation = signs.get(0).getLocation(); //.subtract(0.0, 1.0, 0.0);
startLocation.setPitch(player.getLocation().getPitch());
startLocation.setYaw(player.getLocation().getYaw());
// Move player x blocks away from the sign
double distance = getRegion().getDoubleSetting("general.teleportSignDistance");
if (distance > 0) {
BlockFace facing = getRegion().getSignsFeature().getSigns().get(0).getFacing();
Vector facingVector = new Vector(facing.getModX(), facing.getModY(), facing.getModZ())
.normalize()
.multiply(distance);
startLocation.setX(startLocation.getBlockX() + 0.5);
startLocation.setZ(startLocation.getBlockZ() + 0.5);
startLocation.add(facingVector);
}
} else {
// No sign available
getRegion().message(player, "teleport-changedToNoSign");
toSign.set(false);
}
}
// Use teleportation location that is set for the region
if (startLocation == null && hasTeleportLocation()) {
startLocation = getTeleportLocation();
}
// Calculate a default location
if (startLocation == null) {
// Set to block in the middle, y configured in the config
Vector regionMin = AreaShop.getInstance().getWorldGuardHandler().getMinimumPoint(worldguardRegion);
Vector regionMax = AreaShop.getInstance().getWorldGuardHandler().getMaximumPoint(worldguardRegion);
Vector middle = regionMin.clone().midpoint(regionMax);
String configSetting = getRegion().getStringSetting("general.teleportLocationY");
if ("bottom".equalsIgnoreCase(configSetting)) {
middle = middle.setY(regionMin.getBlockY());
} else if ("top".equalsIgnoreCase(configSetting)) {
middle = middle.setY(regionMax.getBlockY());
} else if ("middle".equalsIgnoreCase(configSetting)) {
middle = middle.setY(middle.getBlockY());
} else {
try {
int vertical = Integer.parseInt(configSetting);
middle = middle.setY(vertical);
} catch (NumberFormatException e) {
AreaShop.warn("Could not parse general.teleportLocationY: '" + configSetting + "'");
}
}
startLocation = new Location(getRegion().getWorld(), middle.getX(), middle.getY(), middle.getZ(), player.getLocation().getYaw(), player.getLocation().getPitch());
}
// Set location in the center of the block
startLocation.setX(startLocation.getBlockX() + 0.5);
startLocation.setZ(startLocation.getBlockZ() + 0.5);
return startLocation;
}
}
@@ -0,0 +1,639 @@
package me.wiefferink.areashop.features.teleport;
import co.aikar.taskchain.TaskChain;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldguard.protection.regions.GlobalProtectedRegion;
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
import com.sk89q.worldguard.protection.regions.ProtectedPolygonalRegion;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import io.papermc.lib.PaperLib;
import me.wiefferink.areashop.AreaShop;
import me.wiefferink.areashop.regions.GeneralRegion;
import me.wiefferink.areashop.tools.Utils;
import me.wiefferink.areashop.tools.Value;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask;
import org.bukkit.util.Vector;
import java.util.*;
import java.util.concurrent.*;
import java.util.function.Function;
class TeleportJob {
private final AreaShop plugin;
private final GeneralRegion region;
private final TeleportFeature feature;
private BukkitTask notifierTask;
private boolean running;
private int checked;
private boolean done;
private boolean blocksInRegionCopy;
private boolean northDone = false, eastDone = false, southDone = false, westDone = false, topDone = false, bottomDone = false;
private boolean continueThisDirection;
private int radius = 1;
public TeleportJob(final TeleportFeature region, final AreaShop plugin) {
this.feature = region;
this.region = region.getRegion();
this.plugin = plugin;
}
private static Function<double[], Boolean> generateContainsFunction(final ProtectedRegion worldguardRegion) {
final BlockVector3 min = worldguardRegion.getMinimumPoint(), max = worldguardRegion.getMaximumPoint();
if (worldguardRegion instanceof GlobalProtectedRegion) {
return (unused) -> true;
} else if (worldguardRegion instanceof ProtectedCuboidRegion) {
return coords -> {
final double x = coords[0];
final double y = coords[1];
final double z = coords[2];
return x >= min.getBlockX() && x < max.getBlockX() + 1
&& y >= min.getBlockY() && y < max.getBlockY() + 1
&& z >= min.getBlockZ() && z < max.getBlockZ() + 1;
};
} else if (worldguardRegion instanceof ProtectedPolygonalRegion) {
final int minY = min.getY(), maxY = max.getY();
final List<BlockVector2> points = worldguardRegion.getPoints();
return coords -> {
int targetX = (int) Math.round(coords[0]); // Width
int targetY = (int) Math.round(coords[1]); // Height
int targetZ = (int) Math.round(coords[2]); // Depth
if (targetY < minY || targetY > maxY) {
return false;
}
//Quick and dirty check.
if (targetX < min.getBlockX() || targetX > max.getBlockX() || targetZ < min.getBlockZ() || targetZ > max.getBlockZ()) {
return false;
}
boolean inside = false;
int npoints = points.size();
int xNew, zNew;
int xOld, zOld;
int x1, z1;
int x2, z2;
long crossproduct;
int i;
xOld = points.get(npoints - 1).getBlockX();
zOld = points.get(npoints - 1).getBlockZ();
for (i = 0; i < npoints; i++) {
xNew = points.get(i).getBlockX();
zNew = points.get(i).getBlockZ();
//Check for corner
if (xNew == targetX && zNew == targetZ) {
return true;
}
if (xNew > xOld) {
x1 = xOld;
x2 = xNew;
z1 = zOld;
z2 = zNew;
} else {
x1 = xNew;
x2 = xOld;
z1 = zNew;
z2 = zOld;
}
if (x1 <= targetX && targetX <= x2) {
crossproduct = ((long) targetZ - (long) z1) * (long) (x2 - x1)
- ((long) z2 - (long) z1) * (long) (targetX - x1);
if (crossproduct == 0) {
if ((z1 <= targetZ) == (targetZ <= z2)) return true; // on edge
} else if (crossproduct < 0 && (x1 != targetX)) {
inside = !inside;
}
}
xOld = xNew;
zOld = zNew;
}
return inside;
};
} else {
throw new UnsupportedOperationException("Unknown region type: " + worldguardRegion.getClass().getCanonicalName());
}
}
public boolean isRunning() {
return running;
}
public CompletableFuture<Boolean> executeTeleport(final Player player, boolean toSign, boolean checkRestrictions) {
if (running) {
throw new IllegalStateException("Task is already running!");
}
running = true;
// Check basics
if (feature == null) {
region.message(player, "general-noRegion");
return CompletableFuture.completedFuture(false);
}
if (region.getWorld() == null) {
region.message(player, "general-noWorld");
return CompletableFuture.completedFuture(false);
}
if (checkRestrictions) {
// Check correct world
if (!region.getBooleanSetting("general.teleportCrossWorld") && !player.getWorld().equals(region.getWorld())) {
region.message(player, "teleport-wrongWorld", player.getWorld().getName());
return CompletableFuture.completedFuture(false);
}
boolean owner = player.getUniqueId().equals(region.getOwner());
boolean friend = region.getFriendsFeature().getFriends().contains(player.getUniqueId());
boolean available = region.isAvailable();
// Teleport to sign instead if they dont have permission for teleporting to region
if ((!toSign && owner && !player.hasPermission("areashop.teleport") && player.hasPermission("areashop.teleportsign")
|| !toSign && !owner && !friend && !player.hasPermission("areashop.teleportall") && player.hasPermission("areashop.teleportsignall")
|| !toSign && !owner && friend && !player.hasPermission("areashop.teleportfriend") && player.hasPermission("areashop.teleportfriendsign")
|| !toSign && !owner && !friend && available && !player.hasPermission("areashop.teleportavailable") && player.hasPermission("areashop.teleportavailablesign"))) {
region.message(player, "teleport-changedToSign");
toSign = true;
}
// Check permissions
if (owner && !available && !player.hasPermission("areashop.teleport") && !toSign) {
region.message(player, "teleport-noPermission");
return CompletableFuture.completedFuture(false);
} else if (!owner && !available && !player.hasPermission("areashop.teleportall") && !toSign && !friend) {
region.message(player, "teleport-noPermissionOther");
return CompletableFuture.completedFuture(false);
} else if (!owner && !available && !player.hasPermission("areashop.teleportfriend") && !toSign && friend) {
region.message(player, "teleport-noPermissionFriend");
return CompletableFuture.completedFuture(false);
} else if (available && !player.hasPermission("areashop.teleportavailable") && !toSign) {
region.message(player, "teleport-noPermissionAvailable");
return CompletableFuture.completedFuture(false);
} else if (owner && !available && !player.hasPermission("areashop.teleportsign") && toSign) {
region.message(player, "teleport-noPermissionSign");
return CompletableFuture.completedFuture(false);
} else if (!owner && !available && !player.hasPermission("areashop.teleportsignall") && toSign && !friend) {
region.message(player, "teleport-noPermissionOtherSign");
return CompletableFuture.completedFuture(false);
} else if (!owner && !available && !player.hasPermission("areashop.teleportfriendsign") && toSign && friend) {
region.message(player, "teleport-noPermissionFriendSign");
return CompletableFuture.completedFuture(false);
} else if (available && !player.hasPermission("areashop.teleportavailablesign") && toSign) {
region.message(player, "teleport-noPermissionAvailableSign");
return CompletableFuture.completedFuture(false);
}
}
// Get the starting location
Value<Boolean> toSignRef = new Value<>(toSign);
Location startLocation = feature.getStartLocation(player, toSignRef);
toSign = toSignRef.get();
boolean insideRegion;
if (toSign) {
insideRegion = region.getBooleanSetting("general.teleportToSignIntoRegion");
} else {
insideRegion = region.getBooleanSetting("general.teleportIntoRegion");
}
// Check locations starting from startLocation and then a cube that increases
// radius around that (until no block in the region is found at all cube sides)
ProtectedRegion worldguardRegion = region.getRegion();
final Function<double[], Boolean> regionContains = generateContainsFunction(worldguardRegion);
boolean blocksInRegion = worldguardRegion.contains(startLocation.getBlockX(), startLocation.getBlockY(), startLocation.getBlockZ());
if (!blocksInRegion && insideRegion) {
region.message(player, "teleport-blocked");
return CompletableFuture.completedFuture(false);
}
// Tracking of which sides to continue the search
final World world = region.getWorld();
BlockVector3 min = worldguardRegion.getMinimumPoint();
BlockVector3 max = worldguardRegion.getMaximumPoint();
final Collection<Chunk> collection = ConcurrentHashMap.newKeySet();
final List<CompletableFuture<Object>> futures = new ArrayList<>();
final Collection<int[]> coords = new HashSet<>();
for (int x = min.getX(); x < max.getX(); x += 16) {
for (int z = min.getZ(); z < max.getZ(); z += 16) {
coords.add(new int[]{x, z});
}
}
final CompletableFuture<?> schedulingFuture;
if (coords.size() < 128) {
schedulingFuture = Utils.runAsBatches(coords, 32,
coord -> futures.add(PaperLib.getChunkAtAsync(world, coord[0], coord[1]).thenApply(chunk -> {
chunk.setForceLoaded(true);
collection.add(chunk);
return chunk;
})), false);
} else {
schedulingFuture = null;
}
final CompletableFuture<Boolean> future = new CompletableFuture<>();
final boolean finalToSign = toSign;
final Runnable task = () -> {
blocksInRegionCopy = blocksInRegion;
int safeY = startLocation.getBlockY();
int safeX = startLocation.getBlockX();
int safeZ = startLocation.getBlockZ();
final Location temp = new Location(world, 0, 0, 0);
// Tries limit tracking
int maxTries = plugin.getConfig().getInt("maximumTries");
// Tracking of which sides to continue the search
try {
this.done = Bukkit.getScheduler().callSyncMethod(plugin, () -> TeleportFeature.isSafe(startLocation)).get(5, TimeUnit.SECONDS);
} catch (ExecutionException | InterruptedException | TimeoutException ex) {
ex.printStackTrace();
this.done = false;
}
Utils.newChain().async(() -> {
while ((blocksInRegionCopy || !insideRegion) && !done) {
blocksInRegionCopy = false;
// North side
continueThisDirection = false;
temp.setX(-radius + 1);
temp.setY(-radius + 1);
temp.setZ(-radius);
for (int x = -radius + 1; x <= radius && !done && !northDone; x++) {
for (int y = -radius + 1; y < radius && !done; y++) {
if (y + safeY > 256 || y + safeY < 0) {
continue;
}
if (!insideRegion || regionContains.apply(new double[]{x + safeX, y + safeY, safeZ - radius})) {
checked++;
try {
this.done = checked > maxTries || Bukkit.getScheduler().callSyncMethod(plugin, () -> TeleportFeature.isSafe(temp)).get(5, TimeUnit.SECONDS);
} catch (ExecutionException | InterruptedException | TimeoutException ex) {
ex.printStackTrace();
this.done = false;
}
blocksInRegionCopy = true;
continueThisDirection = true;
}
temp.add(0, 1, 0);
}
temp.add(1, 0, 0);
}
northDone = northDone || !continueThisDirection;
}
}).abortIf((var0) -> done).async(() -> {
// South side
continueThisDirection = false;
temp.setX(radius - 1);
temp.setY(-radius + 1);
temp.setZ(-radius);
for (int x = radius - 1; x >= -radius && !done && !southDone; x--) {
for (int y = -radius + 1; y < radius && !done; y++) {
if (y + safeY > 256 || y + safeY < 0) {
continue;
}
if (!insideRegion || regionContains.apply(new double[]{safeX + x, safeY + y, safeZ - radius})) {
checked++;
try {
this.done = checked > maxTries || Bukkit.getScheduler().callSyncMethod(plugin, () -> TeleportFeature.isSafe(temp)).get(5, TimeUnit.SECONDS);
} catch (ExecutionException | InterruptedException | TimeoutException ex) {
ex.printStackTrace();
this.done = false;
}
blocksInRegionCopy = true;
continueThisDirection = true;
}
temp.add(0, 1, 0);
}
temp.add(-1, 0, 0);
}
southDone = southDone || !continueThisDirection;
}).abortIf((var0) -> done).async(() -> {
// East side
continueThisDirection = false;
temp.setX(-radius + 1);
temp.setY(-radius + 1);
temp.setZ(0);
for (int z = -radius + 1; z <= radius && !done && !eastDone; z++) {
for (int y = -radius + 1; y < radius && !done; y++) {
if (y + safeY > 256 || y + safeY < 0) {
continue;
}
if (!insideRegion || regionContains.apply(new double[]{safeX + radius, y + safeY, z + safeZ})) {
checked++;
try {
this.done = checked > maxTries || Bukkit.getScheduler().callSyncMethod(plugin, () -> TeleportFeature.isSafe(temp)).get(5, TimeUnit.SECONDS);
} catch (ExecutionException | InterruptedException | TimeoutException ex) {
ex.printStackTrace();
this.done = false;
}
blocksInRegionCopy = true;
continueThisDirection = true;
}
temp.add(0, 1, 0);
}
temp.add(0, 0, 1);
}
eastDone = eastDone || !continueThisDirection;
}).abortIf((var0) -> done).async(() -> {
// West side
continueThisDirection = false;
temp.setX(-radius);
temp.setY(-radius);
temp.setZ(radius - 1);
for (int z = radius - 1; z >= -radius && !done && !westDone; z--) {
for (int y = -radius + 1; y < radius && !done; y++) {
if (y + safeY > 256 || y + safeY < 0) {
continue;
}
if (!insideRegion || regionContains.apply(new double[]{safeX - radius, safeY + y, safeZ + z})) {
checked++;
try {
this.done = checked > maxTries || Bukkit.getScheduler().callSyncMethod(plugin, () -> TeleportFeature.isSafe(temp)).get(5, TimeUnit.SECONDS);
} catch (ExecutionException | InterruptedException | TimeoutException ex) {
ex.printStackTrace();
this.done = false;
}
blocksInRegionCopy = true;
continueThisDirection = true;
}
temp.add(0, 1, 0);
}
temp.add(0, 0, -1);
}
westDone = westDone || !continueThisDirection;
}).abortIf((var0) -> done).async(() -> {
// Top side
continueThisDirection = false;
// Middle block of the top
if ((safeY + radius) > 256) {
topDone = true;
}
if (!done && !topDone) {
temp.setX(0);
temp.setY(radius);
temp.setZ(0);
if (!insideRegion || regionContains.apply(new double[]{safeX, safeY + radius, safeZ})) {
checked++;
try {
this.done = checked > maxTries || Bukkit.getScheduler().callSyncMethod(plugin, () -> TeleportFeature.isSafe(temp)).get(5, TimeUnit.SECONDS);
} catch (ExecutionException | InterruptedException | TimeoutException ex) {
ex.printStackTrace();
this.done = false;
}
blocksInRegionCopy = true;
continueThisDirection = true;
}
}
temp.setY(radius);
for (int r = 1; r <= radius && !done && !topDone; r++) {
temp.setX(-r + 1);
temp.setZ(-r);
for (int x = -r + 1; x <= r && !done; x++) {
if (!insideRegion || regionContains.apply(new double[]{safeX + x, safeY + radius, safeZ - r})) {
checked++;
try {
this.done = checked > maxTries || Bukkit.getScheduler().callSyncMethod(plugin, () -> TeleportFeature.isSafe(temp)).get(5, TimeUnit.SECONDS);
} catch (ExecutionException | InterruptedException | TimeoutException ex) {
ex.printStackTrace();
this.done = false;
}
blocksInRegionCopy = true;
continueThisDirection = true;
}
temp.add(1, 0, 0);
}
// East
temp.setX(r);
temp.setZ(-r + 1);
for (int z = -r + 1; z <= r && !done; z++) {
if (!insideRegion || regionContains.apply(new double[]{safeX + r, safeY + radius, safeZ + z})) {
checked++;
try {
this.done = checked > maxTries || Bukkit.getScheduler().callSyncMethod(plugin, () -> TeleportFeature.isSafe(temp)).get(5, TimeUnit.SECONDS);
} catch (ExecutionException | InterruptedException | TimeoutException ex) {
ex.printStackTrace();
this.done = false;
}
blocksInRegionCopy = true;
continueThisDirection = true;
}
temp.add(0, 0, z);
}
// South side
temp.setX(r - 1);
temp.setZ(r);
for (int x = r - 1; x >= -r && !done; x--) {
if (!insideRegion || regionContains.apply(new double[]{safeX + x, safeY + radius, safeZ + r})) {
checked++;
try {
this.done = checked > maxTries || Bukkit.getScheduler().callSyncMethod(plugin, () -> TeleportFeature.isSafe(temp)).get(5, TimeUnit.SECONDS);
} catch (ExecutionException | InterruptedException | TimeoutException ex) {
ex.printStackTrace();
this.done = false;
}
blocksInRegionCopy = true;
continueThisDirection = true;
}
temp.add(-1, 0, 0);
}
// West side
temp.setX(-r);
temp.setZ(r - 1);
for (int z = r - 1; z >= -r && !done; z--) {
if (!insideRegion || regionContains.apply(new double[]{safeX - r, safeY + radius, safeZ + z})) {
checked++;
try {
this.done = checked > maxTries || Bukkit.getScheduler().callSyncMethod(plugin, () -> TeleportFeature.isSafe(temp)).get(5, TimeUnit.SECONDS);
} catch (ExecutionException | InterruptedException | TimeoutException ex) {
ex.printStackTrace();
this.done = false;
}
blocksInRegionCopy = true;
continueThisDirection = true;
}
temp.add(0, 0, -1);
}
}
topDone = topDone || !continueThisDirection;
}).abortIf(var0 -> done).async(() -> {
// Bottom side
continueThisDirection = false;
// Middle block of the bottom
if (safeY - radius < 0) {
bottomDone = true;
}
if (!done && !bottomDone) {
temp.setX(0);
temp.setY(-radius);
temp.setZ(0);
if (!insideRegion || regionContains.apply(new double[]{safeX, safeY - radius, safeZ})) {
checked++;
try {
this.done = checked > maxTries || Bukkit.getScheduler().callSyncMethod(plugin, () -> TeleportFeature.isSafe(temp)).get(5, TimeUnit.SECONDS);
} catch (ExecutionException | InterruptedException | TimeoutException ex) {
ex.printStackTrace();
this.done = false;
}
blocksInRegionCopy = true;
continueThisDirection = true;
}
}
temp.setY(-radius);
for (int r = 1; r <= radius && !done && !bottomDone; r++) {
// North
temp.setX(-r + 1);
temp.setZ(-r);
for (int x = -r + 1; x <= r && !done; x++) {
if (!insideRegion || regionContains.apply(new double[]{safeX + x, safeY - radius, safeZ - r})) {
checked++;
try {
this.done = checked > maxTries || Bukkit.getScheduler().callSyncMethod(plugin, () -> TeleportFeature.isSafe(temp)).get(5, TimeUnit.SECONDS);
} catch (ExecutionException | InterruptedException | TimeoutException ex) {
ex.printStackTrace();
this.done = false;
}
blocksInRegionCopy = true;
continueThisDirection = true;
}
temp.add(1, 0, 0);
}
// East
temp.setX(0);
temp.setZ(-r + 1);
for (int z = -r + 1; z <= r && !done; z++) {
if (!insideRegion || regionContains.apply(new double[]{safeX + r, safeY - radius, safeZ + z})) {
checked++;
try {
this.done = checked > maxTries || Bukkit.getScheduler().callSyncMethod(plugin, () -> TeleportFeature.isSafe(temp)).get(5, TimeUnit.SECONDS);
} catch (ExecutionException | InterruptedException | TimeoutException ex) {
ex.printStackTrace();
this.done = false;
}
blocksInRegionCopy = true;
continueThisDirection = true;
}
temp.add(0, 0, 1);
}
// South side
temp.setX(r - 1);
temp.setZ(r);
for (int x = r - 1; x >= -r && !done; x--) {
if (!insideRegion || regionContains.apply(new double[]{safeX + x, safeY - radius, safeZ + r})) {
checked++;
try {
this.done = checked > maxTries || Bukkit.getScheduler().callSyncMethod(plugin, () -> TeleportFeature.isSafe(temp)).get(5, TimeUnit.SECONDS);
} catch (ExecutionException | InterruptedException | TimeoutException ex) {
ex.printStackTrace();
this.done = false;
}
blocksInRegionCopy = true;
continueThisDirection = true;
}
temp.add(-1, 0, 0);
}
// West side
temp.setX(-r);
temp.setZ(r - 1);
for (int z = r - 1; z >= -r && !done; z--) {
if (!insideRegion || regionContains.apply(new double[]{safeX - r, safeY - radius, safeZ + z})) {
checked++;
try {
this.done = checked > maxTries || Bukkit.getScheduler().callSyncMethod(plugin, () -> TeleportFeature.isSafe(temp)).get(5, TimeUnit.SECONDS);
} catch (ExecutionException | InterruptedException | TimeoutException ex) {
ex.printStackTrace();
this.done = false;
}
blocksInRegionCopy = true;
continueThisDirection = true;
}
temp.add(0, 0, -1);
}
}
bottomDone = bottomDone || !continueThisDirection;
// Increase cube radius
radius++;
startLocation.add(temp);
}).execute(() -> Bukkit.getScheduler().runTask(plugin, () -> {
if (done && TeleportFeature.isSafe(startLocation)) {
if (finalToSign) {
region.message(player, "teleport-successSign");
// Let the player look at the sign
Vector playerVector = startLocation.toVector();
playerVector.setY(playerVector.getY() + player.getEyeHeight(true));
Vector signVector = region.getSignsFeature().getSigns().get(0).getLocation().toVector().add(new Vector(0.5, 0.5, 0.5));
Vector direction = playerVector.clone().subtract(signVector).normalize();
startLocation.setYaw(180 - (float) Math.toDegrees(Math.atan2(direction.getX(), direction.getZ())));
startLocation.setPitch(90 - (float) Math.toDegrees(Math.acos(direction.getY())));
} else {
region.message(player, "teleport-success");
}
AreaShop.debug("Found location: " + startLocation.toString() + " Tries: " + checked);
PaperLib.teleportAsync(player, startLocation).thenAccept(future::complete);
} else {
region.message(player, "teleport-noSafe", checked, maxTries);
AreaShop.debug("No location found, checked " + checked + " spots of max " + maxTries);
future.complete(false);
}
}));
};
// Start notifying the player, the one issue is that checked/max is 0 is if chunk loading takes up >= ~3s
doNotifications(player.getUniqueId());
TaskChain<?> chain = Utils.newChain();
if (schedulingFuture != null) {
// If there aren't too many chunks, pre-load them. Max will take 10 ticks ~ 500-600ms
chain = chain.asyncFirstFuture(() -> schedulingFuture).asyncFutures((unused) -> futures);
}
// Run the calculation task async
chain.async(task::run).execute();
// Don't keep chunks force-loaded once the teleportation has been completed.
return future.thenApply((unused0) -> {
for (Chunk chunk : collection) {
chunk.setForceLoaded(false); // Should be fine to call async(?)
}
running = false;
return unused0;
});
}
/**
* Get the task which notifies player of teleport progress.
*
* @return Returns the task, may be null.
*/
public BukkitTask getNotifierTask() {
return notifierTask;
}
private void doNotifications(final UUID player0) {
final int maxTries = plugin.getConfig().getInt("maximumTries");
this.notifierTask = new BukkitRunnable() {
@Override
public void run() {
final Player player = Bukkit.getPlayer(player0);
if (TeleportJob.this.done || player == null) {
this.cancel();
TeleportJob.this.notifierTask = null;
return;
}
region.message(player, "teleport-calculation-progress", "%done%", String.valueOf(checked), "%max%", String.valueOf(maxTries));
}
}.runTaskTimer(plugin, Utils.millisToTicks(3000), Utils.millisToTicks(3000));
}
}
@@ -5,7 +5,6 @@ import me.wiefferink.areashop.regions.BuyRegion;
import me.wiefferink.areashop.regions.GeneralRegion;
import me.wiefferink.areashop.regions.RentRegion;
import me.wiefferink.areashop.tools.Utils;
import me.wiefferink.bukkitdo.Do;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
@@ -22,112 +21,109 @@ import java.util.List;
* Notify region expiry and track activity time.
*/
public final class PlayerLoginLogoutListener implements Listener {
private final AreaShop plugin;
private final AreaShop plugin;
/**
* Constructor.
* @param plugin The AreaShop plugin
*/
public PlayerLoginLogoutListener(AreaShop plugin) {
this.plugin = plugin;
}
/**
* Constructor.
*
* @param plugin The AreaShop plugin
*/
public PlayerLoginLogoutListener(AreaShop plugin) {
this.plugin = plugin;
}
/**
* Called when a sign is changed.
* @param event The event
*/
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerLogin(PlayerLoginEvent event) {
if(event.getResult() != Result.ALLOWED) {
return;
}
final Player player = event.getPlayer();
/**
* Called when a sign is changed.
*
* @param event The event
*/
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerLogin(PlayerLoginEvent event) {
if (event.getResult() != Result.ALLOWED) {
return;
}
final Player player = event.getPlayer();
// Schedule task to check for notifications, prevents a lag spike at login
Do.syncTimerLater(25, 25, () -> {
// Delay until all regions are loaded
if(!plugin.isReady()) {
return true;
}
if(!player.isOnline()) {
return false;
}
// Notify for rents that almost run out
for(RentRegion region : plugin.getFileManager().getRents()) {
if(region.isRenter(player)) {
String warningSetting = region.getStringSetting("rent.warningOnLoginTime");
if(warningSetting == null || warningSetting.isEmpty()) {
continue;
}
long warningTime = Utils.durationStringToLong(warningSetting);
if(region.getTimeLeft() < warningTime) {
// Send the warning message later to let it appear after general MOTD messages
AreaShop.getInstance().message(player, "rent-expireWarning", region);
}
}
}
// Schedule task to check for notifications, prevents a lag spike at login
Utils.runCancellingTaskTimer(() -> {
// Delay until all regions are loaded
if (!plugin.isReady()) {
return true;
}
if (!player.isOnline()) {
return false;
}
// Notify for rents that almost run out
for (RentRegion region : plugin.getFileManager().getRents()) {
if (region.isRenter(player)) {
String warningSetting = region.getStringSetting("rent.warningOnLoginTime");
if (warningSetting == null || warningSetting.isEmpty()) {
continue;
}
long warningTime = Utils.durationStringToLong(warningSetting);
if (region.getTimeLeft() < warningTime) {
// Send the warning message later to let it appear after general MOTD messages
AreaShop.getInstance().message(player, "rent-expireWarning", region);
}
}
}
// Notify admins for plugin updates
AreaShop.getInstance().notifyUpdate(player);
return false;
});
// Notify admins for plugin updates
AreaShop.getInstance().notifyUpdate(player);
return false;
}, 25, 25, false);
// Check if the player has regions that use an old name of him and update them
Do.syncTimerLater(22, 10, () -> {
if(!plugin.isReady()) {
return true;
}
// Check if the player has regions that use an old name of him and update them
Utils.runCancellingTaskTimer(() -> {
if (!plugin.isReady()) {
return true;
}
List<GeneralRegion> regions = new ArrayList<>();
for(GeneralRegion region : plugin.getFileManager().getRegions()) {
if(region.isOwner(player)) {
regions.add(region);
}
}
List<GeneralRegion> regions = new ArrayList<>();
for (GeneralRegion region : plugin.getFileManager().getRegions()) {
if (region.isOwner(player)) {
regions.add(region);
}
}
final String name = player.getName();
Utils.runAsBatches(regions,
plugin.getConfig().getInt("nameupdate.regionsPerTick"),
(region) -> {
if (region instanceof BuyRegion || region instanceof RentRegion) {
String key = region instanceof BuyRegion ? "buy.buyerName" : "rent.renterName";
if (!name.equals(region.getStringSetting("buy.buyerName"))) {
region.setSetting(key, player.getName());
region.update();
}
}
}, false);
return false;
}, 22, 10, false);
}
Do.forAll(
plugin.getConfig().getInt("nameupdate.regionsPerTick"),
regions,
region -> {
if(region instanceof BuyRegion) {
if(!player.getName().equals(region.getStringSetting("buy.buyerName"))) {
region.setSetting("buy.buyerName", player.getName());
region.update();
}
} else if(region instanceof RentRegion) {
if(!player.getName().equals(region.getStringSetting("rent.renterName"))) {
region.setSetting("rent.renterName", player.getName());
region.update();
}
}
}
);
return false;
});
}
// Active time updates
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerLogout(PlayerQuitEvent event) {
updateLastActive(event.getPlayer());
}
// Active time updates
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerLogout(PlayerQuitEvent event) {
updateLastActive(event.getPlayer());
}
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerKick(PlayerKickEvent event) {
updateLastActive(event.getPlayer());
}
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerKick(PlayerKickEvent event) {
updateLastActive(event.getPlayer());
}
/**
* Update the last active time for all regions the player is owner off.
* @param player The player to update the active times for
*/
private void updateLastActive(Player player) {
for(GeneralRegion region : plugin.getFileManager().getRegions()) {
if(region.isOwner(player)) {
region.updateLastActiveTime();
}
}
}
/**
* Update the last active time for all regions the player is owner off.
*
* @param player The player to update the active times for
*/
private void updateLastActive(Player player) {
for (GeneralRegion region : plugin.getFileManager().getRegions()) {
if (region.isOwner(player)) {
region.updateLastActiveTime();
}
}
}
}
@@ -39,19 +39,15 @@ import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
import java.util.ArrayList;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.*;
public class CommandManager extends Manager implements CommandExecutor, TabCompleter {
private final ArrayList<CommandAreaShop> commands;
private final List<CommandAreaShop> commands = new ArrayList<>();
/**
* Constructor.
*/
public CommandManager() {
commands = new ArrayList<>();
commands.add(new HelpCommand());
commands.add(new RentCommand());
commands.add(new UnrentCommand());
@@ -96,7 +92,8 @@ public class CommandManager extends Manager implements CommandExecutor, TabCompl
* @return The list with AreaShop commands
*/
public List<CommandAreaShop> getCommands() {
return commands;
// Return a cloned array
return new ArrayList<>(commands);
}
/**
@@ -109,7 +106,7 @@ public class CommandManager extends Manager implements CommandExecutor, TabCompl
return;
}
// Add all messages to a list
ArrayList<String> messages = new ArrayList<>();
List<String> messages = new ArrayList<>(commands.size());
plugin.message(target, "help-header");
plugin.message(target, "help-alias");
for(CommandAreaShop command : commands) {
@@ -132,18 +129,21 @@ public class CommandManager extends Manager implements CommandExecutor, TabCompl
}
// Redirect `/as info player <player>` to `/as me <player>`
if(args.length == 3 && "info".equals(args[0]) && "player".equals(args[1])) {
if(args.length == 3 && "info".equalsIgnoreCase(args[0]) && "player".equalsIgnoreCase(args[1])) {
args[0] = "me";
args[1] = args[2];
}
// Execute command
boolean executed = false;
for(int i = 0; i < commands.size() && !executed; i++) {
if(commands.get(i).canExecute(command, args)) {
commands.get(i).execute(sender, args);
for (final CommandAreaShop cmd : commands) {
if (cmd.canExecute(command, args)) {
cmd.execute(sender, args);
executed = true;
// Can't have two commands with same label
break;
}
}
// Show help
@@ -165,10 +165,10 @@ public class CommandManager extends Manager implements CommandExecutor, TabCompl
@Override
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
List<String> result = new ArrayList<>();
if(!sender.hasPermission("areashop.tabcomplete")) {
return result;
return Collections.emptyList();
}
List<String> result = new ArrayList<>();
int toCompleteNumber = args.length;
String toCompletePrefix = args[args.length - 1].toLowerCase();
//AreaShop.debug("toCompleteNumber=" + toCompleteNumber + ", toCompletePrefix=" + toCompletePrefix + ", length=" + toCompletePrefix.length());
@@ -184,6 +184,7 @@ public class CommandManager extends Manager implements CommandExecutor, TabCompl
for(CommandAreaShop c : commands) {
if(c.canExecute(command, args)) {
result = c.getTabCompleteList(toCompleteNumber, start, sender);
break;
}
}
}
@@ -195,8 +196,7 @@ public class CommandManager extends Manager implements CommandExecutor, TabCompl
set.add(suggestion);
}
}
result.clear();
result.addAll(set);
return new ArrayList<>(set);
}
//AreaShop.debug("Tabcomplete #" + toCompleteNumber + ", prefix="+ toCompletePrefix + ", result=" + result.toString());
return result;
@@ -5,7 +5,7 @@ import me.wiefferink.areashop.features.CommandsFeature;
import me.wiefferink.areashop.features.DebugFeature;
import me.wiefferink.areashop.features.FriendsFeature;
import me.wiefferink.areashop.features.RegionFeature;
import me.wiefferink.areashop.features.TeleportFeature;
import me.wiefferink.areashop.features.teleport.TeleportFeature;
import me.wiefferink.areashop.features.WorldGuardRegionFlagsFeature;
import me.wiefferink.areashop.features.signs.SignsFeature;
import me.wiefferink.areashop.regions.GeneralRegion;
@@ -57,7 +57,7 @@ public class FeatureManager extends Manager {
for(Class<? extends RegionFeature> clazz : featureClasses) {
try {
regionFeatureConstructors.put(clazz, clazz.getConstructor(GeneralRegion.class));
} catch(NoSuchMethodException | IllegalArgumentException e) {
} catch(NoSuchMethodException | IllegalArgumentException ignored) {
// The feature does not have a region specific part
}
}
@@ -71,7 +71,7 @@ public class FeatureManager extends Manager {
}
/**
* Instanciate a feature for a certain region.
* Instantiate a feature for a certain region.
* @param region The region to create a feature for
* @param featureClazz The class of the feature to create
* @return The feature class
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,79 @@
package me.wiefferink.areashop.managers;
import me.wiefferink.areashop.AreaShop;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
import java.sql.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.StringJoiner;
import java.util.concurrent.atomic.AtomicBoolean;
public class SignErrorLogger {
public static final String PREFIX_WARN = "[Warning] [Sign Feature] ";
public static final DateFormat FORMAT = new SimpleDateFormat("MM/dd/yy HH:mm:ss");
private final List<String> cache = new LinkedList<>();
private final AtomicBoolean needsSaving = new AtomicBoolean(false);
private final File file;
public SignErrorLogger(File file) {
this.file = Objects.requireNonNull(file);
}
public void clearCache() {
synchronized (this.cache) {
this.cache.clear();
}
}
public SignErrorLogger submitWarning(String message) {
final String actual = FORMAT.format(Date.from(Instant.now())) + PREFIX_WARN + message;
synchronized (this.cache) {
this.cache.add(actual);
}
return this;
}
public void queueSave() {
this.needsSaving.set(true);
}
public void saveIfDirty() {
if (this.needsSaving.get()) {
save();
}
}
public synchronized void save() {
AreaShop.debugTask("[Sign Feature] Dumping sign errors to disk...");
final String[] copy;
synchronized (this.cache) {
copy = cache.toArray(new String[0]);
}
final StringJoiner joiner = new StringJoiner(System.lineSeparator());
for (String s : copy) {
joiner.add(s);
}
try (OutputStream os = new FileOutputStream(file);
OutputStreamWriter writer = new OutputStreamWriter(os, StandardCharsets.UTF_8)) {
writer.write(joiner.toString());
} catch (IOException ex) {
ex.printStackTrace();
AreaShop.error("Failed to update the sign error log!");
} finally {
AreaShop.debugTask("[Sign Feature] Error dump complete.");
}
}
}
@@ -10,6 +10,9 @@ import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.type.Sign;
import org.bukkit.block.data.type.WallSign;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
@@ -39,7 +42,7 @@ public class SignLinkerManager extends Manager implements Listener {
@Override
public void shutdown() {
for(UUID uuid : signLinkers.keySet()) {
exitSignLinkMode(Bukkit.getPlayer(uuid));
exitSignLinkMode(uuid);
}
}
@@ -71,6 +74,18 @@ public class SignLinkerManager extends Manager implements Listener {
plugin.message(player, "linksigns-stopped");
}
private void exitSignLinkMode(UUID player) {
signLinkers.remove(player);
if(eventsRegistered && signLinkers.isEmpty()) {
eventsRegistered = false;
HandlerList.unregisterAll(this);
}
final Player online = Bukkit.getPlayer(player);
if (online != null) {
plugin.message(player, "linksigns-stopped");
}
}
/**
* Check if the player is in sign linking mode.
* @param player The player to check
@@ -130,7 +145,16 @@ public class SignLinkerManager extends Manager implements Listener {
plugin.message(player, "linksigns-alreadyRegistered", regionSign.getRegion());
return;
}
linker.setSign(block.getLocation(), block.getType(), plugin.getBukkitHandler().getSignFacing(block));
final BlockData blockData = block.getBlockData();
final BlockFace rotation;
if (blockData instanceof Sign) {
rotation = ((Sign) blockData).getRotation();
} else if (blockData instanceof WallSign) {
rotation = ((WallSign) blockData).getFacing();
} else {
rotation = null;
}
linker.setSign(block.getLocation(), block.getType(), rotation);
}
}
}
@@ -551,10 +551,11 @@ public class BuyRegion extends GeneralRegion {
return false;
}
long lastPlayed = getLastActiveTime();
long now = System.currentTimeMillis();
//AreaShop.debug("currentTime=" + Calendar.getInstance().getTimeInMillis() + ", getLastPlayed()=" + lastPlayed + ", timeInactive=" + (Calendar.getInstance().getTimeInMillis()-player.getLastPlayed()) + ", inactiveSetting=" + inactiveSetting);
if(Calendar.getInstance().getTimeInMillis() > (lastPlayed + inactiveSetting)) {
if(now > (lastPlayed + inactiveSetting)) {
AreaShop.info("Region " + getName() + " unrented because of inactivity for player " + getPlayerName());
AreaShop.debug("currentTime=" + Calendar.getInstance().getTimeInMillis() + ", getLastPlayed()=" + lastPlayed + ", timeInactive=" + (Calendar.getInstance().getTimeInMillis() - player.getLastPlayed()) + ", inactiveSetting=" + inactiveSetting);
AreaShop.debug("currentTime=" + now + ", getLastPlayed()=" + lastPlayed + ", timeInactive=" + (now - player.getLastPlayed()) + ", inactiveSetting=" + inactiveSetting);
return this.sell(true, null);
}
return false;
@@ -1,5 +1,6 @@
package me.wiefferink.areashop.regions;
import co.aikar.taskchain.TaskChain;
import com.sk89q.worldguard.protection.regions.ProtectedPolygonalRegion;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import me.wiefferink.areashop.AreaShop;
@@ -7,12 +8,11 @@ import me.wiefferink.areashop.events.NotifyRegionEvent;
import me.wiefferink.areashop.events.notify.UpdateRegionEvent;
import me.wiefferink.areashop.features.FriendsFeature;
import me.wiefferink.areashop.features.RegionFeature;
import me.wiefferink.areashop.features.TeleportFeature;
import me.wiefferink.areashop.features.teleport.TeleportFeature;
import me.wiefferink.areashop.features.signs.SignsFeature;
import me.wiefferink.areashop.interfaces.GeneralRegionInterface;
import me.wiefferink.areashop.managers.FileManager;
import me.wiefferink.areashop.tools.Utils;
import me.wiefferink.bukkitdo.Do;
import me.wiefferink.interactivemessenger.processing.Message;
import me.wiefferink.interactivemessenger.processing.ReplacementProvider;
import org.apache.commons.lang.exception.ExceptionUtils;
@@ -23,6 +23,7 @@ import org.bukkit.World;
import org.bukkit.command.CommandException;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
@@ -38,6 +39,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
public abstract class GeneralRegion implements GeneralRegionInterface, Comparable<GeneralRegion>, ReplacementProvider {
static final AreaShop plugin = AreaShop.getInstance();
@@ -187,12 +189,7 @@ public abstract class GeneralRegion implements GeneralRegionInterface, Comparabl
* @return The feature (either just instantiated or cached)
*/
public <T extends RegionFeature> T getFeature(Class<T> clazz) {
RegionFeature result = features.get(clazz);
if(result == null) {
result = plugin.getFeatureManager().getRegionFeature(this, clazz);
features.put(clazz, result);
}
return clazz.cast(result);
return clazz.cast(features.computeIfAbsent(clazz, (unused) -> plugin.getFeatureManager().getRegionFeature(this, clazz)));
}
/**
@@ -448,7 +445,7 @@ public abstract class GeneralRegion implements GeneralRegionInterface, Comparabl
if(landlordName != null && !landlordName.isEmpty()) {
@SuppressWarnings("deprecation")
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(landlordName);
if(offlinePlayer != null) {
if(offlinePlayer.hasPlayedBefore()) {
return offlinePlayer.getUniqueId();
}
}
@@ -461,7 +458,7 @@ public abstract class GeneralRegion implements GeneralRegionInterface, Comparabl
*/
public String getLandlordName() {
String result = Utils.toName(getLandlord());
if(result == null || result.isEmpty()) {
if(result.isEmpty()) {
result = config.getString("general.landlordName");
if(result == null || result.isEmpty()) {
result = null;
@@ -480,7 +477,7 @@ public abstract class GeneralRegion implements GeneralRegionInterface, Comparabl
setSetting("general.landlord", landlord.toString());
}
String properName = Utils.toName(landlord);
if(properName == null) {
if(properName.isEmpty()) {
properName = name;
}
setSetting("general.landlordName", properName);
@@ -590,8 +587,11 @@ public abstract class GeneralRegion implements GeneralRegionInterface, Comparabl
*/
public List<String> getGroupNames() {
List<String> result = new ArrayList<>();
for(RegionGroup group : getGroups()) {
result.add(group.getName());
// Inline #getGroups
for(RegionGroup group : plugin.getFileManager().getGroups()) {
if(group.isMember(this)) {
result.add(group.getName());
}
}
return result;
}
@@ -779,6 +779,36 @@ public abstract class GeneralRegion implements GeneralRegionInterface, Comparabl
return true;
}
/**
* Save all blocks in a region for restoring later.
* @param fileName The name of the file to save to (extension and folder will be added)
* @return true if the region has been saved properly, otherwise false
*/
public CompletableFuture<Boolean> saveRegionBlocksAsync(String fileName) {
// Check if the region is correct
ProtectedRegion region = getRegion();
if(region == null) {
AreaShop.debug("Region '" + getName() + "' does not exist in WorldGuard, save failed");
return CompletableFuture.completedFuture(false);
}
// The path to save the schematic
File saveFile = new File(plugin.getFileManager().getSchematicFolder() + File.separator + fileName);
// Create parent directories
File parent = saveFile.getParentFile();
if(parent != null && !parent.exists()) {
if(!parent.mkdirs()) {
AreaShop.warn("Did not save region " + getName() + ", schematic directory could not be created: " + saveFile.getAbsolutePath());
return CompletableFuture.completedFuture(false);
}
}
return plugin.getWorldEditHandler().saveRegionBlocksAsync(saveFile, this).thenApply(result -> {
if(result) {
AreaShop.debug("Saved schematic for region " + getName());
}
return result;
});
}
/**
* Restore all blocks in a region for restoring later.
* @param fileName The name of the file to save to (extension and folder will be added)
@@ -796,11 +826,34 @@ public abstract class GeneralRegion implements GeneralRegionInterface, Comparabl
AreaShop.debug("Restored schematic for region " + getName());
// Workaround for signs inside the region in combination with async restore of plugins like AsyncWorldEdit and FastAsyncWorldEdit
Do.syncLater(10, getSignsFeature()::update);
Bukkit.getScheduler().runTaskLater(plugin, getSignsFeature()::update, 10);
}
return result;
}
/**
* Restore all blocks in a region for restoring later.
* @param fileName The name of the file to save to (extension and folder will be added)
* @return true if the region has been restored properly, otherwise false
*/
public CompletableFuture<Boolean> restoreRegionBlocksAsync(String fileName) {
if(getRegion() == null) {
AreaShop.debug("Region '" + getName() + "' does not exist in WorldGuard, restore failed");
return CompletableFuture.completedFuture(false);
}
// The path to save the schematic
File restoreFile = new File(plugin.getFileManager().getSchematicFolder() + File.separator + fileName);
return plugin.getWorldEditHandler().restoreRegionBlocksAsync(restoreFile, this).thenApply(result -> {
if(result) {
AreaShop.debug("Restored schematic for region " + getName());
// Workaround for signs inside the region in combination with async restore of plugins like AsyncWorldEdit and FastAsyncWorldEdit
Bukkit.getScheduler().runTaskLater(plugin, getSignsFeature()::update, 10);
}
return result;
});
}
/**
* Reset all flags of the region.
*/
@@ -845,6 +898,48 @@ public abstract class GeneralRegion implements GeneralRegionInterface, Comparabl
}
}
public CompletableFuture<Boolean> saveNowAsync() {
final YamlConfiguration clone = new YamlConfiguration();
final String fileName = plugin.getFileManager().getRegionFolder() + File.separator + getName().toLowerCase() + ".yml";
try {
clone.loadFromString(config.saveToString());
} catch (InvalidConfigurationException ex) {
ex.printStackTrace();
return CompletableFuture.completedFuture(false);
}
final CompletableFuture<Boolean> future = new CompletableFuture<>();
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
try {
clone.save(new File(fileName));
future.complete(true);
} catch (IOException ex) {
ex.printStackTrace();
future.complete(false);
}
});
return future;
}
public TaskChain<Boolean> saveNowAsync(final TaskChain<?> chain) {
final YamlConfiguration clone = new YamlConfiguration();
final String fileName = plugin.getFileManager().getRegionFolder() + File.separator + getName().toLowerCase() + ".yml";
try {
clone.loadFromString(config.saveToString());
} catch (InvalidConfigurationException ex) {
ex.printStackTrace();
return chain.sync((unused) -> false);
}
return chain.async((unused) -> {
try {
clone.save(new File(fileName));
return true;
} catch (IOException ex) {
ex.printStackTrace();
return false;
}
});
}
// CONFIG
@@ -1274,7 +1369,7 @@ public abstract class GeneralRegion implements GeneralRegionInterface, Comparabl
/**
* Class to store the result of a limits check.
*/
public class LimitResult {
public static class LimitResult {
private final boolean actionAllowed;
private final LimitType limitingFactor;
private final int maximum;
@@ -1389,8 +1484,8 @@ public abstract class GeneralRegion implements GeneralRegionInterface, Comparabl
public boolean matchesLimitGroup(String group) {
List<String> worlds = plugin.getConfig().getStringList("limitGroups." + group + ".worlds");
List<String> groups = plugin.getConfig().getStringList("limitGroups." + group + ".groups");
if((worlds == null || worlds.isEmpty() || worlds.contains(getWorldName()))) {
if(groups == null || groups.isEmpty()) {
if(worlds.isEmpty() || worlds.contains(getWorldName())) {
if(groups.isEmpty()) {
return true;
} else {
boolean inGroups = false;
@@ -1424,12 +1519,12 @@ public abstract class GeneralRegion implements GeneralRegionInterface, Comparabl
// Save the region if needed
if(save != null && !save.isEmpty()) {
save = Message.fromString(save).replacements(this).getSingle();
saveRegionBlocks(save);
saveRegionBlocksAsync(save);
}
// Restore the region if needed
if(restore != null && !restore.isEmpty()) {
restore = Message.fromString(restore).replacements(this).getSingle();
restoreRegionBlocks(restore);
restoreRegionBlocksAsync(restore);
}
}
@@ -721,10 +721,11 @@ public class RentRegion extends GeneralRegion {
return false;
}
long lastPlayed = getLastActiveTime();
final long now = System.currentTimeMillis();
//AreaShop.debug("currentTime=" + Calendar.getInstance().getTimeInMillis() + ", getLastPlayed()=" + lastPlayed + ", timeInactive=" + (Calendar.getInstance().getTimeInMillis()-player.getLastPlayed()) + ", inactiveSetting=" + inactiveSetting);
if(Calendar.getInstance().getTimeInMillis() > (lastPlayed + inactiveSetting)) {
if(now > (lastPlayed + inactiveSetting)) {
AreaShop.info("Region " + getName() + " unrented because of inactivity for player " + getPlayerName());
AreaShop.debug("currentTime=" + Calendar.getInstance().getTimeInMillis() + ", getLastPlayed()=" + lastPlayed + ", timeInactive=" + (Calendar.getInstance().getTimeInMillis() - player.getLastPlayed()) + ", inactiveSetting=" + inactiveSetting);
AreaShop.debug("currentTime=" + now + ", getLastPlayed()=" + lastPlayed + ", timeInactive=" + (now - player.getLastPlayed()) + ", inactiveSetting=" + inactiveSetting);
return this.unRent(true, null);
}
return false;
File diff suppressed because it is too large. Load diff
+1
View File
@@ -343,6 +343,7 @@ destroy-successRent: "%lang:region% successfully deregistered as rental region."
destroy-successBuy: "%lang:region% successfully deregistered as buy region."
teleport-help: "/as tp <region> [sign]."
teleport-calculation-progress: "Teleport in progress, finding safe location %done%/%max% scans complete."
teleport-noRentOrBuy: "The specified region is not registered: %0%."
teleport-noPermission: "You don't have permission to teleport to your region."
teleport-noPermissionOther: "You don't have permission to teleport to regions you do not own."
+1 -1
View File
@@ -1,6 +1,6 @@
name: AreaShop
main: me.wiefferink.areashop.AreaShop
version: "${project.version}${build.number}"
version: "${project.version}"
description: "Selling and renting WorldGuard regions to your players, highly configurable."
depend: [Vault, WorldGuard, WorldEdit]
softdepend: [Multiverse-Core, FastAsyncWorldEdit]
+5 -5
View File
@@ -64,11 +64,11 @@ For a preview join 'mc.go-craft.com' and go to the Survival server, the shops ar
Old video for AreaShop v1.0: [Tutorial by VariationVault](https://www.youtube.com/watch?v=k2HMCxCCOYo)
### Required dependencies
* Java 7 or higher (latest recommended)
* Bukkit/Spigot 1.7.9 or higher (modded servers often include Bukkit/Spigot support, so it should also work on that, but it is not specifically tested for it)
* [WorldGuard](http://dev.bukkit.org/bukkit-plugins/worldguard/): 5.9 or higher (6.0+ recommended)
* [WorldEdit](http://dev.bukkit.org/bukkit-plugins/worldedit/): 5.6.3 or higher (6.0+ recommended)
* [Vault](http://dev.bukkit.org/bukkit-plugins/vault/): 1.4.1 or higher
* Java 8 or higher (latest recommended)
* Bukkit/Spigot 1.13.2 or higher (modded servers often include Bukkit/Spigot support, so it should also work on that, but it is not specifically tested for it)
* [WorldGuard](http://dev.bukkit.org/bukkit-plugins/worldguard/): 7.0.3 or higher
* [WorldEdit](http://dev.bukkit.org/bukkit-plugins/worldedit/): 7.0.1 or higher
* [Vault](http://dev.bukkit.org/bukkit-plugins/vault/): 1.7 or higher
* An economy plugin supported by Vault (check the [Vault page](http://dev.bukkit.org/bukkit-plugins/vault/) for a list of these)
### Metrics
-33
View File
@@ -1,33 +0,0 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>areashop-bukkit-1_12</artifactId>
<packaging>jar</packaging>
<name>AreaShop Bukkit 1.7.9 until 1.12</name>
<version>latest</version>
<parent>
<groupId>me.wiefferink</groupId>
<artifactId>areashop-parent</artifactId>
<version>parent</version>
</parent>
<dependencies>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>craftbukkit</artifactId>
<scope>system</scope>
<version>any</version>
<systemPath>${project.basedir}/../dependencies/craftbukkit-1.7.9-R0.2-SNAPSHOT.jar</systemPath>
<type>jar</type>
<optional>true</optional>
</dependency>
<dependency>
<groupId>me.wiefferink</groupId>
<artifactId>areashop-interface</artifactId>
<version>latest</version>
<type>jar</type>
</dependency>
</dependencies>
</project>
@@ -1,76 +0,0 @@
package me.wiefferink.areashop.handlers;
import me.wiefferink.areashop.interfaces.AreaShopInterface;
import me.wiefferink.areashop.interfaces.BukkitInterface;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
import org.bukkit.material.MaterialData;
public class BukkitHandler1_12 extends BukkitInterface {
public BukkitHandler1_12(AreaShopInterface pluginInterface) {
super(pluginInterface);
}
// Uses Sign, which is deprecated in 1.13+, broken in 1.14+
@Override
public BlockFace getSignFacing(Block block) {
if (block == null) {
return null;
}
BlockState blockState = block.getState();
if (blockState == null) {
return null;
}
MaterialData materialData = blockState.getData();
if(materialData instanceof org.bukkit.material.Sign) {
return ((org.bukkit.material.Sign)materialData).getFacing();
}
return null;
}
@Override
public boolean setSignFacing(Block block, BlockFace facing) {
if (block == null || facing == null) {
return false;
}
BlockState blockState = block.getState();
if (blockState == null) {
return false;
}
org.bukkit.material.Sign signData = (org.bukkit.material.Sign) blockState.getData();
if (signData == null) {
return false;
}
signData.setFacingDirection(facing);
blockState.setData(signData);
blockState.update(true, true);
return true;
}
@Override
public Block getSignAttachedTo(Block block) {
if (block == null) {
return null;
}
BlockState blockState = block.getState();
if (blockState == null) {
return null;
}
org.bukkit.material.Sign signData = (org.bukkit.material.Sign) blockState.getData();
if (signData == null) {
return null;
}
return block.getRelative(signData.getAttachedFace());
}
}
-32
View File
@@ -1,32 +0,0 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>areashop-bukkit-1_13</artifactId>
<packaging>jar</packaging>
<name>AreaShop Bukkit 1.13 and higher</name>
<version>latest</version>
<parent>
<groupId>me.wiefferink</groupId>
<artifactId>areashop-parent</artifactId>
<version>parent</version>
</parent>
<dependencies>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>craftbukkit</artifactId>
<version>1.13-R0.1-SNAPSHOT</version>
<type>jar</type>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>me.wiefferink</groupId>
<artifactId>areashop-interface</artifactId>
<version>latest</version>
<type>jar</type>
</dependency>
</dependencies>
</project>
@@ -1,97 +0,0 @@
package me.wiefferink.areashop.handlers;
import me.wiefferink.areashop.interfaces.AreaShopInterface;
import me.wiefferink.areashop.interfaces.BukkitInterface;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.type.Sign;
import org.bukkit.block.data.type.WallSign;
public class BukkitHandler1_13 extends BukkitInterface {
public BukkitHandler1_13(AreaShopInterface pluginInterface) {
super(pluginInterface);
}
// Uses BlockData, which does not yet exist in 1.12-
@Override
public BlockFace getSignFacing(Block block) {
if (block == null) {
return null;
}
BlockState blockState = block.getState();
if (blockState == null) {
return null;
}
BlockData blockData = blockState.getBlockData();
if (blockData == null) {
return null;
}
if(blockData instanceof WallSign) {
return ((WallSign) blockData).getFacing();
} else if(blockData instanceof Sign) {
return ((Sign) blockData).getRotation();
}
return null;
}
// Uses BlockData, WallSign and Sign which don't exist in 1.12-
@Override
public boolean setSignFacing(Block block, BlockFace facing) {
if (block == null || facing == null) {
return false;
}
BlockState blockState = block.getState();
if (blockState == null) {
return false;
}
BlockData blockData = blockState.getBlockData();
if (blockData == null) {
return false;
}
if(blockData instanceof WallSign) {
((WallSign) blockData).setFacing(facing);
} else if(blockData instanceof Sign) {
((Sign) blockData).setRotation(facing);
} else {
return false;
}
block.setBlockData(blockData);
return true;
}
@Override
public Block getSignAttachedTo(Block block) {
if (block == null) {
return null;
}
BlockState blockState = block.getState();
if (blockState == null) {
return null;
}
org.bukkit.block.data.BlockData blockData = blockState.getBlockData();
if (blockData == null) {
return null;
}
if(blockData instanceof WallSign) {
return block.getRelative(((WallSign) blockData).getFacing().getOppositeFace());
} else if(blockData instanceof Sign) {
return block.getRelative(BlockFace.DOWN);
}
return null;
}
}
-47
View File
@@ -1,47 +0,0 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>areashop-fastasyncworldedit</artifactId>
<packaging>jar</packaging>
<name>AreaShop FastAsyncWorldEdit</name>
<version>latest</version>
<parent>
<groupId>me.wiefferink</groupId>
<artifactId>areashop-parent</artifactId>
<version>parent</version>
</parent>
<dependencies>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>craftbukkit</artifactId>
<version>1.13-R0.1-SNAPSHOT</version>
<type>jar</type>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.sk89q</groupId>
<artifactId>worldedit</artifactId>
<scope>system</scope>
<version>any</version>
<systemPath>${project.basedir}/../dependencies/FastAsyncWorldEdit-bukkit-1.13.132.jar</systemPath>
</dependency>
<dependency>
<groupId>com.sk89q</groupId>
<artifactId>worldguard</artifactId>
<scope>system</scope>
<version>any</version>
<systemPath>${project.basedir}/../dependencies/FastAsyncWorldEdit-worldguard-legacy-7.0.0-SNAPSHOT-dist.jar</systemPath>
</dependency>
<dependency>
<groupId>me.wiefferink</groupId>
<artifactId>areashop-interface</artifactId>
<version>latest</version>
<type>jar</type>
</dependency>
</dependencies>
</project>
@@ -1,193 +0,0 @@
package me.wiefferink.areashop.handlers;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.IncompleteRegionException;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardReader;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter;
import com.sk89q.worldedit.extent.transform.BlockTransformExtent;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.mask.Mask2D;
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.session.ClipboardHolder;
import com.sk89q.worldedit.util.io.Closer;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import com.sk89q.worldguard.protection.regions.RegionType;
import me.wiefferink.areashop.interfaces.AreaShopInterface;
import me.wiefferink.areashop.interfaces.GeneralRegionInterface;
import me.wiefferink.areashop.interfaces.WorldEditInterface;
import me.wiefferink.areashop.interfaces.WorldEditSelection;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.bukkit.entity.Player;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
// Future: this class could use the schematic save/paste api of FAWE: https://github.com/boy0001/FastAsyncWorldedit/wiki/Pasting-a-schematic
// This would not allow for shaping the schematic to a polygon region though
public class FastAsyncWorldEditHandler extends WorldEditInterface {
public FastAsyncWorldEditHandler(AreaShopInterface pluginInterface) {
super(pluginInterface);
}
@Override
public WorldEditSelection getPlayerSelection(Player player) {
try {
Region region = pluginInterface.getWorldEdit().getSession(player).getSelection(BukkitAdapter.adapt(player.getWorld()));
return new WorldEditSelection(
player.getWorld(),
BukkitAdapter.adapt(player.getWorld(), region.getMinimumPoint()),
BukkitAdapter.adapt(player.getWorld(), region.getMaximumPoint())
);
} catch (IncompleteRegionException e) {
return null;
}
}
@Override
public boolean restoreRegionBlocks(File rawFile, GeneralRegionInterface regionInterface) {
// TODO implement using the FastAsyncWorldEdit api to paste async
File file = null;
ClipboardFormat format = null;
for (ClipboardFormat formatOption : ClipboardFormat.values()) {
if (new File(rawFile.getAbsolutePath() + "." + formatOption.getExtension()).exists()) {
file = new File(rawFile.getAbsolutePath() + "." + formatOption.getExtension());
format = formatOption;
}
}
if(file == null) {
pluginInterface.getLogger().info("Did not restore region " + regionInterface.getName() + ", schematic file does not exist: " + rawFile.getAbsolutePath());
return false;
}
pluginInterface.debugI("Trying to restore region", regionInterface.getName(), " from file", file.getAbsolutePath(), "with format", format.name());
com.sk89q.worldedit.world.World world = null;
if(regionInterface.getName() != null) {
world = BukkitAdapter.adapt(regionInterface.getWorld());
}
if(world == null) {
pluginInterface.getLogger().info("Did not restore region " + regionInterface.getName() + ", world not found: " + regionInterface.getWorldName());
return false;
}
EditSession editSession = pluginInterface.getWorldEdit().getWorldEdit().getEditSessionFactory().getEditSession(world, pluginInterface.getConfig().getInt("maximumBlocks"));
editSession.enableQueue();
ProtectedRegion region = regionInterface.getRegion();
// Get the origin and size of the region
Vector origin = new Vector(region.getMinimumPoint().getBlockX(), region.getMinimumPoint().getBlockY(), region.getMinimumPoint().getBlockZ());
// Read the schematic and paste it into the world
try(Closer closer = Closer.create()) {
FileInputStream fis = closer.register(new FileInputStream(file));
BufferedInputStream bis = closer.register(new BufferedInputStream(fis));
ClipboardReader reader = format.getReader(bis);
LocalSession session = new LocalSession(pluginInterface.getWorldEdit().getLocalConfiguration());
Clipboard clipboard = reader.read();
if(clipboard.getDimensions().getY() != regionInterface.getHeight()
|| clipboard.getDimensions().getX() != regionInterface.getWidth()
|| clipboard.getDimensions().getZ() != regionInterface.getDepth()) {
pluginInterface.getLogger().warning("Size of the region " + regionInterface.getName() + " is not the same as the schematic to restore!");
pluginInterface.debugI("schematic|region, x:" + clipboard.getDimensions().getX() + "|" + regionInterface.getWidth() + ", y:" + clipboard.getDimensions().getY() + "|" + regionInterface.getHeight() + ", z:" + clipboard.getDimensions().getZ() + "|" + regionInterface.getDepth());
}
clipboard.setOrigin(clipboard.getMinimumPoint());
ClipboardHolder clipboardHolder = new ClipboardHolder(clipboard);
session.setBlockChangeLimit(pluginInterface.getConfig().getInt("maximumBlocks"));
session.setClipboard(clipboardHolder);
// Build operation
BlockTransformExtent extent = new BlockTransformExtent(clipboardHolder.getClipboard());
ForwardExtentCopy copy = new ForwardExtentCopy(extent, clipboard.getRegion(), clipboard.getOrigin(), editSession, origin);
copy.setTransform(clipboardHolder.getTransform());
// Mask to region (for polygon and other weird shaped regions)
// TODO make this more efficient (especially for polygon regions)
if(region.getType() != RegionType.CUBOID) {
copy.setSourceMask(new Mask() {
@Override
public boolean test(Vector vector) {
return region.contains(vector);
}
@Override
public Mask2D toMask2D() {
return null;
}
});
}
Operations.completeLegacy(copy);
} catch(MaxChangedBlocksException e) {
pluginInterface.getLogger().warning("exceeded the block limit while restoring schematic of " + regionInterface.getName() + ", limit in exception: " + e.getBlockLimit() + ", limit passed by AreaShop: " + pluginInterface.getConfig().getInt("maximumBlocks"));
return false;
} catch(IOException e) {
pluginInterface.getLogger().warning("An error occured while restoring schematic of " + regionInterface.getName() + ", enable debug to see the complete stacktrace");
pluginInterface.debugI(ExceptionUtils.getStackTrace(e));
return false;
} catch (Exception e) {
pluginInterface.getLogger().warning("crashed during restore of " + regionInterface.getName());
pluginInterface.debugI(ExceptionUtils.getStackTrace(e));
return false;
}
editSession.flushQueue();
return true;
}
@Override
public boolean saveRegionBlocks(File file, GeneralRegionInterface regionInterface) {
// TODO implement using the FastAsyncWorldEdit api to save async
ClipboardFormat format = ClipboardFormat.STRUCTURE;
// TODO allow selecting FAWE format in the config? (when enabled you cannot go back to vanilla WorldEdit easily)
file = new File(file.getAbsolutePath() + "." + format.getExtension());
pluginInterface.debugI("Trying to save region", regionInterface.getName(), " to file", file.getAbsolutePath(), "with format", format.name());
com.sk89q.worldedit.world.World world = null;
if(regionInterface.getWorld() != null) {
world = BukkitAdapter.adapt(regionInterface.getWorld());
}
if(world == null) {
pluginInterface.getLogger().warning("Did not save region " + regionInterface.getName() + ", world not found: " + regionInterface.getWorldName());
return false;
}
EditSession editSession = pluginInterface.getWorldEdit().getWorldEdit().getEditSessionFactory().getEditSession(world, pluginInterface.getConfig().getInt("maximumBlocks"));
// Create a clipboard
CuboidRegion selection = new CuboidRegion(world, regionInterface.getRegion().getMinimumPoint(), regionInterface.getRegion().getMaximumPoint());
BlockArrayClipboard clipboard = new BlockArrayClipboard(selection);
clipboard.setOrigin(regionInterface.getRegion().getMinimumPoint());
ForwardExtentCopy copy = new ForwardExtentCopy(editSession, new CuboidRegion(world, regionInterface.getRegion().getMinimumPoint(), regionInterface.getRegion().getMaximumPoint()), clipboard, regionInterface.getRegion().getMinimumPoint());
try {
Operations.completeLegacy(copy);
} catch(MaxChangedBlocksException e) {
pluginInterface.getLogger().warning("Exceeded the block limit while saving schematic of " + regionInterface.getName() + ", limit in exception: " + e.getBlockLimit() + ", limit passed by AreaShop: " + pluginInterface.getConfig().getInt("maximumBlocks"));
return false;
}
try(Closer closer = Closer.create()) {
FileOutputStream fos = closer.register(new FileOutputStream(file));
BufferedOutputStream bos = closer.register(new BufferedOutputStream(fos));
ClipboardWriter writer = closer.register(format.getWriter(bos));
writer.write(clipboard);
} catch(IOException e) {
pluginInterface.getLogger().warning("An error occured while saving schematic of " + regionInterface.getName() + ", enable debug to see the complete stacktrace");
pluginInterface.debugI(ExceptionUtils.getStackTrace(e));
return false;
} catch (Exception e) {
pluginInterface.getLogger().warning("Crashed during save of " + regionInterface.getName());
pluginInterface.debugI(ExceptionUtils.getStackTrace(e));
return false;
}
return true;
}
}
@@ -1,160 +0,0 @@
package me.wiefferink.areashop.handlers;
import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.BlockVector2D;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.domains.DefaultDomain;
import com.sk89q.worldguard.protection.flags.Flag;
import com.sk89q.worldguard.protection.flags.FlagContext;
import com.sk89q.worldguard.protection.flags.Flags;
import com.sk89q.worldguard.protection.flags.InvalidFlagFormat;
import com.sk89q.worldguard.protection.flags.RegionGroup;
import com.sk89q.worldguard.protection.flags.RegionGroupFlag;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import me.wiefferink.areashop.interfaces.AreaShopInterface;
import me.wiefferink.areashop.interfaces.RegionAccessSet;
import me.wiefferink.areashop.interfaces.WorldGuardInterface;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.util.Vector;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
public class FastAsyncWorldEditWorldGuardHandler extends WorldGuardInterface {
public FastAsyncWorldEditWorldGuardHandler(AreaShopInterface pluginInterface) {
super(pluginInterface);
}
@Override
public RegionManager getRegionManager(World world) {
return WorldGuard.getInstance().getPlatform().getRegionContainer().get(BukkitAdapter.adapt(world));
}
@Override
public Set<ProtectedRegion> getApplicableRegionsSet(Location location) {
Set<ProtectedRegion> result = new HashSet<>();
com.sk89q.worldedit.Vector vector = new com.sk89q.worldedit.Vector(location.getX(), location.getY(), location.getZ());
for(ProtectedRegion region : getRegionManager(location.getWorld()).getRegions().values()) {
if(region.contains(vector)) {
result.add(region);
}
}
return result;
}
/**
* Build a DefaultDomain from a RegionAccessSet.
* @param regionAccessSet RegionAccessSet to read
* @return DefaultDomain containing the entities from the RegionAccessSet
*/
private DefaultDomain buildDomain(RegionAccessSet regionAccessSet) {
DefaultDomain owners = new DefaultDomain();
for(String playerName : regionAccessSet.getPlayerNames()) {
owners.addPlayer(playerName);
}
for(UUID uuid : regionAccessSet.getPlayerUniqueIds()) {
owners.addPlayer(uuid);
}
for(String group : regionAccessSet.getGroupNames()) {
owners.addGroup(group);
}
return owners;
}
@Override
public void setOwners(ProtectedRegion region, RegionAccessSet regionAccessSet) {
DefaultDomain defaultDomain = buildDomain(regionAccessSet);
if(!region.getOwners().toUserFriendlyString().equals(defaultDomain.toUserFriendlyString())) {
region.setOwners(defaultDomain);
}
}
@Override
public void setMembers(ProtectedRegion region, RegionAccessSet regionAccessSet) {
DefaultDomain defaultDomain = buildDomain(regionAccessSet);
if(!region.getMembers().toUserFriendlyString().equals(defaultDomain.toUserFriendlyString())) {
region.setMembers(defaultDomain);
}
}
@Override
public boolean containsMember(ProtectedRegion region, UUID player) {
return region.getMembers().contains(player);
}
@Override
public boolean containsOwner(ProtectedRegion region, UUID player) {
return region.getOwners().contains(player);
}
@Override
public RegionAccessSet getMembers(ProtectedRegion region) {
RegionAccessSet result = new RegionAccessSet();
result.getGroupNames().addAll(region.getMembers().getGroups());
result.getPlayerNames().addAll(region.getMembers().getPlayers());
result.getPlayerUniqueIds().addAll(region.getMembers().getUniqueIds());
return result;
}
@Override
public RegionAccessSet getOwners(ProtectedRegion region) {
RegionAccessSet result = new RegionAccessSet();
result.getGroupNames().addAll(region.getOwners().getGroups());
result.getPlayerNames().addAll(region.getOwners().getPlayers());
result.getPlayerUniqueIds().addAll(region.getOwners().getUniqueIds());
return result;
}
@Override
public Flag<?> fuzzyMatchFlag(String flagName) {
return Flags.fuzzyMatchFlag(WorldGuard.getInstance().getFlagRegistry(), flagName);
}
@Override
public <V> V parseFlagInput(Flag<V> flag, String input) throws InvalidFlagFormat {
return flag.parseInput(FlagContext.create().setInput(input).build());
}
@Override
public RegionGroup parseFlagGroupInput(RegionGroupFlag flag, String input) throws InvalidFlagFormat {
return flag.parseInput(FlagContext.create().setInput(input).build());
}
@Override
public Vector getMinimumPoint(ProtectedRegion region) {
BlockVector min = region.getMinimumPoint();
return new Vector(min.getX(), min.getY(), min.getZ());
}
@Override
public Vector getMaximumPoint(ProtectedRegion region) {
BlockVector min = region.getMaximumPoint();
return new Vector(min.getX(), min.getY(), min.getZ());
}
@Override
public List<Vector> getRegionPoints(ProtectedRegion region) {
List<Vector> result = new ArrayList<>();
for (BlockVector2D point : region.getPoints()) {
result.add(new Vector(point.getX(), 0,point.getZ()));
}
return result;
}
@Override
public ProtectedCuboidRegion createCuboidRegion(String name, Vector corner1, Vector corner2) {
return new ProtectedCuboidRegion(name, new BlockVector(corner1.getBlockX(), corner1.getBlockY(), corner1.getBlockZ()), new BlockVector(corner2.getBlockX(), corner2.getBlockY(), corner2.getBlockZ()));
}
}
-42
View File
@@ -1,42 +0,0 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>areashop-interface</artifactId>
<packaging>jar</packaging>
<name>AreaShop Interface</name>
<version>latest</version>
<parent>
<groupId>me.wiefferink</groupId>
<artifactId>areashop-parent</artifactId>
<version>parent</version>
</parent>
<dependencies>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
<scope>system</scope>
<version>any</version>
<systemPath>${project.basedir}/../dependencies/bukkit-1.7.9-R0.2.jar</systemPath>
<type>jar</type>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.sk89q</groupId>
<artifactId>worldedit</artifactId>
<scope>system</scope>
<version>any</version>
<systemPath>${project.basedir}/../dependencies/worldedit-6.0.0-SNAPSHOT.jar</systemPath>
</dependency>
<dependency>
<groupId>com.sk89q</groupId>
<artifactId>worldguard</artifactId>
<scope>system</scope>
<version>any</version>
<systemPath>${project.basedir}/../dependencies/worldguard-6.0.0-SNAPSHOT.jar</systemPath>
</dependency>
</dependencies>
</project>
@@ -1,35 +0,0 @@
package me.wiefferink.areashop.interfaces;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
public abstract class BukkitInterface {
protected final AreaShopInterface pluginInterface;
public BukkitInterface(AreaShopInterface pluginInterface) {
this.pluginInterface = pluginInterface;
}
/**
* Get the direciton a sign is facing.
* @param block Sign block to get the facing from
* @return direction the sign is facing
*/
public abstract BlockFace getSignFacing(Block block);
/**
* Set the direction a sign is facing.
* @param block Sign block to update
* @param facing direction to let the sign face
* @return true when successful, otherwise false
*/
public abstract boolean setSignFacing(Block block, BlockFace facing);
/**
* Get the block a sign is attached to.
* @param block Sign block
* @return Block the sign is attached to, or null when not a sign or not attached
*/
public abstract Block getSignAttachedTo(Block block);
}
-48
View File
@@ -1,48 +0,0 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>areashop-worldedit-5</artifactId>
<packaging>jar</packaging>
<name>AreaShop WorldEdit 5</name>
<version>latest</version>
<parent>
<groupId>me.wiefferink</groupId>
<artifactId>areashop-parent</artifactId>
<version>parent</version>
</parent>
<dependencies>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>craftbukkit</artifactId>
<scope>system</scope>
<version>any</version>
<systemPath>${project.basedir}/../dependencies/craftbukkit-1.7.9-R0.2-SNAPSHOT.jar</systemPath>
<type>jar</type>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.sk89q</groupId>
<artifactId>worldedit</artifactId>
<scope>system</scope>
<version>any</version>
<systemPath>${project.basedir}/../dependencies/worldedit-5.7-SNAPSHOT.jar</systemPath>
</dependency>
<dependency>
<groupId>com.sk89q</groupId>
<artifactId>worldguard</artifactId>
<scope>system</scope>
<version>any</version>
<systemPath>${project.basedir}/../dependencies/worldguard-5.9.1-SNAPSHOT.jar</systemPath>
</dependency>
<dependency>
<groupId>me.wiefferink</groupId>
<artifactId>areashop-interface</artifactId>
<version>latest</version>
<type>jar</type>
</dependency>
</dependencies>
</project>
@@ -1,108 +0,0 @@
package me.wiefferink.areashop.handlers;
import com.sk89q.worldedit.CuboidClipboard;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.bukkit.BukkitWorld;
import com.sk89q.worldedit.bukkit.selections.Selection;
import com.sk89q.worldedit.data.DataException;
import com.sk89q.worldedit.schematic.SchematicFormat;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import me.wiefferink.areashop.interfaces.AreaShopInterface;
import me.wiefferink.areashop.interfaces.GeneralRegionInterface;
import me.wiefferink.areashop.interfaces.WorldEditInterface;
import me.wiefferink.areashop.interfaces.WorldEditSelection;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.bukkit.entity.Player;
import java.io.File;
import java.io.IOException;
public class WorldEditHandler5 extends WorldEditInterface {
public WorldEditHandler5(AreaShopInterface pluginInterface) {
super(pluginInterface);
}
@Override
public WorldEditSelection getPlayerSelection(Player player) {
Selection selection = pluginInterface.getWorldEdit().getSelection(player);
if (selection == null) {
return null;
}
return new WorldEditSelection(
player.getWorld(),
selection.getMinimumPoint(),
selection.getMaximumPoint()
);
}
@Override
public boolean restoreRegionBlocks(File file, GeneralRegionInterface regionInterface) {
file = new File(file.getAbsolutePath() + ".schematic");
if(!file.exists() || !file.isFile()) {
pluginInterface.getLogger().info("Did not restore region " + regionInterface.getName() + ", schematic file does not exist: " + file.getAbsolutePath());
return false;
}
boolean result = true;
EditSession editSession = pluginInterface.getWorldEdit().getWorldEdit().getEditSessionFactory().getEditSession(new BukkitWorld(regionInterface.getWorld()), pluginInterface.getConfig().getInt("maximumBlocks"));
// Get the origin and size of the region
Vector origin = new Vector(regionInterface.getRegion().getMinimumPoint().getBlockX(), regionInterface.getRegion().getMinimumPoint().getBlockY(), regionInterface.getRegion().getMinimumPoint().getBlockZ());
editSession.enableQueue();
Exception otherException = null;
try {
CuboidClipboard clipBoard = SchematicFormat.MCEDIT.load(file);
if(clipBoard.getHeight() != regionInterface.getHeight()
|| clipBoard.getWidth() != regionInterface.getWidth()
|| clipBoard.getLength() != regionInterface.getDepth()) {
pluginInterface.getLogger().warning("Size of the region " + regionInterface.getName() + " is not the same as the schematic to restore!");
pluginInterface.debugI("schematic|region, x:" + clipBoard.getWidth() + "|" + regionInterface.getWidth() + ", y:" + clipBoard.getHeight() + "|" + regionInterface.getHeight() + ", z:" + clipBoard.getLength() + "|" + regionInterface.getDepth());
}
clipBoard.place(editSession, origin, false);
} catch(MaxChangedBlocksException e) {
pluginInterface.getLogger().warning("exceeded the block limit while restoring schematic of " + regionInterface.getName() + ", limit in exception: " + e.getBlockLimit() + ", limit passed by AreaShop: " + pluginInterface.getConfig().getInt("maximumBlocks"));
result = false;
} catch(DataException | IOException e) {
otherException = e;
}
if(otherException != null) {
pluginInterface.getLogger().warning("Failed to restore schematic for region " + regionInterface.getName());
pluginInterface.debugI(ExceptionUtils.getStackTrace(otherException));
result = false;
}
editSession.flushQueue();
return result;
}
@Override
public boolean saveRegionBlocks(File file, GeneralRegionInterface regionInterface) {
file = new File(file.getAbsolutePath() + ".schematic");
boolean result = true;
ProtectedRegion region = regionInterface.getRegion();
// Get the origin and size of the region
Vector origin = new Vector(region.getMinimumPoint().getBlockX(), region.getMinimumPoint().getBlockY(), region.getMinimumPoint().getBlockZ());
Vector size = (new Vector(region.getMaximumPoint().getBlockX(), region.getMaximumPoint().getBlockY(), region.getMaximumPoint().getBlockZ()).subtract(origin)).add(new Vector(1, 1, 1));
EditSession editSession = new EditSession(new BukkitWorld(regionInterface.getWorld()), pluginInterface.getConfig().getInt("maximumBlocks"));
// Save the schematic
editSession.enableQueue();
CuboidClipboard clipboard = new CuboidClipboard(size, origin);
clipboard.copy(editSession);
Exception otherException = null;
try {
SchematicFormat.MCEDIT.save(clipboard, file);
} catch(DataException | IOException e) {
otherException = e;
}
if(otherException != null) {
pluginInterface.getLogger().warning("Failed to save schematic for region " + regionInterface.getName());
pluginInterface.debugI(ExceptionUtils.getStackTrace(otherException));
result = false;
}
editSession.flushQueue();
return result;
}
}
-48
View File
@@ -1,48 +0,0 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>areashop-worldedit-6</artifactId>
<packaging>jar</packaging>
<name>AreaShop WorldEdit 6</name>
<version>latest</version>
<parent>
<groupId>me.wiefferink</groupId>
<artifactId>areashop-parent</artifactId>
<version>parent</version>
</parent>
<dependencies>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>craftbukkit</artifactId>
<scope>system</scope>
<version>any</version>
<systemPath>${project.basedir}/../dependencies/craftbukkit-1.7.9-R0.2-SNAPSHOT.jar</systemPath>
<type>jar</type>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.sk89q</groupId>
<artifactId>worldedit</artifactId>
<scope>system</scope>
<version>any</version>
<systemPath>${project.basedir}/../dependencies/worldedit-6.0.0-SNAPSHOT.jar</systemPath>
</dependency>
<dependency>
<groupId>com.sk89q</groupId>
<artifactId>worldguard</artifactId>
<scope>system</scope>
<version>any</version>
<systemPath>${project.basedir}/../dependencies/worldguard-6.0.0-SNAPSHOT.jar</systemPath>
</dependency>
<dependency>
<groupId>me.wiefferink</groupId>
<artifactId>areashop-interface</artifactId>
<version>latest</version>
<type>jar</type>
</dependency>
</dependencies>
</project>
@@ -1,190 +0,0 @@
package me.wiefferink.areashop.handlers;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.bukkit.BukkitWorld;
import com.sk89q.worldedit.bukkit.selections.Selection;
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardReader;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter;
import com.sk89q.worldedit.extent.transform.BlockTransformExtent;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.mask.Mask2D;
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.internal.LocalWorldAdapter;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.session.ClipboardHolder;
import com.sk89q.worldedit.util.io.Closer;
import com.sk89q.worldedit.world.registry.WorldData;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import com.sk89q.worldguard.protection.regions.RegionType;
import me.wiefferink.areashop.interfaces.AreaShopInterface;
import me.wiefferink.areashop.interfaces.GeneralRegionInterface;
import me.wiefferink.areashop.interfaces.WorldEditInterface;
import me.wiefferink.areashop.interfaces.WorldEditSelection;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.bukkit.entity.Player;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class WorldEditHandler6 extends WorldEditInterface {
public WorldEditHandler6(AreaShopInterface pluginInterface) {
super(pluginInterface);
}
@Override
public WorldEditSelection getPlayerSelection(Player player) {
Selection selection = pluginInterface.getWorldEdit().getSelection(player);
if (selection == null) {
return null;
}
return new WorldEditSelection(
player.getWorld(),
selection.getMinimumPoint(),
selection.getMaximumPoint()
);
}
@Override
public boolean restoreRegionBlocks(File file, GeneralRegionInterface regionInterface) {
file = new File(file.getAbsolutePath() + ".schematic");
if(!file.exists() || !file.isFile()) {
pluginInterface.getLogger().info("Did not restore region " + regionInterface.getName() + ", schematic file does not exist: " + file.getAbsolutePath());
return false;
}
com.sk89q.worldedit.world.World world = null;
if(regionInterface.getName() != null) {
world = LocalWorldAdapter.adapt(new BukkitWorld(regionInterface.getWorld()));
}
if(world == null) {
pluginInterface.getLogger().info("Did not restore region " + regionInterface.getName() + ", world not found: " + regionInterface.getWorldName());
return false;
}
EditSession editSession = pluginInterface.getWorldEdit().getWorldEdit().getEditSessionFactory().getEditSession(world, pluginInterface.getConfig().getInt("maximumBlocks"));
editSession.enableQueue();
ProtectedRegion region = regionInterface.getRegion();
// Get the origin and size of the region
Vector origin = new Vector(region.getMinimumPoint().getBlockX(), region.getMinimumPoint().getBlockY(), region.getMinimumPoint().getBlockZ());
// Read the schematic and paste it into the world
try(Closer closer = Closer.create()) {
FileInputStream fis = closer.register(new FileInputStream(file));
BufferedInputStream bis = closer.register(new BufferedInputStream(fis));
ClipboardReader reader = ClipboardFormat.SCHEMATIC.getReader(bis);
WorldData worldData = world.getWorldData();
LocalSession session = new LocalSession(pluginInterface.getWorldEdit().getLocalConfiguration());
Clipboard clipboard = reader.read(worldData);
if(clipboard.getDimensions().getY() != regionInterface.getHeight()
|| clipboard.getDimensions().getX() != regionInterface.getWidth()
|| clipboard.getDimensions().getZ() != regionInterface.getDepth()) {
pluginInterface.getLogger().warning("Size of the region " + regionInterface.getName() + " is not the same as the schematic to restore!");
pluginInterface.debugI("schematic|region, x:" + clipboard.getDimensions().getX() + "|" + regionInterface.getWidth() + ", y:" + clipboard.getDimensions().getY() + "|" + regionInterface.getHeight() + ", z:" + clipboard.getDimensions().getZ() + "|" + regionInterface.getDepth());
}
clipboard.setOrigin(clipboard.getMinimumPoint());
ClipboardHolder clipboardHolder = new ClipboardHolder(clipboard, worldData);
session.setBlockChangeLimit(pluginInterface.getConfig().getInt("maximumBlocks"));
session.setClipboard(clipboardHolder);
// Build operation
BlockTransformExtent extent = new BlockTransformExtent(clipboardHolder.getClipboard(), clipboardHolder.getTransform(), editSession.getWorld().getWorldData().getBlockRegistry());
ForwardExtentCopy copy = new ForwardExtentCopy(extent, clipboard.getRegion(), clipboard.getOrigin(), editSession, origin);
copy.setTransform(clipboardHolder.getTransform());
// Mask to region (for polygon and other weird shaped regions)
// TODO make this more efficient (especially for polygon regions)
if(region.getType() != RegionType.CUBOID) {
copy.setSourceMask(new Mask() {
@Override
public boolean test(Vector vector) {
return region.contains(vector);
}
@Override
public Mask2D toMask2D() {
return null;
}
});
}
Operations.completeLegacy(copy);
} catch(MaxChangedBlocksException e) {
pluginInterface.getLogger().warning("exceeded the block limit while restoring schematic of " + regionInterface.getName() + ", limit in exception: " + e.getBlockLimit() + ", limit passed by AreaShop: " + pluginInterface.getConfig().getInt("maximumBlocks"));
return false;
} catch(IOException e) {
pluginInterface.getLogger().warning("An error occured while restoring schematic of " + regionInterface.getName() + ", enable debug to see the complete stacktrace");
pluginInterface.debugI(ExceptionUtils.getStackTrace(e));
return false;
}
editSession.flushQueue();
return true;
}
@Override
public boolean saveRegionBlocks(File file, GeneralRegionInterface regionInterface) {
file = new File(file.getAbsolutePath() + ".schematic");
com.sk89q.worldedit.world.World world = null;
if(regionInterface.getWorld() != null) {
world = LocalWorldAdapter.adapt(new BukkitWorld(regionInterface.getWorld()));
}
if(world == null) {
pluginInterface.getLogger().warning("Did not save region " + regionInterface.getName() + ", world not found: " + regionInterface.getWorldName());
return false;
}
EditSession editSession = pluginInterface.getWorldEdit().getWorldEdit().getEditSessionFactory().getEditSession(world, pluginInterface.getConfig().getInt("maximumBlocks"));
// Create a clipboard
CuboidRegion selection = new CuboidRegion(world, regionInterface.getRegion().getMinimumPoint(), regionInterface.getRegion().getMaximumPoint());
BlockArrayClipboard clipboard = new BlockArrayClipboard(selection);
clipboard.setOrigin(regionInterface.getRegion().getMinimumPoint());
ForwardExtentCopy copy = new ForwardExtentCopy(editSession, new CuboidRegion(world, regionInterface.getRegion().getMinimumPoint(), regionInterface.getRegion().getMaximumPoint()), clipboard, regionInterface.getRegion().getMinimumPoint());
try {
Operations.completeLegacy(copy);
} catch(MaxChangedBlocksException e) {
pluginInterface.getLogger().warning("exceeded the block limit while saving schematic of " + regionInterface.getName() + ", limit in exception: " + e.getBlockLimit() + ", limit passed by AreaShop: " + pluginInterface.getConfig().getInt("maximumBlocks"));
return false;
}
try(Closer closer = Closer.create()) {
FileOutputStream fos = closer.register(new FileOutputStream(file));
BufferedOutputStream bos = closer.register(new BufferedOutputStream(fos));
ClipboardWriter writer = closer.register(ClipboardFormat.SCHEMATIC.getWriter(bos));
writer.write(clipboard, world.getWorldData());
} catch(IOException e) {
pluginInterface.getLogger().warning("An error occured while saving schematic of " + regionInterface.getName() + ", enable debug to see the complete stacktrace");
pluginInterface.debugI(ExceptionUtils.getStackTrace(e));
return false;
}
return true;
}
}
-47
View File
@@ -1,47 +0,0 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>areashop-worldedit-7_beta_1</artifactId>
<packaging>jar</packaging>
<name>AreaShop WorldEdit 7_beta_1</name>
<version>latest</version>
<parent>
<groupId>me.wiefferink</groupId>
<artifactId>areashop-parent</artifactId>
<version>parent</version>
</parent>
<dependencies>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>craftbukkit</artifactId>
<version>1.13-R0.1-SNAPSHOT</version>
<scope>provided</scope>
<type>jar</type>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.sk89q</groupId>
<artifactId>worldedit</artifactId>
<scope>system</scope>
<version>any</version>
<systemPath>${project.basedir}/../dependencies/worldedit-bukkit-7.0.0-beta-01.jar</systemPath>
</dependency>
<dependency>
<groupId>com.sk89q</groupId>
<artifactId>worldguard</artifactId>
<scope>system</scope>
<version>any</version>
<systemPath>${project.basedir}/../dependencies/worldguard-legacy-7.0.0-beta-01.jar</systemPath>
</dependency>
<dependency>
<groupId>me.wiefferink</groupId>
<artifactId>areashop-interface</artifactId>
<version>latest</version>
<type>jar</type>
</dependency>
</dependencies>
</project>
@@ -1,226 +0,0 @@
package me.wiefferink.areashop.handlers;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.IncompleteRegionException;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardReader;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter;
import com.sk89q.worldedit.extent.transform.BlockTransformExtent;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.mask.Mask2D;
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.session.ClipboardHolder;
import com.sk89q.worldedit.util.io.Closer;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import com.sk89q.worldguard.protection.regions.RegionType;
import me.wiefferink.areashop.interfaces.AreaShopInterface;
import me.wiefferink.areashop.interfaces.GeneralRegionInterface;
import me.wiefferink.areashop.interfaces.WorldEditInterface;
import me.wiefferink.areashop.interfaces.WorldEditSelection;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.bukkit.entity.Player;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class WorldEditHandler7_beta_1 extends WorldEditInterface {
public WorldEditHandler7_beta_1(AreaShopInterface pluginInterface) {
super(pluginInterface);
}
@Override
public WorldEditSelection getPlayerSelection(Player player) {
try {
Region region = pluginInterface.getWorldEdit().getSession(player).getSelection(BukkitAdapter.adapt(player.getWorld()));
return new WorldEditSelection(
player.getWorld(),
BukkitAdapter.adapt(player.getWorld(), region.getMinimumPoint()),
BukkitAdapter.adapt(player.getWorld(), region.getMaximumPoint())
);
} catch (IncompleteRegionException e) {
return null;
}
}
@Override
public boolean restoreRegionBlocks(File rawFile, GeneralRegionInterface regionInterface) {
File file = null;
ClipboardFormat format = null;
for (ClipboardFormat formatOption : ClipboardFormats.getAll()) {
for (String extension : formatOption.getFileExtensions()) {
File fileOption = new File(rawFile.getAbsolutePath() + "." + extension);
if (fileOption.exists()) {
file = fileOption;
format = formatOption;
}
}
}
if(file == null) {
pluginInterface.getLogger().info("Did not restore region " + regionInterface.getName() + ", schematic file does not exist: " + rawFile.getAbsolutePath());
return false;
}
pluginInterface.debugI("Trying to restore region", regionInterface.getName(), " from file", file.getAbsolutePath(), "with format", format.getName());
com.sk89q.worldedit.world.World world = null;
if(regionInterface.getName() != null) {
world = BukkitAdapter.adapt(regionInterface.getWorld());
}
if(world == null) {
pluginInterface.getLogger().info("Did not restore region " + regionInterface.getName() + ", world not found: " + regionInterface.getWorldName());
return false;
}
EditSession editSession = pluginInterface.getWorldEdit().getWorldEdit().getEditSessionFactory().getEditSession(world, pluginInterface.getConfig().getInt("maximumBlocks"));
editSession.enableQueue();
ProtectedRegion region = regionInterface.getRegion();
// Get the origin and size of the region
Vector origin = new Vector(region.getMinimumPoint().getBlockX(), region.getMinimumPoint().getBlockY(), region.getMinimumPoint().getBlockZ());
// Read the schematic and paste it into the world
try(Closer closer = Closer.create()) {
FileInputStream fis = closer.register(new FileInputStream(file));
BufferedInputStream bis = closer.register(new BufferedInputStream(fis));
ClipboardReader reader = format.getReader(bis);
//WorldData worldData = world.getWorldData();
LocalSession session = new LocalSession(pluginInterface.getWorldEdit().getLocalConfiguration());
Clipboard clipboard = reader.read();
if(clipboard.getDimensions().getY() != regionInterface.getHeight()
|| clipboard.getDimensions().getX() != regionInterface.getWidth()
|| clipboard.getDimensions().getZ() != regionInterface.getDepth()) {
pluginInterface.getLogger().warning("Size of the region " + regionInterface.getName() + " is not the same as the schematic to restore!");
pluginInterface.debugI("schematic|region, x:" + clipboard.getDimensions().getX() + "|" + regionInterface.getWidth() + ", y:" + clipboard.getDimensions().getY() + "|" + regionInterface.getHeight() + ", z:" + clipboard.getDimensions().getZ() + "|" + regionInterface.getDepth());
}
clipboard.setOrigin(clipboard.getMinimumPoint());
ClipboardHolder clipboardHolder = new ClipboardHolder(clipboard);
session.setBlockChangeLimit(pluginInterface.getConfig().getInt("maximumBlocks"));
session.setClipboard(clipboardHolder);
// Build operation
BlockTransformExtent extent = new BlockTransformExtent(clipboardHolder.getClipboard(), clipboardHolder.getTransform());
ForwardExtentCopy copy = new ForwardExtentCopy(extent, clipboard.getRegion(), clipboard.getOrigin(), editSession, origin);
copy.setCopyingEntities(false);
copy.setTransform(clipboardHolder.getTransform());
// Mask to region (for polygon and other weird shaped regions)
// TODO make this more efficient (especially for polygon regions)
if(region.getType() != RegionType.CUBOID) {
copy.setSourceMask(new Mask() {
@Override
public boolean test(Vector vector) {
return region.contains(vector);
}
@Override
public Mask2D toMask2D() {
return null;
}
});
}
Operations.completeLegacy(copy);
} catch(MaxChangedBlocksException e) {
pluginInterface.getLogger().warning("exceeded the block limit while restoring schematic of " + regionInterface.getName() + ", limit in exception: " + e.getBlockLimit() + ", limit passed by AreaShop: " + pluginInterface.getConfig().getInt("maximumBlocks"));
return false;
} catch(IOException e) {
pluginInterface.getLogger().warning("An error occured while restoring schematic of " + regionInterface.getName() + ", enable debug to see the complete stacktrace");
pluginInterface.debugI(ExceptionUtils.getStackTrace(e));
return false;
} catch (Exception e) {
pluginInterface.getLogger().warning("crashed during restore of " + regionInterface.getName());
pluginInterface.debugI(ExceptionUtils.getStackTrace(e));
return false;
}
editSession.flushQueue();
return true;
}
@Override
public boolean saveRegionBlocks(File file, GeneralRegionInterface regionInterface) {
ClipboardFormat format = ClipboardFormats.findByAlias("sponge");
if(format == null) {
// Sponge format does not exist, try to select another one
for(ClipboardFormat otherFormat : ClipboardFormats.getAll()) {
format = otherFormat;
}
if(format == null) {
pluginInterface.getLogger().warning("Cannot find a format to save a schematic in, no available formats!");
return false;
}
}
file = new File(file.getAbsolutePath() + "." + format.getPrimaryFileExtension());
pluginInterface.debugI("Trying to save region", regionInterface.getName(), " to file", file.getAbsolutePath(), "with format", format.getName());
com.sk89q.worldedit.world.World world = null;
if(regionInterface.getWorld() != null) {
world = BukkitAdapter.adapt(regionInterface.getWorld());
}
if(world == null) {
pluginInterface.getLogger().warning("Did not save region " + regionInterface.getName() + ", world not found: " + regionInterface.getWorldName());
return false;
}
EditSession editSession = pluginInterface.getWorldEdit().getWorldEdit().getEditSessionFactory().getEditSession(world, pluginInterface.getConfig().getInt("maximumBlocks"));
// Create a clipboard
CuboidRegion selection = new CuboidRegion(world, regionInterface.getRegion().getMinimumPoint(), regionInterface.getRegion().getMaximumPoint());
BlockArrayClipboard clipboard = new BlockArrayClipboard(selection);
clipboard.setOrigin(regionInterface.getRegion().getMinimumPoint());
ForwardExtentCopy copy = new ForwardExtentCopy(editSession, new CuboidRegion(world, regionInterface.getRegion().getMinimumPoint(), regionInterface.getRegion().getMaximumPoint()), clipboard, regionInterface.getRegion().getMinimumPoint());
try {
Operations.completeLegacy(copy);
} catch(MaxChangedBlocksException e) {
pluginInterface.getLogger().warning("Exceeded the block limit while saving schematic of " + regionInterface.getName() + ", limit in exception: " + e.getBlockLimit() + ", limit passed by AreaShop: " + pluginInterface.getConfig().getInt("maximumBlocks"));
return false;
}
try(Closer closer = Closer.create()) {
FileOutputStream fos = closer.register(new FileOutputStream(file));
BufferedOutputStream bos = closer.register(new BufferedOutputStream(fos));
ClipboardWriter writer = closer.register(format.getWriter(bos));
writer.write(clipboard);
} catch(IOException e) {
pluginInterface.getLogger().warning("An error occured while saving schematic of " + regionInterface.getName() + ", enable debug to see the complete stacktrace");
pluginInterface.debugI(ExceptionUtils.getStackTrace(e));
return false;
} catch (Exception e) {
pluginInterface.getLogger().warning("crashed during save of " + regionInterface.getName());
pluginInterface.debugI(ExceptionUtils.getStackTrace(e));
return false;
}
return true;
}
}
-47
View File
@@ -1,47 +0,0 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>areashop-worldedit-7_beta_4</artifactId>
<packaging>jar</packaging>
<name>AreaShop WorldEdit 7_beta_4</name>
<version>latest</version>
<parent>
<groupId>me.wiefferink</groupId>
<artifactId>areashop-parent</artifactId>
<version>parent</version>
</parent>
<dependencies>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>craftbukkit</artifactId>
<version>1.13-R0.1-SNAPSHOT</version>
<scope>provided</scope>
<type>jar</type>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.sk89q</groupId>
<artifactId>worldedit</artifactId>
<scope>system</scope>
<version>any</version>
<systemPath>${project.basedir}/../dependencies/worldedit-bukkit-7.0.0-beta-04.jar</systemPath>
</dependency>
<dependency>
<groupId>com.sk89q</groupId>
<artifactId>worldguard</artifactId>
<scope>system</scope>
<version>any</version>
<systemPath>${project.basedir}/../dependencies/worldguard-legacy-7.0.0-beta-02.jar</systemPath>
</dependency>
<dependency>
<groupId>me.wiefferink</groupId>
<artifactId>areashop-interface</artifactId>
<version>latest</version>
<type>jar</type>
</dependency>
</dependencies>
</project>
-41
View File
@@ -1,41 +0,0 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>areashop-worldguard-5</artifactId>
<packaging>jar</packaging>
<name>AreaShop WorldGuard 5</name>
<version>latest</version>
<parent>
<groupId>me.wiefferink</groupId>
<artifactId>areashop-parent</artifactId>
<version>parent</version>
</parent>
<dependencies>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
<scope>system</scope>
<version>any</version>
<systemPath>${project.basedir}/../dependencies/bukkit-1.7.9-R0.2.jar</systemPath>
<type>jar</type>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.sk89q</groupId>
<artifactId>worldguard</artifactId>
<scope>system</scope>
<version>any</version>
<systemPath>${project.basedir}/../dependencies/worldguard-5.9.1-SNAPSHOT.jar</systemPath>
</dependency>
<dependency>
<groupId>me.wiefferink</groupId>
<artifactId>areashop-interface</artifactId>
<version>latest</version>
<type>jar</type>
</dependency>
</dependencies>
</project>
@@ -1,172 +0,0 @@
package me.wiefferink.areashop.handlers;
import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.BlockVector2D;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.domains.DefaultDomain;
import com.sk89q.worldguard.protection.flags.DefaultFlag;
import com.sk89q.worldguard.protection.flags.Flag;
import com.sk89q.worldguard.protection.flags.InvalidFlagFormat;
import com.sk89q.worldguard.protection.flags.RegionGroup;
import com.sk89q.worldguard.protection.flags.RegionGroupFlag;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import me.wiefferink.areashop.interfaces.AreaShopInterface;
import me.wiefferink.areashop.interfaces.RegionAccessSet;
import me.wiefferink.areashop.interfaces.WorldGuardInterface;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
public class WorldGuardHandler5 extends WorldGuardInterface {
public WorldGuardHandler5(AreaShopInterface pluginInterface) {
super(pluginInterface);
}
@Override
public RegionManager getRegionManager(World world) {
return WorldGuardPlugin.inst().getRegionManager(world);
}
@Override
public Set<ProtectedRegion> getApplicableRegionsSet(Location location) {
Set<ProtectedRegion> result = new HashSet<>();
Vector vector = new Vector(location.getX(), location.getY(), location.getZ());
for(ProtectedRegion region : pluginInterface.getWorldGuard().getRegionManager(location.getWorld()).getRegions().values()) {
if(region.contains(vector)) {
result.add(region);
}
}
return result;
}
@Override
public void setOwners(ProtectedRegion region, RegionAccessSet regionAccessSet) {
DefaultDomain defaultDomain = buildDomain(regionAccessSet);
if(!region.getOwners().toUserFriendlyString().equals(defaultDomain.toUserFriendlyString())) {
region.setOwners(defaultDomain);
}
}
@Override
public void setMembers(ProtectedRegion region, RegionAccessSet regionAccessSet) {
DefaultDomain defaultDomain = buildDomain(regionAccessSet);
if(!region.getMembers().toUserFriendlyString().equals(defaultDomain.toUserFriendlyString())) {
region.setMembers(defaultDomain);
}
}
@Override
public RegionAccessSet getMembers(ProtectedRegion region) {
RegionAccessSet result = new RegionAccessSet();
result.getGroupNames().addAll(region.getMembers().getGroups());
result.getPlayerNames().addAll(region.getMembers().getPlayers());
return result;
}
@Override
public RegionAccessSet getOwners(ProtectedRegion region) {
RegionAccessSet result = new RegionAccessSet();
result.getGroupNames().addAll(region.getOwners().getGroups());
result.getPlayerNames().addAll(region.getOwners().getPlayers());
return result;
}
/**
* Build a DefaultDomain from a RegionAccessSet.
* @param regionAccessSet RegionAccessSet to read
* @return DefaultDomain containing the entities from the RegionAccessSet
*/
private DefaultDomain buildDomain(RegionAccessSet regionAccessSet) {
DefaultDomain owners = new DefaultDomain();
for(String playerName : regionAccessSet.getPlayerNames()) {
owners.addPlayer(playerName);
}
// Add by name since UUIDs were not yet supported
for(UUID uuid : regionAccessSet.getPlayerUniqueIds()) {
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(uuid);
if(offlinePlayer != null && offlinePlayer.getName() != null) {
owners.addPlayer(offlinePlayer.getName());
}
}
for(String group : regionAccessSet.getGroupNames()) {
owners.addGroup(group);
}
return owners;
}
@Override
public boolean containsMember(ProtectedRegion region, UUID player) {
if(player == null) {
return false;
} else {
String name = Bukkit.getOfflinePlayer(player).getName();
return name != null && region.getMembers().contains(name);
}
}
@Override
public boolean containsOwner(ProtectedRegion region, UUID player) {
if(player == null) {
return false;
} else {
String name = Bukkit.getOfflinePlayer(player).getName();
return name != null && region.getOwners().contains(name);
}
}
@Override
public Flag<?> fuzzyMatchFlag(String flagName) {
return DefaultFlag.fuzzyMatchFlag(flagName);
}
@Override
public <V> V parseFlagInput(Flag<V> flag, String input) throws InvalidFlagFormat {
return flag.parseInput(WorldGuardPlugin.inst(), null, input);
}
@Override
public RegionGroup parseFlagGroupInput(RegionGroupFlag flag, String input) throws InvalidFlagFormat {
return flag.parseInput(WorldGuardPlugin.inst(), null, input);
}
@Override
public org.bukkit.util.Vector getMinimumPoint(ProtectedRegion region) {
BlockVector min = region.getMinimumPoint();
return new org.bukkit.util.Vector(min.getX(), min.getY(), min.getZ());
}
@Override
public org.bukkit.util.Vector getMaximumPoint(ProtectedRegion region) {
BlockVector min = region.getMaximumPoint();
return new org.bukkit.util.Vector(min.getX(), min.getY(), min.getZ());
}
@Override
public List<org.bukkit.util.Vector> getRegionPoints(ProtectedRegion region) {
List<org.bukkit.util.Vector> result = new ArrayList<>();
for (BlockVector2D point : region.getPoints()) {
result.add(new org.bukkit.util.Vector(point.getX(), 0,point.getZ()));
}
return result;
}
@Override
public ProtectedCuboidRegion createCuboidRegion(String name, org.bukkit.util.Vector corner1, org.bukkit.util.Vector corner2) {
return new ProtectedCuboidRegion(name, new BlockVector(corner1.getBlockX(), corner1.getBlockY(), corner1.getBlockZ()), new BlockVector(corner2.getBlockX(), corner2.getBlockY(), corner2.getBlockZ()));
}
}
-41
View File
@@ -1,41 +0,0 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>areashop-worldguard-6</artifactId>
<packaging>jar</packaging>
<name>AreaShop WorldGuard 6</name>
<version>latest</version>
<parent>
<groupId>me.wiefferink</groupId>
<artifactId>areashop-parent</artifactId>
<version>parent</version>
</parent>
<dependencies>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
<scope>system</scope>
<version>any</version>
<systemPath>${project.basedir}/../dependencies/bukkit-1.7.9-R0.2.jar</systemPath>
<type>jar</type>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.sk89q</groupId>
<artifactId>worldguard</artifactId>
<scope>system</scope>
<version>any</version>
<systemPath>${project.basedir}/../dependencies/worldguard-6.0.0-SNAPSHOT.jar</systemPath>
</dependency>
<dependency>
<groupId>me.wiefferink</groupId>
<artifactId>areashop-interface</artifactId>
<version>latest</version>
<type>jar</type>
</dependency>
</dependencies>
</project>
@@ -1,158 +0,0 @@
package me.wiefferink.areashop.handlers;
import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.BlockVector2D;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.domains.DefaultDomain;
import com.sk89q.worldguard.protection.flags.DefaultFlag;
import com.sk89q.worldguard.protection.flags.Flag;
import com.sk89q.worldguard.protection.flags.InvalidFlagFormat;
import com.sk89q.worldguard.protection.flags.RegionGroup;
import com.sk89q.worldguard.protection.flags.RegionGroupFlag;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import me.wiefferink.areashop.interfaces.AreaShopInterface;
import me.wiefferink.areashop.interfaces.RegionAccessSet;
import me.wiefferink.areashop.interfaces.WorldGuardInterface;
import org.bukkit.Location;
import org.bukkit.World;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
public class WorldGuardHandler6 extends WorldGuardInterface {
public WorldGuardHandler6(AreaShopInterface pluginInterface) {
super(pluginInterface);
}
@Override
public RegionManager getRegionManager(World world) {
return WorldGuardPlugin.inst().getRegionManager(world);
}
@Override
public Set<ProtectedRegion> getApplicableRegionsSet(Location location) {
Set<ProtectedRegion> result = new HashSet<>();
Vector vector = new Vector(location.getX(), location.getY(), location.getZ());
for(ProtectedRegion region : getRegionManager(location.getWorld()).getRegions().values()) {
if(region.contains(vector)) {
result.add(region);
}
}
return result;
}
@Override
public void setOwners(ProtectedRegion region, RegionAccessSet regionAccessSet) {
DefaultDomain defaultDomain = buildDomain(regionAccessSet);
if(!region.getOwners().toUserFriendlyString().equals(defaultDomain.toUserFriendlyString())) {
region.setOwners(defaultDomain);
}
}
@Override
public void setMembers(ProtectedRegion region, RegionAccessSet regionAccessSet) {
DefaultDomain defaultDomain = buildDomain(regionAccessSet);
if(!region.getMembers().toUserFriendlyString().equals(defaultDomain.toUserFriendlyString())) {
region.setMembers(defaultDomain);
}
}
@Override
public RegionAccessSet getMembers(ProtectedRegion region) {
RegionAccessSet result = new RegionAccessSet();
result.getGroupNames().addAll(region.getMembers().getGroups());
result.getPlayerNames().addAll(region.getMembers().getPlayers());
result.getPlayerUniqueIds().addAll(region.getMembers().getUniqueIds());
return result;
}
@Override
public RegionAccessSet getOwners(ProtectedRegion region) {
RegionAccessSet result = new RegionAccessSet();
result.getGroupNames().addAll(region.getOwners().getGroups());
result.getPlayerNames().addAll(region.getOwners().getPlayers());
result.getPlayerUniqueIds().addAll(region.getOwners().getUniqueIds());
return result;
}
/**
* Build a DefaultDomain from a RegionAccessSet.
* @param regionAccessSet RegionAccessSet to read
* @return DefaultDomain containing the entities from the RegionAccessSet
*/
private DefaultDomain buildDomain(RegionAccessSet regionAccessSet) {
DefaultDomain owners = new DefaultDomain();
for(String playerName : regionAccessSet.getPlayerNames()) {
owners.addPlayer(playerName);
}
for(UUID uuid : regionAccessSet.getPlayerUniqueIds()) {
owners.addPlayer(uuid);
}
for(String group : regionAccessSet.getGroupNames()) {
owners.addGroup(group);
}
return owners;
}
@Override
public boolean containsMember(ProtectedRegion region, UUID player) {
return region.getMembers().contains(player);
}
@Override
public boolean containsOwner(ProtectedRegion region, UUID player) {
return region.getOwners().contains(player);
}
@Override
public Flag<?> fuzzyMatchFlag(String flagName) {
return DefaultFlag.fuzzyMatchFlag(flagName);
}
@Override
public <V> V parseFlagInput(Flag<V> flag, String input) throws InvalidFlagFormat {
return flag.parseInput(WorldGuardPlugin.inst(), null, input);
}
@Override
public RegionGroup parseFlagGroupInput(RegionGroupFlag flag, String input) throws InvalidFlagFormat {
return flag.parseInput(WorldGuardPlugin.inst(), null, input);
}
@Override
public org.bukkit.util.Vector getMinimumPoint(ProtectedRegion region) {
BlockVector min = region.getMinimumPoint();
return new org.bukkit.util.Vector(min.getX(), min.getY(), min.getZ());
}
@Override
public org.bukkit.util.Vector getMaximumPoint(ProtectedRegion region) {
BlockVector min = region.getMaximumPoint();
return new org.bukkit.util.Vector(min.getX(), min.getY(), min.getZ());
}
@Override
public List<org.bukkit.util.Vector> getRegionPoints(ProtectedRegion region) {
List<org.bukkit.util.Vector> result = new ArrayList<>();
for (BlockVector2D point : region.getPoints()) {
result.add(new org.bukkit.util.Vector(point.getX(), 0,point.getZ()));
}
return result;
}
@Override
public ProtectedCuboidRegion createCuboidRegion(String name, org.bukkit.util.Vector corner1, org.bukkit.util.Vector corner2) {
return new ProtectedCuboidRegion(name, new BlockVector(corner1.getBlockX(), corner1.getBlockY(), corner1.getBlockZ()), new BlockVector(corner2.getBlockX(), corner2.getBlockY(), corner2.getBlockZ()));
}
}
@@ -1,32 +0,0 @@
package me.wiefferink.areashop.handlers;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.protection.flags.DefaultFlag;
import com.sk89q.worldguard.protection.flags.Flag;
import com.sk89q.worldguard.protection.flags.FlagContext;
import com.sk89q.worldguard.protection.flags.InvalidFlagFormat;
import com.sk89q.worldguard.protection.flags.RegionGroup;
import com.sk89q.worldguard.protection.flags.RegionGroupFlag;
import me.wiefferink.areashop.interfaces.AreaShopInterface;
public class WorldGuardHandler6_1_3 extends WorldGuardHandler6 {
public WorldGuardHandler6_1_3(AreaShopInterface pluginInterface) {
super(pluginInterface);
}
@Override
public Flag<?> fuzzyMatchFlag(String flagName) {
return DefaultFlag.fuzzyMatchFlag(WorldGuardPlugin.inst().getFlagRegistry(), flagName);
}
@Override
public <V> V parseFlagInput(Flag<V> flag, String input) throws InvalidFlagFormat {
return flag.parseInput(FlagContext.create().setInput(input).build());
}
@Override
public RegionGroup parseFlagGroupInput(RegionGroupFlag flag, String input) throws InvalidFlagFormat {
return flag.parseInput(FlagContext.create().setInput(input).build());
}
}
@@ -1,160 +0,0 @@
package me.wiefferink.areashop.handlers;
import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.BlockVector2D;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.domains.DefaultDomain;
import com.sk89q.worldguard.protection.flags.Flag;
import com.sk89q.worldguard.protection.flags.FlagContext;
import com.sk89q.worldguard.protection.flags.Flags;
import com.sk89q.worldguard.protection.flags.InvalidFlagFormat;
import com.sk89q.worldguard.protection.flags.RegionGroup;
import com.sk89q.worldguard.protection.flags.RegionGroupFlag;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import me.wiefferink.areashop.interfaces.AreaShopInterface;
import me.wiefferink.areashop.interfaces.RegionAccessSet;
import me.wiefferink.areashop.interfaces.WorldGuardInterface;
import org.bukkit.Location;
import org.bukkit.World;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
public class WorldGuardHandler7_beta_1 extends WorldGuardInterface {
public WorldGuardHandler7_beta_1(AreaShopInterface pluginInterface) {
super(pluginInterface);
}
@Override
public RegionManager getRegionManager(World world) {
return WorldGuard.getInstance().getPlatform().getRegionContainer().get(BukkitAdapter.adapt(world));
}
@Override
public Set<ProtectedRegion> getApplicableRegionsSet(Location location) {
Set<ProtectedRegion> result = new HashSet<>();
Vector vector = new Vector(location.getX(), location.getY(), location.getZ());
for(ProtectedRegion region : getRegionManager(location.getWorld()).getRegions().values()) {
if(region.contains(vector)) {
result.add(region);
}
}
return result;
}
@Override
public void setOwners(ProtectedRegion region, RegionAccessSet regionAccessSet) {
DefaultDomain defaultDomain = buildDomain(regionAccessSet);
if(!region.getOwners().toUserFriendlyString().equals(defaultDomain.toUserFriendlyString())) {
region.setOwners(defaultDomain);
}
}
@Override
public void setMembers(ProtectedRegion region, RegionAccessSet regionAccessSet) {
DefaultDomain defaultDomain = buildDomain(regionAccessSet);
if(!region.getMembers().toUserFriendlyString().equals(defaultDomain.toUserFriendlyString())) {
region.setMembers(defaultDomain);
}
}
@Override
public RegionAccessSet getMembers(ProtectedRegion region) {
RegionAccessSet result = new RegionAccessSet();
result.getGroupNames().addAll(region.getMembers().getGroups());
result.getPlayerNames().addAll(region.getMembers().getPlayers());
result.getPlayerUniqueIds().addAll(region.getMembers().getUniqueIds());
return result;
}
@Override
public RegionAccessSet getOwners(ProtectedRegion region) {
RegionAccessSet result = new RegionAccessSet();
result.getGroupNames().addAll(region.getOwners().getGroups());
result.getPlayerNames().addAll(region.getOwners().getPlayers());
result.getPlayerUniqueIds().addAll(region.getOwners().getUniqueIds());
return result;
}
/**
* Build a DefaultDomain from a RegionAccessSet.
* @param regionAccessSet RegionAccessSet to read
* @return DefaultDomain containing the entities from the RegionAccessSet
*/
private DefaultDomain buildDomain(RegionAccessSet regionAccessSet) {
DefaultDomain owners = new DefaultDomain();
for(String playerName : regionAccessSet.getPlayerNames()) {
owners.addPlayer(playerName);
}
for(UUID uuid : regionAccessSet.getPlayerUniqueIds()) {
owners.addPlayer(uuid);
}
for(String group : regionAccessSet.getGroupNames()) {
owners.addGroup(group);
}
return owners;
}
@Override
public boolean containsMember(ProtectedRegion region, UUID player) {
return region.getMembers().contains(player);
}
@Override
public boolean containsOwner(ProtectedRegion region, UUID player) {
return region.getOwners().contains(player);
}
@Override
public Flag<?> fuzzyMatchFlag(String flagName) {
return Flags.fuzzyMatchFlag(WorldGuard.getInstance().getFlagRegistry(), flagName);
}
@Override
public <V> V parseFlagInput(Flag<V> flag, String input) throws InvalidFlagFormat {
return flag.parseInput(FlagContext.create().setInput(input).build());
}
@Override
public RegionGroup parseFlagGroupInput(RegionGroupFlag flag, String input) throws InvalidFlagFormat {
return flag.parseInput(FlagContext.create().setInput(input).build());
}
@Override
public org.bukkit.util.Vector getMinimumPoint(ProtectedRegion region) {
BlockVector min = region.getMinimumPoint();
return new org.bukkit.util.Vector(min.getX(), min.getY(), min.getZ());
}
@Override
public org.bukkit.util.Vector getMaximumPoint(ProtectedRegion region) {
BlockVector min = region.getMaximumPoint();
return new org.bukkit.util.Vector(min.getX(), min.getY(), min.getZ());
}
@Override
public List<org.bukkit.util.Vector> getRegionPoints(ProtectedRegion region) {
List<org.bukkit.util.Vector> result = new ArrayList<>();
for (BlockVector2D point : region.getPoints()) {
result.add(new org.bukkit.util.Vector(point.getX(), 0,point.getZ()));
}
return result;
}
@Override
public ProtectedCuboidRegion createCuboidRegion(String name, org.bukkit.util.Vector corner1, org.bukkit.util.Vector corner2) {
return new ProtectedCuboidRegion(name, new BlockVector(corner1.getBlockX(), corner1.getBlockY(), corner1.getBlockZ()), new BlockVector(corner2.getBlockX(), corner2.getBlockY(), corner2.getBlockZ()));
}
}
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,41 +1,45 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>areashop-worldguard-7_beta_2</artifactId>
<artifactId>areashop-fawe-1-15</artifactId>
<packaging>jar</packaging>
<name>AreaShop WorldGuard 7_beta_2</name>
<name>AreaShop FastAsyncWorldEdit 1.14+</name>
<version>latest</version>
<parent>
<groupId>me.wiefferink</groupId>
<artifactId>areashop-parent</artifactId>
<version>parent</version>
<version>1.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<repositories>
<repository>
<id>IS-Repo</id>
<url>https://mvn.intellectualsites.com/content/repositories/releases/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>craftbukkit</artifactId>
<version>1.13-R0.1-SNAPSHOT</version>
<scope>provided</scope>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.14.4-R0.1-SNAPSHOT</version>
<type>jar</type>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.sk89q</groupId>
<artifactId>worldedit</artifactId>
<scope>system</scope>
<version>any</version>
<systemPath>${project.basedir}/../dependencies/worldedit-bukkit-7.0.0-beta-04.jar</systemPath>
<groupId>com.intellectualsites.fawe</groupId>
<artifactId>FAWE-Bukkit</artifactId>
<version>1.16-380</version> <!-- Equivalent to WE 7.0.2? -->
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.sk89q</groupId>
<artifactId>worldguard</artifactId>
<scope>system</scope>
<version>any</version>
<systemPath>${project.basedir}/../dependencies/worldguard-legacy-7.0.0-beta-02.jar</systemPath>
<groupId>com.sk89q.worldguard</groupId>
<artifactId>worldguard-bukkit</artifactId>
<version>7.0.3</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -44,5 +48,6 @@
<version>latest</version>
<type>jar</type>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,283 @@
package me.wiefferink.areashop.handlers.fawe.v1_15;
import com.boydti.fawe.FaweAPI;
import com.boydti.fawe.object.FaweLimit;
import com.boydti.fawe.object.RelightMode;
import com.boydti.fawe.object.clipboard.MemoryOptimizedClipboard;
import com.google.common.annotations.Beta;
import com.sk89q.jnbt.NBTInputStream;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.IncompleteRegionException;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.extent.clipboard.io.*;
import com.sk89q.worldedit.extent.transform.BlockTransformExtent;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.mask.Mask2D;
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.session.ClipboardHolder;
import com.sk89q.worldedit.util.io.Closer;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import com.sk89q.worldguard.protection.regions.RegionType;
import me.wiefferink.areashop.interfaces.AreaShopInterface;
import me.wiefferink.areashop.interfaces.GeneralRegionInterface;
import me.wiefferink.areashop.interfaces.WorldEditInterface;
import me.wiefferink.areashop.interfaces.WorldEditSelection;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.bukkit.entity.Player;
import org.bukkit.util.BoundingBox;
import java.io.*;
import java.util.concurrent.CompletableFuture;
import java.util.zip.GZIPInputStream;
// Future: this class could use the schematic save/paste api of FAWE: https://github.com/boy0001/FastAsyncWorldedit/wiki/Pasting-a-schematic
// This would not allow for shaping the schematic to a polygon region though
public class FastAsyncWorldEditHandler extends WorldEditInterface {
public FastAsyncWorldEditHandler(AreaShopInterface pluginInterface) {
super(pluginInterface);
}
private static class RegionBoundMask implements Mask {
private final BoundingBox boundingBox;
public RegionBoundMask(final ProtectedRegion region) {
final BlockVector3 min = region.getMinimumPoint(), max = region.getMaximumPoint();
this.boundingBox = new BoundingBox(min.getX(), min.getY(), min.getZ(), max.getX(), max.getY(), max.getZ());
}
public RegionBoundMask(final BoundingBox boundingBox) {
this.boundingBox = boundingBox.clone();
}
@Override
public boolean test(BlockVector3 vector) {
return boundingBox.contains(vector.getX(), vector.getY(), vector.getZ());
}
@Override
public Mask2D toMask2D() {
return null;
}
@Override
public Mask copy() {
return new RegionBoundMask(boundingBox);
}
}
@Override
@Beta
public CompletableFuture<Boolean> restoreRegionBlocksAsync(File rawFile, GeneralRegionInterface regionInterface) {
File file = null;
ClipboardFormat format = null;
for (ClipboardFormat formatOption : BuiltInClipboardFormat.values()) {
if (new File(rawFile.getAbsolutePath() + "." + formatOption.getPrimaryFileExtension())
.exists()) {
file = new File(
rawFile.getAbsolutePath() + "." + formatOption.getPrimaryFileExtension());
format = formatOption;
break;
}
}
if (file == null) {
pluginInterface.getLogger().info("Did not restore region " + regionInterface.getName()
+ ", schematic file does not exist: " + rawFile.getAbsolutePath());
return CompletableFuture.completedFuture(false);
}
pluginInterface.debugI("Trying to restore region", regionInterface.getName(), " from file",
file.getAbsolutePath(), "with format", format.getName());
com.sk89q.worldedit.world.World world = null;
if (regionInterface.getName() != null) {
world = BukkitAdapter.adapt(regionInterface.getWorld());
}
if (world == null) {
pluginInterface.getLogger().info(
"Did not restore region " + regionInterface.getName() + ", world not found: "
+ regionInterface.getWorldName());
return CompletableFuture.completedFuture(false);
}
final CompletableFuture<Boolean> completableFuture = new CompletableFuture<>();
final FaweLimit limit = new FaweLimit();
limit.MAX_CHANGES = pluginInterface.getConfig().getInt("maximumBlocks");
EditSession editSession = FaweAPI.getEditSessionBuilder(world).limit(limit).relightMode(RelightMode.OPTIMAL).build();
editSession.setReorderMode(EditSession.ReorderMode.MULTI_STAGE);
ProtectedRegion region = regionInterface.getRegion();
final RegionType regionType = region.getType();
// Get the origin and size of the region
final BlockVector3 origin = BlockVector3
.at(region.getMinimumPoint().getBlockX(), region.getMinimumPoint().getBlockY(),
region.getMinimumPoint().getBlockZ());
final RegionBoundMask mask = new RegionBoundMask(region);
final File finalFile = file;
final String regionName = regionInterface.getName();
final double regionWidth = regionInterface.getWidth(), regionHeight = regionInterface.getHeight(), regionDepth = regionInterface.getDepth();
final LocalSession session =
new LocalSession(pluginInterface.getWorldEdit().getLocalConfiguration());
FaweAPI.getTaskManager().async(() -> {
// Read the schematic and paste it into the world
try (Closer closer = Closer.create()) {
FileInputStream fis = closer.register(new FileInputStream(finalFile));
BufferedInputStream bis = closer.register(new BufferedInputStream(fis));
NBTInputStream nbtStream = new NBTInputStream(new GZIPInputStream(bis));
ClipboardReader reader = new FastSchematicReader(nbtStream);
Clipboard clipboard = reader.read();
if (clipboard.getDimensions().getY() != regionHeight
|| clipboard.getDimensions().getX() != regionWidth
|| clipboard.getDimensions().getZ() != regionDepth) {
pluginInterface.getLogger().warning(
"Size of the region " + regionName
+ " is not the same as the schematic to restore!");
pluginInterface.debugI(
"schematic|region, x:" + clipboard.getDimensions().getX() + "|"
+ regionWidth + ", y:" + clipboard.getDimensions().getY()
+ "|" + regionHeight + ", z:" + clipboard.getDimensions()
.getZ() + "|" + regionDepth);
}
clipboard.setOrigin(clipboard.getMinimumPoint());
ClipboardHolder clipboardHolder = new ClipboardHolder(clipboard);
session.setBlockChangeLimit(limit.MAX_CHANGES);
session.setClipboard(clipboardHolder);
// Build operation
BlockTransformExtent extent = new BlockTransformExtent(clipboard);
ForwardExtentCopy copy =
new ForwardExtentCopy(extent, clipboard.getRegion(), clipboard.getOrigin(),
editSession, origin);
copy.setTransform(clipboardHolder.getTransform());
// Mask to region (for polygon and other weird shaped regions)
// TODO make this more efficient (especially for polygon regions)
if (regionType != RegionType.CUBOID) {
copy.setSourceMask(mask);
}
Operations.completeLegacy(copy);
} catch (MaxChangedBlocksException e) {
pluginInterface.getLogger().warning(
"exceeded the block limit while restoring schematic of " + regionInterface.getName()
+ ", limit in exception: " + e.getBlockLimit() + ", limit passed by AreaShop: "
+ pluginInterface.getConfig().getInt("maximumBlocks"));
CompletableFuture.completedFuture(false);
} catch (IOException e) {
pluginInterface.getLogger().warning(
"An error occured while restoring schematic of " + regionInterface.getName()
+ ", enable debug to see the complete stacktrace");
pluginInterface.debugI(ExceptionUtils.getStackTrace(e));
CompletableFuture.completedFuture(false);
} catch (Exception e) {
pluginInterface.getLogger()
.warning("crashed during restore of " + regionInterface.getName());
pluginInterface.debugI(ExceptionUtils.getStackTrace(e));
CompletableFuture.completedFuture(false);
}
editSession.flushQueue();
CompletableFuture.completedFuture(true);
});
return completableFuture;
}
@Override
public boolean restoreRegionBlocks(File rawFile, GeneralRegionInterface regionInterface) {
return restoreRegionBlocksAsync(rawFile, regionInterface).join();
}
@Override
@Beta
public CompletableFuture<Boolean> saveRegionBlocksAsync(File file, GeneralRegionInterface regionInterface) {
// TODO implement using the FastAsyncWorldEdit api to save async
ClipboardFormat format = BuiltInClipboardFormat.MINECRAFT_STRUCTURE;
// TODO allow selecting FAWE format in the config? (when enabled you cannot go back to vanilla WorldEdit easily)
file = new File(file.getAbsolutePath() + "." + format.getPrimaryFileExtension());
pluginInterface.debugI("Trying to save region", regionInterface.getName(), " to file",
file.getAbsolutePath(), "with format", format.getName());
com.sk89q.worldedit.world.World world = null;
if (regionInterface.getWorld() != null) {
world = BukkitAdapter.adapt(regionInterface.getWorld());
}
if (world == null) {
pluginInterface.getLogger().warning(
"Did not save region " + regionInterface.getName() + ", world not found: "
+ regionInterface.getWorldName());
return CompletableFuture.completedFuture(false);
}
final FaweLimit limit = new FaweLimit();
limit.MAX_CHANGES = pluginInterface.getConfig().getInt("maximumBlocks");
EditSession editSession = FaweAPI.getEditSessionBuilder(world).relightMode(RelightMode.OPTIMAL).limit(limit).build();
final ProtectedRegion region = regionInterface.getRegion();
final BlockVector3 min = region.getMinimumPoint(), max = region.getMaximumPoint();
final String regionName = regionInterface.getName();
final World finalWorld = world;
final CompletableFuture<Boolean> completableFuture = new CompletableFuture<>();
final File finalFile = file;
FaweAPI.getTaskManager().async(() -> {
// Create a clipboard
CuboidRegion selection =
new CuboidRegion(finalWorld, min, max);
Clipboard clipboard = new MemoryOptimizedClipboard(selection);
clipboard.setOrigin(min);
ForwardExtentCopy copy = new ForwardExtentCopy(editSession,
selection.clone(), clipboard,
min);
try {
Operations.completeLegacy(copy);
} catch (MaxChangedBlocksException e) {
pluginInterface.getLogger().warning(
"Exceeded the block limit while saving schematic of " + regionName
+ ", limit in exception: " + e.getBlockLimit() + ", limit passed by AreaShop: "
+ pluginInterface.getConfig().getInt("maximumBlocks"));
completableFuture.complete(false);
}
try (Closer closer = Closer.create()) {
FileOutputStream fos = closer.register(new FileOutputStream(finalFile));
BufferedOutputStream bos = closer.register(new BufferedOutputStream(fos));
ClipboardWriter writer = closer.register(format.getWriter(bos));
writer.write(clipboard);
} catch (IOException e) {
pluginInterface.getLogger().warning(
"An error occured while saving schematic of " + regionName
+ ", enable debug to see the complete stacktrace");
pluginInterface.debugI(ExceptionUtils.getStackTrace(e));
completableFuture.complete(false);
} catch (Exception e) {
pluginInterface.getLogger()
.warning("Crashed during save of " + regionName);
pluginInterface.debugI(ExceptionUtils.getStackTrace(e));
completableFuture.complete(false);
}
completableFuture.complete(true);
});
return completableFuture;
}
@Override
public boolean saveRegionBlocks(File file, GeneralRegionInterface regionInterface) {
return saveRegionBlocksAsync(file, regionInterface).join();
}
@Override
public WorldEditSelection getPlayerSelection(Player player) {
try {
Region region = pluginInterface.getWorldEdit().getSession(player)
.getSelection(BukkitAdapter.adapt(player.getWorld()));
return new WorldEditSelection(player.getWorld(),
BukkitAdapter.adapt(player.getWorld(), region.getMinimumPoint()),
BukkitAdapter.adapt(player.getWorld(), region.getMaximumPoint()));
} catch (IncompleteRegionException e) {
return null;
}
}
}
+38
View File
@@ -0,0 +1,38 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>areashop-interface</artifactId>
<packaging>jar</packaging>
<name>AreaShop Interface</name>
<version>latest</version>
<parent>
<groupId>me.wiefferink</groupId>
<artifactId>areashop-parent</artifactId>
<version>1.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.13.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.sk89q.worldedit</groupId>
<artifactId>worldedit-bukkit</artifactId>
<version>7.1.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.sk89q.worldguard</groupId>
<artifactId>worldguard-bukkit</artifactId>
<version>7.0.3</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
@@ -3,10 +3,11 @@ package me.wiefferink.areashop.interfaces;
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.Plugin;
import java.util.logging.Logger;
public interface AreaShopInterface {
public interface AreaShopInterface extends Plugin {
void debugI(Object... message);
YamlConfiguration getConfig();
@@ -56,7 +56,7 @@ public class RegionAccessSet {
result.addAll(playerUniqueIds);
for(String playerName : playerNames) {
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(playerName);
if(offlinePlayer != null && offlinePlayer.getUniqueId() != null) {
if (offlinePlayer.hasPlayedBefore()) {
result.add(offlinePlayer.getUniqueId());
}
}
@@ -3,6 +3,7 @@ package me.wiefferink.areashop.interfaces;
import org.bukkit.entity.Player;
import java.io.File;
import java.util.concurrent.CompletableFuture;
public abstract class WorldEditInterface {
protected final AreaShopInterface pluginInterface;
@@ -20,6 +21,10 @@ public abstract class WorldEditInterface {
*/
public abstract boolean restoreRegionBlocks(File file, GeneralRegionInterface regionInterface);
public CompletableFuture<Boolean> restoreRegionBlocksAsync(File file, GeneralRegionInterface regionInterface) {
return CompletableFuture.completedFuture(restoreRegionBlocks(file, regionInterface));
}
/**
* Different way to save blocks per implementation, newer ones support entities as well.
* Why: the schematic api has changed between WorldEdit 5 and 6, and the schematic format changed between 6 and 7
@@ -29,6 +34,10 @@ public abstract class WorldEditInterface {
*/
public abstract boolean saveRegionBlocks(File file, GeneralRegionInterface regionInterface);
public CompletableFuture<Boolean> saveRegionBlocksAsync(File file, GeneralRegionInterface regionInterface) {
return CompletableFuture.completedFuture(saveRegionBlocks(file, regionInterface));
}
/**
* Get the selection of the player.
* Why: the underlying WorldEdit selection class has changed from interface <-> class
@@ -1,41 +1,45 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>areashop-worldguard-7_beta_1</artifactId>
<artifactId>areashop-worldedit-7</artifactId>
<packaging>jar</packaging>
<name>AreaShop WorldGuard 7_beta_1</name>
<name>AreaShop WorldEdit 7</name>
<version>latest</version>
<description>
World Edit compatibility handler
- Deprecated usages on 7.2.0
- Compiles against 7.0.1, 7.1.0-SNAPSHOT, 7.2.0-SNAPSHOT
</description>
<parent>
<groupId>me.wiefferink</groupId>
<artifactId>areashop-parent</artifactId>
<version>parent</version>
<version>1.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>craftbukkit</artifactId>
<version>1.13-R0.1-SNAPSHOT</version>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.13.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
<type>jar</type>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.sk89q</groupId>
<artifactId>worldedit</artifactId>
<scope>system</scope>
<version>any</version>
<systemPath>${project.basedir}/../dependencies/worldedit-bukkit-7.0.0-beta-01.jar</systemPath>
<groupId>com.sk89q.worldedit</groupId>
<artifactId>worldedit-bukkit</artifactId>
<version>7.0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.sk89q</groupId>
<artifactId>worldguard</artifactId>
<scope>system</scope>
<version>any</version>
<systemPath>${project.basedir}/../dependencies/worldguard-legacy-7.0.0-beta-01.jar</systemPath>
<groupId>com.sk89q.worldguard</groupId>
<artifactId>worldguard-bukkit</artifactId>
<version>7.0.4-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -1,4 +1,4 @@
package me.wiefferink.areashop.handlers;
package me.wiefferink.areashop.handlers.worldedit.v7;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.IncompleteRegionException;
@@ -37,9 +37,9 @@ import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class WorldEditHandler7_beta_4 extends WorldEditInterface {
public class WorldEditHandler extends WorldEditInterface {
public WorldEditHandler7_beta_4(AreaShopInterface pluginInterface) {
public WorldEditHandler(AreaShopInterface pluginInterface) {
super(pluginInterface);
}
@@ -84,7 +84,9 @@ public class WorldEditHandler7_beta_4 extends WorldEditInterface {
pluginInterface.getLogger().info("Did not restore region " + regionInterface.getName() + ", world not found: " + regionInterface.getWorldName());
return false;
}
EditSession editSession = pluginInterface.getWorldEdit().getWorldEdit().getEditSessionFactory().getEditSession(world, pluginInterface.getConfig().getInt("maximumBlocks"));
EditSession editSession = pluginInterface.getWorldEdit().getWorldEdit() // WARNING Deprecated in 7.2.0!
.getEditSessionFactory()
.getEditSession(world, pluginInterface.getConfig().getInt("maximumBlocks"));
ProtectedRegion region = regionInterface.getRegion();
// Get the origin and size of the region
BlockVector3 origin = BlockVector3.at(region.getMinimumPoint().getBlockX(), region.getMinimumPoint().getBlockY(), region.getMinimumPoint().getBlockZ());
@@ -142,7 +144,7 @@ public class WorldEditHandler7_beta_4 extends WorldEditInterface {
pluginInterface.debugI(ExceptionUtils.getStackTrace(e));
return false;
}
editSession.flushSession();
editSession.close();
return true;
}
@@ -170,7 +172,9 @@ public class WorldEditHandler7_beta_4 extends WorldEditInterface {
pluginInterface.getLogger().warning("Did not save region " + regionInterface.getName() + ", world not found: " + regionInterface.getWorldName());
return false;
}
EditSession editSession = pluginInterface.getWorldEdit().getWorldEdit().getEditSessionFactory().getEditSession(world, pluginInterface.getConfig().getInt("maximumBlocks"));
EditSession editSession = pluginInterface.getWorldEdit().getWorldEdit() // WARNING Deprecated in 7.2.0!
.getEditSessionFactory()
.getEditSession(world, pluginInterface.getConfig().getInt("maximumBlocks"));
// Create a clipboard
CuboidRegion selection = new CuboidRegion(world, regionInterface.getRegion().getMinimumPoint(), regionInterface.getRegion().getMaximumPoint());
@@ -1,41 +1,38 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>areashop-worldguard-6_1_3</artifactId>
<artifactId>areashop-worldguard-7</artifactId>
<packaging>jar</packaging>
<name>AreaShop WorldGuard 6_1_3</name>
<name>AreaShop WorldGuard 7</name>
<version>latest</version>
<parent>
<groupId>me.wiefferink</groupId>
<artifactId>areashop-parent</artifactId>
<version>parent</version>
<version>1.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
<scope>system</scope>
<version>any</version>
<systemPath>${project.basedir}/../dependencies/bukkit-1.7.9-R0.2.jar</systemPath>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.13.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
<type>jar</type>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.sk89q.worldguard</groupId>
<artifactId>worldguard-legacy</artifactId>
<scope>system</scope>
<version>any</version>
<systemPath>${project.basedir}/../dependencies/worldguard-legacy-6.1.3-SNAPSHOT.jar</systemPath>
<groupId>com.sk89q.worldedit</groupId>
<artifactId>worldedit-bukkit</artifactId>
<scope>provided</scope>
<version>7.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>me.wiefferink</groupId>
<artifactId>areashop-worldguard-6</artifactId>
<version>latest</version>
<type>jar</type>
<groupId>com.sk89q.worldguard</groupId>
<artifactId>worldguard-bukkit</artifactId>
<version>7.0.4-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
@@ -46,4 +43,5 @@
<type>jar</type>
</dependency>
</dependencies>
</project>
@@ -1,4 +1,4 @@
package me.wiefferink.areashop.handlers;
package me.wiefferink.areashop.handlers.worldguard.v7;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.math.BlockVector2;
@@ -27,9 +27,9 @@ import java.util.List;
import java.util.Set;
import java.util.UUID;
public class WorldGuardHandler7_beta_2 extends WorldGuardInterface {
public class WorldGuardHandler extends WorldGuardInterface {
public WorldGuardHandler7_beta_2(AreaShopInterface pluginInterface) {
public WorldGuardHandler(AreaShopInterface pluginInterface) {
super(pluginInterface);
}
+31 -18
View File
@@ -4,7 +4,7 @@
<groupId>me.wiefferink</groupId>
<artifactId>areashop-parent</artifactId>
<packaging>pom</packaging>
<version>parent</version>
<version>1.0</version>
<name>AreaShop Parent</name>
<url>https://github.com/NLthijs48/AreaShop</url>
@@ -39,34 +39,46 @@
<id>bstats-repo</id>
<url>http://repo.bstats.org/content/repositories/releases/</url>
</repository>
<repository>
<id>mvn-repo</id>
<url>https://mvnrepository.com/artifact/org.bstats/bstats-bukkit</url>
</repository>
<repository>
<id>sk89q-repo</id>
<url>https://maven.enginehub.org/repo/</url>
</repository>
<repository>
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
</repositories>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<build.number>#CUSTOM</build.number>
<!--build.number>#CUSTOM</build.number-->
</properties>
<modules>
<module>areashop-interface</module>
<module>areashop-bukkit-1_12</module>
<module>areashop-bukkit-1_13</module>
<module>areashop-worldguard-5</module>
<module>areashop-worldguard-6</module>
<module>areashop-worldguard-6_1_3</module>
<module>areashop-worldguard-7_beta_1</module>
<module>areashop-worldguard-7_beta_2</module>
<module>areashop-worldedit-5</module>
<module>areashop-worldedit-6</module>
<module>areashop-worldedit-7_beta_1</module>
<module>areashop-worldedit-7_beta_4</module>
<module>areashop-fastasyncworldedit</module>
<module>hooks/areashop-interface</module>
<!-- FAWE Compat -->
<module>hooks/areashop-fawe-1-15</module>
<!-- World Edit Compat -->
<module>hooks/areashop-worldedit-7</module>
<!-- World Guard Compat -->
<module>hooks/areashop-worldguard-7</module>
<module>AreaShop</module>
</modules>
<build>
<plugins>
<defaultGoal>clean package</defaultGoal>
<!--plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
@@ -85,7 +97,8 @@
<configuration>
<configLocation>config/checkstyle.xml</configLocation>
<suppressionsLocation>config/checkstyle-suppressions.xml</suppressionsLocation>
<suppressionsFileExpression>config/checkstyle.suppressions.file</suppressionsFileExpression>
<suppressionsFileExpression>config/checkstyle.suppressions.file
</suppressionsFileExpression>
<encoding>UTF-8</encoding>
<consoleOutput>true</consoleOutput>
<failsOnError>true</failsOnError>
@@ -97,7 +110,7 @@
</execution>
</executions>
</plugin>
</plugins>
</plugins-->
</build>
</project>