mirror of
https://github.com/md5sha256/AreaShop.git
synced 2026-11-07 01:42:34 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b8fbb53633 | ||
|
|
cfda4f56e3 | ||
|
|
832d8967a3 | ||
|
|
c369d23f74 | ||
|
|
b50d57739f | ||
|
|
ce9438eaeb | ||
|
|
47cc259c40 | ||
|
|
e6ae122b86 | ||
|
|
2562075b90 | ||
|
|
9fc5d8a314 | ||
|
|
e96b179c48 | ||
|
|
49bed6f655 | ||
|
|
ffc5b03a75 | ||
|
|
69fea8ab7e | ||
|
|
29fc2c4205 | ||
|
|
2dd6d4ec4a | ||
|
|
789073f6d6 | ||
|
|
d211bf2f43 | ||
|
|
a6659cb14d | ||
|
|
880218cca0 | ||
|
|
3426381273 | ||
|
|
80a73fecea | ||
|
|
590d5a4988 | ||
|
|
dda4a090fb | ||
|
|
3a415513dd |
No files matched your search
+33
-27
@@ -1,32 +1,38 @@
|
||||
# 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 : "build"
|
||||
|
||||
name: Java CI with Maven
|
||||
on : [ "pull_request", "push" ]
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
jobs :
|
||||
build :
|
||||
strategy :
|
||||
matrix :
|
||||
java : [ 16 ]
|
||||
# java: ["1.8", "11"]
|
||||
os : [ "ubuntu-18.04" ]
|
||||
runs-on : "${{ matrix.os }}"
|
||||
steps :
|
||||
- name : "Checkout Repository"
|
||||
uses : "actions/checkout@v2.3.4"
|
||||
|
||||
jobs:
|
||||
build:
|
||||
- name : "Checkout submodules"
|
||||
uses : "srt32/git-actions@v0.0.3"
|
||||
with :
|
||||
args : "git submodule update --init --recursive"
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
- name : "Restore Gradle cache"
|
||||
uses : "actions/cache@v2"
|
||||
with :
|
||||
path : "~/.gradle/caches"
|
||||
key : "${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }}"
|
||||
restore-keys : |
|
||||
${{ runner.os }}-gradle-
|
||||
- name : "Setup JDK ${{ matrix.java }}"
|
||||
uses : "actions/setup-java@v1.4.3"
|
||||
with :
|
||||
java-version : "${{ matrix.java }}"
|
||||
|
||||
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
|
||||
|
||||
- name : "Grant execute permission for gradlew"
|
||||
run : "chmod +x gradlew"
|
||||
|
||||
- name : "Build with Gradle"
|
||||
run : "./gradlew clean build"
|
||||
+22
-3
@@ -1,4 +1,4 @@
|
||||
# Maven stuff
|
||||
### Maven ###
|
||||
target
|
||||
|
||||
.project
|
||||
@@ -14,12 +14,31 @@ local.properties
|
||||
.settings/
|
||||
.loadpath
|
||||
|
||||
# Locally stored "Eclipse launch configurations"
|
||||
### Locally stored "Eclipse launch configurations" ###
|
||||
*.launch
|
||||
|
||||
# IntelliJ IDEA
|
||||
### IntelliJ IDEA ###
|
||||
*.iml
|
||||
.idea
|
||||
dependency-reduced-pom.xml
|
||||
|
||||
desktop.ini
|
||||
|
||||
### Gradle ###
|
||||
.gradle
|
||||
build/
|
||||
|
||||
# Ignore Gradle GUI config
|
||||
gradle-app.setting
|
||||
|
||||
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
|
||||
!gradle-wrapper.jar
|
||||
|
||||
# Cache of project
|
||||
.gradletasknamecache
|
||||
|
||||
# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898
|
||||
# gradle/wrapper/gradle-wrapper.properties
|
||||
|
||||
### Gradle Patch ###
|
||||
**/build/
|
||||
@@ -0,0 +1,60 @@
|
||||
import org.apache.tools.ant.filters.ReplaceTokens
|
||||
|
||||
plugins {
|
||||
id 'java-library'
|
||||
id 'com.github.johnrengelman.shadow' version '7.0.0'
|
||||
}
|
||||
|
||||
description = 'AreaShop'
|
||||
version = '2.6.6'
|
||||
|
||||
dependencies {
|
||||
// Spigot api
|
||||
compileOnly 'org.spigotmc:spigot-api:1.16.5-R0.1-SNAPSHOT'
|
||||
|
||||
// Libs
|
||||
implementation 'com.github.NLthijs48:InteractiveMessenger:e7749258ca'
|
||||
implementation 'co.aikar:taskchain-bukkit:3.7.2'
|
||||
implementation 'io.papermc:paperlib:1.0.6'
|
||||
|
||||
// Hooks
|
||||
implementation project(':areashop-interface')
|
||||
implementation project(':areashop-worldguard-7')
|
||||
implementation project(':areashop-worldedit-7')
|
||||
implementation project(':areashop-fawe-1-16')
|
||||
implementation project(':areashop-fawe-1-17')
|
||||
implementation project(':areashop-nms-1-16-5')
|
||||
implementation project(':areashop-nms-1-17')
|
||||
|
||||
// Runtime plugins
|
||||
compileOnly 'com.sk89q.worldedit:worldedit-bukkit:7.2.5'
|
||||
compileOnly 'com.sk89q.worldguard:worldguard-bukkit:7.0.5'
|
||||
compileOnly 'com.github.MilkBowl:VaultAPI:1.7'
|
||||
}
|
||||
|
||||
processResources {
|
||||
|
||||
from (sourceSets.main.resources) {
|
||||
filter ReplaceTokens, tokens: [version: project.version]
|
||||
duplicatesStrategy(DuplicatesStrategy.INCLUDE)
|
||||
}
|
||||
}
|
||||
|
||||
assemble {
|
||||
dependsOn(shadowJar)
|
||||
}
|
||||
|
||||
jar {
|
||||
archiveBaseName.set('AreaShop')
|
||||
classifier('original')
|
||||
}
|
||||
|
||||
shadowJar {
|
||||
archiveBaseName.set('AreaShop')
|
||||
String relocationBase = 'me.wiefferink.areashop.shaded'
|
||||
classifier('')
|
||||
relocate('co.aikar.taskchain', "${relocationBase}.taskchain")
|
||||
relocate('me.wiefferink.interactivemessenger', "${relocationBase}.interactivemessenger")
|
||||
relocate('org.bstats', "${relocationBase}.bstats")
|
||||
relocate('io.papermc', "${relocationBase}.papermc")
|
||||
}
|
||||
@@ -1,285 +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>
|
||||
|
||||
<parent>
|
||||
<groupId>me.wiefferink</groupId>
|
||||
<artifactId>areashop-parent</artifactId>
|
||||
<version>1.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>areashop</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>AreaShop</name>
|
||||
<version>2.6.2</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.13.2+ -->
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.13.2-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- InteractiveMessenger library -->
|
||||
<dependency>
|
||||
<groupId>me.wiefferink</groupId>
|
||||
<artifactId>interactivemessenger</artifactId>
|
||||
<version>1.1-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<!-- TaskChain library -->
|
||||
<dependency>
|
||||
<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.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>
|
||||
|
||||
<!-- Interfaces that specific WorldGuard and WorldEdit versions are built against -->
|
||||
<dependency>
|
||||
<groupId>me.wiefferink</groupId>
|
||||
<artifactId>areashop-interface</artifactId>
|
||||
<version>latest</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- WorldGuard implementations -->
|
||||
<dependency>
|
||||
<groupId>me.wiefferink</groupId>
|
||||
<artifactId>areashop-worldguard-7</artifactId>
|
||||
<version>latest</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- WorldEdit implementations -->
|
||||
<dependency>
|
||||
<groupId>me.wiefferink</groupId>
|
||||
<artifactId>areashop-worldedit-7</artifactId>
|
||||
<version>latest</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- FAWE compat -->
|
||||
<dependency>
|
||||
<groupId>me.wiefferink</groupId>
|
||||
<artifactId>areashop-fawe-1-15</artifactId>
|
||||
<version>latest</version>
|
||||
<type>jar</type>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Vault -->
|
||||
<dependency>
|
||||
<groupId>net.milkbowl.vault</groupId>
|
||||
<artifactId>VaultAPI</artifactId>
|
||||
<version>1.7</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- bStats -->
|
||||
<dependency>
|
||||
<groupId>org.bstats</groupId>
|
||||
<artifactId>bstats-bukkit</artifactId>
|
||||
<version>1.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<profiles>
|
||||
<!-- Copy the jar file to a test server, activate by using -DcopyResult="/path/to/test/server" -->
|
||||
<profile>
|
||||
<id>test-locally</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>copyResult</name>
|
||||
</property>
|
||||
</activation>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
<version>1.8</version>
|
||||
<configuration>
|
||||
<target>
|
||||
<copy file="./target/${project.build.finalName}.jar"
|
||||
tofile="${copyResult}\${project.build.finalName}.jar"/>
|
||||
</target>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>run</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
|
||||
<!-- Package the source files in a jar, activate by using -Dsources -->
|
||||
<profile>
|
||||
<id>package-sources</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>sources</name>
|
||||
</property>
|
||||
</activation>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<version>3.2.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<id>attach-sources</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
|
||||
<!-- Produce javadoc files, activate by using -Djavadoc -->
|
||||
<profile>
|
||||
<id>generate-javadoc</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>javadoc</name>
|
||||
</property>
|
||||
</activation>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<id>attach-javadocs</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<excludePackageNames>me.wiefferink.areashop.lib</excludePackageNames>
|
||||
<destDir>${javadoc}</destDir>
|
||||
<links>
|
||||
<link>https://hub.spigotmc.org/javadocs/bukkit/</link>
|
||||
<link>http://docs.sk89q.com/worldedit/apidocs/</link>
|
||||
<link>http://docs.sk89q.com/worldguard/apidocs/</link>
|
||||
</links>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<build>
|
||||
<directory>target</directory>
|
||||
<finalName>AreaShop</finalName>
|
||||
<resources>
|
||||
<resource>
|
||||
<targetPath>.</targetPath>
|
||||
<filtering>true</filtering>
|
||||
<directory>src/main/resources</directory>
|
||||
<includes>
|
||||
<include>plugin.yml</include>
|
||||
<include>config.yml</include>
|
||||
<include>hiddenConfig.yml</include>
|
||||
<include>default.yml</include>
|
||||
<include>README.md</include>
|
||||
<include>lang/*.yml</include>
|
||||
</includes>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.2.3</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</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 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>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.1</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -5,11 +5,11 @@ import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
import me.wiefferink.areashop.interfaces.AreaShopInterface;
|
||||
import me.wiefferink.areashop.interfaces.NMS;
|
||||
import me.wiefferink.areashop.interfaces.WorldEditInterface;
|
||||
import me.wiefferink.areashop.interfaces.WorldGuardInterface;
|
||||
import me.wiefferink.areashop.listeners.PlayerLoginLogoutListener;
|
||||
import me.wiefferink.areashop.managers.*;
|
||||
import me.wiefferink.areashop.tools.Analytics;
|
||||
import me.wiefferink.areashop.tools.GithubUpdateCheck;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import me.wiefferink.interactivemessenger.processing.Message;
|
||||
@@ -29,6 +29,7 @@ import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@@ -51,6 +52,7 @@ public final class AreaShop extends JavaPlugin implements AreaShopInterface {
|
||||
public static final String configFile = "config.yml";
|
||||
public static final String configFileHidden = "hiddenConfig.yml";
|
||||
public static final String versionFile = "versions";
|
||||
public static final String signErrorFile = "sign-errors.yml";
|
||||
// Euro tag for in the config
|
||||
public static final String currencyEuro = "%euro%";
|
||||
// Constants for handling file versions
|
||||
@@ -111,7 +113,7 @@ public final class AreaShop extends JavaPlugin implements AreaShopInterface {
|
||||
public static final String tagTeleportWorld = "tpworld";
|
||||
// REGEX Matcher for Versions which follow a x.x.x format.
|
||||
private static final Pattern VERSION_MATCHER_3 = Pattern.compile("([0-9]+)\\.([0-9]+)\\.([0-9]+)");
|
||||
private static final Pattern VERSION_MATCHER_2 = Pattern.compile("([0-9]+)\\.([0-9]+)\\.([0-9]+)");
|
||||
private static final Pattern VERSION_MATCHER_2 = Pattern.compile("([0-9]+)\\.([0-9]+)");
|
||||
// Statically available instance
|
||||
private static AreaShop instance = null;
|
||||
// General variables
|
||||
@@ -129,6 +131,8 @@ public final class AreaShop extends JavaPlugin implements AreaShopInterface {
|
||||
private List<String> chatprefix = null;
|
||||
private boolean ready = false;
|
||||
private GithubUpdateCheck githubUpdateCheck = null;
|
||||
private NMS nms;
|
||||
private SignErrorLogger signErrorLogger;
|
||||
|
||||
public static AreaShop getInstance() {
|
||||
return AreaShop.instance;
|
||||
@@ -264,6 +268,14 @@ public final class AreaShop extends JavaPlugin implements AreaShopInterface {
|
||||
this.chatprefix = chatprefix;
|
||||
}
|
||||
|
||||
public NMS getNMSHelper() {
|
||||
return this.nms;
|
||||
}
|
||||
|
||||
public SignErrorLogger getSignErrorLogger() {
|
||||
return this.signErrorLogger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to get WorldGuardInterface for version dependent things.
|
||||
*
|
||||
@@ -563,6 +575,22 @@ public final class AreaShop extends JavaPlugin implements AreaShopInterface {
|
||||
HandlerList.unregisterAll(this);
|
||||
}
|
||||
|
||||
private void setupNMS() throws IllegalStateException {
|
||||
final String packageName = Bukkit.getServer().getClass().getPackage().getName();
|
||||
final String[] split = packageName.split("\\.");
|
||||
final String nmsRevision = split[3];
|
||||
try {
|
||||
Class<?> rawClazz = Class.forName("me.wiefferink.areashop.nms." + nmsRevision + ".NMSImpl");
|
||||
if (!NMS.class.isAssignableFrom(rawClazz)) {
|
||||
throw new IllegalStateException("Invalid NMS Impl: " + rawClazz.getCanonicalName() + " does not implement the NMS!");
|
||||
}
|
||||
Class<? extends NMS> casted = rawClazz.asSubclass(NMS.class);
|
||||
this.nms = casted.getConstructor().newInstance();
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
throw new IllegalStateException("Failed to instantiate the NMS Helper!", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called on start or reload of the server.
|
||||
*/
|
||||
@@ -579,6 +607,11 @@ public final class AreaShop extends JavaPlugin implements AreaShopInterface {
|
||||
error = true;
|
||||
}
|
||||
|
||||
this.signErrorLogger = new SignErrorLogger(new File(getDataFolder(), signErrorFile));
|
||||
|
||||
// Setup the NMS helper
|
||||
setupNMS();
|
||||
|
||||
// Load all data from files and check versions
|
||||
fileManager = new FileManager();
|
||||
managers.add(fileManager);
|
||||
@@ -607,11 +640,6 @@ public final class AreaShop extends JavaPlugin implements AreaShopInterface {
|
||||
signLinkerManager = new SignLinkerManager();
|
||||
managers.add(signLinkerManager);
|
||||
|
||||
// Enable Metrics if config allows it
|
||||
if (getConfig().getBoolean("sendStats")) {
|
||||
Analytics.start();
|
||||
}
|
||||
|
||||
// Register dynamic permission (things declared in config)
|
||||
registerDynamicPermissions();
|
||||
|
||||
@@ -622,9 +650,10 @@ public final class AreaShop extends JavaPlugin implements AreaShopInterface {
|
||||
Matcher matcher0 = VERSION_MATCHER_3.matcher(latestVersion);
|
||||
boolean dual0 = false;
|
||||
if (!matcher0.find()) {
|
||||
matcher0 = VERSION_MATCHER_3.matcher(latestVersion);
|
||||
matcher0 = VERSION_MATCHER_2.matcher(latestVersion);
|
||||
if (!matcher0.find()) {
|
||||
throw new IllegalArgumentException("Invalid Versions Detected!");
|
||||
// FIXME log invalid version
|
||||
return false;
|
||||
}
|
||||
dual0 = true;
|
||||
}
|
||||
@@ -633,7 +662,8 @@ public final class AreaShop extends JavaPlugin implements AreaShopInterface {
|
||||
if (!matcher1.find()) {
|
||||
matcher1 = VERSION_MATCHER_2.matcher(currentVersion);
|
||||
if (!matcher1.find()) {
|
||||
throw new IllegalArgumentException("Invalid Versions Detected!");
|
||||
// FIXME log invalid version
|
||||
return false;
|
||||
}
|
||||
dual1 = true;
|
||||
}
|
||||
@@ -681,6 +711,32 @@ public final class AreaShop extends JavaPlugin implements AreaShopInterface {
|
||||
return true;
|
||||
}
|
||||
final String packageName = "me.wiefferink.areashop.handlers.";
|
||||
final Plugin fawe = getServer().getPluginManager().getPlugin("FastAsyncWorldEdit");
|
||||
if (fawe != null && fawe.isEnabled()) {
|
||||
final String version = fawe.getDescription().getVersion();
|
||||
if (version.startsWith("1.16")) {
|
||||
try {
|
||||
this.worldEditInterface = (WorldEditInterface) Class.forName(packageName + "fawe.v1_16.FastAsyncWorldEditHandler")
|
||||
.getDeclaredConstructor(AreaShopInterface.class)
|
||||
.newInstance(this);
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
getLogger().log(Level.SEVERE, "Failed to hook into FAWE!");
|
||||
ex.printStackTrace();
|
||||
}
|
||||
} else if (version.startsWith("1.17")) {
|
||||
try {
|
||||
this.worldEditInterface = (WorldEditInterface) Class.forName(packageName + "fawe.v1_17.FastAsyncWorldEditHandler")
|
||||
.getDeclaredConstructor(AreaShopInterface.class)
|
||||
.newInstance(this);
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
getLogger().log(Level.SEVERE, "Failed to hook into FAWE!");
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (this.worldEditInterface == null) {
|
||||
info("FAWE Version: " + version + " detected, no compatible handler found. Using the WorldEdit handler instead.");
|
||||
}
|
||||
}
|
||||
if (this.worldEditInterface == null) {
|
||||
final String version = worldEdit.getDescription().getVersion();
|
||||
Matcher matcher = VERSION_MATCHER_3.matcher(version);
|
||||
@@ -702,23 +758,6 @@ public final class AreaShop extends JavaPlugin implements AreaShopInterface {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
this.worldEdit = (WorldEditPlugin) worldEdit;
|
||||
final Plugin fawe = getServer().getPluginManager().getPlugin("FastAsyncWorldEdit");
|
||||
if (fawe != null && fawe.isEnabled()) {
|
||||
final String version = fawe.getDescription().getVersion();
|
||||
if (version.startsWith("1.15") || version.startsWith("1.16")) {
|
||||
try {
|
||||
this.worldEditInterface = (WorldEditInterface) Class.forName(packageName + "fawe.v1_15.FastAsyncWorldEditHandler")
|
||||
.getDeclaredConstructor(AreaShopInterface.class).newInstance(this);
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
getLogger().log(Level.SEVERE, "Failed to hook into FAWE!");
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (this.worldEditInterface == null) {
|
||||
info("FAWE Version: " + version + " detected, no compatible handler found. Using the WorldEdit handler instead.");
|
||||
}
|
||||
}
|
||||
final String wgVersion = worldGuard.getDescription().getVersion();
|
||||
Matcher matcher = VERSION_MATCHER_3.matcher(wgVersion);
|
||||
if (!matcher.find()) {
|
||||
@@ -796,7 +835,3 @@ public final class AreaShop extends JavaPlugin implements AreaShopInterface {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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.
|
||||
@@ -46,7 +43,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 +86,7 @@ public abstract class CommandAreaShop {
|
||||
return false;
|
||||
}
|
||||
|
||||
private class CommandTime {
|
||||
private static class CommandTime {
|
||||
public final String command;
|
||||
public final long time;
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import org.bukkit.entity.Player;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.TreeSet;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class DelCommand extends CommandAreaShop {
|
||||
|
||||
@@ -92,37 +93,41 @@ public class DelCommand extends CommandAreaShop {
|
||||
plugin.message(sender, "del-cancelled", Utils.combinedMessage(regionsCancelled, "region"));
|
||||
}
|
||||
} else {
|
||||
GeneralRegion region = plugin.getFileManager().getRegion(args[1]);
|
||||
if(region == null) {
|
||||
plugin.message(sender, "cmd-notRegistered", args[1]);
|
||||
return;
|
||||
}
|
||||
boolean isLandlord = sender instanceof Player && region.isLandlord(((Player)sender).getUniqueId());
|
||||
if(region instanceof RentRegion) {
|
||||
// Remove the rent if the player has permission
|
||||
if(sender.hasPermission("areashop.destroyrent") || (isLandlord && sender.hasPermission("areashop.destroyrent.landlord"))) {
|
||||
DeletingRegionEvent event = plugin.getFileManager().deleteRegion(region, true);
|
||||
if (event.isCancelled()) {
|
||||
plugin.message(sender, "general-cancelled", event.getReason());
|
||||
} else {
|
||||
plugin.message(sender, "destroy-successRent", region);
|
||||
}
|
||||
} else {
|
||||
plugin.message(sender, "destroy-noPermissionRent", region);
|
||||
}
|
||||
} else if(region instanceof BuyRegion) {
|
||||
// Remove the buy if the player has permission
|
||||
if(sender.hasPermission("areashop.destroybuy") || (isLandlord && sender.hasPermission("areashop.destroybuy.landlord"))) {
|
||||
DeletingRegionEvent event = plugin.getFileManager().deleteRegion(region, true);
|
||||
if (event.isCancelled()) {
|
||||
plugin.message(sender, "general-cancelled", event.getReason());
|
||||
} else {
|
||||
plugin.message(sender, "destroy-successBuy", region);
|
||||
}
|
||||
} else {
|
||||
plugin.message(sender, "destroy-noPermissionBuy", region);
|
||||
}
|
||||
}
|
||||
CompletableFuture<GeneralRegion> future = plugin.getFileManager().getRegionUnsafe(args[1]);
|
||||
Utils.newChain()
|
||||
.future(future)
|
||||
.syncLast(region -> {
|
||||
if(region == null) {
|
||||
plugin.message(sender, "cmd-notRegistered", args[1]);
|
||||
return;
|
||||
}
|
||||
boolean isLandlord = sender instanceof Player && region.isLandlord(((Player)sender).getUniqueId());
|
||||
if(region instanceof RentRegion) {
|
||||
// Remove the rent if the player has permission
|
||||
if(sender.hasPermission("areashop.destroyrent") || (isLandlord && sender.hasPermission("areashop.destroyrent.landlord"))) {
|
||||
DeletingRegionEvent event = plugin.getFileManager().deleteRegion(region, true);
|
||||
if (event.isCancelled()) {
|
||||
plugin.message(sender, "general-cancelled", event.getReason());
|
||||
} else {
|
||||
plugin.message(sender, "destroy-successRent", region);
|
||||
}
|
||||
} else {
|
||||
plugin.message(sender, "destroy-noPermissionRent", region);
|
||||
}
|
||||
} else if(region instanceof BuyRegion) {
|
||||
// Remove the buy if the player has permission
|
||||
if(sender.hasPermission("areashop.destroybuy") || (isLandlord && sender.hasPermission("areashop.destroybuy.landlord"))) {
|
||||
DeletingRegionEvent event = plugin.getFileManager().deleteRegion(region, true);
|
||||
if (event.isCancelled()) {
|
||||
plugin.message(sender, "general-cancelled", event.getReason());
|
||||
} else {
|
||||
plugin.message(sender, "destroy-successBuy", region);
|
||||
}
|
||||
} else {
|
||||
plugin.message(sender, "destroy-noPermissionBuy", region);
|
||||
}
|
||||
}
|
||||
}).execute();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import me.wiefferink.areashop.tools.Utils;
|
||||
import me.wiefferink.areashop.tools.Value;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Tag;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
@@ -41,9 +42,9 @@ public class TeleportFeature extends RegionFeature {
|
||||
*/
|
||||
private static boolean isSafe(Location location) {
|
||||
Block feet = location.getBlock();
|
||||
BlockState head = PaperLib.getBlockState(feet.getRelative(BlockFace.UP), true).getState();
|
||||
BlockState below = PaperLib.getBlockState(feet.getRelative(BlockFace.DOWN), true).getState();
|
||||
BlockState above = PaperLib.getBlockState(head.getBlock().getRelative(BlockFace.UP), true).getState();
|
||||
BlockState head = PaperLib.getBlockState(feet.getRelative(BlockFace.UP), false).getState();
|
||||
BlockState below = PaperLib.getBlockState(feet.getRelative(BlockFace.DOWN), false).getState();
|
||||
BlockState above = PaperLib.getBlockState(head.getBlock().getRelative(BlockFace.UP), false).getState();
|
||||
|
||||
// Check the block at the feet and head of the player
|
||||
if ((feet.getType().isSolid() && !canSpawnIn(feet.getType())) || feet.isLiquid()) {
|
||||
@@ -66,7 +67,7 @@ public class TeleportFeature extends RegionFeature {
|
||||
continue;
|
||||
}
|
||||
|
||||
around.add(PaperLib.getBlockState(below.getBlock().getRelative(x, y, z), true).getState().getType());
|
||||
around.add(PaperLib.getBlockState(below.getBlock().getRelative(x, y, z), false).getState().getType());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -101,17 +102,14 @@ public class TeleportFeature extends RegionFeature {
|
||||
* @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");
|
||||
return switch (material) {
|
||||
case CACTUS, DRAGON_EGG, MAGMA_BLOCK -> false;
|
||||
default -> !Tag.SIGNS.isTagged(material)
|
||||
&& !Tag.FENCES.isTagged(material)
|
||||
&& !Tag.FENCE_GATES.isTagged(material)
|
||||
&& !Tag.WALL_SIGNS.isTagged(material)
|
||||
&& !Tag.DOORS.isTagged(material);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -121,11 +119,10 @@ public class TeleportFeature extends RegionFeature {
|
||||
* @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");
|
||||
return switch (material) {
|
||||
case LAVA, CACTUS, FIRE, MAGMA_BLOCK -> false;
|
||||
default -> true;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -288,7 +285,9 @@ public class TeleportFeature extends RegionFeature {
|
||||
if (safeLocation.getBlockY() > 256 || safeLocation.getBlockY() < 0) {
|
||||
continue;
|
||||
}
|
||||
if (worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
|
||||
if (!insideRegion || worldguardRegion.contains(safeLocation.getBlockX(),
|
||||
safeLocation.getBlockY(),
|
||||
safeLocation.getBlockZ())) {
|
||||
checked++;
|
||||
done = isSafe(safeLocation) || checked > maxTries;
|
||||
blocksInRegionCopy = true;
|
||||
@@ -306,7 +305,9 @@ public class TeleportFeature extends RegionFeature {
|
||||
if (safeLocation.getBlockY() > 256 || safeLocation.getBlockY() < 0) {
|
||||
continue;
|
||||
}
|
||||
if (worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
|
||||
if (!insideRegion || worldguardRegion.contains(safeLocation.getBlockX(),
|
||||
safeLocation.getBlockY(),
|
||||
safeLocation.getBlockZ())) {
|
||||
checked++;
|
||||
done = isSafe(safeLocation) || checked > maxTries;
|
||||
blocksInRegionCopy = true;
|
||||
@@ -324,7 +325,9 @@ public class TeleportFeature extends RegionFeature {
|
||||
if (safeLocation.getBlockY() > 256 || safeLocation.getBlockY() < 0) {
|
||||
continue;
|
||||
}
|
||||
if (worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
|
||||
if (!insideRegion || worldguardRegion.contains(safeLocation.getBlockX(),
|
||||
safeLocation.getBlockY(),
|
||||
safeLocation.getBlockZ())) {
|
||||
checked++;
|
||||
done = isSafe(safeLocation) || checked > maxTries;
|
||||
blocksInRegionCopy = true;
|
||||
@@ -342,7 +345,9 @@ public class TeleportFeature extends RegionFeature {
|
||||
if (safeLocation.getBlockY() > 256 || safeLocation.getBlockY() < 0) {
|
||||
continue;
|
||||
}
|
||||
if (worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
|
||||
if (!insideRegion || worldguardRegion.contains(safeLocation.getBlockX(),
|
||||
safeLocation.getBlockY(),
|
||||
safeLocation.getBlockZ())) {
|
||||
checked++;
|
||||
done = isSafe(safeLocation) || checked > maxTries;
|
||||
blocksInRegionCopy = true;
|
||||
@@ -360,7 +365,9 @@ public class TeleportFeature extends RegionFeature {
|
||||
}
|
||||
if (!done && !topDone) {
|
||||
safeLocation = startLocation.clone().add(0, radius, 0);
|
||||
if (worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
|
||||
if (!insideRegion || worldguardRegion.contains(safeLocation.getBlockX(),
|
||||
safeLocation.getBlockY(),
|
||||
safeLocation.getBlockZ())) {
|
||||
checked++;
|
||||
done = isSafe(safeLocation) || checked > maxTries;
|
||||
blocksInRegionCopy = true;
|
||||
@@ -371,7 +378,9 @@ public class TeleportFeature extends RegionFeature {
|
||||
// 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) {
|
||||
if (!insideRegion || worldguardRegion.contains(safeLocation.getBlockX(),
|
||||
safeLocation.getBlockY(),
|
||||
safeLocation.getBlockZ())) {
|
||||
checked++;
|
||||
done = isSafe(safeLocation) || checked > maxTries;
|
||||
blocksInRegionCopy = true;
|
||||
@@ -381,7 +390,9 @@ public class TeleportFeature extends RegionFeature {
|
||||
// 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) {
|
||||
if (!insideRegion || worldguardRegion.contains(safeLocation.getBlockX(),
|
||||
safeLocation.getBlockY(),
|
||||
safeLocation.getBlockZ())) {
|
||||
checked++;
|
||||
done = isSafe(safeLocation) || checked > maxTries;
|
||||
blocksInRegionCopy = true;
|
||||
@@ -391,7 +402,9 @@ public class TeleportFeature extends RegionFeature {
|
||||
// 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) {
|
||||
if (!insideRegion || worldguardRegion.contains(safeLocation.getBlockX(),
|
||||
safeLocation.getBlockY(),
|
||||
safeLocation.getBlockZ())) {
|
||||
checked++;
|
||||
done = isSafe(safeLocation) || checked > maxTries;
|
||||
blocksInRegionCopy = true;
|
||||
@@ -401,7 +414,9 @@ public class TeleportFeature extends RegionFeature {
|
||||
// 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) {
|
||||
if (!insideRegion || worldguardRegion.contains(safeLocation.getBlockX(),
|
||||
safeLocation.getBlockY(),
|
||||
safeLocation.getBlockZ())) {
|
||||
checked++;
|
||||
done = isSafe(safeLocation) || checked > maxTries;
|
||||
blocksInRegionCopy = true;
|
||||
@@ -419,7 +434,9 @@ public class TeleportFeature extends RegionFeature {
|
||||
}
|
||||
if (!done && !bottomDone) {
|
||||
safeLocation = startLocation.clone().add(0, -radius, 0);
|
||||
if (worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
|
||||
if (!insideRegion || worldguardRegion.contains(safeLocation.getBlockX(),
|
||||
safeLocation.getBlockY(),
|
||||
safeLocation.getBlockZ())) {
|
||||
checked++;
|
||||
done = isSafe(safeLocation) || checked > maxTries;
|
||||
blocksInRegionCopy = true;
|
||||
@@ -430,7 +447,9 @@ public class TeleportFeature extends RegionFeature {
|
||||
// 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) {
|
||||
if (!insideRegion || worldguardRegion.contains(safeLocation.getBlockX(),
|
||||
safeLocation.getBlockY(),
|
||||
safeLocation.getBlockZ())) {
|
||||
checked++;
|
||||
done = isSafe(safeLocation) || checked > maxTries;
|
||||
blocksInRegionCopy = true;
|
||||
@@ -440,7 +459,9 @@ public class TeleportFeature extends RegionFeature {
|
||||
// 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) {
|
||||
if (!insideRegion || worldguardRegion.contains(safeLocation.getBlockX(),
|
||||
safeLocation.getBlockY(),
|
||||
safeLocation.getBlockZ())) {
|
||||
checked++;
|
||||
done = isSafe(safeLocation) || checked > maxTries;
|
||||
blocksInRegionCopy = true;
|
||||
@@ -450,7 +471,9 @@ public class TeleportFeature extends RegionFeature {
|
||||
// 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) {
|
||||
if (!insideRegion || worldguardRegion.contains(safeLocation.getBlockX(),
|
||||
safeLocation.getBlockY(),
|
||||
safeLocation.getBlockZ())) {
|
||||
checked++;
|
||||
done = isSafe(safeLocation) || checked > maxTries;
|
||||
blocksInRegionCopy = true;
|
||||
@@ -460,7 +483,9 @@ public class TeleportFeature extends RegionFeature {
|
||||
// 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) {
|
||||
if (!insideRegion || worldguardRegion.contains(safeLocation.getBlockX(),
|
||||
safeLocation.getBlockY(),
|
||||
safeLocation.getBlockZ())) {
|
||||
checked++;
|
||||
done = isSafe(safeLocation) || checked > maxTries;
|
||||
blocksInRegionCopy = true;
|
||||
@@ -586,7 +611,7 @@ public class TeleportFeature extends RegionFeature {
|
||||
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());
|
||||
startLocation = middle.toLocation(getRegion().getWorld(), player.getLocation().getYaw(), player.getLocation().getPitch());
|
||||
}
|
||||
|
||||
// Set location in the center of the block
|
||||
|
||||
@@ -4,6 +4,8 @@ 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.interfaces.BlockBehaviourHelper;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.tools.Materials;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
@@ -11,6 +13,7 @@ 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;
|
||||
@@ -23,12 +26,51 @@ import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* Sign that is connected to a region to display information and interact with the region.
|
||||
*/
|
||||
public class RegionSign {
|
||||
|
||||
|
||||
public static final BlockBehaviourHelper behaviourHelper = AreaShop.getInstance().getNMSHelper().behaviourHelper();
|
||||
public static Level invalidSignLogLevel;
|
||||
public static boolean removeInvalidSigns;
|
||||
|
||||
static {
|
||||
YamlConfiguration configuration = AreaShop.getInstance().getConfig();
|
||||
removeInvalidSigns = configuration.getBoolean("signs.removeInvalid");
|
||||
final String rawLogLevel = configuration.getString("signs.invalidSignLogLevel", "WARNING");
|
||||
try {
|
||||
assert rawLogLevel != null;
|
||||
invalidSignLogLevel = Level.parse(rawLogLevel);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
AreaShop.warn("Invalid Logging Level: " + rawLogLevel);
|
||||
invalidSignLogLevel = Level.WARNING;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static boolean canLogSignError() {
|
||||
return AreaShop.getInstance().getLogger().isLoggable(invalidSignLogLevel);
|
||||
}
|
||||
|
||||
private static void logSignError(String... messages) {
|
||||
if (invalidSignLogLevel == Level.OFF) {
|
||||
return;
|
||||
}
|
||||
if (invalidSignLogLevel == Level.SEVERE) {
|
||||
AreaShop.error((Object) messages);
|
||||
} else if (invalidSignLogLevel == Level.WARNING) {
|
||||
AreaShop.warn((Object) messages);
|
||||
} else if (invalidSignLogLevel.intValue() >= Level.FINE.intValue()) {
|
||||
AreaShop.debug((Object) messages);
|
||||
} else {
|
||||
AreaShop.info((Object) messages);
|
||||
}
|
||||
}
|
||||
|
||||
private final SignsFeature signsFeature;
|
||||
private final String key;
|
||||
|
||||
@@ -109,7 +151,7 @@ public class RegionSign {
|
||||
/**
|
||||
* 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.
|
||||
* @return Material of the sign, usually, a sign or {@link Material#AIR} if none.
|
||||
*/
|
||||
public Material getMaterial() {
|
||||
String name = getRegion().getConfig().getString("general.signs." + key + ".signType");
|
||||
@@ -156,30 +198,31 @@ public class RegionSign {
|
||||
block.setType(Material.AIR);
|
||||
return true;
|
||||
}
|
||||
final BlockStateSnapshotResult snapshotResult = PaperLib.getBlockState(block, true);
|
||||
final BlockState blockState = snapshotResult.getState();
|
||||
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 (!Materials.isSign(block.getType())) {
|
||||
Material signType = getMaterial();
|
||||
if (signType.name().contains("SIGN")) {
|
||||
final BlockData data = blockState.getBlockData();
|
||||
// Don't do physics here, we first need to update the direction
|
||||
blockState.setType(signType);
|
||||
if (data instanceof WallSign) {
|
||||
((WallSign) data).setFacing(getFacing());
|
||||
} else if (data instanceof Sign) {
|
||||
((org.bukkit.block.data.type.Sign) data).setRotation(getFacing());
|
||||
}
|
||||
blockState.setBlockData(data);
|
||||
blockState.update(false, false);
|
||||
// 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;
|
||||
}
|
||||
} else {
|
||||
AreaShop.warn("Setting sign", key, "of region", getRegion().getName(), "failed, RegionSign material was: " + signType.name());
|
||||
if (!Materials.isSign(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, getRegion().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, getRegion().getName(), signType.name()));
|
||||
}
|
||||
|
||||
// Save current rotation and type
|
||||
@@ -214,7 +257,8 @@ public class RegionSign {
|
||||
signLines[i] = Utils.applyColors(signLines[i]);
|
||||
signState.setLine(i, signLines[i]);
|
||||
}
|
||||
return signState.update(false, false);
|
||||
// BlockState#update *should* return true here.
|
||||
return blockState.update(true, false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
package me.wiefferink.areashop.features.signs;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.events.notify.UpdateRegionEvent;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.world.ChunkLoadEvent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class SignCache implements Listener {
|
||||
|
||||
private final Map<String, RegionSign> allSigns = new HashMap<>();
|
||||
private final Map<String, List<RegionSign>> signsByChunk = new HashMap<>();
|
||||
|
||||
public void registerListeners() {
|
||||
Bukkit.getPluginManager().registerEvents(this, AreaShop.getInstance());
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a location to a string to use as map key.
|
||||
*
|
||||
* @param location The location to get the key for
|
||||
* @return A string to use in a map for a location
|
||||
*/
|
||||
public static String locationToString(Location location) {
|
||||
return location.getWorld().getName() + ";" + location.getBlockX() + ";" + location.getBlockY() + ";" + location.getBlockZ();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a chunk to a string to use as map key.
|
||||
*
|
||||
* @param location The location to get the key for
|
||||
* @return A string to use in a map for a chunk
|
||||
*/
|
||||
public static String chunkToString(Location location) {
|
||||
return location.getWorld().getName() + ";" + (location.getBlockX() >> 4) + ";" + (location.getBlockZ() >> 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a chunk to a string to use as map key.
|
||||
* Use a Location argument to prevent chunk loading!
|
||||
*
|
||||
* @param chunk The location to get the key for
|
||||
* @return A string to use in a map for a chunk
|
||||
*/
|
||||
public static String chunkToString(Chunk chunk) {
|
||||
return chunk.getWorld().getName() + ";" + chunk.getX() + ";" + chunk.getZ();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a sign by a location.
|
||||
*
|
||||
* @param location The location to get the sign for
|
||||
* @return The RegionSign that is at the location, or null if none
|
||||
*/
|
||||
public RegionSign getSignByLocation(Location location) {
|
||||
return allSigns.get(locationToString(location));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the map with all signs.
|
||||
*
|
||||
* @return Map with all signs: locationString -> RegionSign
|
||||
*/
|
||||
public Map<String, RegionSign> getAllSigns() {
|
||||
return allSigns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the map with signs by chunk.
|
||||
*
|
||||
* @return Map with signs by chunk: chunkString -> List<RegionSign>
|
||||
*/
|
||||
public Map<String, List<RegionSign>> getSignsByChunk() {
|
||||
return signsByChunk;
|
||||
}
|
||||
|
||||
public void addSign(RegionSign regionSign) {
|
||||
signsByChunk.computeIfAbsent(regionSign.getStringChunk(), (unused) -> new ArrayList<>()).add(regionSign);
|
||||
}
|
||||
|
||||
public void removeSign(RegionSign regionSign) {
|
||||
final List<RegionSign> signs = signsByChunk.get(regionSign.getStringChunk());
|
||||
if (signs != null) {
|
||||
signs.remove(regionSign);
|
||||
}
|
||||
allSigns.remove(regionSign.getStringLocation());
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
HandlerList.unregisterAll(this);
|
||||
signsByChunk.clear();
|
||||
allSigns.clear();
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void regionUpdate(UpdateRegionEvent event) {
|
||||
event.getRegion().getSignsFeature().update();
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onChunkLoad(ChunkLoadEvent event) {
|
||||
List<RegionSign> chunkSigns = signsByChunk.get(chunkToString(event.getChunk()));
|
||||
if (chunkSigns == null) {
|
||||
return;
|
||||
}
|
||||
int batchSize = Math.max(chunkSigns.size() / 10, 10);
|
||||
Utils.runAsBatches(chunkSigns, batchSize, RegionSign::update, false);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,9 +4,10 @@ import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.events.ask.AddingRegionEvent;
|
||||
import me.wiefferink.areashop.events.notify.UpdateRegionEvent;
|
||||
import me.wiefferink.areashop.features.RegionFeature;
|
||||
import me.wiefferink.areashop.interfaces.BlockBehaviourHelper;
|
||||
import me.wiefferink.areashop.managers.FileManager;
|
||||
import me.wiefferink.areashop.managers.SignErrorLogger;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.regions.RentRegion;
|
||||
@@ -31,14 +32,22 @@ import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.event.block.BlockPhysicsEvent;
|
||||
import org.bukkit.event.block.SignChangeEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.event.world.ChunkLoadEvent;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class SignsFeature extends RegionFeature {
|
||||
|
||||
private static final Map<String, RegionSign> allSigns = Collections.synchronizedMap(new HashMap<>());
|
||||
private static final Map<String, List<RegionSign>> signsByChunk = Collections.synchronizedMap(new HashMap<>());
|
||||
public static final SignCache signCache = new SignCache();
|
||||
|
||||
private static final BlockBehaviourHelper behaviourHelper = AreaShop.getInstance().getNMSHelper().behaviourHelper();
|
||||
|
||||
static {
|
||||
signCache.registerListeners();
|
||||
}
|
||||
|
||||
public static void shutdownGlobalState() {
|
||||
signCache.shutdown();
|
||||
}
|
||||
|
||||
private Map<String, RegionSign> signs;
|
||||
|
||||
@@ -56,19 +65,19 @@ public class SignsFeature extends RegionFeature {
|
||||
signs = new HashMap<>();
|
||||
// Setup current signs
|
||||
ConfigurationSection signSection = region.getConfig().getConfigurationSection("general.signs");
|
||||
SignErrorLogger errorLogger = AreaShop.getInstance().getSignErrorLogger();
|
||||
if (signSection != null) {
|
||||
for (String signKey : signSection.getKeys(false)) {
|
||||
RegionSign sign = new RegionSign(this, signKey);
|
||||
Location location = sign.getLocation();
|
||||
if (location == null) {
|
||||
AreaShop.warn("Sign with key " + signKey + " of region " + region.getName() + " does not have a proper location");
|
||||
final String message = "Sign with key $1%s of region $2%s does not have a proper location";
|
||||
errorLogger.submitWarning(String.format(message, signKey, region.getName()));
|
||||
continue;
|
||||
}
|
||||
signs.put(sign.getStringLocation(), sign);
|
||||
signsByChunk.computeIfAbsent(sign.getStringChunk(), key -> new ArrayList<>())
|
||||
.add(sign);
|
||||
signCache.addSign(sign);
|
||||
}
|
||||
allSigns.putAll(signs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,7 +119,7 @@ public class SignsFeature extends RegionFeature {
|
||||
* @return The RegionSign that is at the location, or null if none
|
||||
*/
|
||||
public static RegionSign getSignByLocation(Location location) {
|
||||
return allSigns.get(locationToString(location));
|
||||
return signCache.getSignByLocation(location);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -119,7 +128,7 @@ public class SignsFeature extends RegionFeature {
|
||||
* @return Map with all signs: locationString -> RegionSign
|
||||
*/
|
||||
public static Map<String, RegionSign> getAllSigns() {
|
||||
return allSigns;
|
||||
return signCache.getAllSigns();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -128,7 +137,7 @@ public class SignsFeature extends RegionFeature {
|
||||
* @return Map with signs by chunk: chunkString -> List<RegionSign>
|
||||
*/
|
||||
public static Map<String, List<RegionSign>> getSignsByChunk() {
|
||||
return signsByChunk;
|
||||
return signCache.getSignsByChunk();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -136,24 +145,26 @@ public class SignsFeature extends RegionFeature {
|
||||
// Deregister signs from the registry
|
||||
if (signs != null) {
|
||||
for (Map.Entry<String, RegionSign> entry : signs.entrySet()) {
|
||||
allSigns.remove(entry.getKey());
|
||||
signsByChunk.get(entry.getValue().getStringChunk()).remove(entry.getValue());
|
||||
signCache.removeSign(entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void onSignBreak(BlockBreakEvent event) {
|
||||
if (event.isCancelled()) {
|
||||
Block block = event.getBlock();
|
||||
RegionSign regionSign = SignsFeature.getSignByLocation(block.getLocation());
|
||||
if (regionSign == null) {
|
||||
return;
|
||||
}
|
||||
Block block = event.getBlock();
|
||||
if (regionSign.getRegion().invalidated()) {
|
||||
AreaShop.warn("SignsFeature: Sign feature for an invalidated region is still active!");
|
||||
}
|
||||
// Check if it is a sign
|
||||
if (Materials.isSign(block.getType())) {
|
||||
// Check if the rent sign is really the same as a saved rent
|
||||
RegionSign regionSign = SignsFeature.getSignByLocation(block.getLocation());
|
||||
if (regionSign == null) {
|
||||
return;
|
||||
if (regionSign.getRegion().invalidated()) {
|
||||
AreaShop.warn("SignsFeature: Sign feature for an invalidated region object is still active!");
|
||||
}
|
||||
// Remove the sign of the rental region if the player has permission
|
||||
if (event.getPlayer().hasPermission("areashop.delsign")) {
|
||||
@@ -168,26 +179,7 @@ public class SignsFeature extends RegionFeature {
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onIndirectSignBreak(BlockPhysicsEvent event) {
|
||||
// Check if the block is a sign
|
||||
if (!Materials.isSign(event.getBlock().getType())) {
|
||||
return;
|
||||
}
|
||||
final Block block = event.getBlock();
|
||||
final BlockData blockData = block.getBlockData();
|
||||
final Block attachedBlock;
|
||||
if (blockData instanceof WallSign) {
|
||||
attachedBlock = block.getRelative(((WallSign) blockData).getFacing().getOppositeFace());
|
||||
} else if (blockData instanceof Sign) {
|
||||
attachedBlock = block.getRelative(BlockFace.DOWN);
|
||||
} else {
|
||||
attachedBlock = null;
|
||||
}
|
||||
|
||||
// Check if still attached to a block
|
||||
// TODO: signs cannot be placed on all blocks, improve this check to isSolid()?
|
||||
if (attachedBlock == null || attachedBlock.getType() != Material.AIR) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the sign is really the same as a saved rent
|
||||
RegionSign regionSign = SignsFeature.getSignByLocation(event.getBlock().getLocation());
|
||||
@@ -195,6 +187,18 @@ public class SignsFeature extends RegionFeature {
|
||||
return;
|
||||
}
|
||||
|
||||
if (regionSign.getRegion().invalidated()) {
|
||||
AreaShop.warn("SignsFeature: Sign feature for an invalidated region is still active!");
|
||||
}
|
||||
// Check if the block is a sign
|
||||
if (!Materials.isSign(event.getBlock().getType())) {
|
||||
return;
|
||||
}
|
||||
// If the block is in an invalid position then we remove the sign
|
||||
if (!behaviourHelper.isBlockValid(block)) {
|
||||
regionSign.remove();
|
||||
}
|
||||
|
||||
// Remove the sign so that it does not fall on the floor as an item (next region update will place it back when possible)
|
||||
AreaShop.debug("onIndirectSignBreak: Removed block of sign for", regionSign.getRegion().getName(), "at", regionSign.getStringLocation());
|
||||
event.getBlock().setType(Material.AIR);
|
||||
@@ -207,6 +211,15 @@ public class SignsFeature extends RegionFeature {
|
||||
if (block == null) {
|
||||
return;
|
||||
}
|
||||
// Check if this sign belongs to a region
|
||||
RegionSign regionSign = SignsFeature.getSignByLocation(block.getLocation());
|
||||
if (regionSign == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (regionSign.getRegion().invalidated()) {
|
||||
AreaShop.warn("SignsFeature: Sign feature for an invalidated region is still active!");
|
||||
}
|
||||
|
||||
// Only listen to left and right clicks on blocks
|
||||
if (!(event.getAction() == Action.RIGHT_CLICK_BLOCK || event.getAction() == Action.LEFT_CLICK_BLOCK)) {
|
||||
@@ -218,11 +231,6 @@ public class SignsFeature extends RegionFeature {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if this sign belongs to a region
|
||||
RegionSign regionSign = SignsFeature.getSignByLocation(block.getLocation());
|
||||
if (regionSign == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Ignore players that are in sign link mode (which will handle the event itself)
|
||||
Player player = event.getPlayer();
|
||||
@@ -248,11 +256,17 @@ public class SignsFeature extends RegionFeature {
|
||||
event.setCancelled(ran);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onSignChange(SignChangeEvent event) {
|
||||
if (event.isCancelled()) {
|
||||
|
||||
RegionSign regionSign = SignsFeature.getSignByLocation(event.getBlock().getLocation());
|
||||
if (regionSign == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (regionSign.getRegion().invalidated()) {
|
||||
AreaShop.warn("SignsFeature: Sign feature for an invalidated region is still active!");
|
||||
}
|
||||
Player player = event.getPlayer();
|
||||
if (!plugin.isReady()) {
|
||||
plugin.message(player, "general-notReady");
|
||||
@@ -532,21 +546,6 @@ public class SignsFeature extends RegionFeature {
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void regionUpdate(UpdateRegionEvent event) {
|
||||
event.getRegion().getSignsFeature().update();
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onChunkLoad(ChunkLoadEvent event) {
|
||||
List<RegionSign> chunkSigns = signsByChunk.get(chunkToString(event.getChunk()));
|
||||
if (chunkSigns == null) {
|
||||
return;
|
||||
}
|
||||
int batchSize = Math.max(chunkSigns.size() / 10, 10);
|
||||
Utils.runAsBatches(chunkSigns, batchSize, RegionSign::update, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update all signs connected to this region.
|
||||
*
|
||||
@@ -629,9 +628,7 @@ public class SignsFeature extends RegionFeature {
|
||||
// Add to the map
|
||||
RegionSign sign = new RegionSign(this, i + "");
|
||||
signs.put(sign.getStringLocation(), sign);
|
||||
allSigns.put(sign.getStringLocation(), sign);
|
||||
signsByChunk.computeIfAbsent(sign.getStringChunk(), key -> new ArrayList<>())
|
||||
.add(sign);
|
||||
signCache.addSign(sign);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -34,17 +34,11 @@ import me.wiefferink.areashop.commands.StackCommand;
|
||||
import me.wiefferink.areashop.commands.StopresellCommand;
|
||||
import me.wiefferink.areashop.commands.TeleportCommand;
|
||||
import me.wiefferink.areashop.commands.UnrentCommand;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.TabCompleter;
|
||||
import org.bukkit.command.*;
|
||||
|
||||
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 {
|
||||
public class CommandManager extends Manager implements TabExecutor {
|
||||
private final ArrayList<CommandAreaShop> commands;
|
||||
|
||||
/**
|
||||
@@ -88,7 +82,6 @@ public class CommandManager extends Manager implements CommandExecutor, TabCompl
|
||||
|
||||
// Register commands in bukkit
|
||||
plugin.getCommand("AreaShop").setExecutor(this);
|
||||
plugin.getCommand("AreaShop").setTabCompleter(this);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -165,10 +158,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());
|
||||
|
||||
@@ -68,6 +68,8 @@ public class FeatureManager extends Manager {
|
||||
for(RegionFeature feature : globalFeatures) {
|
||||
feature.shutdown();
|
||||
}
|
||||
// FIXME make this system less hacky!
|
||||
SignsFeature.shutdownGlobalState();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -154,6 +154,25 @@ public class FileManager extends Manager {
|
||||
return allRegions.get(name.toLowerCase());
|
||||
}
|
||||
|
||||
public CompletableFuture<GeneralRegion> getRegionUnsafe(String name) {
|
||||
final GeneralRegion cached = allRegions.get(name);
|
||||
if (cached != null) {
|
||||
return CompletableFuture.completedFuture(cached);
|
||||
}
|
||||
final File file = new File(regionsPath, name + ".yml");
|
||||
if (!file.exists()) {
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
CompletableFuture<GeneralRegion> completableFuture = new CompletableFuture<>();
|
||||
Utils.newChain()
|
||||
.async(() -> {
|
||||
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(file);
|
||||
completableFuture.complete(loadRegion(configuration));
|
||||
})
|
||||
.execute();
|
||||
return completableFuture;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a rental region.
|
||||
*
|
||||
@@ -292,10 +311,16 @@ public class FileManager extends Manager {
|
||||
// Forcefully remove regions from cache.
|
||||
buyRegions.remove(name);
|
||||
rentRegions.remove(name);
|
||||
final GeneralRegion existing;
|
||||
if (region instanceof BuyRegion) {
|
||||
buyRegions.put(region.getName().toLowerCase(), (BuyRegion) region);
|
||||
existing = buyRegions.put(region.getName().toLowerCase(), (BuyRegion) region);
|
||||
} else if (region instanceof RentRegion) {
|
||||
rentRegions.put(region.getName().toLowerCase(), (RentRegion) region);
|
||||
existing = rentRegions.put(region.getName().toLowerCase(), (RentRegion) region);
|
||||
} else {
|
||||
existing = null;
|
||||
}
|
||||
if (existing != null) {
|
||||
AreaShop.debug("FileManager: Region ", existing.getName(), " was overwritten.");
|
||||
}
|
||||
allRegions.put(region.getName().toLowerCase(), region);
|
||||
Bukkit.getPluginManager().callEvent(new AddedRegionEvent(region));
|
||||
@@ -865,6 +890,9 @@ public class FileManager extends Manager {
|
||||
* Load all region files.
|
||||
*/
|
||||
public void loadRegionFiles() {
|
||||
buyRegions.values().forEach(GeneralRegion::invalidate);
|
||||
buyRegions.clear();
|
||||
rentRegions.values().forEach(GeneralRegion::invalidate);
|
||||
rentRegions.clear();
|
||||
buyRegions.clear();
|
||||
allRegions.clear();
|
||||
@@ -880,6 +908,20 @@ public class FileManager extends Manager {
|
||||
}
|
||||
}
|
||||
|
||||
private GeneralRegion loadRegion(YamlConfiguration config) {
|
||||
// Construct the correct type of region
|
||||
String type = config.getString("general.type");
|
||||
GeneralRegion region;
|
||||
if (RegionType.RENT.getValue().equals(type)) {
|
||||
region = new RentRegion(config);
|
||||
} else if (RegionType.BUY.getValue().equals(type)) {
|
||||
region = new BuyRegion(config);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
return region;
|
||||
}
|
||||
|
||||
private void loadRegionFilesNow() {
|
||||
File file = new File(regionsPath);
|
||||
File[] regionFiles = file.listFiles();
|
||||
@@ -911,17 +953,11 @@ public class FileManager extends Manager {
|
||||
}
|
||||
|
||||
// Construct the correct type of region
|
||||
String type = regionConfig.getString("general.type");
|
||||
GeneralRegion region;
|
||||
if (RegionType.RENT.getValue().equals(type)) {
|
||||
region = new RentRegion(regionConfig);
|
||||
} else if (RegionType.BUY.getValue().equals(type)) {
|
||||
region = new BuyRegion(regionConfig);
|
||||
} else {
|
||||
GeneralRegion region = loadRegion(regionConfig);
|
||||
if (region == null) {
|
||||
noRegionType.add(regionFile.getPath());
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check consistency
|
||||
boolean added = false;
|
||||
if (region.getName() == null) {
|
||||
|
||||
@@ -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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -366,7 +366,7 @@ public class BuyRegion extends GeneralRegion {
|
||||
r = null;
|
||||
OfflinePlayer oldOwnerPlayer = Bukkit.getOfflinePlayer(oldOwner);
|
||||
String oldOwnerName = getPlayerName();
|
||||
if(oldOwnerPlayer != null && oldOwnerPlayer.getName() != null) {
|
||||
if(oldOwnerPlayer.hasPlayedBefore() && oldOwnerPlayer.getName() != null) {
|
||||
r = plugin.getEconomy().depositPlayer(oldOwnerPlayer, getWorldName(), getResellPrice());
|
||||
oldOwnerName = oldOwnerPlayer.getName();
|
||||
} else if(oldOwnerName != null) {
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,143 +0,0 @@
|
||||
package me.wiefferink.areashop.tools;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.regions.RentRegion;
|
||||
import org.bstats.Metrics;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class Analytics {
|
||||
|
||||
private Analytics() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Start analytics tracking.
|
||||
*/
|
||||
public static void start() {
|
||||
// bStats statistics
|
||||
try {
|
||||
Metrics metrics = new Metrics(AreaShop.getInstance());
|
||||
|
||||
// Number of regions
|
||||
metrics.addCustomChart(new Metrics.SingleLineChart("region_count") {
|
||||
@Override
|
||||
public int getValue() {
|
||||
return AreaShop.getInstance().getFileManager().getRegions().size();
|
||||
}
|
||||
});
|
||||
|
||||
// Number of rental regions
|
||||
metrics.addCustomChart(new Metrics.SingleLineChart("rental_region_count") {
|
||||
@Override
|
||||
public int getValue() {
|
||||
return AreaShop.getInstance().getFileManager().getRents().size();
|
||||
}
|
||||
});
|
||||
|
||||
// Number of buy regions
|
||||
metrics.addCustomChart(new Metrics.SingleLineChart("buy_region_count") {
|
||||
@Override
|
||||
public int getValue() {
|
||||
return AreaShop.getInstance().getFileManager().getBuys().size();
|
||||
}
|
||||
});
|
||||
|
||||
// Language
|
||||
metrics.addCustomChart(new Metrics.SimplePie("language") {
|
||||
@Override
|
||||
public String getValue() {
|
||||
return AreaShop.getInstance().getConfig().getString("language");
|
||||
}
|
||||
});
|
||||
|
||||
// Pie with region states
|
||||
metrics.addCustomChart(new Metrics.AdvancedPie("region_state") {
|
||||
@Override
|
||||
public HashMap<String, Integer> getValues(HashMap<String, Integer> result) {
|
||||
RegionStateStats stats = getStateStats();
|
||||
result.put("For Rent", stats.forrent);
|
||||
result.put("Rented", stats.rented);
|
||||
result.put("For Sale", stats.forsale);
|
||||
result.put("Sold", stats.sold);
|
||||
result.put("Reselling", stats.reselling);
|
||||
return result;
|
||||
}
|
||||
});
|
||||
|
||||
// Time series of each region state
|
||||
metrics.addCustomChart(new Metrics.SingleLineChart("forrent_region_count") {
|
||||
@Override
|
||||
public int getValue() {
|
||||
return getStateStats().forrent;
|
||||
}
|
||||
});
|
||||
metrics.addCustomChart(new Metrics.SingleLineChart("rented_region_count") {
|
||||
@Override
|
||||
public int getValue() {
|
||||
return getStateStats().rented;
|
||||
}
|
||||
});
|
||||
metrics.addCustomChart(new Metrics.SingleLineChart("forsale_region_count") {
|
||||
@Override
|
||||
public int getValue() {
|
||||
return getStateStats().forsale;
|
||||
}
|
||||
});
|
||||
metrics.addCustomChart(new Metrics.SingleLineChart("sold_region_count") {
|
||||
@Override
|
||||
public int getValue() {
|
||||
return getStateStats().sold;
|
||||
}
|
||||
});
|
||||
metrics.addCustomChart(new Metrics.SingleLineChart("reselling_region_count") {
|
||||
@Override
|
||||
public int getValue() {
|
||||
return getStateStats().reselling;
|
||||
}
|
||||
});
|
||||
|
||||
// TODO track rent/buy/unrent/sell/resell actions (so that it can be reported per collection interval)
|
||||
|
||||
AreaShop.debug("Started bstats.org statistics service");
|
||||
} catch(Exception e) {
|
||||
AreaShop.debug("Could not start bstats.org statistics service");
|
||||
}
|
||||
}
|
||||
|
||||
private static class RegionStateStats {
|
||||
int forrent = 0;
|
||||
int forsale = 0;
|
||||
int rented = 0;
|
||||
int sold = 0;
|
||||
int reselling = 0;
|
||||
}
|
||||
|
||||
private static RegionStateStats getStateStats() {
|
||||
RegionStateStats result = new RegionStateStats();
|
||||
for(GeneralRegion region : AreaShop.getInstance().getFileManager().getRegions()) {
|
||||
if(region instanceof RentRegion) {
|
||||
RentRegion rent = (RentRegion)region;
|
||||
if(rent.isAvailable()) {
|
||||
result.forrent++;
|
||||
} else {
|
||||
result.rented++;
|
||||
}
|
||||
} else if(region instanceof BuyRegion) {
|
||||
BuyRegion buy = (BuyRegion)region;
|
||||
if(buy.isAvailable()) {
|
||||
result.forsale++;
|
||||
} else if(buy.isInResellingMode()) {
|
||||
result.reselling++;
|
||||
} else {
|
||||
result.sold++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
package me.wiefferink.areashop.tools;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonObject;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.lang.exception.ExceptionUtils;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.JSONValue;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
@@ -18,234 +18,242 @@ import java.util.logging.Logger;
|
||||
|
||||
public class GithubUpdateCheck {
|
||||
|
||||
public static final String API_HOST = "https://api.github.com/repos";
|
||||
public static final String API_LATEST_RELEASE = "releases/latest";
|
||||
public static final String USER_AGENT = "GithubUpdateCheck by NLThijs48";
|
||||
public static final boolean DEBUG = false;
|
||||
public static final String API_HOST = "https://api.github.com/repos";
|
||||
public static final String API_LATEST_RELEASE = "releases/latest";
|
||||
public static final String USER_AGENT = "GithubUpdateCheck by NLThijs48";
|
||||
public static final boolean DEBUG = false;
|
||||
private static final Gson GSON = new GsonBuilder().create();
|
||||
|
||||
private final String author;
|
||||
private final String repository;
|
||||
private final Plugin plugin;
|
||||
private final Logger logger;
|
||||
private URL url;
|
||||
private VersionComparator versionComparator;
|
||||
private final String author;
|
||||
private final String repository;
|
||||
private final Plugin plugin;
|
||||
private final Logger logger;
|
||||
private final String currentVersion;
|
||||
private URL url;
|
||||
private VersionComparator versionComparator;
|
||||
// Status
|
||||
private boolean checking;
|
||||
private boolean error;
|
||||
private boolean hasUpdate;
|
||||
private String latestVersion;
|
||||
|
||||
// Status
|
||||
private boolean checking;
|
||||
private boolean error;
|
||||
private boolean hasUpdate;
|
||||
private String latestVersion;
|
||||
private final String currentVersion;
|
||||
/**
|
||||
* Create a new GithubUpdateCheck with the required information.
|
||||
*
|
||||
* @param plugin The plugin to create it for (used for logging and checking version)
|
||||
* @param author The author of the plugin as used on Github
|
||||
* @param repository The repository name of the plugin on Github
|
||||
*/
|
||||
public GithubUpdateCheck(Plugin plugin, String author, String repository) {
|
||||
this.plugin = plugin;
|
||||
this.logger = plugin.getLogger();
|
||||
this.author = author;
|
||||
this.repository = repository;
|
||||
this.currentVersion = plugin.getDescription().getVersion();
|
||||
this.versionComparator = (latest, current) ->
|
||||
!latest.equalsIgnoreCase(current);
|
||||
|
||||
/**
|
||||
* Create a new GithubUpdateCheck with the required information.
|
||||
* @param plugin The plugin to create it for (used for logging and checking version)
|
||||
* @param author The author of the plugin as used on Github
|
||||
* @param repository The repository name of the plugin on Github
|
||||
*/
|
||||
public GithubUpdateCheck(Plugin plugin, String author, String repository) {
|
||||
this.plugin = plugin;
|
||||
this.logger = plugin.getLogger();
|
||||
this.author = author;
|
||||
this.repository = repository;
|
||||
this.currentVersion = plugin.getDescription().getVersion();
|
||||
this.versionComparator = (latest, current) ->
|
||||
!latest.equalsIgnoreCase(current);
|
||||
this.checking = false;
|
||||
this.error = false;
|
||||
this.hasUpdate = false;
|
||||
}
|
||||
|
||||
this.checking = false;
|
||||
this.error = false;
|
||||
this.hasUpdate = false;
|
||||
}
|
||||
/**
|
||||
* Change the version comparator.
|
||||
*
|
||||
* @param versionComparator VersionComparator to use for checking if one version is newer than the other
|
||||
* @return this
|
||||
*/
|
||||
public GithubUpdateCheck withVersionComparator(VersionComparator versionComparator) {
|
||||
this.versionComparator = versionComparator;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the version comparator.
|
||||
* @param versionComparator VersionComparator to use for checking if one version is newer than the other
|
||||
* @return this
|
||||
*/
|
||||
public GithubUpdateCheck withVersionComparator(VersionComparator versionComparator) {
|
||||
this.versionComparator = versionComparator;
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Check if an update is available.
|
||||
*/
|
||||
public void checkUpdate() {
|
||||
checkUpdate(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an update is available.
|
||||
*/
|
||||
public void checkUpdate() {
|
||||
checkUpdate(null);
|
||||
}
|
||||
/**
|
||||
* Check if an update is available.
|
||||
*
|
||||
* @param callback Callback to execute when the update check is done
|
||||
* @return GithubUpdateCheck containing the status of the check
|
||||
*/
|
||||
public GithubUpdateCheck checkUpdate(UpdateCallback callback) {
|
||||
checking = true;
|
||||
final GithubUpdateCheck self = this;
|
||||
// Check for update on async thread
|
||||
Utils.newChain()
|
||||
.async(() -> {
|
||||
try {
|
||||
try {
|
||||
String rawUrl = API_HOST + "/" + author + "/" + repository + "/" + API_LATEST_RELEASE;
|
||||
url = new URL(rawUrl);
|
||||
} catch (MalformedURLException e) {
|
||||
logger.severe("Invalid url: '" + url + "', are the author '" + author + "' and repository '" + repository + "' correct?");
|
||||
error = true;
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an update is available.
|
||||
* @param callback Callback to execute when the update check is done
|
||||
* @return GithubUpdateCheck containing the status of the check
|
||||
*/
|
||||
public GithubUpdateCheck checkUpdate(UpdateCallback callback) {
|
||||
checking = true;
|
||||
final GithubUpdateCheck self = this;
|
||||
// Check for update on asyn thread
|
||||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
try {
|
||||
String rawUrl = API_HOST + "/" + author + "/" + repository + "/" + API_LATEST_RELEASE;
|
||||
url = new URL(rawUrl);
|
||||
} catch(MalformedURLException e) {
|
||||
logger.severe("Invalid url: '" + url + "', are the author '" + author + "' and repository '" + repository + "' correct?");
|
||||
error = true;
|
||||
return;
|
||||
}
|
||||
try {
|
||||
URLConnection conn = url.openConnection();
|
||||
// Give up after 15 seconds
|
||||
conn.setConnectTimeout(15000);
|
||||
// Identify ourselves
|
||||
conn.addRequestProperty("User-Agent", USER_AGENT);
|
||||
// Make sure we access the correct api version
|
||||
conn.addRequestProperty("Accept", "application/vnd.github.v3+json");
|
||||
// We want to read the result
|
||||
conn.setDoOutput(true);
|
||||
// Open connection
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {
|
||||
String response = reader.readLine();
|
||||
debug("Response:", response);
|
||||
|
||||
try {
|
||||
URLConnection conn = url.openConnection();
|
||||
// Give up after 15 seconds
|
||||
conn.setConnectTimeout(15000);
|
||||
// Identify ourselves
|
||||
conn.addRequestProperty("User-Agent", USER_AGENT);
|
||||
// Make sure we access the correct api version
|
||||
conn.addRequestProperty("Accept", "application/vnd.github.v3+json");
|
||||
// We want to read the result
|
||||
conn.setDoOutput(true);
|
||||
// Open connection
|
||||
try(BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {
|
||||
String response = reader.readLine();
|
||||
debug("Response:", response);
|
||||
JsonObject latestRelease = GSON.fromJson(response, JsonObject.class);
|
||||
|
||||
JSONObject latestRelease = (JSONObject)JSONValue.parse(response);
|
||||
if (latestRelease.isJsonNull()) {
|
||||
logger.warning("Failed to get api response from " + url);
|
||||
error = true;
|
||||
return;
|
||||
}
|
||||
debug("json: " + latestRelease.toString());
|
||||
|
||||
if(latestRelease.isEmpty()) {
|
||||
logger.warning("Failed to get api response from " + url);
|
||||
error = true;
|
||||
return;
|
||||
}
|
||||
debug("json: " + latestRelease.toJSONString());
|
||||
// Latest version
|
||||
latestVersion = latestRelease.get("tag_name").getAsString();
|
||||
debug("Tag name:", latestVersion);
|
||||
|
||||
// Latest version
|
||||
latestVersion = (String)latestRelease.get("tag_name");
|
||||
debug("Tag name:", latestVersion);
|
||||
// Current version
|
||||
debug("Plugin version:", currentVersion);
|
||||
|
||||
// Current version
|
||||
debug("Plugin version:", currentVersion);
|
||||
// Compare version
|
||||
hasUpdate = versionComparator.isNewer(latestVersion, currentVersion);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logger.severe("Failed to get latest release:" + ExceptionUtils
|
||||
.getStackTrace(e));
|
||||
error = true;
|
||||
} catch (ClassCastException e) {
|
||||
logger.info("Unexpected structure of the result, failed to parse it");
|
||||
error = true;
|
||||
}
|
||||
} finally {
|
||||
checking = false;
|
||||
debug("result:", self);
|
||||
}
|
||||
}
|
||||
).syncLast(x -> {
|
||||
if (callback != null) {
|
||||
callback.run(this);
|
||||
}
|
||||
}).execute();
|
||||
return this;
|
||||
}
|
||||
|
||||
// Compare version
|
||||
hasUpdate = versionComparator.isNewer(latestVersion, currentVersion);
|
||||
}
|
||||
} catch(IOException e) {
|
||||
logger.severe("Failed to get latest release:" + ExceptionUtils.getStackTrace(e));
|
||||
error = true;
|
||||
} catch(ClassCastException e) {
|
||||
logger.info("Unexpected structure of the result, failed to parse it");
|
||||
error = true;
|
||||
}
|
||||
} finally {
|
||||
checking = false;
|
||||
debug("result:", self);
|
||||
if(callback != null) {
|
||||
// Switch back to main thread and call the callback
|
||||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
callback.run(self);
|
||||
}
|
||||
}.runTask(plugin);
|
||||
}
|
||||
}
|
||||
}
|
||||
}.runTaskAsynchronously(plugin);
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Check if an update check is running.
|
||||
*
|
||||
* @return true if an update check is running
|
||||
*/
|
||||
public boolean isChecking() {
|
||||
return checking;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an update check is running.
|
||||
* @return true if an update check is running
|
||||
*/
|
||||
public boolean isChecking() {
|
||||
return checking;
|
||||
}
|
||||
/**
|
||||
* Check if the update check failed.
|
||||
*
|
||||
* @return true if the update check failed (an error message has been logged)
|
||||
*/
|
||||
public boolean hasFailed() {
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the update check failed.
|
||||
* @return true if the update check failed (an error message has been logged)
|
||||
*/
|
||||
public boolean hasFailed() {
|
||||
return error;
|
||||
}
|
||||
/**
|
||||
* Check if an update has been found.
|
||||
*
|
||||
* @return true if an update has been found
|
||||
*/
|
||||
public boolean hasUpdate() {
|
||||
return hasUpdate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an update has been found.
|
||||
* @return true if an update has been found
|
||||
*/
|
||||
public boolean hasUpdate() {
|
||||
return hasUpdate;
|
||||
}
|
||||
/**
|
||||
* Get the repository that this update checker is checking.
|
||||
*
|
||||
* @return Used repository
|
||||
*/
|
||||
public String getRepository() {
|
||||
return repository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the repository that this update checker is checking.
|
||||
* @return Used repository
|
||||
*/
|
||||
public String getRepository() {
|
||||
return repository;
|
||||
}
|
||||
/**
|
||||
* Get the author that this update checker is checking.
|
||||
*
|
||||
* @return Used author
|
||||
*/
|
||||
public String getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the author that this update checker is checking.
|
||||
* @return Used author
|
||||
*/
|
||||
public String getAuthor() {
|
||||
return author;
|
||||
}
|
||||
/**
|
||||
* Get the current version.
|
||||
*
|
||||
* @return Current version of the plugin
|
||||
*/
|
||||
public String getCurrentVersion() {
|
||||
return currentVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current version.
|
||||
* @return Current version of the plugin
|
||||
*/
|
||||
public String getCurrentVersion() {
|
||||
return currentVersion;
|
||||
}
|
||||
/**
|
||||
* Get the latest version.
|
||||
*
|
||||
* @return Latest version of the plugin (if checking is complete)
|
||||
*/
|
||||
public String getLatestVersion() {
|
||||
return latestVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the latest version.
|
||||
* @return Latest version of the plugin (if checking is complete)
|
||||
*/
|
||||
public String getLatestVersion() {
|
||||
return latestVersion;
|
||||
}
|
||||
/**
|
||||
* Print a debug message if DEBUG is enabled.
|
||||
*
|
||||
* @param message Message to print
|
||||
*/
|
||||
private void debug(Object... message) {
|
||||
if (DEBUG) {
|
||||
logger.info("[" + this.getClass().getSimpleName() + "] [DEBUG] " + StringUtils
|
||||
.join(message, " "));
|
||||
}
|
||||
}
|
||||
|
||||
public interface VersionComparator {
|
||||
/**
|
||||
* Check if a version should be considered 'newer' than another.
|
||||
* @param latestVersion Version that is available on Github
|
||||
* @param currentVersion Version of the current plugin
|
||||
* @return true if the latestVersion is newer than the localVersion, otherwise false
|
||||
*/
|
||||
boolean isNewer(String latestVersion, String currentVersion);
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return "GithubUpdateCheck(" + StringUtils.join(Arrays.asList(
|
||||
"author=" + author,
|
||||
"repository=" + repository,
|
||||
"plugin=" + plugin.getName(),
|
||||
"checking=" + checking,
|
||||
"hasUpdate=" + hasUpdate,
|
||||
"error=" + error,
|
||||
"currentVersion=" + currentVersion,
|
||||
"latestVersion=" + latestVersion
|
||||
), ", ") + ")";
|
||||
}
|
||||
|
||||
public interface UpdateCallback {
|
||||
void run(GithubUpdateCheck result);
|
||||
}
|
||||
public interface VersionComparator {
|
||||
/**
|
||||
* Check if a version should be considered 'newer' than another.
|
||||
*
|
||||
* @param latestVersion Version that is available on Github
|
||||
* @param currentVersion Version of the current plugin
|
||||
* @return true if the latestVersion is newer than the localVersion, otherwise false
|
||||
*/
|
||||
boolean isNewer(String latestVersion, String currentVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a debug message if DEBUG is enabled.
|
||||
* @param message Message to print
|
||||
*/
|
||||
private void debug(Object... message) {
|
||||
if(DEBUG) {
|
||||
logger.info("[" + this.getClass().getSimpleName() + "] [DEBUG] " + StringUtils.join(message, " "));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "GithubUpdateCheck(" + StringUtils.join(Arrays.asList(
|
||||
"author=" + author,
|
||||
"repository=" + repository,
|
||||
"plugin=" + plugin.getName(),
|
||||
"checking=" + checking,
|
||||
"hasUpdate=" + hasUpdate,
|
||||
"error=" + error,
|
||||
"currentVersion=" + currentVersion,
|
||||
"latestVersion=" + latestVersion
|
||||
), ", ") + ")";
|
||||
}
|
||||
public interface UpdateCallback {
|
||||
void run(GithubUpdateCheck result);
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package me.wiefferink.areashop.tools;
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Tag;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
@@ -11,52 +12,6 @@ import java.util.List;
|
||||
public class Materials {
|
||||
|
||||
private Materials() {
|
||||
|
||||
}
|
||||
|
||||
private static final HashSet<String> WALL_SIGN_TYPES = new HashSet<>(Arrays.asList(
|
||||
// 1.14+ types
|
||||
"ACACIA_WALL_SIGN",
|
||||
"BIRCH_WALL_SIGN",
|
||||
"DARK_OAK_WALL_SIGN",
|
||||
"JUNGLE_WALL_SIGN",
|
||||
"OAK_WALL_SIGN",
|
||||
"SPRUCE_WALL_SIGN",
|
||||
|
||||
// Legacy types
|
||||
"LEGACY_WALL_SIGN",
|
||||
"WALL_SIGN"
|
||||
));
|
||||
private static final HashSet<String> FLOOR_SIGN_TYPES = new HashSet<>(Arrays.asList(
|
||||
// 1.14+ types
|
||||
"ACACIA_SIGN",
|
||||
"BIRCH_SIGN",
|
||||
"DARK_OAK_SIGN",
|
||||
"JUNGLE_SIGN",
|
||||
"OAK_SIGN",
|
||||
"SPRUCE_SIGN",
|
||||
|
||||
// Legacy types
|
||||
"LEGACY_SIGN",
|
||||
"LEGACY_SIGN_POST",
|
||||
"SIGN",
|
||||
"SIGN_POST"
|
||||
));
|
||||
|
||||
private static boolean legacyMaterials = false;
|
||||
|
||||
static {
|
||||
List<String> legacyMaterialVersions = Arrays.asList("1.7", "1.8", "1.9", "1.10", "1.11", "1.12");
|
||||
for(String legacyMaterialVersion : legacyMaterialVersions) {
|
||||
String version = Bukkit.getBukkitVersion();
|
||||
// Detects '1.8', '1.8.3', '1.8-pre1' style versions
|
||||
if(version.equals(legacyMaterialVersion)
|
||||
|| version.startsWith(legacyMaterialVersion + ".")
|
||||
|| version.startsWith(legacyMaterialVersion + "-")) {
|
||||
legacyMaterials = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -69,46 +24,12 @@ public class Materials {
|
||||
if (!isSign(name)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Material result = null;
|
||||
if (legacyMaterials) {
|
||||
// 1.12 and lower just know SIGN_POST, WALL_SIGN and SIGN
|
||||
if (FLOOR_SIGN_TYPES.contains(name)) {
|
||||
result = Material.getMaterial("SIGN_POST");
|
||||
} else if (WALL_SIGN_TYPES.contains(name)) {
|
||||
result = Material.getMaterial("WALL_SIGN");
|
||||
if (result == null) {
|
||||
result = Material.getMaterial("SIGN");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Try saved name (works for wood types on 1.14, regular types for below)
|
||||
result = Material.getMaterial(name);
|
||||
if (result == null) {
|
||||
// Cases for 1.13, which don't know wood types, but need new materials
|
||||
if (FLOOR_SIGN_TYPES.contains(name)) {
|
||||
// SIGN -> OAK_SIGN for 1.14
|
||||
result = Material.getMaterial("OAK_SIGN");
|
||||
// Fallback for 1.13
|
||||
if (result == null) {
|
||||
result = Material.getMaterial("SIGN");
|
||||
}
|
||||
} else if (WALL_SIGN_TYPES.contains(name)) {
|
||||
// WALL_SIGN -> OAK_WALL_SIGN for 1.14
|
||||
result = Material.getMaterial("OAK_WALL_SIGN");
|
||||
// Fallback for 1.13
|
||||
if (result == null) {
|
||||
result = Material.getMaterial("WALL_SIGN");
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
return Material.matchMaterial(name);
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
AreaShop.debug("Materials.get() null result:", name);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (result == null) {
|
||||
AreaShop.debug("Materials.get() null result:", name, "legacyMaterials:", legacyMaterials);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -117,7 +38,7 @@ public class Materials {
|
||||
* @return true if the given material is a sign
|
||||
*/
|
||||
public static boolean isSign(Material material) {
|
||||
return isSign(material.name());
|
||||
return Tag.SIGNS.isTagged(material) || Tag.WALL_SIGNS.isTagged(material);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -126,7 +47,12 @@ public class Materials {
|
||||
* @return true if the given material is a sign
|
||||
*/
|
||||
public static boolean isSign(String name) {
|
||||
return name != null && (FLOOR_SIGN_TYPES.contains(name) || WALL_SIGN_TYPES.contains(name));
|
||||
try {
|
||||
return isSign(Material.matchMaterial(name));
|
||||
} catch (IllegalArgumentException ex) {
|
||||
AreaShop.debug("Invalid Material: " + name + " passed when performing sign check.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
package me.wiefferink.areashop.tools;
|
||||
|
||||
/**
|
||||
* Parse math from a string
|
||||
* Adapted from:
|
||||
* https://stackoverflow.com/questions/3422673/how-to-evaluate-a-math-expression-given-in-string-form
|
||||
*/
|
||||
public final class OperandParser {
|
||||
|
||||
private final String str;
|
||||
|
||||
private OperandParser(final String str) {
|
||||
this.str = str;
|
||||
}
|
||||
|
||||
public static double parse(final String str) throws ParseException {
|
||||
return new OperandParser(str).parse();
|
||||
}
|
||||
|
||||
|
||||
private int pos = -1, ch;
|
||||
|
||||
private void nextChar() {
|
||||
ch = (++pos < str.length()) ? str.charAt(pos) : -1;
|
||||
}
|
||||
|
||||
private boolean eat(int charToEat) {
|
||||
while (ch == ' ') nextChar();
|
||||
if (ch == charToEat) {
|
||||
nextChar();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private double parse() throws ParseException {
|
||||
nextChar();
|
||||
double x = parseExpression();
|
||||
if (pos < str.length())
|
||||
{
|
||||
throw new ParseException("Unexpected: " + (char) ch);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
// Grammar:
|
||||
// expression = term | expression `+` term | expression `-` term
|
||||
// term = factor | term `*` factor | term `/` factor
|
||||
// factor = `+` factor | `-` factor | `(` expression `)`
|
||||
// | number | functionName factor | factor `^` factor
|
||||
|
||||
private double parseExpression() throws ParseException {
|
||||
double x = parseTerm();
|
||||
for (; ; ) {
|
||||
if (eat('+')) {
|
||||
// addition
|
||||
x += parseTerm();
|
||||
}
|
||||
else if (eat('-')) {
|
||||
// subtraction
|
||||
x -= parseTerm();
|
||||
}
|
||||
else return x;
|
||||
}
|
||||
}
|
||||
|
||||
private double parseTerm() throws ParseException {
|
||||
double x = parseFactor();
|
||||
for (; ; ) {
|
||||
if (eat('*')) {
|
||||
// multiplication
|
||||
x *= parseFactor();
|
||||
}
|
||||
else if (eat('/')) {
|
||||
// division
|
||||
x /= parseFactor();
|
||||
}
|
||||
else return x;
|
||||
}
|
||||
}
|
||||
|
||||
private double parseFactor() throws ParseException {
|
||||
if (eat('+')) {
|
||||
// unary plus
|
||||
return parseFactor();
|
||||
}
|
||||
if (eat('-')) {
|
||||
// unary minus
|
||||
return -parseFactor();
|
||||
}
|
||||
|
||||
double x;
|
||||
int startPos = this.pos;
|
||||
if (eat('(')) {
|
||||
// parentheses
|
||||
x = parseExpression();
|
||||
eat(')');
|
||||
} else if ((ch >= '0' && ch <= '9') || ch == '.') {
|
||||
// numbers
|
||||
while ((ch >= '0' && ch <= '9') || ch == '.') {
|
||||
nextChar();
|
||||
}
|
||||
x = Double.parseDouble(str.substring(startPos, this.pos));
|
||||
} else if (ch >= 'a' && ch <= 'z') {
|
||||
// functions
|
||||
while (ch >= 'a' && ch <= 'z') {
|
||||
nextChar();
|
||||
}
|
||||
String func = str.substring(startPos, this.pos);
|
||||
x = parseFactor();
|
||||
x = switch (func) {
|
||||
case "sqrt" -> Math.sqrt(x);
|
||||
case "sin" -> Math.sin(Math.toRadians(x));
|
||||
case "cos" -> Math.cos(Math.toRadians(x));
|
||||
case "tan" -> Math.tan(Math.toRadians(x));
|
||||
default -> throw new ParseException("Unknown function: " + func);
|
||||
};
|
||||
} else {
|
||||
throw new ParseException("Unexpected: " + (char) ch);
|
||||
}
|
||||
|
||||
if (eat('^')) {
|
||||
// exponentiation
|
||||
x = Math.pow(x, parseFactor());
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
public static class ParseException extends Exception {
|
||||
|
||||
public ParseException() {
|
||||
}
|
||||
|
||||
public ParseException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public ParseException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public ParseException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public ParseException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -12,7 +12,10 @@ import me.wiefferink.areashop.regions.RentRegion;
|
||||
import me.wiefferink.interactivemessenger.Log;
|
||||
import me.wiefferink.interactivemessenger.processing.Message;
|
||||
import org.apache.commons.lang.exception.ExceptionUtils;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.configuration.Configuration;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
@@ -22,10 +25,6 @@ import org.bukkit.scheduler.BukkitRunnable;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import javax.script.ScriptEngine;
|
||||
import javax.script.ScriptEngineManager;
|
||||
import javax.script.ScriptException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.*;
|
||||
@@ -46,7 +45,6 @@ public class Utils {
|
||||
private static Set<String> weeks;
|
||||
private static Set<String> months;
|
||||
private static Set<String> years;
|
||||
private static ScriptEngine scriptEngine;
|
||||
private static Map<Double, String> suffixes;
|
||||
|
||||
// Not used
|
||||
@@ -156,19 +154,8 @@ public class Utils {
|
||||
*
|
||||
* @return Online players
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Collection<? extends Player> getOnlinePlayers() {
|
||||
try {
|
||||
Method onlinePlayerMethod = Server.class.getMethod("getOnlinePlayers");
|
||||
if (onlinePlayerMethod.getReturnType().equals(Collection.class)) {
|
||||
return ((Collection<? extends Player>) onlinePlayerMethod.invoke(Bukkit.getServer()));
|
||||
} else {
|
||||
return Arrays.asList((Player[]) onlinePlayerMethod.invoke(Bukkit.getServer()));
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
AreaShop.debug("getOnlinePlayers error: " + ex.getMessage());
|
||||
}
|
||||
return new HashSet<>();
|
||||
return Bukkit.getOnlinePlayers();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -779,16 +766,11 @@ public class Utils {
|
||||
return Double.parseDouble(input);
|
||||
}
|
||||
|
||||
// Lazy init scriptEngine
|
||||
if (scriptEngine == null) {
|
||||
scriptEngine = new ScriptEngineManager().getEngineByName("JavaScript");
|
||||
}
|
||||
|
||||
// Evaluate expression
|
||||
Object result;
|
||||
try {
|
||||
result = scriptEngine.eval(input);
|
||||
} catch (ScriptException e) {
|
||||
result = OperandParser.parse(input);
|
||||
} catch (OperandParser.ParseException e) {
|
||||
AreaShop.warn("Price of region", region.getName(), "is set with an invalid expression: '" + input + "', exception:", ExceptionUtils.getStackTrace(e));
|
||||
return 99999999999.0; // High fallback for safety
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
name: AreaShop
|
||||
main: me.wiefferink.areashop.AreaShop
|
||||
version: "${project.version}"
|
||||
version: "@version@"
|
||||
description: "Selling and renting WorldGuard regions to your players, highly configurable."
|
||||
depend: [Vault, WorldGuard, WorldEdit]
|
||||
softdepend: [Multiverse-Core, FastAsyncWorldEdit]
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
}
|
||||
|
||||
group = "me.wiefferink.areashop"
|
||||
version = '2.6.6'
|
||||
|
||||
subprojects {
|
||||
|
||||
plugins.apply('java')
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven {
|
||||
name = 'paper-repo'
|
||||
url = uri('https://papermc.io/repo/repository/maven-public/')
|
||||
}
|
||||
maven {
|
||||
name = 'spigot-repo'
|
||||
url = uri('https://hub.spigotmc.org/nexus/content/repositories/snapshots/')
|
||||
}
|
||||
maven {
|
||||
name = 'jitpack'
|
||||
url = uri('https://jitpack.io')
|
||||
content {
|
||||
includeGroupByRegex("com\\.github.*")
|
||||
}
|
||||
}
|
||||
maven {
|
||||
name = 'aikar-repo'
|
||||
url = uri('https://repo.aikar.co/content/groups/aikar/')
|
||||
}
|
||||
maven {
|
||||
name = 'enginehub-repo'
|
||||
url = uri('https://maven.enginehub.org/repo/')
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType(JavaCompile) {
|
||||
tasks.withType(JavaCompile) {
|
||||
javaToolchains.compilerFor {
|
||||
JavaLanguageVersion.of(16)
|
||||
}
|
||||
options.release.set(16)
|
||||
options.encoding = 'UTF-8'
|
||||
options.fork = true
|
||||
options.deprecation = true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
org.gradle.parallel=true
|
||||
org.gradle.java.installations.auto-download=false
|
||||
Vendored
BIN
Binary file not shown.
+5
@@ -0,0 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.1-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
@@ -0,0 +1,185 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#
|
||||
# Copyright 2015 the original author or authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
case $i in
|
||||
0) set -- ;;
|
||||
1) set -- "$args0" ;;
|
||||
2) set -- "$args0" "$args1" ;;
|
||||
3) set -- "$args0" "$args1" "$args2" ;;
|
||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=`save "$@"`
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
Vendored
+89
@@ -0,0 +1,89 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
@@ -1,53 +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-fawe-1-15</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>AreaShop FastAsyncWorldEdit 1.15+</name>
|
||||
<version>latest</version>
|
||||
|
||||
<parent>
|
||||
<groupId>me.wiefferink</groupId>
|
||||
<artifactId>areashop-parent</artifactId>
|
||||
<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.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.15.2-R0.1-SNAPSHOT</version>
|
||||
<type>jar</type>
|
||||
<scope>provided</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<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.worldguard</groupId>
|
||||
<artifactId>worldguard-bukkit</artifactId>
|
||||
<version>7.0.3</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>me.wiefferink</groupId>
|
||||
<artifactId>areashop-interface</artifactId>
|
||||
<version>latest</version>
|
||||
<type>jar</type>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</project>
|
||||
-242
@@ -1,242 +0,0 @@
|
||||
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.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.BlockArrayClipboard;
|
||||
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.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.*;
|
||||
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 Mask newMask(final ProtectedRegion region) {
|
||||
return new Mask() {
|
||||
@Override
|
||||
public boolean test(BlockVector3 vector) {
|
||||
return region.contains(vector);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mask2D toMask2D() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mask copy() {
|
||||
return this;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@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 : 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 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;
|
||||
}
|
||||
final FaweLimit limit = new FaweLimit();
|
||||
limit.MAX_CHANGES = pluginInterface.getConfig().getInt("maximumBlocks");
|
||||
EditSession editSession = FaweAPI.getEditSessionBuilder(world).limit(limit).build();
|
||||
editSession.setReorderMode(EditSession.ReorderMode.MULTI_STAGE);
|
||||
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());
|
||||
|
||||
|
||||
// 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));
|
||||
NBTInputStream nbtStream = new NBTInputStream(new GZIPInputStream(bis));
|
||||
ClipboardReader reader = new FastSchematicReader(nbtStream)) {
|
||||
|
||||
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(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 (region.getType() != RegionType.CUBOID) {
|
||||
copy.setSourceMask(newMask(region));
|
||||
}
|
||||
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 = 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 false;
|
||||
}
|
||||
final FaweLimit limit = new FaweLimit();
|
||||
limit.MAX_CHANGES = pluginInterface.getConfig().getInt("maximumBlocks");
|
||||
EditSession editSession = FaweAPI.getEditSessionBuilder(world).limit(limit).relightMode(RelightMode.OPTIMAL).build();
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
repositories {
|
||||
maven {
|
||||
name = 'IS-Repo'
|
||||
url = uri('https://mvn.intellectualsites.com/content/repositories/releases/')
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly project(':areashop-interface')
|
||||
compileOnly 'org.spigotmc:spigot-api:1.16.5-R0.1-SNAPSHOT'
|
||||
compileOnly ('com.intellectualsites.fawe:FAWE-Core:1.16-725')
|
||||
compileOnly ('com.intellectualsites.fawe:FAWE-Bukkit:1.16-725')
|
||||
compileOnly 'com.sk89q.worldguard:worldguard-bukkit:7.0.5'
|
||||
}
|
||||
|
||||
description = 'AreaShop FastAsyncWorldEdit 1.16'
|
||||
+289
@@ -0,0 +1,289 @@
|
||||
package me.wiefferink.areashop.handlers.fawe.v1_16;
|
||||
|
||||
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.boydti.fawe.util.EditSessionBuilder;
|
||||
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.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
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 = new EditSessionBuilder(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 = new EditSessionBuilder(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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
repositories {
|
||||
maven {
|
||||
name = 'IS-Repo'
|
||||
url = uri('https://mvn.intellectualsites.com/content/repositories/releases/')
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly project(':areashop-interface')
|
||||
compileOnly('org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT')
|
||||
compileOnly("com.fastasyncworldedit:FAWE-Core:1.17-138")
|
||||
compileOnly("com.fastasyncworldedit:FAWE-Bukkit:1.17-138")
|
||||
compileOnly('com.sk89q.worldguard:worldguard-bukkit:7.0.5')
|
||||
}
|
||||
|
||||
description = 'AreaShop FastAsyncWorldEdit 1.17'
|
||||
+290
@@ -0,0 +1,290 @@
|
||||
package me.wiefferink.areashop.handlers.fawe.v1_17;
|
||||
|
||||
import com.fastasyncworldedit.core.FaweAPI;
|
||||
import com.fastasyncworldedit.core.extent.clipboard.MemoryOptimizedClipboard;
|
||||
import com.fastasyncworldedit.core.extent.clipboard.io.FastSchematicReader;
|
||||
import com.fastasyncworldedit.core.extent.processor.lighting.RelightMode;
|
||||
import com.fastasyncworldedit.core.object.FaweLimit;
|
||||
import com.fastasyncworldedit.core.util.EditSessionBuilder;
|
||||
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.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
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 = new EditSessionBuilder(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 = new EditSessionBuilder(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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
dependencies {
|
||||
compileOnly 'org.spigotmc:spigot-api:1.16.5-R0.1-SNAPSHOT'
|
||||
compileOnly 'com.sk89q.worldedit:worldedit-bukkit:7.2.5-SNAPSHOT'
|
||||
compileOnly 'com.sk89q.worldguard:worldguard-bukkit:7.0.5'
|
||||
}
|
||||
|
||||
description = 'AreaShop Interface'
|
||||
@@ -1,38 +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>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>
|
||||
+2
-1
@@ -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();
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package me.wiefferink.areashop.interfaces;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
|
||||
public interface BlockBehaviourHelper {
|
||||
|
||||
default boolean canPlace(Location location, Material material) {
|
||||
return canPlace(location, material.createBlockData());
|
||||
}
|
||||
|
||||
boolean canPlace(Location location, BlockData blockData);
|
||||
|
||||
/**
|
||||
* Check if a sign is valid.
|
||||
*
|
||||
* @param block The block
|
||||
* @return Returns true if the sign can exist in that location, false otherwise.
|
||||
*/
|
||||
boolean isBlockValid(Block block);
|
||||
|
||||
boolean isBlockStateValid(BlockState blockState);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package me.wiefferink.areashop.interfaces;
|
||||
|
||||
public interface NMS {
|
||||
|
||||
BlockBehaviourHelper behaviourHelper();
|
||||
|
||||
}
|
||||
+2
-2
@@ -51,9 +51,9 @@ public class RegionAccessSet {
|
||||
* Get this access set as a list of player UUIDs.
|
||||
* @return List of player UUIDs, first players already added by UUID, then players added by name, groups are not in the list
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public List<UUID> asUniqueIdList() {
|
||||
List<UUID> result = new ArrayList<>();
|
||||
result.addAll(playerUniqueIds);
|
||||
List<UUID> result = new ArrayList<>(playerUniqueIds);
|
||||
for(String playerName : playerNames) {
|
||||
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(playerName);
|
||||
if (offlinePlayer.hasPlayedBefore()) {
|
||||
|
||||
+9
@@ -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
-1
@@ -9,7 +9,7 @@ public class WorldEditSelection {
|
||||
private final Location maximum;
|
||||
|
||||
/**
|
||||
* Craete a WorldEditSelection.
|
||||
* Create a WorldEditSelection.
|
||||
* @param world World the selection is in
|
||||
* @param a Primary selection location
|
||||
* @param b Secondary selection location
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
repositories {
|
||||
mavenLocal()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly project(':areashop-interface')
|
||||
compileOnly 'org.spigotmc:spigot:1.16.5-R0.1-SNAPSHOT'
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
package me.wiefferink.areashop.nms.v1_16_R3;
|
||||
|
||||
import me.wiefferink.areashop.interfaces.BlockBehaviourHelper;
|
||||
import net.minecraft.server.v1_16_R3.BlockPosition;
|
||||
import net.minecraft.server.v1_16_R3.IBlockData;
|
||||
import net.minecraft.server.v1_16_R3.World;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.craftbukkit.v1_16_R3.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_16_R3.block.CraftBlock;
|
||||
import org.bukkit.craftbukkit.v1_16_R3.block.CraftBlockState;
|
||||
import org.bukkit.craftbukkit.v1_16_R3.block.data.CraftBlockData;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class BlockBehaviourHelperImpl implements BlockBehaviourHelper {
|
||||
|
||||
@Override
|
||||
public boolean canPlace(Location location, BlockData blockData) {
|
||||
Objects.requireNonNull(location.getWorld(), "Null World!");
|
||||
final BlockPosition blockPosition = new BlockPosition(location.getX(), location.getY(), location.getZ());
|
||||
final CraftWorld craftWorld = (CraftWorld) location.getWorld();
|
||||
final World world = craftWorld.getHandle();
|
||||
final CraftBlockData craftBlockData = (CraftBlockData) blockData;
|
||||
final IBlockData ibd = craftBlockData.getState();
|
||||
return ibd.canPlace(world, blockPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBlockValid(Block block) {
|
||||
final CraftBlock craftBlock = (CraftBlock) block;
|
||||
final CraftWorld craftWorld = (CraftWorld) craftBlock.getWorld();
|
||||
final World world = craftWorld.getHandle();
|
||||
final IBlockData ibd = craftBlock.getNMS();
|
||||
return ibd.canPlace(world, craftBlock.getPosition());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBlockStateValid(BlockState blockState) {
|
||||
final CraftBlockState craftBlockState = (CraftBlockState) blockState;
|
||||
final IBlockData ibd = craftBlockState.getHandle();
|
||||
return ibd.canPlace(craftBlockState.getBlock().getCraftWorld().getHandle(), craftBlockState.getPosition());
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package me.wiefferink.areashop.nms.v1_16_R3;
|
||||
|
||||
import me.wiefferink.areashop.interfaces.BlockBehaviourHelper;
|
||||
import me.wiefferink.areashop.interfaces.NMS;
|
||||
|
||||
public final class NMSImpl implements NMS {
|
||||
|
||||
private BlockBehaviourHelper signHelper = new BlockBehaviourHelperImpl();
|
||||
|
||||
@Override
|
||||
public BlockBehaviourHelper behaviourHelper() {
|
||||
return this.signHelper;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
repositories {
|
||||
mavenLocal()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly project(':areashop-interface')
|
||||
compileOnly 'org.spigotmc:spigot:1.17.1-R0.1-SNAPSHOT'
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
package me.wiefferink.areashop.nms.v1_17_R1;
|
||||
|
||||
import me.wiefferink.areashop.interfaces.BlockBehaviourHelper;
|
||||
import net.minecraft.core.BlockPosition;
|
||||
import net.minecraft.world.level.World;
|
||||
import net.minecraft.world.level.block.state.IBlockData;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.craftbukkit.v1_17_R1.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_17_R1.block.CraftBlock;
|
||||
import org.bukkit.craftbukkit.v1_17_R1.block.CraftBlockState;
|
||||
import org.bukkit.craftbukkit.v1_17_R1.block.data.CraftBlockData;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class BlockBehaviourHelperImpl implements BlockBehaviourHelper {
|
||||
|
||||
@Override
|
||||
public boolean canPlace(Location location, BlockData blockData) {
|
||||
Objects.requireNonNull(location.getWorld(), "Null World!");
|
||||
final BlockPosition blockPosition = new BlockPosition(location.getX(), location.getY(), location.getZ());
|
||||
final CraftWorld craftWorld = (CraftWorld) location.getWorld();
|
||||
final World world = craftWorld.getHandle();
|
||||
final CraftBlockData craftBlockData = (CraftBlockData) blockData;
|
||||
final IBlockData ibd = craftBlockData.getState();
|
||||
return ibd.canPlace(world, blockPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBlockValid(Block block) {
|
||||
final CraftBlock craftBlock = (CraftBlock) block;
|
||||
final CraftWorld craftWorld = (CraftWorld) craftBlock.getWorld();
|
||||
final World world = craftWorld.getHandle();
|
||||
final IBlockData ibd = craftBlock.getNMS();
|
||||
return ibd.canPlace(world, craftBlock.getPosition());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBlockStateValid(BlockState blockState) {
|
||||
final CraftBlockState craftBlockState = (CraftBlockState) blockState;
|
||||
final IBlockData ibd = craftBlockState.getHandle();
|
||||
return ibd.canPlace(craftBlockState.getBlock().getCraftWorld().getHandle(), craftBlockState.getPosition());
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package me.wiefferink.areashop.nms.v1_17_R1;
|
||||
|
||||
import me.wiefferink.areashop.interfaces.BlockBehaviourHelper;
|
||||
import me.wiefferink.areashop.interfaces.NMS;
|
||||
|
||||
public final class NMSImpl implements NMS {
|
||||
|
||||
private BlockBehaviourHelper signHelper = new BlockBehaviourHelperImpl();
|
||||
|
||||
@Override
|
||||
public BlockBehaviourHelper behaviourHelper() {
|
||||
return this.signHelper;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
dependencies {
|
||||
implementation project(':areashop-interface')
|
||||
compileOnly 'org.spigotmc:spigot-api:1.16.5-R0.1-SNAPSHOT'
|
||||
compileOnly 'com.sk89q.worldedit:worldedit-bukkit:7.2.5'
|
||||
compileOnly 'com.sk89q.worldguard:worldguard-bukkit:7.0.5'
|
||||
}
|
||||
|
||||
description = 'AreaShop WorldEdit 7'
|
||||
@@ -1,52 +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</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<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>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>
|
||||
<type>jar</type>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.sk89q.worldedit</groupId>
|
||||
<artifactId>worldedit-bukkit</artifactId>
|
||||
<version>7.0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sk89q.worldguard</groupId>
|
||||
<artifactId>worldguard-bukkit</artifactId>
|
||||
<version>7.0.4-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>me.wiefferink</groupId>
|
||||
<artifactId>areashop-interface</artifactId>
|
||||
<version>latest</version>
|
||||
<type>jar</type>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
+12
-6
@@ -91,9 +91,12 @@ public class WorldEditHandler extends WorldEditInterface {
|
||||
pluginInterface.getLogger().info("Did not restore region " + regionInterface.getName() + ", world not found: " + regionInterface.getWorldName());
|
||||
return false;
|
||||
}
|
||||
EditSession editSession = pluginInterface.getWorldEdit().getWorldEdit() // WARNING Deprecated in 7.2.0!
|
||||
.getEditSessionFactory()
|
||||
.getEditSession(world, pluginInterface.getConfig().getInt("maximumBlocks"));
|
||||
EditSession editSession = pluginInterface.getWorldEdit()
|
||||
.getWorldEdit()
|
||||
.newEditSessionBuilder()
|
||||
.world(world)
|
||||
.maxBlocks(pluginInterface.getConfig().getInt("maximumBlocks"))
|
||||
.build();
|
||||
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());
|
||||
@@ -179,9 +182,12 @@ public class WorldEditHandler extends WorldEditInterface {
|
||||
pluginInterface.getLogger().warning("Did not save region " + regionInterface.getName() + ", world not found: " + regionInterface.getWorldName());
|
||||
return false;
|
||||
}
|
||||
EditSession editSession = pluginInterface.getWorldEdit().getWorldEdit() // WARNING Deprecated in 7.2.0!
|
||||
.getEditSessionFactory()
|
||||
.getEditSession(world, pluginInterface.getConfig().getInt("maximumBlocks"));
|
||||
EditSession editSession = pluginInterface.getWorldEdit()
|
||||
.getWorldEdit()
|
||||
.newEditSessionBuilder()
|
||||
.world(world)
|
||||
.maxBlocks(pluginInterface.getConfig().getInt("maximumBlocks"))
|
||||
.build();
|
||||
|
||||
// Create a clipboard
|
||||
CuboidRegion selection = new CuboidRegion(world, regionInterface.getRegion().getMinimumPoint(), regionInterface.getRegion().getMaximumPoint());
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
dependencies {
|
||||
implementation project(':areashop-interface')
|
||||
compileOnly 'org.spigotmc:spigot-api:1.16.5-R0.1-SNAPSHOT'
|
||||
compileOnly 'com.sk89q.worldedit:worldedit-bukkit:7.2.5'
|
||||
compileOnly 'com.sk89q.worldguard:worldguard-bukkit:7.0.5'
|
||||
}
|
||||
|
||||
description = 'AreaShop WorldGuard 7'
|
||||
@@ -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-worldguard-7</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>AreaShop WorldGuard 7</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>
|
||||
<type>jar</type>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.sk89q.worldedit</groupId>
|
||||
<artifactId>worldedit-bukkit</artifactId>
|
||||
<scope>provided</scope>
|
||||
<version>7.2.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sk89q.worldguard</groupId>
|
||||
<artifactId>worldguard-bukkit</artifactId>
|
||||
<version>7.0.4-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>me.wiefferink</groupId>
|
||||
<artifactId>areashop-interface</artifactId>
|
||||
<version>latest</version>
|
||||
<type>jar</type>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -1,116 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<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>
|
||||
<groupId>me.wiefferink</groupId>
|
||||
<artifactId>areashop-parent</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<version>1.0</version>
|
||||
<name>AreaShop Parent</name>
|
||||
<url>https://github.com/NLthijs48/AreaShop</url>
|
||||
|
||||
<licenses>
|
||||
<license>
|
||||
<name>GNU General Public License v3.0</name>
|
||||
<url>https://www.gnu.org/licenses/gpl-3.0.en.html</url>
|
||||
<distribution>repo</distribution>
|
||||
</license>
|
||||
</licenses>
|
||||
|
||||
<issueManagement>
|
||||
<url>https://github.com/NLthijs48/AreaShop/issues</url>
|
||||
<system>GitHub Issues</system>
|
||||
</issueManagement>
|
||||
|
||||
<ciManagement>
|
||||
<system>Jenkins</system>
|
||||
<url>http://jenkins.wiefferink.me/job/AreaShop</url>
|
||||
</ciManagement>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>vault-repo</id>
|
||||
<url>http://nexus.hc.to/content/repositories/pub_releases</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>wiefferink-repo</id>
|
||||
<url>http://maven.wiefferink.me</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<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-->
|
||||
</properties>
|
||||
|
||||
<modules>
|
||||
<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>
|
||||
<defaultGoal>clean package</defaultGoal>
|
||||
<!--plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.puppycrawl.tools</groupId>
|
||||
<artifactId>checkstyle</artifactId>
|
||||
<version>8.29</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>validate</id>
|
||||
<phase>validate</phase>
|
||||
<configuration>
|
||||
<configLocation>config/checkstyle.xml</configLocation>
|
||||
<suppressionsLocation>config/checkstyle-suppressions.xml</suppressionsLocation>
|
||||
<suppressionsFileExpression>config/checkstyle.suppressions.file
|
||||
</suppressionsFileExpression>
|
||||
<encoding>UTF-8</encoding>
|
||||
<consoleOutput>true</consoleOutput>
|
||||
<failsOnError>true</failsOnError>
|
||||
<violationSeverity>error</violationSeverity>
|
||||
</configuration>
|
||||
<goals>
|
||||
<goal>check</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins-->
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,17 @@
|
||||
rootProject.name = 'areashop-parent'
|
||||
include(':areashop-worldguard-7')
|
||||
include(':areashop-interface')
|
||||
include(':areashop-fawe-1-16')
|
||||
include(':areashop-fawe-1-17')
|
||||
include(':areashop-worldedit-7')
|
||||
include(':areashop-nms-1-16-5')
|
||||
include(':areashop-nms-1-17')
|
||||
include(':areashop')
|
||||
project(":areashop-worldguard-7").projectDir = file('hooks/areashop-worldguard-7')
|
||||
project(":areashop-interface").projectDir = file('hooks/areashop-interface')
|
||||
project(":areashop-fawe-1-16").projectDir = file('hooks/areashop-fawe-1-16')
|
||||
project(":areashop-fawe-1-17").projectDir = file('hooks/areashop-fawe-1-17')
|
||||
project(":areashop-worldedit-7").projectDir = file('hooks/areashop-worldedit-7')
|
||||
project(":areashop-nms-1-16-5").projectDir = file('hooks/areashop-nms-1-16-5')
|
||||
project(":areashop-nms-1-17").projectDir = file('hooks/areashop-nms-1-17')
|
||||
project(":areashop").projectDir = file('AreaShop')
|
||||
Reference in new issue
Block a user